1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
import os
import subprocess
import sys
import tempfile
import unittest
from pathlib import Path
SCRIPT = Path(__file__).resolve().parent.parent / "scripts" / "publish_snapshot.py"
ENV = {**os.environ, "GIT_AUTHOR_NAME": "t", "GIT_AUTHOR_EMAIL": "t@t", "GIT_COMMITTER_NAME": "t",
"GIT_COMMITTER_EMAIL": "t@t", "GIT_CONFIG_GLOBAL": "/dev/null"}
def git(cwd, *args):
return subprocess.run(["git", *args], cwd=cwd, capture_output=True, text=True, env=ENV, check=True).stdout
class PublishSnapshotTest(unittest.TestCase):
def setUp(self):
self.tmp = tempfile.TemporaryDirectory()
t = Path(self.tmp.name)
self.src, self.dest, self.deny = t / "tool", t / "pub", t / "deny.txt"
self.src.mkdir()
git(self.src, "init", "-q", "-b", "master")
self.put({"wf.py": "print('hi')\n", "CHANGES.md": "# Changes\n\n- 2026-01-01 first.\n",
"wflib/a.py": "x = 1\n", "docs/d.md": "doc\n",
"inbox.md": "tracked inbox\n", "out/log": "x\n", "sub/__pycache__/c.pyc": "bin\n"})
(self.src / "wf.py").chmod(0o755)
self.commit("one")
self.deny.write_text("# private\nSecretProj\n\n")
def tearDown(self):
self.tmp.cleanup()
def put(self, files):
for p, text in files.items():
f = self.src / p
f.parent.mkdir(parents=True, exist_ok=True)
f.write_text(text)
def commit(self, msg):
git(self.src, "add", "-A")
git(self.src, "commit", "-qm", msg)
def run_it(self, *extra):
return subprocess.run([sys.executable, str(SCRIPT), str(self.dest), "--src", str(self.src),
"--denylist", str(self.deny), *extra], capture_output=True, text=True, env=ENV)
def files(self):
return sorted(git(self.dest, "ls-files").split())
def test_first_run_one_commit_excludes(self):
r = self.run_it()
self.assertEqual(r.returncode, 0, r.stderr)
self.assertEqual(self.files(), ["CHANGES.md", "docs/d.md", "wf.py", "wflib/a.py"])
self.assertEqual(git(self.dest, "log", "--format=%s").splitlines(), ["initial public snapshot"])
self.assertTrue(os.access(self.dest / "wf.py", os.X_OK))
self.assertEqual(git(self.dest, "remote"), "")
def test_denylist_hit_content_and_path_writes_nothing(self):
self.put({"docs/d.md": "doc\nsee secretproj here\n", "SecretProj.md": "x\n"})
self.commit("leak")
r = self.run_it()
self.assertEqual(r.returncode, 1)
self.assertIn("docs/d.md:2: SecretProj", r.stderr)
self.assertIn("SecretProj.md: SecretProj (path)", r.stderr)
self.assertFalse(self.dest.exists())
def test_uncommitted_files_not_published(self):
(self.src / "wip.py").write_text("SecretProj\n")
r = self.run_it()
self.assertEqual(r.returncode, 0, r.stderr)
self.assertNotIn("wip.py", self.files())
def test_missing_or_empty_denylist_refuses(self):
self.deny.unlink()
r = self.run_it()
self.assertEqual(r.returncode, 1)
self.assertIn("no denylist", r.stderr)
self.deny.write_text("# only comments\n")
self.assertEqual(self.run_it().returncode, 1)
self.assertFalse(self.dest.exists())
def test_second_run_commit_message_new_changes_lines(self):
self.run_it()
self.put({"CHANGES.md": "# Changes\n\n- 2026-01-03 third.\n- 2026-01-02 second.\n- 2026-01-01 first.\n",
"wflib/b.py": "y = 2\n"})
(self.src / "docs/d.md").unlink()
self.commit("two")
r = self.run_it()
self.assertEqual(r.returncode, 0, r.stderr)
self.assertEqual(git(self.dest, "log", "-1", "--format=%B").strip(),
"public snapshot\n\n- 2026-01-03 third.\n- 2026-01-02 second.")
self.assertEqual(self.files(), ["CHANGES.md", "wf.py", "wflib/a.py", "wflib/b.py"])
self.assertEqual(len(git(self.dest, "log", "--format=%h").split()), 2)
def test_no_change_no_commit(self):
self.run_it()
r = self.run_it()
self.assertEqual(r.returncode, 0, r.stderr)
self.assertIn("nothing new", r.stdout)
self.assertEqual(len(git(self.dest, "log", "--format=%h").split()), 1)
def test_ref_option_and_never_touches_remote(self):
self.run_it()
git(self.dest, "remote", "add", "home", "/nonexistent")
self.put({"wflib/a.py": "x = 2\n"})
self.commit("two")
self.assertEqual(self.run_it("--ref", "HEAD~1").stdout.strip(), "nothing new: no commit")
r = self.run_it()
self.assertIn("committed", r.stdout)
self.assertEqual(git(self.dest, "remote").split(), ["home"])
def test_nonempty_non_git_dest_refused(self):
self.dest.mkdir()
(self.dest / "keep.txt").write_text("x")
r = self.run_it()
self.assertEqual(r.returncode, 1)
self.assertIn("not a git repo", r.stderr)
if __name__ == "__main__":
unittest.main()
|