From eeb492f28490c4af3587eb2f549cd8699dd1f386 Mon Sep 17 00:00:00 2001 From: Ben Renninson Date: Sun, 16 Oct 2022 17:33:55 +1100 Subject: [PATCH] Support duplicate board names (#44) --- T2MDCli/Cli.cs | 39 ++++++++++++++++++++++++++++++--------- T2MDCli/T2MDCli.csproj | 2 +- T2MDCliTests/CliTests.cs | 3 ++- 3 files changed, 33 insertions(+), 11 deletions(-) diff --git a/T2MDCli/Cli.cs b/T2MDCli/Cli.cs index 5c70d0f..fab48e4 100644 --- a/T2MDCli/Cli.cs +++ b/T2MDCli/Cli.cs @@ -175,6 +175,13 @@ private static async Task RunAsync(CliOptions options) AnsiConsole.MarkupLine($" [blue]{trelloApiBoard.Name}[/]"); } + // deduplicate board names once for all boards. They can then just read their suffix in + // their processing task + Dictionary duplicateBoardSuffixes = GetDuplicateSuffixes( + trelloApiBoards, + options + ); + // process each board asynchronously. The downloading, writing, as much of the process // as possible. AnsiConsole.MarkupLine("[magenta]Processing each board (phase 1):[/]"); @@ -184,7 +191,12 @@ private static async Task RunAsync(CliOptions options) // Starting each board with Task.Run is consistently faster than just async/await // within the board, even though it's I/O bound. Probably because the JSON parsing // is CPU bound and it's doing enough of it per board. - boardTasks.Add(Task.Run(() => ProcessTrelloBoardAsync(trelloApiBoard, options))); + boardTasks.Add( + Task.Run( + () => + ProcessTrelloBoardAsync(trelloApiBoard, options, duplicateBoardSuffixes) + ) + ); } await Task.WhenAll(boardTasks).ConfigureAwait(false); IEnumerable trelloBoards = boardTasks.Select(task => task.Result); @@ -261,7 +273,8 @@ private static void RemoveEmptyFolders(string RootFolderPath) /// private static async Task ProcessTrelloBoardAsync( TrelloApiBoardModel trelloApiBoard, - CliOptions options + CliOptions options, + Dictionary duplicateBoardSuffixes ) { AnsiConsole.MarkupLine($" [blue]Starting {trelloApiBoard.Name}[/]"); @@ -292,8 +305,11 @@ CliOptions options // write the json to file (overwrite): - // without this linux will happily write /'s - string usableBoardName = GetUsableBoardName(trelloApiBoard, options); + string usableBoardName = GetUsableBoardName( + trelloApiBoard, + options, + duplicateBoardSuffixes + ); string boardOutputFilePath = Path.Combine(_outputPath, $"{usableBoardName}.json"); using FileStream fileStream = File.Create(boardOutputFilePath); @@ -431,14 +447,19 @@ await boardJsonStreamReader.ReadToEndAsync().ConfigureAwait(false), /// Trims preceding and trailing whitespace to avoid Windows being unable to use the folder /// (and to neaten things up). /// Replaces multiple whitespace with a single space (usually from removing emoji). - /// If specified in options, emoji are removed here as well. + /// If specified in options, emoji are removed here as well. + /// Uses the suffix of this board from duplicateBoardSuffixes to deduplicate board names. /// public static string GetUsableBoardName( TrelloApiBoardModel trelloApiBoard, - CliOptions options + CliOptions options, + Dictionary duplicateBoardSuffixes ) { - string usableBoardName = FileSystem.SanitiseForPath(trelloApiBoard.Name); + string suffix = duplicateBoardSuffixes[trelloApiBoard]; + // without this linux will happily write /'s + string filesystemSafeName = FileSystem.SanitiseForPath(trelloApiBoard.Name); + string usableBoardName = $"{filesystemSafeName} {suffix}"; if (options.RemoveEmoji) { usableBoardName = Emoji.ReplaceEmoji(usableBoardName, ""); @@ -1311,11 +1332,11 @@ await File.WriteAllTextAsync(commentsPath, replacedCommentsContents) /// Dict containing each input entry as a key, and a unique incrementing (per duplicate /// name, not total) number in a string as their value if they had a duplicate name, or an /// empty string if they didn't. - /// Cards will be de-duplicated per list. /// E.g.
/// ["Card 1", "Card 2", "Card 1"]
/// would return
/// {"Card 1": "1", "Card 2"; "", "Card 1": "2"}. + /// Cards will be de-duplicated per list. /// /// /// @@ -1368,7 +1389,7 @@ CliOptions options } /// - /// Generates the card/list name key used in GetDuplicateSuffixes(). + /// Generates the name key used in GetDuplicateSuffixes(). /// Card names are differentiated within each list. /// private static string GetDuplicateNameKey( diff --git a/T2MDCli/T2MDCli.csproj b/T2MDCli/T2MDCli.csproj index c85da31..8b25541 100644 --- a/T2MDCli/T2MDCli.csproj +++ b/T2MDCli/T2MDCli.csproj @@ -8,7 +8,7 @@ t2md Ben Renninson Golden Syrup Games - 4.0.2 + 4.0.3 2022 Golden Syrup Games diff --git a/T2MDCliTests/CliTests.cs b/T2MDCliTests/CliTests.cs index d820787..19fc01c 100644 --- a/T2MDCliTests/CliTests.cs +++ b/T2MDCliTests/CliTests.cs @@ -258,7 +258,8 @@ public void GetUsableBoardName_PrecedingTrailingInnerDoubleSpaces_TrimmedAndRemo string expectedOutput = "board title"; var options = new CliOptions(); - string actualOutput = Cli.GetUsableBoardName(board, options); + var duplicateBoardNames = new Dictionary() { { board, "" } }; + string actualOutput = Cli.GetUsableBoardName(board, options, duplicateBoardNames); Assert.AreEqual(expectedOutput, actualOutput); }