{ nixpkgs, treefmt-nix, git-hooks, releaseScriptPath, shellHookTemplatePath, }: let lib = nixpkgs.lib; supportedSystems = [ "x86_64-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin" ]; defaultReleaseChannels = [ "alpha" "beta" "rc" "internal" ]; importPkgs = nixpkgsInput: system: import nixpkgsInput { inherit system; }; duplicateStrings = names: lib.unique ( builtins.filter ( name: builtins.length (builtins.filter (candidate: candidate == name) names) > 1 ) names ); mergeUniqueAttrs = label: left: right: let overlap = builtins.attrNames (lib.intersectAttrs left right); in if overlap != [ ] then throw "repo-lib: duplicate ${label}: ${lib.concatStringsSep ", " overlap}" else left // right; sanitizeName = name: lib.strings.sanitizeDerivationName name; normalizeStrictTool = pkgs: tool: let version = { args = [ "--version" ]; regex = null; group = 0; line = 1; } // (tool.version or { }); banner = { color = "YELLOW"; } // (tool.banner or { }); executable = if tool ? exe && tool.exe != null then "${lib.getExe' tool.package tool.exe}" else "${lib.getExe tool.package}"; in if !(tool ? package) then throw "repo-lib: tool '${tool.name or ""}' is missing 'package'" else { kind = "strict"; inherit executable version banner; name = tool.name; package = tool.package; required = tool.required or true; }; normalizeLegacyTool = pkgs: tool: if tool ? package then normalizeStrictTool pkgs tool else { kind = "legacy"; name = tool.name; command = tool.bin; versionCommand = tool.versionCmd or "--version"; banner = { color = tool.color or "YELLOW"; }; required = tool.required or false; }; normalizeCheck = pkgs: name: rawCheck: let check = { stage = "pre-commit"; passFilenames = false; runtimeInputs = [ ]; } // rawCheck; wrapperName = "repo-lib-check-${sanitizeName name}"; wrapper = pkgs.writeShellApplication { name = wrapperName; runtimeInputs = check.runtimeInputs; text = '' set -euo pipefail ${check.command} ''; }; in if !(check ? command) then throw "repo-lib: check '${name}' is missing 'command'" else if !(builtins.elem check.stage [ "pre-commit" "pre-push" ]) then throw "repo-lib: check '${name}' has unsupported stage '${check.stage}'" else { enable = true; entry = "${wrapper}/bin/${wrapperName}"; pass_filenames = check.passFilenames; stages = [ check.stage ]; }; normalizeReleaseStep = step: if step ? writeFile then { kind = "writeFile"; path = step.writeFile.path; text = step.writeFile.text; runtimeInputs = [ ]; } else if step ? replace then { kind = "replace"; path = step.replace.path; regex = step.replace.regex; replacement = step.replace.replacement; runtimeInputs = [ ]; } else if step ? run && builtins.isAttrs step.run then { kind = "run"; script = step.run.script; runtimeInputs = step.run.runtimeInputs or [ ]; } else if step ? run then { kind = "run"; script = step.run; runtimeInputs = [ ]; } else if step ? file then { kind = "writeFile"; path = step.file; text = step.content; runtimeInputs = [ ]; } else throw "repo-lib: release step must contain one of writeFile, replace, or run"; releaseStepScript = step: if step.kind == "writeFile" then '' target_path="$ROOT_DIR/${step.path}" mkdir -p "$(dirname "$target_path")" cat >"$target_path" << NIXEOF ${step.text} NIXEOF log "Generated version file: ${step.path}" '' else if step.kind == "replace" then '' target_path="$ROOT_DIR/${step.path}" REPO_LIB_STEP_REGEX=$(cat <<'NIXEOF' ${step.regex} NIXEOF ) REPO_LIB_STEP_REPLACEMENT=$(cat <