// SPDX-License-Identifier: AGPL-3.0-only // SPDX-FileCopyrightText: Copyright (C) 2026 Catcrafts® export module Crafter.Review:Artifact; import std; // The frozen artifact and the tree it was cut from: the hash formula, the // HEAD a format-patch export names, the tree checks. export namespace Crafter::Review::Artifact { std::string Sha256File(const std::filesystem::path& path); // reply: the sha256 of the draft file; series and commits: the sha256 of // the sorted *.patch files concatenated (`cat $(ls *.patch | sort) | // sha256sum`). std::string ArtifactHash(std::string_view mode, const std::filesystem::path& path); // The *.patch names in the directory, sorted by code point. std::vector PatchFiles(const std::filesystem::path& path); // K of a format-patch file name, ^(?:v\d+-)?(\d{4})-: 1 for // 0001-x.patch and v2-0001-x.patch; nullopt for a name without one. std::optional PatchNumber(std::string_view name); // {K: text} of the export, each patch read as Dyn::ReadText reads a file // (strict UTF-8, universal newlines). Dyn::Error (AttributeError) for a // patch name without a number. std::map PatchTexts(const std::filesystem::path& path); // The commit the last patch was cut from (its `From ` line): the // range HEAD. std::optional PatchHead(const std::filesystem::path& path); // `git -C `'s stdout; Dyn::Error (RuntimeError) with git's // message when it fails. std::string Git(const std::filesystem::path& tree, std::span args); bool IsToplevel(const std::filesystem::path& tree); std::string TreeHead(const std::filesystem::path& tree); // Tracked changes only (untracked files never reach a commit); "" when // clean. std::string TreeDirty(const std::filesystem::path& tree); }