< Summary

Information
Class: Punch.CLI.PunchCommand
Assembly: punch
File(s): /home/runner/work/punch/punch/src/Punch.CLI/PunchCommand.cs
Line coverage
49%
Covered lines: 35
Uncovered lines: 36
Coverable lines: 71
Total lines: 99
Line coverage: 49.2%
Branch coverage
65%
Covered branches: 13
Total branches: 20
Branch coverage: 65%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
Execute(...)65%822046.26%

File(s)

/home/runner/work/punch/punch/src/Punch.CLI/PunchCommand.cs

#LineLine coverage
 1using System.Reflection;
 2using Spectre.Console;
 3using Spectre.Console.Cli;
 4
 5namespace Punch.CLI;
 6
 7internal sealed class PunchCommand : Command<PunchCommandSettings>
 8{
 9    private readonly IAnsiConsole _console;
 10
 711    public PunchCommand(IAnsiConsole console)
 712    {
 713        _console = console;
 714    }
 15
 16    public override int Execute(CommandContext context, PunchCommandSettings settings)
 717    {
 718        if (settings.Version)
 219        {
 220            var version = Assembly.GetExecutingAssembly()
 221                .GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion ?? "0.0.0";
 222            Console.WriteLine(version);
 223            return 0;
 24        }
 25
 526        if (settings.Date != null && settings.Yesterday)
 127        {
 128            Console.Error.WriteLine("Cannot combine --date and --yesterday.");
 129            return 1;
 30        }
 31
 32        DateOnly workingDate;
 433        if (settings.Date != null)
 234        {
 235            if (!DateOnly.TryParseExact(settings.Date, "yyyy-MM-dd", out workingDate))
 136            {
 137                Console.Error.WriteLine($"Invalid date format: '{settings.Date}'. Expected yyyy-MM-dd.");
 138                return 1;
 39            }
 140        }
 241        else if (settings.Yesterday)
 242        {
 243            workingDate = DateOnly.FromDateTime(DateTime.Now).AddDays(-1);
 244        }
 45        else
 046        {
 047            workingDate = DateOnly.FromDateTime(DateTime.Now);
 048        }
 49
 350        var filePath = PunchStorage.GetDisplayPath(workingDate);
 51        DaySchedule schedule;
 52        try
 353        {
 354            schedule = new DaySchedule(PunchStorage.Load(workingDate));
 055        }
 356        catch (Exception ex)
 357        {
 358            _console.MarkupLine($"[bold red]Error:[/] Failed to load time log from [bold cyan]{Markup.Escape(filePath)}[
 359            _console.MarkupLine($"[bold yellow]Reason:[/] {Markup.Escape(ex.Message)}");
 360            return 1;
 61        }
 62
 063        var cursorSlot = 34; // default to 8:30am
 064        if (schedule.Count > 0)
 065        {
 066            var lastEnd = schedule.Blocks.Max(b => b.StartSlot + b.Length);
 067            if (lastEnd < 96)
 068                cursorSlot = lastEnd;
 069        }
 70
 071        var appSettings = PunchStorage.LoadSettings();
 072        var session = new PunchSession(schedule, workingDate, filePath, cursorSlot, appSettings.GetTargetHours(workingDa
 73
 074        AnsiConsole.AlternateScreen(() =>
 075        {
 076            try
 077            {
 078                AnsiConsole.Cursor.Hide();
 079
 080            var layout = new Layout("Root")
 081                .SplitRows(
 082                    new Layout("Timeline").Size(5),
 083                    new Layout("Messages").Ratio(4),
 084                    new Layout("Input").Size(4),
 085                    new Layout("StatusBar").Size(1));
 086            var view = new PunchView(layout);
 087            var controller = new PunchController(session, view);
 088
 089            AnsiConsole.Live(layout).Start(controller.Run);
 090            }
 091            finally
 092            {
 093                AnsiConsole.Cursor.Show();
 094            }
 095        });
 96
 097        return 0;
 798    }
 99}