From 8a5dc8325d487276d8d0d91280fd5cbb1a242694 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 9 May 2026 06:27:14 +0000 Subject: [PATCH] Expand ktsu.Semantics.Paths usage across services (#14) Migrate public service entry points off raw string paths to AbsoluteDirectoryPath / AbsoluteFilePath, with conversion at the Spectre command boundary: - MarkdownService.CleanAsync / LintAsync - RepoService.DiscoverRepositoriesAsync / BuildAndTestAsync / PullAllAsync / UpdatePackagesAsync - PackagesService.UpdateAsync (overloads for dir + single csproj) - PackagesService.MigrateToCpmAsync - SvnMigrateService.MigrateAsync (target dir + optional authors file) - ImageService.ProcessAsync (input + output dirs) - SyncService.RunAsync (root path) Each affected csproj now references ktsu.Semantics.Paths, and each command translates its string CommandSettings field via AbsoluteDirectoryPath.Create / AbsoluteFilePath.Create. RepoServiceTests updated for the new signature. https://claude.ai/code/session_015z5JX7CrrvNdfjWDZNV3Hy --- KtsuTools.Image/ImageService.cs | 15 ++++++++--- KtsuTools.Image/KtsuTools.Image.csproj | 1 + KtsuTools.Markdown/KtsuTools.Markdown.csproj | 1 + KtsuTools.Markdown/MarkdownService.cs | 11 +++++--- KtsuTools.Packages/KtsuTools.Packages.csproj | 1 + KtsuTools.Packages/PackagesService.cs | 25 ++++++++++++++----- KtsuTools.Repo/KtsuTools.Repo.csproj | 1 + KtsuTools.Repo/RepoService.cs | 17 +++++++------ .../KtsuTools.SvnMigrate.csproj | 1 + KtsuTools.SvnMigrate/SvnMigrateService.cs | 10 +++++--- KtsuTools.Sync/SyncService.cs | 21 +++++++++------- KtsuTools.Test/RepoServiceTests.cs | 7 ++++-- KtsuTools/Commands/ImageProcessCommand.cs | 8 ++++-- KtsuTools/Commands/MarkdownCleanCommand.cs | 5 +++- KtsuTools/Commands/MarkdownLintCommand.cs | 5 +++- .../Commands/PackagesMigrateCpmCommand.cs | 5 +++- KtsuTools/Commands/PackagesUpdateCommand.cs | 17 ++++++++++++- KtsuTools/Commands/RepoBuildCommand.cs | 5 +++- KtsuTools/Commands/RepoDiscoverCommand.cs | 5 +++- KtsuTools/Commands/RepoPullCommand.cs | 5 +++- .../Commands/RepoUpdatePackagesCommand.cs | 5 +++- KtsuTools/Commands/SvnMigrateCommand.cs | 10 ++++++-- KtsuTools/Commands/SyncCommand.cs | 5 +++- 23 files changed, 136 insertions(+), 50 deletions(-) diff --git a/KtsuTools.Image/ImageService.cs b/KtsuTools.Image/ImageService.cs index 0dc1ee2..3ddb191 100644 --- a/KtsuTools.Image/ImageService.cs +++ b/KtsuTools.Image/ImageService.cs @@ -7,6 +7,8 @@ namespace KtsuTools.Image; using System.Globalization; using System.IO; +using ktsu.Semantics.Paths; + using SixLabors.ImageSharp; using SixLabors.ImageSharp.Formats.Png; using SixLabors.ImageSharp.PixelFormats; @@ -31,17 +33,22 @@ public static class ImageService /// Padding in pixels added around the content. Must be less than size / 2. /// Cancellation token. /// The number of successfully processed files. - public static async Task ProcessAsync(string inputPath, string outputPath, string color = "#FFFFFF", int size = 128, int padding = 0, CancellationToken ct = default) + public static async Task ProcessAsync(AbsoluteDirectoryPath inputPath, AbsoluteDirectoryPath outputPath, string color = "#FFFFFF", int size = 128, int padding = 0, CancellationToken ct = default) { + Ensure.NotNull(inputPath); + Ensure.NotNull(outputPath); Ensure.NotNull(color); - if (!ValidateArguments(inputPath, outputPath, size, padding)) + string inputDir = inputPath.ToString(); + string outputDir = outputPath.ToString(); + + if (!ValidateArguments(inputDir, outputDir, size, padding)) { return 0; } Rgba32 targetColor = ParseHexColor(color); - string[] files = Directory.GetFiles(inputPath); + string[] files = Directory.GetFiles(inputDir); int processedCount = 0; await AnsiConsole.Progress() @@ -58,7 +65,7 @@ await AnsiConsole.Progress() foreach (string file in files) { ct.ThrowIfCancellationRequested(); - bool succeeded = ProcessFileWithErrorHandling(file, outputPath, targetColor, size, padding); + bool succeeded = ProcessFileWithErrorHandling(file, outputDir, targetColor, size, padding); if (succeeded) { diff --git a/KtsuTools.Image/KtsuTools.Image.csproj b/KtsuTools.Image/KtsuTools.Image.csproj index 2c995c0..471dac4 100644 --- a/KtsuTools.Image/KtsuTools.Image.csproj +++ b/KtsuTools.Image/KtsuTools.Image.csproj @@ -11,6 +11,7 @@ + diff --git a/KtsuTools.Markdown/KtsuTools.Markdown.csproj b/KtsuTools.Markdown/KtsuTools.Markdown.csproj index 781d85d..8eddfdb 100644 --- a/KtsuTools.Markdown/KtsuTools.Markdown.csproj +++ b/KtsuTools.Markdown/KtsuTools.Markdown.csproj @@ -12,6 +12,7 @@ + diff --git a/KtsuTools.Markdown/MarkdownService.cs b/KtsuTools.Markdown/MarkdownService.cs index 4561f88..a3ca7c8 100644 --- a/KtsuTools.Markdown/MarkdownService.cs +++ b/KtsuTools.Markdown/MarkdownService.cs @@ -7,6 +7,7 @@ namespace KtsuTools.Markdown; using Spectre.Console; using ktsu.Frontmatter; +using ktsu.Semantics.Paths; /// /// Service for cleaning and linting markdown files. @@ -22,10 +23,11 @@ public class MarkdownService /// Cancellation token. /// The number of files that were modified. #pragma warning disable CA1822, S2325 // Mark members as static - instance method required for DI injection - public async Task CleanAsync(string directoryPath, bool applyLinting, bool standardizeLineEndings, CancellationToken ct) + public async Task CleanAsync(AbsoluteDirectoryPath directoryPath, bool applyLinting, bool standardizeLineEndings, CancellationToken ct) #pragma warning restore CA1822, S2325 { - string fullPath = Path.GetFullPath(directoryPath); + Ensure.NotNull(directoryPath); + string fullPath = directoryPath.ToString(); if (!Directory.Exists(fullPath)) { @@ -78,10 +80,11 @@ await AnsiConsole.Progress() /// Cancellation token. /// The number of files that were modified. #pragma warning disable CA1822, S2325 // Mark members as static - instance method required for DI injection - public async Task LintAsync(string directoryPath, CancellationToken ct) + public async Task LintAsync(AbsoluteDirectoryPath directoryPath, CancellationToken ct) #pragma warning restore CA1822, S2325 { - string fullPath = Path.GetFullPath(directoryPath); + Ensure.NotNull(directoryPath); + string fullPath = directoryPath.ToString(); if (!Directory.Exists(fullPath)) { diff --git a/KtsuTools.Packages/KtsuTools.Packages.csproj b/KtsuTools.Packages/KtsuTools.Packages.csproj index 4d92c11..a5832d2 100644 --- a/KtsuTools.Packages/KtsuTools.Packages.csproj +++ b/KtsuTools.Packages/KtsuTools.Packages.csproj @@ -9,6 +9,7 @@ + diff --git a/KtsuTools.Packages/PackagesService.cs b/KtsuTools.Packages/PackagesService.cs index 94ba0f9..fe74414 100644 --- a/KtsuTools.Packages/PackagesService.cs +++ b/KtsuTools.Packages/PackagesService.cs @@ -7,6 +7,7 @@ namespace KtsuTools.Packages; using System.Net.Http; using System.Text.Json; using System.Xml.Linq; +using ktsu.Semantics.Paths; using KtsuTools.Core.Services.Process; using Spectre.Console; @@ -21,14 +22,26 @@ public class PackagesService(IProcessService processService) private static readonly HttpClient SharedHttpClient = new(); /// - /// Updates NuGet packages in projects at the specified path. + /// Updates NuGet packages in all .csproj files under the specified directory. /// - public async Task UpdateAsync(string path, bool whatIf = false, bool includePrerelease = false, string source = "nuget", CancellationToken ct = default) + public Task UpdateAsync(AbsoluteDirectoryPath path, bool whatIf = false, bool includePrerelease = false, string source = "nuget", CancellationToken ct = default) + { + Ensure.NotNull(path); + return UpdateInternalAsync(path.ToString(), whatIf, includePrerelease, source, ct); + } + + /// + /// Updates NuGet packages in a single .csproj file. + /// + public Task UpdateAsync(AbsoluteFilePath path, bool whatIf = false, bool includePrerelease = false, string source = "nuget", CancellationToken ct = default) { - _ = processService; Ensure.NotNull(path); + return UpdateInternalAsync(path.ToString(), whatIf, includePrerelease, source, ct); + } - string fullPath = Path.GetFullPath(path); + private async Task UpdateInternalAsync(string fullPath, bool whatIf, bool includePrerelease, string source, CancellationToken ct) + { + _ = processService; if (!Directory.Exists(fullPath) && !File.Exists(fullPath)) { @@ -77,12 +90,12 @@ await AnsiConsole.Progress() /// /// Migrates projects to Central Package Management. /// - public async Task MigrateToCpmAsync(string path, CancellationToken ct = default) + public async Task MigrateToCpmAsync(AbsoluteDirectoryPath path, CancellationToken ct = default) { _ = processService; Ensure.NotNull(path); - string fullPath = Path.GetFullPath(path); + string fullPath = path.ToString(); if (!Directory.Exists(fullPath)) { diff --git a/KtsuTools.Repo/KtsuTools.Repo.csproj b/KtsuTools.Repo/KtsuTools.Repo.csproj index 4d92c11..a5832d2 100644 --- a/KtsuTools.Repo/KtsuTools.Repo.csproj +++ b/KtsuTools.Repo/KtsuTools.Repo.csproj @@ -9,6 +9,7 @@ + diff --git a/KtsuTools.Repo/RepoService.cs b/KtsuTools.Repo/RepoService.cs index 8d12180..bc522c4 100644 --- a/KtsuTools.Repo/RepoService.cs +++ b/KtsuTools.Repo/RepoService.cs @@ -6,6 +6,7 @@ namespace KtsuTools.Repo; using System.Collections.Concurrent; using System.Collections.ObjectModel; +using ktsu.Semantics.Paths; using KtsuTools.Core.Services.Git; using KtsuTools.Core.Services.Process; using Spectre.Console; @@ -38,12 +39,12 @@ public class RepoService(IGitService gitService, IProcessService processService) /// /// Discovers git repositories in the given directory. /// - public async Task> DiscoverRepositoriesAsync(string path, CancellationToken ct = default) + public async Task> DiscoverRepositoriesAsync(AbsoluteDirectoryPath path, CancellationToken ct = default) { _ = gitService; Ensure.NotNull(path); - string fullPath = Path.GetFullPath(path); + string fullPath = path.ToString(); if (!Directory.Exists(fullPath)) { @@ -85,12 +86,12 @@ await AnsiConsole.Status() /// /// Builds and tests all solutions found in repositories under the given path. /// - public async Task BuildAndTestAsync(string path, bool parallel = false, CancellationToken ct = default) + public async Task BuildAndTestAsync(AbsoluteDirectoryPath path, bool parallel = false, CancellationToken ct = default) { _ = parallel; Ensure.NotNull(path); - string fullPath = Path.GetFullPath(path); + string fullPath = path.ToString(); List solutionFiles = DiscoverSolutionFiles(fullPath); if (solutionFiles.Count == 0) @@ -157,12 +158,12 @@ await AnsiConsole.Progress() /// /// Pulls all repositories under the given path. /// - public async Task PullAllAsync(string path, CancellationToken ct = default) + public async Task PullAllAsync(AbsoluteDirectoryPath path, CancellationToken ct = default) { _ = gitService; Ensure.NotNull(path); - string fullPath = Path.GetFullPath(path); + string fullPath = path.ToString(); ConcurrentBag repos = []; DiscoverGitReposRecursive(fullPath, repos); @@ -223,11 +224,11 @@ await AnsiConsole.Progress() /// /// Updates NuGet packages in all projects under the given path. /// - public async Task UpdatePackagesAsync(string path, bool includePrerelease = false, CancellationToken ct = default) + public async Task UpdatePackagesAsync(AbsoluteDirectoryPath path, bool includePrerelease = false, CancellationToken ct = default) { Ensure.NotNull(path); - string fullPath = Path.GetFullPath(path); + string fullPath = path.ToString(); List solutionFiles = DiscoverSolutionFiles(fullPath); if (solutionFiles.Count == 0) diff --git a/KtsuTools.SvnMigrate/KtsuTools.SvnMigrate.csproj b/KtsuTools.SvnMigrate/KtsuTools.SvnMigrate.csproj index 4d92c11..a5832d2 100644 --- a/KtsuTools.SvnMigrate/KtsuTools.SvnMigrate.csproj +++ b/KtsuTools.SvnMigrate/KtsuTools.SvnMigrate.csproj @@ -9,6 +9,7 @@ + diff --git a/KtsuTools.SvnMigrate/SvnMigrateService.cs b/KtsuTools.SvnMigrate/SvnMigrateService.cs index e5e3761..83cc97f 100644 --- a/KtsuTools.SvnMigrate/SvnMigrateService.cs +++ b/KtsuTools.SvnMigrate/SvnMigrateService.cs @@ -4,6 +4,7 @@ namespace KtsuTools.SvnMigrate; +using ktsu.Semantics.Paths; using KtsuTools.Core.Services.Process; using Spectre.Console; @@ -17,15 +18,16 @@ public class SvnMigrateService(IProcessService processService) /// /// Migrates an SVN repository to Git. /// - public async Task MigrateAsync(Uri svnUrl, string targetPath, string? authorsFile = null, bool preserveEmptyDirs = true, CancellationToken ct = default) + public async Task MigrateAsync(Uri svnUrl, AbsoluteDirectoryPath targetPath, AbsoluteFilePath? authorsFile = null, bool preserveEmptyDirs = true, CancellationToken ct = default) { Ensure.NotNull(svnUrl); Ensure.NotNull(targetPath); - string gitRepoPath = Path.GetFullPath(targetPath); + string gitRepoPath = targetPath.ToString(); + string? authorsFilePath = authorsFile?.ToString(); // Validate prerequisites - List errors = await ValidateAsync(svnUrl, gitRepoPath, authorsFile, ct).ConfigureAwait(false); + List errors = await ValidateAsync(svnUrl, gitRepoPath, authorsFilePath, ct).ConfigureAwait(false); if (errors.Count > 0) { foreach (string error in errors) @@ -53,7 +55,7 @@ await AnsiConsole.Progress() // Phase 1: Clone SVN repository task.Description = "[green]Cloning SVN repository with git-svn...[/]"; - await CloneSvnRepositoryAsync(svnUrl.ToString(), gitRepoPath, authorsFile, preserveEmptyDirs, ct).ConfigureAwait(false); + await CloneSvnRepositoryAsync(svnUrl.ToString(), gitRepoPath, authorsFilePath, preserveEmptyDirs, ct).ConfigureAwait(false); task.Value = 50; // Phase 2: Cleanup references diff --git a/KtsuTools.Sync/SyncService.cs b/KtsuTools.Sync/SyncService.cs index 070c2e9..7c2c0d0 100644 --- a/KtsuTools.Sync/SyncService.cs +++ b/KtsuTools.Sync/SyncService.cs @@ -42,7 +42,7 @@ public class SyncService(IProcessService processService) /// The filename pattern to scan for. /// Cancellation token. /// Exit code (0 for success). - public Task RunAsync(string path, string filename, CancellationToken ct = default) => + public Task RunAsync(AbsoluteDirectoryPath path, string filename, CancellationToken ct = default) => RunAsync(path, [filename], autoPush: false, ct); /// @@ -53,13 +53,16 @@ public Task RunAsync(string path, string filename, CancellationToken ct = d /// When true, repos whose unpushed commits are all authored by KtsuTools are pushed without prompting. /// Cancellation token. /// Exit code (0 for success). - public async Task RunAsync(string path, IReadOnlyList filenames, bool autoPush, CancellationToken ct = default) + public async Task RunAsync(AbsoluteDirectoryPath path, IReadOnlyList filenames, bool autoPush, CancellationToken ct = default) { + Ensure.NotNull(path); ct.ThrowIfCancellationRequested(); - if (!Directory.Exists(path)) + string pathString = path.ToString(); + + if (!Directory.Exists(pathString)) { - AnsiConsole.MarkupLine($"[red]Path does not exist: {path.EscapeMarkup()}[/]"); + AnsiConsole.MarkupLine($"[red]Path does not exist: {pathString.EscapeMarkup()}[/]"); return 1; } @@ -75,14 +78,14 @@ public async Task RunAsync(string path, IReadOnlyList filenames, bo } AnsiConsole.MarkupLine($"[bold]Scanning for:[/] {string.Join(", ", patterns).EscapeMarkup()}"); - AnsiConsole.MarkupLine($"[bold]In:[/] {path.EscapeMarkup()}"); + AnsiConsole.MarkupLine($"[bold]In:[/] {pathString.EscapeMarkup()}"); AnsiConsole.WriteLine(); HashSet seen = new(StringComparer.Ordinal); Collection fileEnumeration = []; foreach (string pattern in patterns) { - foreach (string file in Directory.EnumerateFiles(path, pattern, SearchOption.AllDirectories) + foreach (string file in Directory.EnumerateFiles(pathString, pattern, SearchOption.AllDirectories) .Where(f => !IsRepoNested(AbsoluteFilePath.Create(f).AbsoluteDirectoryPath))) { if (seen.Add(file)) @@ -103,12 +106,12 @@ public async Task RunAsync(string path, IReadOnlyList filenames, bo foreach (string uniqueFilename in uniqueFilenames) { ct.ThrowIfCancellationRequested(); - await ProcessUniqueFilenameAsync(uniqueFilename, fileEnumeration, path, commitDirectories, ct).ConfigureAwait(false); + await ProcessUniqueFilenameAsync(uniqueFilename, fileEnumeration, pathString, commitDirectories, ct).ConfigureAwait(false); } - await CommitChangedFilesAsync(commitDirectories, expandedFilesToSync, path).ConfigureAwait(false); + await CommitChangedFilesAsync(commitDirectories, expandedFilesToSync, pathString).ConfigureAwait(false); - await PushToRemoteAsync(commitDirectories, path, autoPush, ct).ConfigureAwait(false); + await PushToRemoteAsync(commitDirectories, pathString, autoPush, ct).ConfigureAwait(false); return 0; } diff --git a/KtsuTools.Test/RepoServiceTests.cs b/KtsuTools.Test/RepoServiceTests.cs index 772e99e..6334850 100644 --- a/KtsuTools.Test/RepoServiceTests.cs +++ b/KtsuTools.Test/RepoServiceTests.cs @@ -5,6 +5,7 @@ namespace KtsuTools.Test; using System.IO; +using ktsu.Semantics.Paths; using KtsuTools.Core.Services.Git; using KtsuTools.Core.Services.Process; using KtsuTools.Repo; @@ -18,7 +19,8 @@ public async Task DiscoverRepositoriesAsyncMissingDirectoryReturnsEmpty() { RepoService service = new(new Mock().Object, new Mock().Object); string missing = Path.Combine(Path.GetTempPath(), $"ktsu_missing_{Guid.NewGuid():N}"); - IReadOnlyList result = await service.DiscoverRepositoriesAsync(missing).ConfigureAwait(false); + AbsoluteDirectoryPath missingPath = AbsoluteDirectoryPath.Create(missing); + IReadOnlyList result = await service.DiscoverRepositoriesAsync(missingPath).ConfigureAwait(false); Assert.AreEqual(0, result.Count); } @@ -35,7 +37,8 @@ public async Task DiscoverRepositoriesAsyncFindsGitDirectories() try { RepoService service = new(new Mock().Object, new Mock().Object); - IReadOnlyList result = await service.DiscoverRepositoriesAsync(root).ConfigureAwait(false); + AbsoluteDirectoryPath rootPath = AbsoluteDirectoryPath.Create(root); + IReadOnlyList result = await service.DiscoverRepositoriesAsync(rootPath).ConfigureAwait(false); Assert.AreEqual(2, result.Count, "Should find exactly the two .git directories."); CollectionAssert.AreEquivalent( new[] { repoA, repoB }, diff --git a/KtsuTools/Commands/ImageProcessCommand.cs b/KtsuTools/Commands/ImageProcessCommand.cs index a970292..61890d0 100644 --- a/KtsuTools/Commands/ImageProcessCommand.cs +++ b/KtsuTools/Commands/ImageProcessCommand.cs @@ -5,6 +5,8 @@ namespace KtsuTools.Commands; using System.ComponentModel; +using System.IO; +using ktsu.Semantics.Paths; using KtsuTools.Core.UI; using KtsuTools.Image; using Spectre.Console; @@ -44,9 +46,11 @@ public override async Task ExecuteAsync(CommandContext context, Settings se AnsiConsole.MarkupLine("[bold]Image Process[/]"); using CtrlCScope scope = new(); + AbsoluteDirectoryPath inputPath = AbsoluteDirectoryPath.Create(Path.GetFullPath(settings.InputPath)); + AbsoluteDirectoryPath outputPath = AbsoluteDirectoryPath.Create(Path.GetFullPath(settings.OutputPath)); int processed = await ImageService.ProcessAsync( - settings.InputPath, - settings.OutputPath, + inputPath, + outputPath, settings.Color, settings.Size, settings.Padding, diff --git a/KtsuTools/Commands/MarkdownCleanCommand.cs b/KtsuTools/Commands/MarkdownCleanCommand.cs index 202c268..21f915a 100644 --- a/KtsuTools/Commands/MarkdownCleanCommand.cs +++ b/KtsuTools/Commands/MarkdownCleanCommand.cs @@ -5,6 +5,8 @@ namespace KtsuTools.Commands; using System.ComponentModel; +using System.IO; +using ktsu.Semantics.Paths; using KtsuTools.Core.UI; using KtsuTools.Markdown; using Spectre.Console; @@ -37,8 +39,9 @@ public override async Task ExecuteAsync(CommandContext context, Settings se AnsiConsole.MarkupLine("[bold]Markdown Clean[/]"); using CtrlCScope scope = new(); + AbsoluteDirectoryPath path = AbsoluteDirectoryPath.Create(Path.GetFullPath(settings.Path)); int modifiedCount = await markdownService.CleanAsync( - settings.Path, + path, settings.ApplyLinting, settings.StandardizeLineEndings, scope.Token).ConfigureAwait(false); diff --git a/KtsuTools/Commands/MarkdownLintCommand.cs b/KtsuTools/Commands/MarkdownLintCommand.cs index 8e9d8fe..0aeefca 100644 --- a/KtsuTools/Commands/MarkdownLintCommand.cs +++ b/KtsuTools/Commands/MarkdownLintCommand.cs @@ -5,6 +5,8 @@ namespace KtsuTools.Commands; using System.ComponentModel; +using System.IO; +using ktsu.Semantics.Paths; using KtsuTools.Core.UI; using KtsuTools.Markdown; using Spectre.Console; @@ -27,8 +29,9 @@ public override async Task ExecuteAsync(CommandContext context, Settings se AnsiConsole.MarkupLine("[bold]Markdown Lint[/]"); using CtrlCScope scope = new(); + AbsoluteDirectoryPath path = AbsoluteDirectoryPath.Create(Path.GetFullPath(settings.Path)); int modifiedCount = await markdownService.LintAsync( - settings.Path, + path, scope.Token).ConfigureAwait(false); AnsiConsole.MarkupLine($"[bold green]Done.[/] {modifiedCount} file(s) linted."); diff --git a/KtsuTools/Commands/PackagesMigrateCpmCommand.cs b/KtsuTools/Commands/PackagesMigrateCpmCommand.cs index 8f81ce4..c994443 100644 --- a/KtsuTools/Commands/PackagesMigrateCpmCommand.cs +++ b/KtsuTools/Commands/PackagesMigrateCpmCommand.cs @@ -5,6 +5,8 @@ namespace KtsuTools.Commands; using System.ComponentModel; +using System.IO; +using ktsu.Semantics.Paths; using KtsuTools.Core.UI; using KtsuTools.Packages; using Spectre.Console.Cli; @@ -24,8 +26,9 @@ public override async Task ExecuteAsync(CommandContext context, Settings se { Ensure.NotNull(settings); using CtrlCScope scope = new(); + AbsoluteDirectoryPath path = AbsoluteDirectoryPath.Create(Path.GetFullPath(settings.Path)); return await packagesService.MigrateToCpmAsync( - settings.Path, + path, scope.Token).ConfigureAwait(false); } } diff --git a/KtsuTools/Commands/PackagesUpdateCommand.cs b/KtsuTools/Commands/PackagesUpdateCommand.cs index f967a09..cb4f158 100644 --- a/KtsuTools/Commands/PackagesUpdateCommand.cs +++ b/KtsuTools/Commands/PackagesUpdateCommand.cs @@ -5,6 +5,8 @@ namespace KtsuTools.Commands; using System.ComponentModel; +using System.IO; +using ktsu.Semantics.Paths; using KtsuTools.Core.UI; using KtsuTools.Packages; using Spectre.Console.Cli; @@ -39,8 +41,21 @@ public override async Task ExecuteAsync(CommandContext context, Settings se { Ensure.NotNull(settings); using CtrlCScope scope = new(); + string fullPath = Path.GetFullPath(settings.Path); + if (File.Exists(fullPath)) + { + AbsoluteFilePath filePath = AbsoluteFilePath.Create(fullPath); + return await packagesService.UpdateAsync( + filePath, + settings.WhatIf, + settings.IncludePrerelease, + settings.Source, + scope.Token).ConfigureAwait(false); + } + + AbsoluteDirectoryPath dirPath = AbsoluteDirectoryPath.Create(fullPath); return await packagesService.UpdateAsync( - settings.Path, + dirPath, settings.WhatIf, settings.IncludePrerelease, settings.Source, diff --git a/KtsuTools/Commands/RepoBuildCommand.cs b/KtsuTools/Commands/RepoBuildCommand.cs index 7cf4669..4df1fcf 100644 --- a/KtsuTools/Commands/RepoBuildCommand.cs +++ b/KtsuTools/Commands/RepoBuildCommand.cs @@ -5,6 +5,8 @@ namespace KtsuTools.Commands; using System.ComponentModel; +using System.IO; +using ktsu.Semantics.Paths; using KtsuTools.Core.UI; using KtsuTools.Repo; using Spectre.Console.Cli; @@ -30,8 +32,9 @@ public override async Task ExecuteAsync(CommandContext context, Settings se { Ensure.NotNull(settings); using CtrlCScope scope = new(); + AbsoluteDirectoryPath path = AbsoluteDirectoryPath.Create(Path.GetFullPath(settings.Path)); return await repoService.BuildAndTestAsync( - settings.Path, + path, settings.Parallel, scope.Token).ConfigureAwait(false); } diff --git a/KtsuTools/Commands/RepoDiscoverCommand.cs b/KtsuTools/Commands/RepoDiscoverCommand.cs index f9438eb..62796ff 100644 --- a/KtsuTools/Commands/RepoDiscoverCommand.cs +++ b/KtsuTools/Commands/RepoDiscoverCommand.cs @@ -5,6 +5,8 @@ namespace KtsuTools.Commands; using System.ComponentModel; +using System.IO; +using ktsu.Semantics.Paths; using KtsuTools.Core.UI; using KtsuTools.Repo; using Spectre.Console.Cli; @@ -25,7 +27,8 @@ public override async Task ExecuteAsync(CommandContext context, Settings se { Ensure.NotNull(settings); using CtrlCScope scope = new(); - await repoService.DiscoverRepositoriesAsync(settings.Path, scope.Token).ConfigureAwait(false); + AbsoluteDirectoryPath path = AbsoluteDirectoryPath.Create(Path.GetFullPath(settings.Path)); + await repoService.DiscoverRepositoriesAsync(path, scope.Token).ConfigureAwait(false); return 0; } } diff --git a/KtsuTools/Commands/RepoPullCommand.cs b/KtsuTools/Commands/RepoPullCommand.cs index 06df0e4..8d20139 100644 --- a/KtsuTools/Commands/RepoPullCommand.cs +++ b/KtsuTools/Commands/RepoPullCommand.cs @@ -5,6 +5,8 @@ namespace KtsuTools.Commands; using System.ComponentModel; +using System.IO; +using ktsu.Semantics.Paths; using KtsuTools.Core.UI; using KtsuTools.Repo; using Spectre.Console.Cli; @@ -25,8 +27,9 @@ public override async Task ExecuteAsync(CommandContext context, Settings se { Ensure.NotNull(settings); using CtrlCScope scope = new(); + AbsoluteDirectoryPath path = AbsoluteDirectoryPath.Create(Path.GetFullPath(settings.Path)); return await repoService.PullAllAsync( - settings.Path, + path, scope.Token).ConfigureAwait(false); } } diff --git a/KtsuTools/Commands/RepoUpdatePackagesCommand.cs b/KtsuTools/Commands/RepoUpdatePackagesCommand.cs index 312f833..a6bf4ce 100644 --- a/KtsuTools/Commands/RepoUpdatePackagesCommand.cs +++ b/KtsuTools/Commands/RepoUpdatePackagesCommand.cs @@ -5,6 +5,8 @@ namespace KtsuTools.Commands; using System.ComponentModel; +using System.IO; +using ktsu.Semantics.Paths; using KtsuTools.Core.UI; using KtsuTools.Repo; using Spectre.Console.Cli; @@ -30,8 +32,9 @@ public override async Task ExecuteAsync(CommandContext context, Settings se { Ensure.NotNull(settings); using CtrlCScope scope = new(); + AbsoluteDirectoryPath path = AbsoluteDirectoryPath.Create(Path.GetFullPath(settings.Path)); return await repoService.UpdatePackagesAsync( - settings.Path, + path, settings.IncludePrerelease, scope.Token).ConfigureAwait(false); } diff --git a/KtsuTools/Commands/SvnMigrateCommand.cs b/KtsuTools/Commands/SvnMigrateCommand.cs index 37b9499..0375578 100644 --- a/KtsuTools/Commands/SvnMigrateCommand.cs +++ b/KtsuTools/Commands/SvnMigrateCommand.cs @@ -6,6 +6,8 @@ namespace KtsuTools.Commands; using System.ComponentModel; using System.Diagnostics.CodeAnalysis; +using System.IO; +using ktsu.Semantics.Paths; using KtsuTools.Core.UI; using KtsuTools.SvnMigrate; using Spectre.Console.Cli; @@ -39,10 +41,14 @@ public override async Task ExecuteAsync(CommandContext context, Settings se { Ensure.NotNull(settings); using CtrlCScope scope = new(); + AbsoluteDirectoryPath targetPath = AbsoluteDirectoryPath.Create(Path.GetFullPath(settings.TargetPath)); + AbsoluteFilePath? authorsFile = string.IsNullOrWhiteSpace(settings.AuthorsFile) + ? null + : AbsoluteFilePath.Create(Path.GetFullPath(settings.AuthorsFile)); return await svnMigrateService.MigrateAsync( new Uri(settings.SvnUrl), - settings.TargetPath, - settings.AuthorsFile, + targetPath, + authorsFile, settings.PreserveEmptyDirs, scope.Token).ConfigureAwait(false); } diff --git a/KtsuTools/Commands/SyncCommand.cs b/KtsuTools/Commands/SyncCommand.cs index bbd5abe..4540833 100644 --- a/KtsuTools/Commands/SyncCommand.cs +++ b/KtsuTools/Commands/SyncCommand.cs @@ -7,8 +7,10 @@ namespace KtsuTools.Commands; using System; using System.Collections.Generic; using System.ComponentModel; +using System.IO; using System.Linq; using System.Threading.Tasks; +using ktsu.Semantics.Paths; using KtsuTools.Core.UI; using KtsuTools.Sync; using Spectre.Console; @@ -67,7 +69,8 @@ public override async Task ExecuteAsync(CommandContext context, Settings se } using CtrlCScope scope = new(); - return await syncService.RunAsync(path, filenames, settings.AutoPush, scope.Token).ConfigureAwait(false); + AbsoluteDirectoryPath rootPath = AbsoluteDirectoryPath.Create(Path.GetFullPath(path)); + return await syncService.RunAsync(rootPath, filenames, settings.AutoPush, scope.Token).ConfigureAwait(false); } private static List ExpandFilenames(IEnumerable raw) =>