Skip to content

Commit 7b6c9ce

Browse files
Updates to permissions tables generation (#284)
* Account for HTML annotations that are differently formatted * Add check to identify permissions block from annotations * Simplify how we compute where to start looking for the next permissions table after finding the first one
1 parent bf8d5c7 commit 7b6c9ce

File tree

1 file changed

+83
-49
lines changed

1 file changed

+83
-49
lines changed

ApiDoctor.Console/Program.cs

Lines changed: 83 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -2034,7 +2034,8 @@ private static string GenerateSnippetsTabSectionForMethod(MethodDefinition metho
20342034
{
20352035
sampleCodeIncludeText = $"[!INCLUDE [sample-code](../{ReplaceWindowsByLinuxPathSeparators(Path.Combine(relativePathFolder, codeFenceString, versionString, snippetFileName))})]";
20362036
}
2037-
else{
2037+
else
2038+
{
20382039
sampleCodeIncludeText = $"[!INCLUDE [sample-code](../{ReplaceWindowsByLinuxPathSeparators(Path.Combine(relativePathFolder, codeFenceString, snippetFileName))})]";
20392040
}
20402041
var tabText = $"# [{language}](#tab/{codeFenceString})\r\n" +
@@ -2047,7 +2048,7 @@ private static string GenerateSnippetsTabSectionForMethod(MethodDefinition metho
20472048
if (codeSnippet != null)
20482049
{
20492050
var snippetFileContents = "---\r\ndescription: \"Automatically generated file. DO NOT MODIFY\"\r\n---\r\n\r\n" + //header
2050-
$"```{codeFenceString.Replace("cli","bash")}\r\n\r\n" + // code fence
2051+
$"```{codeFenceString.Replace("cli", "bash")}\r\n\r\n" + // code fence
20512052
$"{codeSnippet}\r\n\r\n" + // generated code snippet
20522053
"```"; // closing fence
20532054

@@ -2645,8 +2646,8 @@ private static async Task<bool> GeneratePermissionFilesAsync(GeneratePermissionF
26452646
int foundPermissionTablesOrBlocks = 0, foundHttpRequestBlocks = 0;
26462647
bool finishedParsing = false, isBootstrapped = false, ignorePermissionTableUpdate = false,
26472648
foundAllPermissionTables = false, mergePermissions = false;
2648-
int insertionStartLine = -1, insertionEndLine = -1, httpRequestStartLine = -1, httpRequestEndLine = -1,
2649-
boilerplateStartLine = -1, boilerplateEndLine = -1, permissionsHeaderIndex = -1, codeBlockAnnotationEndLine = -1;
2649+
int insertionStartLine = -1, insertionEndLine = -1, httpRequestStartLine = -1, httpRequestEndLine = -1, boilerplateStartLine = -1,
2650+
boilerplateEndLine = -1, permissionsHeaderIndex = -1, codeBlockAnnotationEndLine = -1, permissionsBlockLineCount = -1;
26502651
string[] requestUrlsForPermissions = null;
26512652
for (var currentIndex = 0; currentIndex < originalFileContents.Length && !finishedParsing; currentIndex++)
26522653
{
@@ -2666,33 +2667,10 @@ private static async Task<bool> GeneratePermissionFilesAsync(GeneratePermissionF
26662667
ignorePermissionTableUpdate = true;
26672668
}
26682669

2669-
// Extract HTML comment
2670-
if (codeBlockAnnotationEndLine != -1 && (requestUrlsForPermissions != null || !mergePermissions))
2671-
{
2672-
var htmlComment = insertionStartLine == codeBlockAnnotationEndLine
2673-
? originalFileContents[insertionStartLine]
2674-
: string.Join(" ", originalFileContents.Skip(insertionStartLine).Take(codeBlockAnnotationEndLine + 1 - insertionStartLine));
2675-
var metadataJsonString = DocFile.StripHtmlCommentTags(htmlComment);
2676-
var annotation = CodeBlockAnnotation.ParseMetadata(metadataJsonString);
2677-
requestUrlsForPermissions = annotation?.RequestUrls;
2678-
mergePermissions = annotation?.MergePermissions ?? false;
2679-
}
2680-
2681-
if (currentLine.StartsWith("<!-- {") || currentLine.Contains("<!--{"))
2682-
{
2683-
insertionStartLine = currentIndex;
2684-
if (currentLine.Contains("} -->") || currentLine.Contains("}-->"))
2685-
{
2686-
codeBlockAnnotationEndLine = currentIndex;
2687-
}
2688-
}
2689-
else if (currentLine.Contains("} -->") || currentLine.Contains("}-->"))
2690-
{
2691-
codeBlockAnnotationEndLine = currentIndex;
2692-
}
2693-
else if (currentLine.Contains("[!INCLUDE [permissions-table](", StringComparison.OrdinalIgnoreCase)) // bootstrapping already took place
2670+
if (currentLine.Contains("[!INCLUDE [permissions-table](", StringComparison.OrdinalIgnoreCase)) // bootstrapping already took place
26942671
{
26952672
foundPermissionTablesOrBlocks++;
2673+
insertionEndLine = currentIndex; // [!INCLUDE [permissions-table]... is the end of the insertion block
26962674
if (ignorePermissionTableUpdate)
26972675
{
26982676
FancyConsole.WriteLine(ConsoleColor.Yellow, $"Skipping update of permissions table ({foundPermissionTablesOrBlocks}) in {docFile.DisplayName}");
@@ -2701,13 +2679,65 @@ private static async Task<bool> GeneratePermissionFilesAsync(GeneratePermissionF
27012679
}
27022680

27032681
isBootstrapped = true;
2682+
27042683
if (!options.BootstrappingOnly)
27052684
{
2706-
insertionEndLine = currentIndex; // [!INCLUDE [permissions-table]... is the end of the insertion block
2707-
parseStatus = (requestUrlsForPermissions?.Length ?? 0) == 0
2708-
? PermissionsInsertionState.FindHttpRequestHeading
2709-
: PermissionsInsertionState.InsertPermissionBlock;
2710-
break;
2685+
// find the permissions block start line
2686+
var previousContents = "";
2687+
for (var i = currentIndex - 1; i > 0; i--)
2688+
{
2689+
var lineContents = originalFileContents[i].Trim();
2690+
if (lineContents.EndsWith("-->"))
2691+
{
2692+
codeBlockAnnotationEndLine = i;
2693+
}
2694+
if (lineContents.StartsWith("<!--") && (lineContents[4..].Trim().StartsWith('{') || previousContents.StartsWith('{')))
2695+
{
2696+
insertionStartLine = i;
2697+
parseStatus = PermissionsInsertionState.FindHttpRequestHeading;
2698+
break;
2699+
}
2700+
previousContents = lineContents;
2701+
}
2702+
2703+
// Extract HTML comment
2704+
if (codeBlockAnnotationEndLine != -1 && insertionStartLine != -1)
2705+
{
2706+
var htmlComment = insertionStartLine == codeBlockAnnotationEndLine
2707+
? originalFileContents[insertionStartLine]
2708+
: string.Join(" ", originalFileContents.Skip(insertionStartLine).Take(codeBlockAnnotationEndLine + 1 - insertionStartLine));
2709+
var metadataJsonString = DocFile.StripHtmlCommentTags(htmlComment);
2710+
try
2711+
{
2712+
var annotation = CodeBlockAnnotation.ParseMetadata(metadataJsonString);
2713+
if (annotation.BlockType == CodeBlockType.Permissions)
2714+
{
2715+
requestUrlsForPermissions = annotation?.RequestUrls;
2716+
mergePermissions = annotation?.MergePermissions ?? false;
2717+
}
2718+
else // Something's wrong with the metadata
2719+
{
2720+
ignorePermissionTableUpdate = true;
2721+
parseStatus = PermissionsInsertionState.FindNextPermissionBlock;
2722+
FancyConsole.WriteLine(ConsoleColor.Red, $"The HTML metadata for permissions table({foundPermissionTablesOrBlocks}) in {docFile.DisplayName} is wrong)");
2723+
break;
2724+
}
2725+
}
2726+
catch (Exception ex)
2727+
{
2728+
ignorePermissionTableUpdate = true;
2729+
parseStatus = PermissionsInsertionState.FindNextPermissionBlock;
2730+
FancyConsole.WriteLine(ConsoleColor.Red, $"Unable to parse permissions block metadata in '{docFile.DisplayName}', line: {insertionStartLine + 1}", ex);
2731+
break;
2732+
}
2733+
}
2734+
else
2735+
{
2736+
// If we are here, the metadata for the permissions table is missing or incomplete. Aim to add it.
2737+
codeBlockAnnotationEndLine = insertionStartLine = currentIndex;
2738+
parseStatus = PermissionsInsertionState.FindHttpRequestHeading;
2739+
break;
2740+
}
27112741
}
27122742
}
27132743
else if (currentLine.Contains('|') && currentLine.Contains("Permission type", StringComparison.OrdinalIgnoreCase)) // found the permissions table
@@ -2730,12 +2760,12 @@ private static async Task<bool> GeneratePermissionFilesAsync(GeneratePermissionF
27302760
for (int index = permissionsHeaderIndex + 1; index < currentIndex; index++)
27312761
{
27322762
// if the line is not empty and is not a sub header, this is the boilerplate start line
2733-
if (!string.IsNullOrWhiteSpace(originalFileContents[index]) && !originalFileContents[index].StartsWith('#'))
2734-
{
2763+
if (!string.IsNullOrWhiteSpace(originalFileContents[index]) && !originalFileContents[index].StartsWith('#'))
2764+
{
27352765
if (boilerplateStartLine == permissionsHeaderIndex)
27362766
boilerplateStartLine = index;
27372767
boilerplateEndLine = index;
2738-
}
2768+
}
27392769
}
27402770
}
27412771
}
@@ -2826,7 +2856,7 @@ private static async Task<bool> GeneratePermissionFilesAsync(GeneratePermissionF
28262856
if (!isBootstrapped)
28272857
{
28282858
var existingPermissionsTable = originalFileContents.Skip(insertionStartLine + 2).Take(insertionEndLine - insertionStartLine - 1);
2829-
permissionFileContents = $"{includeFileMetadata}{ConvertToThreeColumnPermissionsTable(existingPermissionsTable)}";
2859+
permissionFileContents = $"{includeFileMetadata}{ConvertToThreeColumnPermissionsTable(existingPermissionsTable)}";
28302860
}
28312861

28322862
if (!options.BootstrappingOnly)
@@ -2843,7 +2873,7 @@ private static async Task<bool> GeneratePermissionFilesAsync(GeneratePermissionF
28432873
var httpRequests = (requestUrlsForPermissions?.Length ?? 0) != 0
28442874
? requestUrlsForPermissions
28452875
: originalFileContents.Skip(httpRequestStartLine + 1).Take(httpRequestEndLine - httpRequestStartLine - 1).Where(x => !string.IsNullOrWhiteSpace(x));
2846-
var newPermissionFileContents = GetPermissionsMarkdownTableForHttpRequestBlock(permissionsDocument, httpRequests,
2876+
var newPermissionFileContents = GetPermissionsMarkdownTableForHttpRequestBlock(permissionsDocument, httpRequests,
28472877
mergePermissions, docFile.DisplayName, foundPermissionTablesOrBlocks); // get from Kibali
28482878
if (!string.IsNullOrWhiteSpace(newPermissionFileContents))
28492879
{
@@ -2868,15 +2898,16 @@ private static async Task<bool> GeneratePermissionFilesAsync(GeneratePermissionF
28682898
if (foundPermissionTablesOrBlocks == 1)
28692899
{
28702900
// We do not have a boilerplate text in this case, add new next line
2871-
if(boilerplateStartLine == permissionsHeaderIndex)
2901+
if (boilerplateStartLine == permissionsHeaderIndex)
28722902
{
28732903
// insert a new line to hold boilerplate text
28742904
originalFileContents = FileSplicer(originalFileContents, boilerplateStartLine, Constants.PermissionConstants.DefaultBoilerPlateText).ToArray();
28752905
boilerplateStartLine++;
28762906
insertionStartLine++;
28772907
insertionEndLine++;
28782908
}
2879-
else {
2909+
else
2910+
{
28802911
if (boilerplateEndLine > boilerplateStartLine)
28812912
{
28822913
int extraLinesToRemove = boilerplateEndLine - boilerplateStartLine;
@@ -2887,7 +2918,8 @@ private static async Task<bool> GeneratePermissionFilesAsync(GeneratePermissionF
28872918
originalFileContents[boilerplateStartLine] = Constants.PermissionConstants.DefaultBoilerPlateText;
28882919
}
28892920
}
2890-
else if (foundPermissionTablesOrBlocks == 2) {
2921+
else if (foundPermissionTablesOrBlocks == 2)
2922+
{
28912923
originalFileContents[boilerplateStartLine] = Constants.PermissionConstants.MultipleTableBoilerPlateText;
28922924
}
28932925
}
@@ -2908,7 +2940,8 @@ private static async Task<bool> GeneratePermissionFilesAsync(GeneratePermissionF
29082940
await File.WriteAllTextAsync(permissionsMarkdownFilePath, permissionFileContents);
29092941

29102942
// insert permissions block text into doc file
2911-
var permissionsBlockText = GeneratePermissionsBlockText(docFileName, Path.Combine(permissionsFileRelativePath, permissionsFileName), requestUrlsForPermissions, mergePermissions);
2943+
var permissionsBlockText = GeneratePermissionsBlockText(docFileName, Path.Combine(permissionsFileRelativePath, permissionsFileName), requestUrlsForPermissions, mergePermissions);
2944+
permissionsBlockLineCount = permissionsBlockText.Split(Environment.NewLine).Length;
29122945
IEnumerable<string> updatedFileContents = originalFileContents;
29132946
updatedFileContents = updatedFileContents.Splice(insertionStartLine, insertionEndLine + 1 - insertionStartLine);
29142947
updatedFileContents = FileSplicer(updatedFileContents.ToArray(), insertionStartLine - 1, permissionsBlockText);
@@ -2919,11 +2952,12 @@ private static async Task<bool> GeneratePermissionFilesAsync(GeneratePermissionF
29192952
if (!ignorePermissionTableUpdate)
29202953
{
29212954
var newFileContents = await File.ReadAllLinesAsync(docFile.FullPath);
2922-
currentIndex = newFileContents.Length == originalFileContents.Length
2955+
currentIndex = newFileContents.Length == originalFileContents.Length
29232956
? insertionEndLine
2924-
: codeBlockAnnotationEndLine - (originalFileContents.Length - newFileContents.Length) + 1;
2957+
: insertionStartLine + permissionsBlockLineCount - 1;
29252958
originalFileContents = newFileContents;
2926-
insertionStartLine = insertionEndLine = httpRequestStartLine = httpRequestEndLine = codeBlockAnnotationEndLine = - 1;
2959+
insertionStartLine = insertionEndLine = httpRequestStartLine = httpRequestEndLine =
2960+
codeBlockAnnotationEndLine = permissionsBlockLineCount = -1;
29272961
mergePermissions = false;
29282962
requestUrlsForPermissions = null;
29292963
foundHttpRequestBlocks = 0;
@@ -2996,11 +3030,11 @@ private static string GeneratePermissionsBlockText(string docFileName, string pe
29963030
return permissionsBlockText;
29973031
}
29983032

2999-
private static string GetPermissionsMarkdownTableForHttpRequestBlock(PermissionsDocument permissionsDocument, IEnumerable<string> httpRequests, bool mergePermissions,
3033+
private static string GetPermissionsMarkdownTableForHttpRequestBlock(PermissionsDocument permissionsDocument, IEnumerable<string> httpRequests, bool mergePermissions,
30003034
string docFileName, int permissionsTablePosition)
30013035
{
30023036
var requestPaths = new List<HttpRequest>();
3003-
3037+
30043038
// check validity of request paths
30053039
foreach (var request in httpRequests)
30063040
{
@@ -3051,7 +3085,7 @@ private static string GetPermissionsMarkdownTableForHttpRequestBlock(Permissions
30513085
var requestPermissions = generator.GenerateTable();
30523086
newPermissionFileContents ??= requestPermissions;
30533087

3054-
if (!newPermissionFileContents.Equals(requestPermissions, StringComparison.OrdinalIgnoreCase))
3088+
if (!newPermissionFileContents.Equals(requestPermissions, StringComparison.OrdinalIgnoreCase))
30553089
{
30563090
FancyConsole.WriteLine(ConsoleColor.Yellow, $"Encountered request URL(s) for permissions table ({permissionsTablePosition}) in {docFileName} with a different set of permissions");
30573091
}

0 commit comments

Comments
 (0)