Skip to content

Commit 7d8ebd4

Browse files
Catch exception when trying to convert permissions table to three columns (#298)
* Catch exception when trying to convert permissions table to three columns * Move Regex to static variable * Correctly extract permissions table when the HTML metadata spans more than one line
1 parent a34a80d commit 7d8ebd4

File tree

2 files changed

+38
-25
lines changed

2 files changed

+38
-25
lines changed

ApiDoctor.Console/Constants.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ public static class PermissionsConstants
1212
" For details about delegated and application permissions, see [Permission types](/graph/permissions-overview#permission-types). To learn more about these permissions, see the [permissions reference](/graph/permissions-reference).";
1313
public const string MultipleTableBoilerPlateText = "The following tables show the least privileged permission or permissions required to call this API on each supported resource type." +
1414
" Follow [best practices](/graph/permissions-overview#best-practices-for-using-microsoft-graph-permissions) to request least privileged permissions." +
15-
" For details about delegated and application permissions, see [Permission types](/graph/permissions-overview#permission-types). To learn more about these permissions, see the [permissions reference](/graph/permissions-reference).";
15+
" For details about delegated and application permissions, see [Permission types](/graph/permissions-overview#permission-types). To learn more about these permissions, see the [permissions reference](/graph/permissions-reference).";
1616
}
1717
public static readonly Regex FunctionParameterRegex = new(@"(?<=\=)[^)]+(?=\))", RegexOptions.Compiled, TimeSpan.FromSeconds(5));
1818
public static readonly Regex QueryOptionSegementRegex = new(@"(\$.*)", RegexOptions.Compiled, TimeSpan.FromSeconds(5));

ApiDoctor.Console/Program.cs

Lines changed: 37 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2647,7 +2647,7 @@ private static async Task<bool> GeneratePermissionFilesAsync(GeneratePermissionF
26472647
bool finishedParsing = false, isBootstrapped = false, ignorePermissionTableUpdate = false,
26482648
foundAllPermissionTables = false, mergePermissions = false, hasBoilerplateText = false;
26492649
int insertionStartLine = -1, insertionEndLine = -1, httpRequestStartLine = -1, httpRequestEndLine = -1, boilerplateStartLine = -1,
2650-
boilerplateEndLine = -1, permissionsHeaderIndex = -1, codeBlockAnnotationEndLine = -1, permissionsBlockLineCount = -1;
2650+
boilerplateEndLine = -1, permissionsHeaderIndex = -1, codeBlockAnnotationEndLine = -1, permissionsBlockLineCount = -1, permissionsTableStartLine = -1;
26512651
string[] requestUrlsForPermissions = null;
26522652
for (var currentIndex = 0; currentIndex < originalFileContents.Length && !finishedParsing; currentIndex++)
26532653
{
@@ -2662,8 +2662,8 @@ private static async Task<bool> GeneratePermissionFilesAsync(GeneratePermissionF
26622662
}
26632663
break;
26642664
case PermissionsInsertionState.FindInsertionStartLine:
2665-
if (foundPermissionTablesOrBlocks == 0 && currentLine.Equals(Constants.PermissionsConstants.DefaultBoilerPlateText, StringComparison.OrdinalIgnoreCase)
2666-
|| currentLine.Equals(Constants.PermissionsConstants.MultipleTableBoilerPlateText, StringComparison.OrdinalIgnoreCase))
2665+
if (foundPermissionTablesOrBlocks == 0 && (currentLine.Equals(Constants.PermissionsConstants.DefaultBoilerPlateText, StringComparison.OrdinalIgnoreCase)
2666+
|| currentLine.Equals(Constants.PermissionsConstants.MultipleTableBoilerPlateText, StringComparison.OrdinalIgnoreCase)))
26672667
{
26682668
hasBoilerplateText = true;
26692669
boilerplateStartLine = boilerplateEndLine = currentIndex;
@@ -2674,6 +2674,7 @@ private static async Task<bool> GeneratePermissionFilesAsync(GeneratePermissionF
26742674
{
26752675
isBootstrapped = true;
26762676
foundPermissionTablesOrBlocks++;
2677+
permissionsTableStartLine = currentIndex;
26772678
insertionEndLine = currentIndex; // [!INCLUDE [permissions-table]... is the end of the insertion block
26782679

26792680
if (!options.BootstrappingOnly)
@@ -2717,6 +2718,7 @@ private static async Task<bool> GeneratePermissionFilesAsync(GeneratePermissionF
27172718
}
27182719
else if (currentLine.Contains('|') && currentLine.Contains("Permission type", StringComparison.OrdinalIgnoreCase)) // found the permissions table
27192720
{
2721+
permissionsTableStartLine = currentIndex;
27202722
foundPermissionTablesOrBlocks++;
27212723
var annotation = ExtractCodeBlockAnnotationForPermissionsTable(
27222724
docFile.DisplayName,
@@ -2848,8 +2850,8 @@ private static async Task<bool> GeneratePermissionFilesAsync(GeneratePermissionF
28482850
var permissionFileContents = string.Empty;
28492851
if (!isBootstrapped)
28502852
{
2851-
var existingPermissionsTable = originalFileContents.Skip(insertionStartLine + 2).Take(insertionEndLine - insertionStartLine - 1);
2852-
permissionFileContents = $"{includeFileMetadata}{ConvertToThreeColumnPermissionsTable(existingPermissionsTable)}";
2853+
var existingPermissionsTable = originalFileContents.Skip(permissionsTableStartLine).Take(insertionEndLine - permissionsTableStartLine + 1);
2854+
permissionFileContents = $"{includeFileMetadata}{ConvertToThreeColumnPermissionsTable(existingPermissionsTable, docFile.DisplayName)}";
28532855
}
28542856

28552857
if (!options.BootstrappingOnly)
@@ -2950,7 +2952,7 @@ private static async Task<bool> GeneratePermissionFilesAsync(GeneratePermissionF
29502952
: insertionStartLine + permissionsBlockLineCount - 1;
29512953
originalFileContents = newFileContents;
29522954
insertionStartLine = insertionEndLine = httpRequestStartLine = httpRequestEndLine =
2953-
codeBlockAnnotationEndLine = permissionsBlockLineCount = -1;
2955+
codeBlockAnnotationEndLine = permissionsBlockLineCount = permissionsTableStartLine = -1;
29542956
mergePermissions = false;
29552957
requestUrlsForPermissions = null;
29562958
foundHttpRequestBlocks = 0;
@@ -3039,32 +3041,41 @@ private static CodeBlockAnnotation ExtractCodeBlockAnnotationForPermissionsTable
30393041
return null;
30403042
}
30413043

3042-
private static string ConvertToThreeColumnPermissionsTable(IEnumerable<string> tableRows)
3044+
private static string ConvertToThreeColumnPermissionsTable(IEnumerable<string> tableRows, string fileName)
30433045
{
30443046
var tableString = new StringBuilder("|Permission type|Least privileged permissions|Higher privileged permissions|");
30453047
tableString.Append("\r\n|:---|:---|:---|");
30463048
foreach (string row in tableRows)
30473049
{
3048-
string[] cells = Regex.Split(row.Trim(), @"\s*\|\s*").Where(static x => !string.IsNullOrWhiteSpace(x)).ToArray();
3049-
3050-
// We already have the 3 column permissions table, abort
3051-
if (cells.Length == 3)
3050+
try
30523051
{
3053-
return string.Join("\r\n", tableRows);
3054-
}
3052+
string[] cells = PipeDelimiterRegex.Split(row.Trim()).Where(static x => !string.IsNullOrWhiteSpace(x)).ToArray();
3053+
3054+
// We already have the 3 column permissions table, abort
3055+
if (cells.Length == 3)
3056+
{
3057+
return string.Join("\r\n", tableRows);
3058+
}
30553059

3056-
var allPermissions = cells[1].Trim().Split(',', StringSplitOptions.TrimEntries)
3057-
.Where(x => !string.IsNullOrWhiteSpace(x) && !PermissionKeywordsToIgnore.Contains(x))
3058-
.ToList();
3060+
var allPermissions = cells[1].Trim().Split(',', StringSplitOptions.TrimEntries)
3061+
.Where(x => !string.IsNullOrWhiteSpace(x) && !PermissionKeywordsToIgnore.Contains(x))
3062+
.ToList();
3063+
3064+
var permissionType = cells[0];
3065+
var leastPrivilegePermission = allPermissions.Any() ? allPermissions.First().Trim() : "Not supported.";
3066+
var higherPrivilegePermissions = !allPermissions.Any()
3067+
? "Not supported."
3068+
: allPermissions.Count() == 1
3069+
? "Not available."
3070+
: string.Join(", ", allPermissions.Skip(1).Select(x => x.Trim()).ToList());
3071+
tableString.Append($"\r\n|{permissionType}|{leastPrivilegePermission}|{higherPrivilegePermissions}|");
3072+
}
3073+
catch (Exception ex)
3074+
{
3075+
Console.WriteLine($"Could not convert permissions table in {fileName} to three columns: {ex.Message}");
3076+
return string.Join(Environment.NewLine, tableRows);
3077+
}
30593078

3060-
var permissionType = cells[0];
3061-
var leastPrivilegePermission = allPermissions.Any() ? allPermissions.First().Trim() : "Not supported.";
3062-
var higherPrivilegePermissions = !allPermissions.Any()
3063-
? "Not supported."
3064-
: allPermissions.Count() == 1
3065-
? "Not available."
3066-
: string.Join(", ", allPermissions.Skip(1).Select(x => x.Trim()).ToList());
3067-
tableString.Append($"\r\n|{permissionType}|{leastPrivilegePermission}|{higherPrivilegePermissions}|");
30683079
}
30693080
return tableString.ToString();
30703081
}
@@ -3194,6 +3205,8 @@ private enum PermissionsInsertionState
31943205
FindNextPermissionBlock
31953206
}
31963207

3208+
private static readonly Regex PipeDelimiterRegex = new Regex(@"\s*\|\s*", RegexOptions.Compiled);
3209+
31973210
#endregion
31983211

31993212
/// <summary>

0 commit comments

Comments
 (0)