cgitize 8.0.6__tar.gz → 9.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. {cgitize-8.0.6 → cgitize-9.1.0}/.github/workflows/ci.yml +10 -2
  2. cgitize-9.1.0/.gitmodules +3 -0
  3. cgitize-9.1.0/CHANGELOG.md +73 -0
  4. {cgitize-8.0.6 → cgitize-9.1.0}/DEVELOPMENT.md +19 -16
  5. {cgitize-8.0.6 → cgitize-9.1.0}/Makefile +12 -12
  6. {cgitize-8.0.6 → cgitize-9.1.0}/PKG-INFO +1 -1
  7. {cgitize-8.0.6 → cgitize-9.1.0}/cgitize/cgit.py +8 -9
  8. {cgitize-8.0.6 → cgitize-9.1.0}/cgitize/git.py +25 -45
  9. {cgitize-8.0.6 → cgitize-9.1.0}/cgitize.egg-info/PKG-INFO +1 -1
  10. {cgitize-8.0.6 → cgitize-9.1.0}/cgitize.egg-info/SOURCES.txt +24 -10
  11. {cgitize-8.0.6 → cgitize-9.1.0}/cgitize.egg-info/scm_file_list.json +24 -10
  12. cgitize-9.1.0/cgitize.egg-info/scm_version.json +8 -0
  13. {cgitize-8.0.6 → cgitize-9.1.0}/docker/Dockerfile +3 -5
  14. {cgitize-8.0.6 → cgitize-9.1.0}/docker/README.md +8 -5
  15. cgitize-9.1.0/test/integration/docker/docker-compose.yml +29 -0
  16. cgitize-9.1.0/test/integration/docker/git_server/Dockerfile +16 -0
  17. cgitize-9.1.0/test/integration/docker/git_server/entrypoint.sh +64 -0
  18. cgitize-9.1.0/test/integration/docker/git_server/setup.sh +68 -0
  19. {cgitize-8.0.6 → cgitize-9.1.0}/test/integration/docker/test.sh +3 -82
  20. cgitize-9.1.0/test/integration/lib/basic.sh +72 -0
  21. cgitize-9.1.0/test/integration/lib/common.sh +92 -0
  22. cgitize-9.1.0/test/integration/lib/example.sh +47 -0
  23. cgitize-9.1.0/test/integration/runner/.gitattributes +3 -0
  24. cgitize-9.1.0/test/integration/runner/LICENSE.txt +21 -0
  25. cgitize-9.1.0/test/integration/runner/README.md +95 -0
  26. cgitize-9.1.0/test/integration/runner/harness +148 -0
  27. cgitize-9.1.0/test/integration/runner/src/log.sh +139 -0
  28. cgitize-9.1.0/test/integration/runner/src/main.sh +148 -0
  29. cgitize-9.1.0/test/integration/runner/src/test.sh +23 -0
  30. cgitize-9.1.0/test/integration/tst-basic-error.sh +21 -0
  31. cgitize-9.1.0/test/integration/tst-basic.sh +21 -0
  32. cgitize-9.1.0/test/integration/tst-example-https-private.sh +33 -0
  33. cgitize-9.1.0/test/integration/tst-example-https.sh +31 -0
  34. cgitize-9.1.0/test/integration/tst-example-one-repo.sh +10 -0
  35. cgitize-9.1.0/test/integration/tst-example-ssh-private.sh +33 -0
  36. cgitize-9.1.0/test/integration/tst-example-ssh.sh +31 -0
  37. cgitize-8.0.6/.dockerignore +0 -5
  38. cgitize-8.0.6/cgitize.egg-info/scm_version.json +0 -8
  39. cgitize-8.0.6/docker-compose.yml +0 -25
  40. cgitize-8.0.6/examples/docker/cgitize.toml +0 -7
  41. cgitize-8.0.6/test/integration/docker/.dockerignore +0 -5
  42. cgitize-8.0.6/test/integration/docker/docker-compose.yml +0 -21
  43. cgitize-8.0.6/test/integration/docker/git_server/Dockerfile +0 -24
  44. cgitize-8.0.6/test/integration/docker/git_server/setup_repo.sh +0 -30
  45. cgitize-8.0.6/test/integration/example/test.sh +0 -312
  46. cgitize-8.0.6/test/integration/local/test.sh +0 -244
  47. {cgitize-8.0.6 → cgitize-9.1.0}/.git-blame-ignore-revs +0 -0
  48. {cgitize-8.0.6 → cgitize-9.1.0}/.gitattributes +0 -0
  49. {cgitize-8.0.6 → cgitize-9.1.0}/.github/dependabot.yml +0 -0
  50. {cgitize-8.0.6 → cgitize-9.1.0}/.github/workflows/maintenance.yml +0 -0
  51. {cgitize-8.0.6 → cgitize-9.1.0}/.gitignore +0 -0
  52. {cgitize-8.0.6 → cgitize-9.1.0}/.python-version +0 -0
  53. {cgitize-8.0.6 → cgitize-9.1.0}/LICENSE.txt +0 -0
  54. {cgitize-8.0.6 → cgitize-9.1.0}/README.md +0 -0
  55. {cgitize-8.0.6 → cgitize-9.1.0}/cgitize/__init__.py +0 -0
  56. {cgitize-8.0.6 → cgitize-9.1.0}/cgitize/bitbucket.py +0 -0
  57. {cgitize-8.0.6 → cgitize-9.1.0}/cgitize/config.py +0 -0
  58. {cgitize-8.0.6 → cgitize-9.1.0}/cgitize/github.py +0 -0
  59. {cgitize-8.0.6 → cgitize-9.1.0}/cgitize/gitlab.py +0 -0
  60. {cgitize-8.0.6 → cgitize-9.1.0}/cgitize/header.py +0 -0
  61. {cgitize-8.0.6 → cgitize-9.1.0}/cgitize/main.py +0 -0
  62. {cgitize-8.0.6 → cgitize-9.1.0}/cgitize/repo.py +0 -0
  63. {cgitize-8.0.6 → cgitize-9.1.0}/cgitize/url.py +0 -0
  64. {cgitize-8.0.6 → cgitize-9.1.0}/cgitize/utils.py +0 -0
  65. {cgitize-8.0.6 → cgitize-9.1.0}/cgitize/version.py +0 -0
  66. {cgitize-8.0.6 → cgitize-9.1.0}/cgitize.egg-info/dependency_links.txt +0 -0
  67. {cgitize-8.0.6 → cgitize-9.1.0}/cgitize.egg-info/entry_points.txt +0 -0
  68. {cgitize-8.0.6 → cgitize-9.1.0}/cgitize.egg-info/requires.txt +0 -0
  69. {cgitize-8.0.6 → cgitize-9.1.0}/cgitize.egg-info/top_level.txt +0 -0
  70. {cgitize-8.0.6 → cgitize-9.1.0}/docker/frontend/Dockerfile +0 -0
  71. {cgitize-8.0.6 → cgitize-9.1.0}/docker/frontend/cmd.sh +0 -0
  72. {cgitize-8.0.6 → cgitize-9.1.0}/docker/frontend/etc/cgit/common +0 -0
  73. {cgitize-8.0.6 → cgitize-9.1.0}/docker/frontend/etc/cgitrc +0 -0
  74. {cgitize-8.0.6 → cgitize-9.1.0}/docker/frontend/etc/nginx/conf.d/default.conf +0 -0
  75. {cgitize-8.0.6 → cgitize-9.1.0}/docker/frontend/usr/lib/cgit/filters/about-formatting.sh +0 -0
  76. {cgitize-8.0.6 → cgitize-9.1.0}/docker/frontend/usr/lib/cgit/filters/html-converters/.gitattributes +0 -0
  77. {cgitize-8.0.6 → cgitize-9.1.0}/docker/frontend/usr/lib/cgit/filters/html-converters/md2html +0 -0
  78. {cgitize-8.0.6 → cgitize-9.1.0}/docker/get_output_dir.py +0 -0
  79. {cgitize-8.0.6 → cgitize-9.1.0}/docker/in_cron.sh +0 -0
  80. /cgitize-8.0.6/docker/cgitize.sh → /cgitize-9.1.0/docker/run.sh +0 -0
  81. {cgitize-8.0.6 → cgitize-9.1.0}/docs/api.md +0 -0
  82. {cgitize-8.0.6 → cgitize-9.1.0}/docs/auth.md +0 -0
  83. {cgitize-8.0.6 → cgitize-9.1.0}/examples/cgitize.toml +0 -0
  84. {cgitize-8.0.6 → cgitize-9.1.0}/prelude.mk +0 -0
  85. {cgitize-8.0.6 → cgitize-9.1.0}/pyproject.toml +0 -0
  86. {cgitize-8.0.6 → cgitize-9.1.0}/requirements.txt +0 -0
  87. {cgitize-8.0.6 → cgitize-9.1.0}/setup.cfg +0 -0
  88. {cgitize-8.0.6 → cgitize-9.1.0}/test/__init__.py +0 -0
  89. {cgitize-8.0.6/test/integration/docker/cgitize → cgitize-9.1.0/test/integration/docker}/.gitignore +0 -0
  90. {cgitize-8.0.6/test/integration/docker/cgitize → cgitize-9.1.0/test/integration/docker}/etc/cgitize.toml +0 -0
  91. {cgitize-8.0.6 → cgitize-9.1.0}/test/set_credentials.sh +0 -0
  92. {cgitize-8.0.6 → cgitize-9.1.0}/test/unit/__init__.py +0 -0
  93. {cgitize-8.0.6 → cgitize-9.1.0}/test/unit/test_bitbucket.py +0 -0
  94. {cgitize-8.0.6 → cgitize-9.1.0}/test/unit/test_github.py +0 -0
  95. {cgitize-8.0.6 → cgitize-9.1.0}/test/unit/test_gitlab.py +0 -0
@@ -43,6 +43,7 @@ jobs:
43
43
  uses: actions/checkout@v7
44
44
  with:
45
45
  fetch-depth: 0
46
+ submodules: recursive
46
47
  - name: Set up Python
47
48
  uses: actions/setup-python@v7
48
49
  with:
@@ -61,6 +62,8 @@ jobs:
61
62
  steps:
62
63
  - name: Checkout
63
64
  uses: actions/checkout@v7
65
+ with:
66
+ submodules: recursive
64
67
  - name: Integration test (Docker)
65
68
  run: sudo make test/docker
66
69
 
@@ -80,6 +83,8 @@ jobs:
80
83
  steps:
81
84
  - name: Checkout
82
85
  uses: actions/checkout@v7
86
+ with:
87
+ submodules: recursive
83
88
  - name: Set up Python
84
89
  uses: actions/setup-python@v7
85
90
  with:
@@ -90,8 +95,8 @@ jobs:
90
95
  uses: webfactory/ssh-agent@v0.10.0
91
96
  with:
92
97
  ssh-private-key: '${{ secrets.SSH_KEY }}'
93
- - name: Integration test (example config)
94
- run: make test/example
98
+ - name: Integration tests
99
+ run: make test/integration
95
100
 
96
101
  publish_docker:
97
102
  needs:
@@ -110,6 +115,8 @@ jobs:
110
115
  steps:
111
116
  - name: Checkout
112
117
  uses: actions/checkout@v7
118
+ with:
119
+ submodules: recursive
113
120
  # https://github.com/docker/metadata-action#semver
114
121
  - id: meta
115
122
  name: Docker Hub metadata
@@ -168,6 +175,7 @@ jobs:
168
175
  uses: actions/checkout@v7
169
176
  with:
170
177
  fetch-depth: 0
178
+ submodules: recursive
171
179
  - name: Set up Python
172
180
  uses: actions/setup-python@v7
173
181
  - name: Verify package can be installed
@@ -0,0 +1,3 @@
1
+ [submodule "test/integration/local/runner"]
2
+ path = test/integration/runner
3
+ url = https://github.com/egor-tensin/test-harness.git
@@ -0,0 +1,73 @@
1
+ v9.0
2
+ ====
3
+
4
+ ### Breaking changes
5
+
6
+ * Docker images: SSH agent should now be mapped to /ssh/agent.sock (instead of
7
+ /ssh-agent.sock).
8
+
9
+ v9.1
10
+ ----
11
+
12
+ * The global ~/.gitconfig is no longer used for HTTPS authentication.
13
+ Instead, a temporary file is used.
14
+ * Internally, `git` is now executed with the `GIT_CONFIG_NOSYSTEM` and
15
+ `GIT_CONFIG_GLOBAL` environment variables set.
16
+ This might break existing setups in some way.
17
+
18
+ v8.0
19
+ ====
20
+
21
+ ### Breaking changes
22
+
23
+ * Since Bitbucket deprecated "app passwords", an Atlassian API token is now
24
+ required in place of those.
25
+ * In cgitize.toml, the field `bitbucket.username` is replaced with
26
+ `bitbucket.email`, since the API tokens are tied to the Atlassian account now.
27
+
28
+ v7.0
29
+ ====
30
+
31
+ ### Breaking changes
32
+
33
+ * For forge users, only publicly visible repositories are fetched by default.
34
+ * New fields in cgitize.toml `{github,bitbucket,gitlab}.users.*.{public,private}`
35
+ control whether to fetch public or private repositories, or both.
36
+ * The `public` field is set to `true` by default; `private` is `false`.
37
+
38
+ v6.0
39
+ ====
40
+
41
+ * Major version bumps for the dependencies.
42
+ * Otherwise, no breaking changes.
43
+
44
+ v5.0
45
+ ====
46
+
47
+ ### Breaking changes
48
+
49
+ * GitHub: private user repositories are also cloned now.
50
+ * This change is consistent with how Gitlab and Bitbucket backend work.
51
+ * If `github.token` is set in cgitize.toml, `github.username` must also be
52
+ set.
53
+
54
+ v5.1
55
+ ----
56
+
57
+ ### New features
58
+
59
+ * In case of an error, a message is displayed in the frontend's header.
60
+
61
+ v4.0
62
+ ====
63
+
64
+ ### Breaking changes
65
+
66
+ * Fields `access_token` & `app_password` in cgitize.toml renamed to simply
67
+ `token`.
68
+ * Repositories are cloned into directories with the ".git" suffix now.
69
+
70
+ v3.0
71
+ ====
72
+
73
+ * The latest release that I'm still not too lazy to look up.
@@ -8,8 +8,8 @@ Workspace setup
8
8
  Testing
9
9
  -------
10
10
 
11
- N.B.: `make test` is a shortcut for unit tests and the `local` integration
12
- test.
11
+ N.B.: `make test` is a shortcut for unit tests and the "basic" integration
12
+ tests.
13
13
 
14
14
  ### Unit tests
15
15
 
@@ -29,22 +29,24 @@ You can run `. test/set_credentials.sh`; it'll ask you to fill in the secrets.
29
29
 
30
30
  ### Integration
31
31
 
32
- * There're three integration tests: `local`, `docker` and `example`.
33
- Run them using
32
+ make test/integration
34
33
 
35
- make test/local
36
- sudo make test/docker
37
- make test/example
38
-
39
- * The `example` test uses the forges' APIs and might easily hit their rate
34
+ * The "example" tests use the forges' APIs and might easily hit their rate
40
35
  limits.
41
36
  Use the tokens used for unit tests.
42
- * Additionally, it tests cloning via SSH (the `clone_via_ssh` setting) too,
43
- so you need to add the secret project-specific SSH key to your agent as well
44
- (make sure it's the only one in the agent; if there's a key associated with
45
- another user, it could get used instead).
37
+ * Additionally, it tests cloning via SSH (the `clone_via_ssh` setting) too, so
38
+ you need to add the secret project-specific SSH key to your agent as well (make
39
+ sure it's the only one in the agent; if there's a key associated with another
40
+ user, it could get used instead).
41
+ * Run only basic integration tests:
42
+
43
+ make test/integration/basic
44
+
45
+ ### Docker setup
46
+
47
+ sudo make test/docker
46
48
 
47
- [examples/cgitize.toml]: examples/cgitize.toml
49
+ It's a separate test to check Docker container building & setup.
48
50
 
49
51
  Upgrading dependencies
50
52
  ----------------------
@@ -61,9 +63,10 @@ Upgrading dependencies
61
63
  Releases
62
64
  --------
63
65
 
64
- * Make a new tag using the semantic versioning policy (you can use [tag-release]
65
- to do that), review and push it.
66
66
  * For a new major version, update the version in the docker-compose definition
67
67
  in docker/README.md.
68
+ * Update CHANGELOG.md if necessary.
69
+ * Make a new tag using the semantic versioning policy (you can use [tag-release]
70
+ to do that), review and push it.
68
71
 
69
72
  [tag-release]: https://github.com/egor-tensin/tag-release
@@ -50,7 +50,7 @@ python:
50
50
  repl: python
51
51
 
52
52
  .PHONY: test
53
- test: test/unit test/local
53
+ test: test/unit test/integration/basic
54
54
 
55
55
  .PHONY: test/unit
56
56
  test/unit:
@@ -59,12 +59,19 @@ test/unit:
59
59
  @echo ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
60
60
  python -m unittest --verbose --buffer
61
61
 
62
- .PHONY: test/local
63
- test/local:
62
+ .PHONY: test/integration
63
+ test/integration:
64
64
  @echo ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
65
- @echo Integration test: local
65
+ @echo Integration tests
66
66
  @echo ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
67
- ./test/integration/local/test.sh
67
+ ./test/integration/runner/harness
68
+
69
+ .PHONY: test/integration/basic
70
+ test/integration/basic:
71
+ @echo ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
72
+ @echo Basic integration tests
73
+ @echo ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
74
+ ./test/integration/runner/harness -f '*basic*'
68
75
 
69
76
  .PHONY: test/docker
70
77
  test/docker:
@@ -72,10 +79,3 @@ test/docker:
72
79
  @echo Integration test: docker
73
80
  @echo ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
74
81
  ./test/integration/docker/test.sh
75
-
76
- .PHONY: test/example
77
- test/example:
78
- @echo ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
79
- @echo Integration test: example
80
- @echo ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
81
- ./test/integration/example/test.sh
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cgitize
3
- Version: 8.0.6
3
+ Version: 9.1.0
4
4
  Summary: Self-host your repositories using cgit
5
5
  Author-email: Egor Tensin <egor@tensin.name>
6
6
  License-Expression: MIT
@@ -70,7 +70,7 @@ class AgeFile:
70
70
  # Except I think that the committer date, not author date better
71
71
  # represents activity.
72
72
  with chdir(repo_dir):
73
- success, output = Git.capture(
73
+ success, output = Git().capture(
74
74
  "for-each-ref",
75
75
  "--sort=-committerdate",
76
76
  "--count=1",
@@ -123,7 +123,7 @@ class CGitRepositories:
123
123
  return self._mirror(repo)
124
124
 
125
125
  with chdir(repo_dir):
126
- success, output = Git.capture("rev-parse", "--is-inside-work-tree")
126
+ success, output = Git().capture("rev-parse", "--is-inside-work-tree")
127
127
  if not success:
128
128
  # Overwrite the existing directory if it's not a Git repository.
129
129
  logging.warning(
@@ -132,7 +132,7 @@ class CGitRepositories:
132
132
  )
133
133
  return self._mirror(repo)
134
134
 
135
- success, output = Git.capture("config", "--get", "remote.origin.url")
135
+ success, output = Git().capture("config", "--get", "remote.origin.url")
136
136
  if not success:
137
137
  # Every repository managed by this script should have the
138
138
  # 'origin' remote. If it doesn't, it's trash. Overwrite the
@@ -171,17 +171,16 @@ class CGitRepositories:
171
171
  except Exception as e:
172
172
  logging.exception(e)
173
173
  return False
174
- with Git.setup_auth(repo):
175
- return Git.check("clone", "--mirror", "--quiet", repo.clone_url, repo_dir)
174
+ with Git.setup_auth(repo) as git:
175
+ return git.check("clone", "--mirror", "--quiet", repo.clone_url, repo_dir)
176
176
 
177
177
  def _fix_upstream_url(self, repo):
178
178
  repo_dir = self.get_repo_dir(repo)
179
179
  with chdir(repo_dir):
180
- return Git.check("remote", "set-url", "origin", repo.clone_url)
180
+ return Git().check("remote", "set-url", "origin", repo.clone_url)
181
181
 
182
182
  def _update_existing(self, repo):
183
183
  logging.info("Updating repository '%s'", repo.name)
184
184
  repo_dir = self.get_repo_dir(repo)
185
- with chdir(repo_dir):
186
- with Git.setup_auth(repo):
187
- return Git.check("remote", "update", "--prune")
185
+ with chdir(repo_dir), Git.setup_auth(repo) as git:
186
+ return git.check("remote", "update", "--prune")
@@ -5,6 +5,7 @@
5
5
 
6
6
  from contextlib import contextmanager
7
7
  import os
8
+ import tempfile
8
9
 
9
10
  from cgitize import utils
10
11
 
@@ -12,37 +13,21 @@ GIT_ENV = os.environ.copy()
12
13
  GIT_ENV["GIT_SSH_COMMAND"] = (
13
14
  "ssh -oBatchMode=yes -oLogLevel=QUIET -oStrictHostKeyChecking=no -oUserKnownHostsFile=/dev/null"
14
15
  )
16
+ GIT_ENV["GIT_CONFIG_NOSYSTEM"] = "true"
17
+ GIT_ENV["GIT_CONFIG_GLOBAL"] = "/dev/null"
15
18
 
16
19
 
17
20
  class Config:
18
- def __init__(self, path):
19
- self.path = path
20
-
21
- def exists(self):
22
- return os.path.exists(self.path)
23
-
24
- def open(self, mode="r"):
25
- return open(self.path, mode=mode, encoding="utf-8")
26
-
27
- def read(self):
28
- with self.open(mode="r") as fd:
29
- return fd.read()
30
-
31
- def write(self, contents):
32
- with self.open(mode="w") as fd:
33
- fd.write(contents)
34
-
35
- @contextmanager
36
- def backup(self):
37
- old_contents = self.read()
38
- try:
39
- yield old_contents
40
- finally:
41
- self.write(old_contents)
42
-
43
21
  # What follows is an exteremely loose interpretation of what the .gitconfig
44
22
  # syntax is. The source was git-config(1).
45
23
 
24
+ @staticmethod
25
+ @contextmanager
26
+ def make_tmp():
27
+ tmp = tempfile.NamedTemporaryFile(mode="w", encoding="utf-8")
28
+ with tmp as result, utils.protected_file(result.name):
29
+ yield result
30
+
46
31
  class Section:
47
32
  def __init__(self, name, variables):
48
33
  Config.Section.validate_name(name)
@@ -148,31 +133,26 @@ class Config:
148
133
  class Git:
149
134
  EXE = "git"
150
135
 
151
- @staticmethod
152
- def check(*args, **kwargs):
153
- return utils.try_run(Git.EXE, *args, env=GIT_ENV, **kwargs)
136
+ def __init__(self, config=None):
137
+ self._env = GIT_ENV.copy()
138
+ if config is not None:
139
+ self._env["GIT_CONFIG_GLOBAL"] = config
154
140
 
155
- @staticmethod
156
- def capture(*args, **kwargs):
157
- return utils.try_capture(Git.EXE, *args, env=GIT_ENV, **kwargs)
141
+ def check(self, *args, **kwargs):
142
+ return utils.try_run(Git.EXE, *args, env=self._env, **kwargs)
158
143
 
159
- @staticmethod
160
- def get_global_config():
161
- return Config(os.path.expanduser("~/.gitconfig"))
144
+ def capture(self, *args, **kwargs):
145
+ return utils.try_capture(Git.EXE, *args, env=self._env, **kwargs)
162
146
 
163
147
  @staticmethod
164
148
  @contextmanager
165
149
  def setup_auth(repo):
166
150
  if not repo.url_auth:
167
- yield
151
+ yield Git()
168
152
  return
169
- config = Git.get_global_config()
170
- with utils.protected_file(config.path):
171
- with config.backup() as old_contents:
172
- variables = [Config.Variable("insteadOf", repo.clone_url)]
173
- subsection = Config.Subsection(
174
- "url", repo.clone_url_with_auth, variables
175
- )
176
- new_contents = f"{old_contents}\n{subsection.format()}"
177
- config.write(new_contents)
178
- yield
153
+ with Config.make_tmp() as config:
154
+ variables = [Config.Variable("insteadOf", repo.clone_url)]
155
+ subsection = Config.Subsection("url", repo.clone_url_with_auth, variables)
156
+ config.write(subsection.format())
157
+ config.flush()
158
+ yield Git(config.name)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cgitize
3
- Version: 8.0.6
3
+ Version: 9.1.0
4
4
  Summary: Self-host your repositories using cgit
5
5
  Author-email: Egor Tensin <egor@tensin.name>
6
6
  License-Expression: MIT
@@ -1,13 +1,13 @@
1
- .dockerignore
2
1
  .git-blame-ignore-revs
3
2
  .gitattributes
4
3
  .gitignore
4
+ .gitmodules
5
5
  .python-version
6
+ CHANGELOG.md
6
7
  DEVELOPMENT.md
7
8
  LICENSE.txt
8
9
  Makefile
9
10
  README.md
10
- docker-compose.yml
11
11
  prelude.mk
12
12
  pyproject.toml
13
13
  requirements.txt
@@ -37,9 +37,9 @@ cgitize.egg-info/scm_version.json
37
37
  cgitize.egg-info/top_level.txt
38
38
  docker/Dockerfile
39
39
  docker/README.md
40
- docker/cgitize.sh
41
40
  docker/get_output_dir.py
42
41
  docker/in_cron.sh
42
+ docker/run.sh
43
43
  docker/frontend/Dockerfile
44
44
  docker/frontend/cmd.sh
45
45
  docker/frontend/etc/cgitrc
@@ -51,18 +51,32 @@ docker/frontend/usr/lib/cgit/filters/html-converters/md2html
51
51
  docs/api.md
52
52
  docs/auth.md
53
53
  examples/cgitize.toml
54
- examples/docker/cgitize.toml
55
54
  test/__init__.py
56
55
  test/set_credentials.sh
57
- test/integration/docker/.dockerignore
56
+ test/integration/tst-basic-error.sh
57
+ test/integration/tst-basic.sh
58
+ test/integration/tst-example-https-private.sh
59
+ test/integration/tst-example-https.sh
60
+ test/integration/tst-example-one-repo.sh
61
+ test/integration/tst-example-ssh-private.sh
62
+ test/integration/tst-example-ssh.sh
63
+ test/integration/docker/.gitignore
58
64
  test/integration/docker/docker-compose.yml
59
65
  test/integration/docker/test.sh
60
- test/integration/docker/cgitize/.gitignore
61
- test/integration/docker/cgitize/etc/cgitize.toml
66
+ test/integration/docker/etc/cgitize.toml
62
67
  test/integration/docker/git_server/Dockerfile
63
- test/integration/docker/git_server/setup_repo.sh
64
- test/integration/example/test.sh
65
- test/integration/local/test.sh
68
+ test/integration/docker/git_server/entrypoint.sh
69
+ test/integration/docker/git_server/setup.sh
70
+ test/integration/lib/basic.sh
71
+ test/integration/lib/common.sh
72
+ test/integration/lib/example.sh
73
+ test/integration/runner/.gitattributes
74
+ test/integration/runner/LICENSE.txt
75
+ test/integration/runner/README.md
76
+ test/integration/runner/harness
77
+ test/integration/runner/src/log.sh
78
+ test/integration/runner/src/main.sh
79
+ test/integration/runner/src/test.sh
66
80
  test/unit/__init__.py
67
81
  test/unit/test_bitbucket.py
68
82
  test/unit/test_github.py
@@ -1,13 +1,14 @@
1
1
  {
2
2
  "files": [
3
- ".dockerignore",
4
3
  ".git-blame-ignore-revs",
5
4
  ".gitattributes",
6
5
  ".github/dependabot.yml",
7
6
  ".github/workflows/ci.yml",
8
7
  ".github/workflows/maintenance.yml",
9
8
  ".gitignore",
9
+ ".gitmodules",
10
10
  ".python-version",
11
+ "CHANGELOG.md",
11
12
  "DEVELOPMENT.md",
12
13
  "LICENSE.txt",
13
14
  "Makefile",
@@ -25,10 +26,8 @@
25
26
  "cgitize/url.py",
26
27
  "cgitize/utils.py",
27
28
  "cgitize/version.py",
28
- "docker-compose.yml",
29
29
  "docker/Dockerfile",
30
30
  "docker/README.md",
31
- "docker/cgitize.sh",
32
31
  "docker/frontend/Dockerfile",
33
32
  "docker/frontend/cmd.sh",
34
33
  "docker/frontend/etc/cgit/common",
@@ -39,23 +38,38 @@
39
38
  "docker/frontend/usr/lib/cgit/filters/html-converters/md2html",
40
39
  "docker/get_output_dir.py",
41
40
  "docker/in_cron.sh",
41
+ "docker/run.sh",
42
42
  "docs/api.md",
43
43
  "docs/auth.md",
44
44
  "examples/cgitize.toml",
45
- "examples/docker/cgitize.toml",
46
45
  "prelude.mk",
47
46
  "pyproject.toml",
48
47
  "requirements.txt",
49
48
  "test/__init__.py",
50
- "test/integration/docker/.dockerignore",
51
- "test/integration/docker/cgitize/.gitignore",
52
- "test/integration/docker/cgitize/etc/cgitize.toml",
49
+ "test/integration/docker/.gitignore",
53
50
  "test/integration/docker/docker-compose.yml",
51
+ "test/integration/docker/etc/cgitize.toml",
54
52
  "test/integration/docker/git_server/Dockerfile",
55
- "test/integration/docker/git_server/setup_repo.sh",
53
+ "test/integration/docker/git_server/entrypoint.sh",
54
+ "test/integration/docker/git_server/setup.sh",
56
55
  "test/integration/docker/test.sh",
57
- "test/integration/example/test.sh",
58
- "test/integration/local/test.sh",
56
+ "test/integration/lib/basic.sh",
57
+ "test/integration/lib/common.sh",
58
+ "test/integration/lib/example.sh",
59
+ "test/integration/runner/.gitattributes",
60
+ "test/integration/runner/LICENSE.txt",
61
+ "test/integration/runner/README.md",
62
+ "test/integration/runner/harness",
63
+ "test/integration/runner/src/log.sh",
64
+ "test/integration/runner/src/main.sh",
65
+ "test/integration/runner/src/test.sh",
66
+ "test/integration/tst-basic-error.sh",
67
+ "test/integration/tst-basic.sh",
68
+ "test/integration/tst-example-https-private.sh",
69
+ "test/integration/tst-example-https.sh",
70
+ "test/integration/tst-example-one-repo.sh",
71
+ "test/integration/tst-example-ssh-private.sh",
72
+ "test/integration/tst-example-ssh.sh",
59
73
  "test/set_credentials.sh",
60
74
  "test/unit/__init__.py",
61
75
  "test/unit/test_bitbucket.py",
@@ -0,0 +1,8 @@
1
+ {
2
+ "tag": "9.1.0",
3
+ "distance": 0,
4
+ "node": "gc233bd4a3aa3025394c80ccd3c8efc81d0baca75",
5
+ "dirty": false,
6
+ "branch": "HEAD",
7
+ "node_date": "2026-10-15"
8
+ }
@@ -35,11 +35,9 @@ RUN apk add -q --no-cache bash git openssh-client tini
35
35
  COPY --from=build ["/deps", "/deps/"]
36
36
  ENV PYTHONPATH="/deps:/usr/src"
37
37
 
38
- ARG ssh_sock_dir=/
39
- ARG ssh_sock_path="$ssh_sock_dir/ssh-agent.sock"
40
- ENV SSH_AUTH_SOCK="$ssh_sock_path"
38
+ ENV SSH_AUTH_SOCK="/ssh/agent.sock"
41
39
 
42
- COPY ["docker/cgitize.sh", "/"]
40
+ COPY ["docker/run.sh", "/"]
43
41
  COPY ["docker/get_output_dir.py", "/"]
44
42
  COPY ["docker/in_cron.sh", "/"]
45
43
  COPY ["cgitize/", "/usr/src/cgitize/"]
@@ -48,6 +46,6 @@ ENV SCHEDULE_ON_START=1
48
46
  ENTRYPOINT ["/sbin/tini", "--", "/in_cron.sh"]
49
47
 
50
48
  WORKDIR /usr/src
51
- CMD ["/cgitize.sh"]
49
+ CMD ["/run.sh"]
52
50
 
53
51
  HEALTHCHECK --interval=5m --retries=3 CMD ! test -f /fail
@@ -8,7 +8,7 @@ The `SCHEDULE` environment variable controls how often it gets run (see below).
8
8
  * Volumes:
9
9
  * `/etc/cgitize/cgitize.toml`: configuration file path.
10
10
  * `/mnt/cgitize`: by default, cloned repositories will be written here.
11
- * `/ssh-agent.sock`: if you use SSH, map the agent socket here.
11
+ * `/ssh/agent.sock`: if you use SSH, map the agent socket here.
12
12
  * Environment variables:
13
13
  * `SCHEDULE`: defaults to "once", which makes the container exit after the
14
14
  first run.
@@ -49,18 +49,21 @@ services:
49
49
  SCHEDULE: '0 */3 * * *'
50
50
  # Set CGITIZE_{GITHUB,BITBUCKET,GITLAB}_{USERNAME,TOKEN} variables
51
51
  # here or in the config file.
52
- image: egortensin/cgitize:8
52
+ image: egortensin/cgitize:9
53
53
  restart: unless-stopped
54
54
  volumes:
55
55
  - ./example.toml:/etc/cgitize/cgitize.toml:ro
56
- - /srv/volumes/cgitize:/mnt/cgitize
56
+ - repositories:/mnt/cgitize
57
57
  frontend:
58
- image: egortensin/cgitize-frontend:8
58
+ image: egortensin/cgitize-frontend:9
59
59
  ports:
60
60
  - '127.0.0.1:80:80'
61
61
  restart: unless-stopped
62
62
  volumes:
63
- - /srv/volumes/cgitize:/mnt/cgitize:ro
63
+ - repositories:/mnt/cgitize:ro
64
+
65
+ volumes:
66
+ repositories:
64
67
  ```
65
68
 
66
69
  In this configuration, cgitize pulls repositories defined in example.toml every
@@ -0,0 +1,29 @@
1
+ services:
2
+ git_server:
3
+ build:
4
+ context: .
5
+ dockerfile: git_server/Dockerfile
6
+ volumes:
7
+ - ssh:/ssh
8
+ cgitize:
9
+ build:
10
+ context: ../../..
11
+ dockerfile: docker/Dockerfile
12
+ depends_on:
13
+ - git_server
14
+ environment:
15
+ SCHEDULE: once
16
+ volumes:
17
+ - ./etc:/etc/cgitize:ro
18
+ - ./output:/mnt/cgitize
19
+ - ssh:/ssh:ro
20
+ frontend:
21
+ build:
22
+ context: ../../../docker/frontend
23
+ ports:
24
+ - '127.0.0.1:80:80'
25
+ volumes:
26
+ - ./output:/mnt/cgitize:ro
27
+
28
+ volumes:
29
+ ssh:
@@ -0,0 +1,16 @@
1
+ FROM alpine:3.24
2
+
3
+ RUN apk add -q --no-cache bash git openssh-client-common openssh-server tini && \
4
+ echo 'root:root' | chpasswd && \
5
+ sed -ri 's/^#?PermitRootLogin\s+.*/PermitRootLogin yes/' /etc/ssh/sshd_config
6
+
7
+ USER root
8
+ WORKDIR /root
9
+
10
+ COPY ["git_server/setup.sh", "./"]
11
+ RUN ./setup.sh
12
+
13
+ COPY ["git_server/entrypoint.sh", "/"]
14
+ ENTRYPOINT ["/sbin/tini", "--", "/entrypoint.sh"]
15
+
16
+ CMD ["/usr/sbin/sshd", "-D"]