Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support duplicate board names #44

Merged
merged 2 commits into from
Oct 16, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 30 additions & 9 deletions T2MDCli/Cli.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<ITrelloCommon, string> 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):[/]");
Expand All @@ -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<TrelloBoardModel> trelloBoards = boardTasks.Select(task => task.Result);
Expand Down Expand Up @@ -261,7 +273,8 @@ private static void RemoveEmptyFolders(string RootFolderPath)
/// <returns></returns>
private static async Task<TrelloBoardModel> ProcessTrelloBoardAsync(
TrelloApiBoardModel trelloApiBoard,
CliOptions options
CliOptions options,
Dictionary<ITrelloCommon, string> duplicateBoardSuffixes
)
{
AnsiConsole.MarkupLine($" [blue]Starting {trelloApiBoard.Name}[/]");
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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). <para />
/// Replaces multiple whitespace with a single space (usually from removing emoji). <para />
/// If specified in options, emoji are removed here as well.
/// If specified in options, emoji are removed here as well. <para />
/// Uses the suffix of this board from duplicateBoardSuffixes to deduplicate board names.
/// </summary>
public static string GetUsableBoardName(
TrelloApiBoardModel trelloApiBoard,
CliOptions options
CliOptions options,
Dictionary<ITrelloCommon, string> 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, "");
Expand Down Expand Up @@ -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. <para />
/// Cards will be de-duplicated per list.
/// E.g.<br />
/// ["Card 1", "Card 2", "Card 1"]<br />
/// would return<br />
/// {"Card 1": "1", "Card 2"; "", "Card 1": "2"}. <para />
/// Cards will be de-duplicated per list.
/// </summary>
/// <param name="potentialDuplicates"></param>
/// <returns></returns>
Expand Down Expand Up @@ -1368,7 +1389,7 @@ CliOptions options
}

/// <summary>
/// Generates the card/list name key used in GetDuplicateSuffixes(). <para/>
/// Generates the name key used in GetDuplicateSuffixes(). <para/>
/// Card names are differentiated within each list. <para />
/// </summary>
private static string GetDuplicateNameKey(
Expand Down
2 changes: 1 addition & 1 deletion T2MDCli/T2MDCli.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<AssemblyName>t2md</AssemblyName>
<Authors>Ben Renninson</Authors>
<Company>Golden Syrup Games</Company>
<Version>4.0.2</Version>
<Version>4.0.3</Version>
<Copyright>2022 Golden Syrup Games</Copyright>
<PackageLicenseExpression></PackageLicenseExpression>

Expand Down
3 changes: 2 additions & 1 deletion T2MDCliTests/CliTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<ITrelloCommon, string>() { { board, "" } };
string actualOutput = Cli.GetUsableBoardName(board, options, duplicateBoardNames);

Assert.AreEqual(expectedOutput, actualOutput);
}
Expand Down