< Summary

Information
Class: Orchestrator.Commands.Utility.Snapshots.SnapshotsEncryptCommand
Assembly: Orchestrator
File(s): /home/runner/work/KicktippAi/KicktippAi/src/Orchestrator/Commands/Utility/Snapshots/SnapshotsEncryptCommand.cs
Line coverage
100%
Covered lines: 72
Uncovered lines: 0
Coverable lines: 72
Total lines: 129
Line coverage: 100%
Branch coverage
100%
Covered branches: 12
Total branches: 12
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
ExecuteAsync()100%66100%
EncryptSnapshotsAsync()100%22100%
<EncryptSnapshotsAsync()100%44100%

File(s)

/home/runner/work/KicktippAi/KicktippAi/src/Orchestrator/Commands/Utility/Snapshots/SnapshotsEncryptCommand.cs

#LineLine coverage
 1using Microsoft.Extensions.Logging;
 2using Spectre.Console;
 3using Spectre.Console.Cli;
 4
 5namespace Orchestrator.Commands.Utility.Snapshots;
 6
 7/// <summary>
 8/// Command for encrypting HTML snapshots for safe committing.
 9/// </summary>
 10public class SnapshotsEncryptCommand : AsyncCommand<SnapshotsEncryptSettings>
 11{
 12    private readonly IAnsiConsole _console;
 13    private readonly ILogger<SnapshotsEncryptCommand> _logger;
 14
 115    public SnapshotsEncryptCommand(IAnsiConsole console, ILogger<SnapshotsEncryptCommand> logger)
 16    {
 117        _console = console;
 118        _logger = logger;
 119    }
 20
 21    public override async Task<int> ExecuteAsync(CommandContext context, SnapshotsEncryptSettings settings)
 22    {
 23
 24        try
 25        {
 26            // Get encryption key from environment (loaded at startup)
 127            var encryptionKey = Environment.GetEnvironmentVariable("KICKTIPP_FIXTURE_KEY");
 128            if (string.IsNullOrEmpty(encryptionKey))
 29            {
 130                _console.MarkupLine("[red]Error: KICKTIPP_FIXTURE_KEY environment variable is not set.[/]");
 131                _console.WriteLine();
 132                _console.MarkupLine("[yellow]To generate a new key:[/]");
 133                _console.MarkupLine("[dim]  .\\Encrypt-Fixture.ps1 -GenerateKey[/]");
 134                _console.WriteLine();
 135                _console.MarkupLine("[yellow]Then store the key in:[/]");
 136                _console.MarkupLine("[dim]  <repo>/../KicktippAi.Secrets/tests/KicktippIntegration.Tests/.env[/]");
 137                return 1;
 38            }
 39
 140            var inputPath = Path.GetFullPath(settings.InputDirectory);
 41            // Output to community-specific subdirectory
 142            var outputPath = Path.GetFullPath(Path.Combine(settings.OutputDirectory, settings.Community));
 43
 144            if (!Directory.Exists(inputPath))
 45            {
 146                _console.MarkupLine($"[red]Error: Input directory not found: {inputPath}[/]");
 147                return 1;
 48            }
 49
 150            _console.MarkupLine("[green]Encrypting snapshots...[/]");
 151            _console.MarkupLine($"[blue]Community:[/] [yellow]{settings.Community}[/]");
 152            _console.MarkupLine($"[blue]Input directory:[/] [yellow]{inputPath}[/]");
 153            _console.MarkupLine($"[blue]Output directory:[/] [yellow]{outputPath}[/]");
 154            _console.WriteLine();
 55
 156            var (encryptedCount, deletedCount) = await EncryptSnapshotsAsync(
 157                _console, inputPath, outputPath, encryptionKey, settings.DeleteOriginals);
 58
 159            _console.WriteLine();
 160            _console.MarkupLine($"[green]Done![/] Encrypted {encryptedCount} file(s) to [yellow]{outputPath}[/]");
 61
 162            if (deletedCount > 0)
 63            {
 164                _console.MarkupLine($"[dim]Deleted {deletedCount} original HTML file(s)[/]");
 65            }
 66
 167            return 0;
 68        }
 169        catch (Exception ex)
 70        {
 171            _logger.LogError(ex, "Error encrypting snapshots");
 172            _console.MarkupLine($"[red]Error:[/] {ex.Message}");
 173            return 1;
 74        }
 175    }
 76
 77    internal static async Task<(int encryptedCount, int deletedCount)> EncryptSnapshotsAsync(
 78        IAnsiConsole console,
 79        string inputPath,
 80        string outputPath,
 81        string encryptionKey,
 82        bool deleteOriginals)
 83    {
 184        var encryptedCount = 0;
 185        var deletedCount = 0;
 86
 87        // Create output directory
 188        Directory.CreateDirectory(outputPath);
 89
 90        // Find all HTML files
 191        var htmlFiles = Directory.GetFiles(inputPath, "*.html");
 92
 193        if (htmlFiles.Length == 0)
 94        {
 195            console.MarkupLine("[yellow]No HTML files found to encrypt[/]");
 196            return (0, 0);
 97        }
 98
 199        await console.Status()
 1100            .StartAsync("Encrypting files...", async ctx =>
 1101            {
 1102                foreach (var htmlFile in htmlFiles)
 1103                {
 1104                    var fileName = Path.GetFileName(htmlFile);
 1105                    ctx.Status($"Encrypting {fileName}...");
 1106
 1107                    // Read and encrypt
 1108                    var content = await File.ReadAllTextAsync(htmlFile);
 1109                    var encrypted = SnapshotEncryptor.Encrypt(content, encryptionKey);
 1110
 1111                    // Write encrypted file
 1112                    var outputFile = Path.Combine(outputPath, $"{fileName}.enc");
 1113                    await File.WriteAllTextAsync(outputFile, encrypted);
 1114                    encryptedCount++;
 1115
 1116                    console.MarkupLine($"[green]✓[/] Encrypted {fileName} → {Path.GetFileName(outputFile)}");
 1117
 1118                    // Delete original if requested
 1119                    if (deleteOriginals)
 1120                    {
 1121                        File.Delete(htmlFile);
 1122                        deletedCount++;
 1123                    }
 1124                }
 1125            });
 126
 1127        return (encryptedCount, deletedCount);
 1128    }
 129}