mirror of
https://github.com/gastownhall/beads.git
synced 2026-09-14 20:17:24 +08:00
6748ef650c
* build: make repository text EOL deterministic Apply one repository-wide LF policy to detected text so Windows checkout settings cannot turn ordinary Go source or future text formats into CRLF. Preserve concise rationale for LF-sensitive hook templates, embedded Markdown, migration hashes, and generated-doc comparisons; keep the tracked JPEG explicitly binary and remove redundant path selectors. Exercise a real isolated Git checkout with core.autocrlf=true through a narrow test package. Bind the existing required Ubuntu, macOS, and Windows matrix to exact expected GOOS values, fail closed on missing or wrong host identity and skipped or zero EOL coverage, and preserve the original doc-freshness command as a separate step. Resolve and positively identify one canonical Git executable, reuse it under a curated environment with repo-local hooks, and protect the workflow topology with regression tests. Bind the required aggregate to startup-clean absolute Linux Bash and uname identities, require the exact POSIX checkout workspace, and re-enter privileged profile-free Bash with exec so ambient functions or startup state cannot turn a gate failure into success. Exercise the aggregate shell boundary in subprocess regressions with hostile exported source and exit functions, poisoned startup options, paired clean and failing fixtures, wrong-host falsification, and invalid-workspace cases. Agent-Signature: codex-gpt-5-unknown-reasoning on behalf of Ewen Cuthiell * build: split CI-gate hardening from EOL policy Remove the profile-free CI-gate host-binding chain and its structural and subprocess tests from PR #5319 so the final diff matches the accepted repository EOL motivation. Preserve the required three-host EOL policy lane and its CI Gate propagation. The merge-gate hardening will be reconstructed from current main under its own threat model and review vehicle. Agent-Signature: codex-gpt-5-unknown-reasoning on behalf of Ewen Cuthiell
102 lines
2.5 KiB
Go
102 lines
2.5 KiB
Go
package gitattributespolicy_test
|
|
|
|
import (
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func resolveEOLPolicyGit(t *testing.T) string {
|
|
t.Helper()
|
|
|
|
discovered, err := exec.LookPath("git")
|
|
if err != nil {
|
|
t.Fatalf("resolve Git once: %v", err)
|
|
}
|
|
absolute, err := filepath.Abs(discovered)
|
|
if err != nil {
|
|
t.Fatalf("make resolved Git path absolute: %v", err)
|
|
}
|
|
canonical, err := filepath.EvalSymlinks(absolute)
|
|
if err != nil {
|
|
t.Fatalf("canonicalize resolved Git path %q: %v", absolute, err)
|
|
}
|
|
canonical = filepath.Clean(canonical)
|
|
if !filepath.IsAbs(canonical) {
|
|
t.Fatalf("canonical Git path is not absolute: %q", canonical)
|
|
}
|
|
info, err := os.Stat(canonical)
|
|
if err != nil {
|
|
t.Fatalf("stat canonical Git path %q: %v", canonical, err)
|
|
}
|
|
if !info.Mode().IsRegular() {
|
|
t.Fatalf("canonical Git path is not a regular file: %q (%s)", canonical, info.Mode())
|
|
}
|
|
return canonical
|
|
}
|
|
|
|
func requireEOLPolicyGitVersion(t *testing.T, gitPath, repository string) {
|
|
t.Helper()
|
|
|
|
version := strings.TrimSpace(runEOLPolicyGit(t, gitPath, repository, "--version"))
|
|
if strings.ContainsAny(version, "\r\n") {
|
|
t.Fatalf("Git version identity is not one line: %q", version)
|
|
}
|
|
fields := strings.Fields(version)
|
|
if len(fields) < 3 || fields[0] != "git" || fields[1] != "version" ||
|
|
fields[2] == "" || fields[2][0] < '0' || fields[2][0] > '9' ||
|
|
!strings.Contains(fields[2], ".") {
|
|
t.Fatalf("resolved executable did not positively identify as Git: %q", version)
|
|
}
|
|
}
|
|
|
|
func runEOLPolicyGit(
|
|
t *testing.T,
|
|
gitPath string,
|
|
repository string,
|
|
arguments ...string,
|
|
) string {
|
|
t.Helper()
|
|
command := exec.Command(gitPath, arguments...)
|
|
command.Dir = repository
|
|
command.Env = eolPolicyGitEnvironment(repository, gitPath)
|
|
output, err := command.CombinedOutput()
|
|
if err != nil {
|
|
t.Fatalf("git %s failed: %v\n%s", strings.Join(arguments, " "), err, output)
|
|
}
|
|
return string(output)
|
|
}
|
|
|
|
func eolPolicyGitEnvironment(repository, gitPath string) []string {
|
|
environment := make([]string, 0, 18)
|
|
for _, name := range []string{
|
|
"COMSPEC",
|
|
"LANG",
|
|
"LC_ALL",
|
|
"LC_CTYPE",
|
|
"PATHEXT",
|
|
"SYSTEMDRIVE",
|
|
"SYSTEMROOT",
|
|
"TEMP",
|
|
"TMP",
|
|
"TMPDIR",
|
|
"WINDIR",
|
|
} {
|
|
if value, ok := os.LookupEnv(name); ok {
|
|
environment = append(environment, name+"="+value)
|
|
}
|
|
}
|
|
return append(
|
|
environment,
|
|
"PATH="+filepath.Dir(gitPath),
|
|
"HOME="+repository,
|
|
"XDG_CONFIG_HOME="+filepath.Join(repository, ".xdg"),
|
|
"GIT_ATTR_NOSYSTEM=1",
|
|
"GIT_CONFIG_GLOBAL="+os.DevNull,
|
|
"GIT_CONFIG_NOSYSTEM=1",
|
|
"GIT_PAGER=cat",
|
|
"GIT_TERMINAL_PROMPT=0")
|
|
}
|