using CliWrap; using InnovEnergy.Lib.Utils; using static System.StringSplitOptions; using static InnovEnergy.Server.FirmwareCiDaemon.ExitException; namespace InnovEnergy.Server.FirmwareCiDaemon; public static class Fossil { public static String FossilFile { get; set; } public static String FossilUser { get; set; } // TODO: get commit/branch without checkout public static Commit Checkout(this Branch branch) { var fossilDir = Open(); Update(fossilDir, branch, FossilUser); return new Commit(fossilDir); } public static CommitInfo GetLatestCommitInfo(this Branch branch) { using var fossilDir = Open(); var (hash, comment) = Update(fossilDir, branch, FossilUser); return new CommitInfo { Hash = hash, Comment = comment, Branch = branch}; } private static Disposable Open() { var fossilDir = FileSystem.CreateTmpDir(); var fossilCmd = Cli .Wrap("fossil") .WithWorkingDirectory(fossilDir); var open = fossilCmd .WithArguments($"open {FossilFile} --empty") .ExecuteSync(); if (open.exitCode != 0) { fossilDir.Dispose(); Exit("failed to open " + Path.GetFileName(FossilFile) + "\n" + open.stdOut + "\n" + open.stdErr); } return fossilDir.BeforeDisposeDo(Close); void Close() => fossilCmd.WithArguments("close").ExecuteSync(); } public static (String hash, String comment) Update(String fossilDir, Branch branch, String fossilUser) { var fossil = Cli .Wrap("fossil") .WithArguments($"update --user {fossilUser} {branch.GetName()}") .WithWorkingDirectory(fossilDir) .WithValidation(CommandResultValidation.None) .ExecuteSync(); if (fossil.exitCode != 0) Exit($"failed to update!\n{fossil.stdOut}"); var fossilOutLines = fossil.stdOut.SplitLines(); const String checkoutPrefix = "updated-to:"; const String commentPrefix = "comment:"; var hash = fossilOutLines .Single(l => l.StartsWith(checkoutPrefix)) .Split(" ", RemoveEmptyEntries) .ElementAt(1); var comment = fossilOutLines .Single(l => l.StartsWith(commentPrefix)) .Substring(commentPrefix.Length) .SkipWhile(c => c == ' ') .TakeWhile(c => c != '(') // there is a (user: ig) at the end, stops at the first (, but whatever .Apply(String.Concat) .Trim(); return (hash, comment); } }