git-goose 0.0.1__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 (36) hide show
  1. git_goose-0.0.1/LICENSE +29 -0
  2. git_goose-0.0.1/PKG-INFO +235 -0
  3. git_goose-0.0.1/README.md +213 -0
  4. git_goose-0.0.1/pyproject.toml +74 -0
  5. git_goose-0.0.1/setup.cfg +4 -0
  6. git_goose-0.0.1/src/git_goose.egg-info/PKG-INFO +235 -0
  7. git_goose-0.0.1/src/git_goose.egg-info/SOURCES.txt +34 -0
  8. git_goose-0.0.1/src/git_goose.egg-info/dependency_links.txt +1 -0
  9. git_goose-0.0.1/src/git_goose.egg-info/requires.txt +7 -0
  10. git_goose-0.0.1/src/git_goose.egg-info/top_level.txt +1 -0
  11. git_goose-0.0.1/src/goose/__init__.py +0 -0
  12. git_goose-0.0.1/src/goose/__main__.py +251 -0
  13. git_goose-0.0.1/src/goose/_utils/__init__.py +0 -0
  14. git_goose-0.0.1/src/goose/_utils/pydantic.py +10 -0
  15. git_goose-0.0.1/src/goose/asyncio.py +19 -0
  16. git_goose-0.0.1/src/goose/backend/__init__.py +0 -0
  17. git_goose-0.0.1/src/goose/backend/base.py +76 -0
  18. git_goose-0.0.1/src/goose/backend/index.py +20 -0
  19. git_goose-0.0.1/src/goose/backend/node.py +190 -0
  20. git_goose-0.0.1/src/goose/backend/python.py +185 -0
  21. git_goose-0.0.1/src/goose/config.py +74 -0
  22. git_goose-0.0.1/src/goose/context.py +34 -0
  23. git_goose-0.0.1/src/goose/environment.py +259 -0
  24. git_goose-0.0.1/src/goose/executable_unit.py +11 -0
  25. git_goose-0.0.1/src/goose/filter.py +10 -0
  26. git_goose-0.0.1/src/goose/git/__init__.py +0 -0
  27. git_goose-0.0.1/src/goose/git/shared.py +48 -0
  28. git_goose-0.0.1/src/goose/git/status.py +155 -0
  29. git_goose-0.0.1/src/goose/manifest.py +160 -0
  30. git_goose-0.0.1/src/goose/orphan_environments.py +20 -0
  31. git_goose-0.0.1/src/goose/parallel.py +40 -0
  32. git_goose-0.0.1/src/goose/paths.py +22 -0
  33. git_goose-0.0.1/src/goose/process.py +26 -0
  34. git_goose-0.0.1/src/goose/scheduler.py +154 -0
  35. git_goose-0.0.1/src/goose/targets.py +103 -0
  36. git_goose-0.0.1/tests/test_targets.py +0 -0
@@ -0,0 +1,29 @@
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2024, Anton Agestam
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without
7
+ modification, are permitted provided that the following conditions are met:
8
+
9
+ 1. Redistributions of source code must retain the above copyright notice, this
10
+ list of conditions and the following disclaimer.
11
+
12
+ 2. Redistributions in binary form must reproduce the above copyright notice,
13
+ this list of conditions and the following disclaimer in the documentation
14
+ and/or other materials provided with the distribution.
15
+
16
+ 3. Neither the name of the copyright holder nor the names of its
17
+ contributors may be used to endorse or promote products derived from
18
+ this software without specific prior written permission.
19
+
20
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,235 @@
1
+ Metadata-Version: 2.1
2
+ Name: git-goose
3
+ Version: 0.0.1
4
+ Summary: A picky and eager Git hook runner.
5
+ Author-email: Anton Agestam <git@antonagestam.se>
6
+ License: BSD 3-Clause
7
+ Project-URL: Source Repository, https://github.com/antonagestam/goose
8
+ Classifier: Intended Audience :: Developers
9
+ Classifier: Operating System :: OS Independent
10
+ Classifier: Programming Language :: Python :: 3.12
11
+ Classifier: Typing :: Typed
12
+ Requires-Python: <3.13,>3.12
13
+ Description-Content-Type: text/markdown; charset=UTF-8
14
+ License-File: LICENSE
15
+ Requires-Dist: pydantic
16
+ Requires-Dist: PyYAML
17
+ Requires-Dist: nodeenv
18
+ Requires-Dist: identify
19
+ Requires-Dist: typer
20
+ Requires-Dist: rich
21
+ Requires-Dist: shellingham
22
+
23
+ <!-- prettier-ignore-start -->
24
+ <!-- https://github.com/prettier/prettier/issues/15479 -->
25
+
26
+ > [!NOTE]
27
+ > This project is in its infancy. Please try it out and report and help fix any issues or missing features, but expect a somewhat broken experience.
28
+ >
29
+ > Breaking CLI changes is to be expected without notice between arbitrary versions until version 1.0 is released.
30
+
31
+ <!-- prettier-ignore-end -->
32
+
33
+ <h1 align=center>goose<br>🦆🧪💻</h1>
34
+
35
+ <p align=center>A <i>picky</i> and <i>eager</i> <a href=https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks>Git hook</a> runner.</p>
36
+
37
+ - Reproducible builds.
38
+ - Dynamic parallelism.
39
+ - Small file-system footprint.
40
+
41
+ ### Features
42
+
43
+ - Smart parallelism schedules hooks across CPUs while avoiding concurrent writes.
44
+ - Deterministic environments by using ecosystem-specific lock files.
45
+ - Environments are shared across hooks.
46
+ - Self-contained definitions means there's no need to push tool-specific configuration
47
+ upstream, or to maintain brittle mirroring schemes.
48
+
49
+ ### Parallelism
50
+
51
+ Goose takes care to keep your CPUs as busy as possible, optimizing to have the full
52
+ suite of hooks finish as soon as possible. It does this by distributing units of work to
53
+ all available processing cores.
54
+
55
+ Parameterized hooks, or hooks that take files as command line arguments, are divided to
56
+ one unit of work per available core. Whenever a core becomes available for more work, a
57
+ new unit is chosen for execution.
58
+
59
+ The scheduler takes care to never run more than one mutating hook on the same file. It
60
+ does this by taking into account hooks marked as `read_only` and by comparing sets of
61
+ files a unit of work is assigned to. Two incompatible hooks can be simultaneously
62
+ working on two separate parts of the code-base.
63
+
64
+ ### Deterministic environments
65
+
66
+ Goose uses lock files to facilitate deterministic results across developer environments
67
+ and CI. You specify dependencies in `goose.yaml`, and invoking `goose run` will produce
68
+ the appropriate lock files under a `.goose/` directory. The `.goose/` directory is meant
69
+ to be checked into git, so that future invocations of `goose run` can use the lock files
70
+ it contains to produce identical environments for hooks to run in.
71
+
72
+ ## Usage
73
+
74
+ Create a `goose.yaml` file in the repository root.
75
+
76
+ ```yaml
77
+ environments:
78
+ - id: python
79
+ ecosystem:
80
+ language: python
81
+ version: "3.12"
82
+ dependencies:
83
+ - ruff
84
+
85
+ hooks:
86
+ - id: ruff
87
+ environment: python
88
+ command: ruff
89
+ args: [check, --force-exclude, --fix]
90
+ types: [python]
91
+
92
+ - id: ruff-format
93
+ environment: python
94
+ command: ruff
95
+ args: [format, --force-exclude]
96
+ types: [python]
97
+ ```
98
+
99
+ Bootstrap environments, generate lock files, and install dependencies.
100
+
101
+ ```sh
102
+ $ python -m goose upgrade
103
+ ```
104
+
105
+ Run all hooks over all files.
106
+
107
+ ```sh
108
+ $ python -m goose run --select=all
109
+ ```
110
+
111
+ Commit configuration and lock files.
112
+
113
+ ```sh
114
+ $ git add goose.yaml .goose
115
+ $ git commit -m 'Add goose configuration'
116
+ ```
117
+
118
+ ### Upgrading hook versions
119
+
120
+ As pinning of hook versions is handled with lock files, there's no need to change
121
+ configuration to upgrade hook dependency versions, instead you just run the upgrade
122
+ command.
123
+
124
+ ```sh
125
+ $ python -m goose upgrade
126
+ $ git add .goose
127
+ $ git commit -m 'Bump goose dependencies'
128
+ ```
129
+
130
+ ### Example node hook
131
+
132
+ Goose currently supports Python and Node environments, here's an example using
133
+ [Prettier] to format Markdown files.
134
+
135
+ [Prettier]: https://prettier.io/
136
+
137
+ ```yaml
138
+ environments:
139
+ - id: node
140
+ ecosystem:
141
+ language: node
142
+ version: "21.7.1"
143
+ dependencies:
144
+ - prettier
145
+
146
+ hooks:
147
+ - id: prettier
148
+ environment: node
149
+ command: prettier
150
+ types: [markdown]
151
+ args:
152
+ - --write
153
+ - --ignore-unknown
154
+ - --parser=markdown
155
+ - --print-width=88
156
+ - --prose-wrap=always
157
+ ```
158
+
159
+ ### Read-only hooks
160
+
161
+ You will likely want to use a mix of pure linters, as well as formatters and
162
+ auto-fixers. Tools that don't mutate files can be more heavily parallelized by Goose,
163
+ because they can inspect overlapping sets of files simultaneously as other tools. To
164
+ enable this you set `read_only: true` in hook configuration.
165
+
166
+ ```yaml
167
+ environments:
168
+ - id: python
169
+ ecosystem:
170
+ language: python
171
+ version: "3.12"
172
+ dependencies:
173
+ - pre-commit-hooks
174
+
175
+ hooks:
176
+ - id: check-case-conflict
177
+ environment: python
178
+ command: check-case-conflict
179
+ read_only: true
180
+
181
+ - id: check-merge-conflict
182
+ environment: python
183
+ command: check-merge-conflict
184
+ read_only: true
185
+ types: [text]
186
+
187
+ - id: python-debug-statements
188
+ environment: python
189
+ command: debug-statement-hook
190
+ read_only: true
191
+ types: [python]
192
+
193
+ - id: detect-private-key
194
+ environment: python
195
+ command: detect-private-key
196
+ read_only: true
197
+ types: [text]
198
+
199
+ - id: end-of-file-fixer
200
+ environment: python
201
+ command: end-of-file-fixer
202
+ types: [text]
203
+
204
+ - id: trailing-whitespace-fixer
205
+ environment: python
206
+ command: trailing-whitespace-fixer
207
+ types: [text]
208
+ ```
209
+
210
+ Hooks that do not specify `read_only: true` will never run simultaneously as other tools
211
+ over the same file.
212
+
213
+ ### Non-parameterized hooks
214
+
215
+ Some tools don't support passing files, or just work better if given the responsibility
216
+ to parallelize work itself. One such tool is mypy. You can instruct goose to not pass
217
+ filenames to a hook (and as a consequence, also not spawn multiple parallel jobs for
218
+ this hook).
219
+
220
+ ```yaml
221
+ environments:
222
+ - id: mypy
223
+ ecosystem:
224
+ language: python
225
+ version: "3.12"
226
+ dependencies:
227
+ - mypy
228
+
229
+ hooks:
230
+ - id: mypy
231
+ environment: mypy
232
+ command: mypy
233
+ read_only: true
234
+ parameterize: false
235
+ ```
@@ -0,0 +1,213 @@
1
+ <!-- prettier-ignore-start -->
2
+ <!-- https://github.com/prettier/prettier/issues/15479 -->
3
+
4
+ > [!NOTE]
5
+ > This project is in its infancy. Please try it out and report and help fix any issues or missing features, but expect a somewhat broken experience.
6
+ >
7
+ > Breaking CLI changes is to be expected without notice between arbitrary versions until version 1.0 is released.
8
+
9
+ <!-- prettier-ignore-end -->
10
+
11
+ <h1 align=center>goose<br>🦆🧪💻</h1>
12
+
13
+ <p align=center>A <i>picky</i> and <i>eager</i> <a href=https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks>Git hook</a> runner.</p>
14
+
15
+ - Reproducible builds.
16
+ - Dynamic parallelism.
17
+ - Small file-system footprint.
18
+
19
+ ### Features
20
+
21
+ - Smart parallelism schedules hooks across CPUs while avoiding concurrent writes.
22
+ - Deterministic environments by using ecosystem-specific lock files.
23
+ - Environments are shared across hooks.
24
+ - Self-contained definitions means there's no need to push tool-specific configuration
25
+ upstream, or to maintain brittle mirroring schemes.
26
+
27
+ ### Parallelism
28
+
29
+ Goose takes care to keep your CPUs as busy as possible, optimizing to have the full
30
+ suite of hooks finish as soon as possible. It does this by distributing units of work to
31
+ all available processing cores.
32
+
33
+ Parameterized hooks, or hooks that take files as command line arguments, are divided to
34
+ one unit of work per available core. Whenever a core becomes available for more work, a
35
+ new unit is chosen for execution.
36
+
37
+ The scheduler takes care to never run more than one mutating hook on the same file. It
38
+ does this by taking into account hooks marked as `read_only` and by comparing sets of
39
+ files a unit of work is assigned to. Two incompatible hooks can be simultaneously
40
+ working on two separate parts of the code-base.
41
+
42
+ ### Deterministic environments
43
+
44
+ Goose uses lock files to facilitate deterministic results across developer environments
45
+ and CI. You specify dependencies in `goose.yaml`, and invoking `goose run` will produce
46
+ the appropriate lock files under a `.goose/` directory. The `.goose/` directory is meant
47
+ to be checked into git, so that future invocations of `goose run` can use the lock files
48
+ it contains to produce identical environments for hooks to run in.
49
+
50
+ ## Usage
51
+
52
+ Create a `goose.yaml` file in the repository root.
53
+
54
+ ```yaml
55
+ environments:
56
+ - id: python
57
+ ecosystem:
58
+ language: python
59
+ version: "3.12"
60
+ dependencies:
61
+ - ruff
62
+
63
+ hooks:
64
+ - id: ruff
65
+ environment: python
66
+ command: ruff
67
+ args: [check, --force-exclude, --fix]
68
+ types: [python]
69
+
70
+ - id: ruff-format
71
+ environment: python
72
+ command: ruff
73
+ args: [format, --force-exclude]
74
+ types: [python]
75
+ ```
76
+
77
+ Bootstrap environments, generate lock files, and install dependencies.
78
+
79
+ ```sh
80
+ $ python -m goose upgrade
81
+ ```
82
+
83
+ Run all hooks over all files.
84
+
85
+ ```sh
86
+ $ python -m goose run --select=all
87
+ ```
88
+
89
+ Commit configuration and lock files.
90
+
91
+ ```sh
92
+ $ git add goose.yaml .goose
93
+ $ git commit -m 'Add goose configuration'
94
+ ```
95
+
96
+ ### Upgrading hook versions
97
+
98
+ As pinning of hook versions is handled with lock files, there's no need to change
99
+ configuration to upgrade hook dependency versions, instead you just run the upgrade
100
+ command.
101
+
102
+ ```sh
103
+ $ python -m goose upgrade
104
+ $ git add .goose
105
+ $ git commit -m 'Bump goose dependencies'
106
+ ```
107
+
108
+ ### Example node hook
109
+
110
+ Goose currently supports Python and Node environments, here's an example using
111
+ [Prettier] to format Markdown files.
112
+
113
+ [Prettier]: https://prettier.io/
114
+
115
+ ```yaml
116
+ environments:
117
+ - id: node
118
+ ecosystem:
119
+ language: node
120
+ version: "21.7.1"
121
+ dependencies:
122
+ - prettier
123
+
124
+ hooks:
125
+ - id: prettier
126
+ environment: node
127
+ command: prettier
128
+ types: [markdown]
129
+ args:
130
+ - --write
131
+ - --ignore-unknown
132
+ - --parser=markdown
133
+ - --print-width=88
134
+ - --prose-wrap=always
135
+ ```
136
+
137
+ ### Read-only hooks
138
+
139
+ You will likely want to use a mix of pure linters, as well as formatters and
140
+ auto-fixers. Tools that don't mutate files can be more heavily parallelized by Goose,
141
+ because they can inspect overlapping sets of files simultaneously as other tools. To
142
+ enable this you set `read_only: true` in hook configuration.
143
+
144
+ ```yaml
145
+ environments:
146
+ - id: python
147
+ ecosystem:
148
+ language: python
149
+ version: "3.12"
150
+ dependencies:
151
+ - pre-commit-hooks
152
+
153
+ hooks:
154
+ - id: check-case-conflict
155
+ environment: python
156
+ command: check-case-conflict
157
+ read_only: true
158
+
159
+ - id: check-merge-conflict
160
+ environment: python
161
+ command: check-merge-conflict
162
+ read_only: true
163
+ types: [text]
164
+
165
+ - id: python-debug-statements
166
+ environment: python
167
+ command: debug-statement-hook
168
+ read_only: true
169
+ types: [python]
170
+
171
+ - id: detect-private-key
172
+ environment: python
173
+ command: detect-private-key
174
+ read_only: true
175
+ types: [text]
176
+
177
+ - id: end-of-file-fixer
178
+ environment: python
179
+ command: end-of-file-fixer
180
+ types: [text]
181
+
182
+ - id: trailing-whitespace-fixer
183
+ environment: python
184
+ command: trailing-whitespace-fixer
185
+ types: [text]
186
+ ```
187
+
188
+ Hooks that do not specify `read_only: true` will never run simultaneously as other tools
189
+ over the same file.
190
+
191
+ ### Non-parameterized hooks
192
+
193
+ Some tools don't support passing files, or just work better if given the responsibility
194
+ to parallelize work itself. One such tool is mypy. You can instruct goose to not pass
195
+ filenames to a hook (and as a consequence, also not spawn multiple parallel jobs for
196
+ this hook).
197
+
198
+ ```yaml
199
+ environments:
200
+ - id: mypy
201
+ ecosystem:
202
+ language: python
203
+ version: "3.12"
204
+ dependencies:
205
+ - mypy
206
+
207
+ hooks:
208
+ - id: mypy
209
+ environment: mypy
210
+ command: mypy
211
+ read_only: true
212
+ parameterize: false
213
+ ```
@@ -0,0 +1,74 @@
1
+ [project]
2
+ name = "git-goose"
3
+ authors = [
4
+ { name="Anton Agestam", email="git@antonagestam.se" },
5
+ ]
6
+ description = "A picky and eager Git hook runner."
7
+ license = {text = "BSD 3-Clause"}
8
+ version = "0.0.1"
9
+ requires-python = ">3.12,<3.13"
10
+ classifiers = [
11
+ "Intended Audience :: Developers",
12
+ "Operating System :: OS Independent",
13
+ "Programming Language :: Python :: 3.12",
14
+ "Typing :: Typed",
15
+ ]
16
+ dynamic = ["readme"]
17
+ dependencies = [
18
+ "pydantic",
19
+ "PyYAML",
20
+ "nodeenv",
21
+ "identify",
22
+ "typer",
23
+ # https://typer.tiangolo.com/#optional-dependencies
24
+ "rich",
25
+ # https://typer.tiangolo.com/#optional-dependencies
26
+ "shellingham",
27
+ ]
28
+
29
+ [project.urls]
30
+ "Source Repository" = "https://github.com/antonagestam/goose"
31
+
32
+ [build-system]
33
+ requires = ["setuptools==70.3.0", "wheel==0.43.0"]
34
+ build-backend = "setuptools.build_meta"
35
+
36
+ [tool.setuptools]
37
+ include-package-data = true
38
+
39
+ [tool.setuptools.dynamic]
40
+ readme = {file = "README.md", content-type = "text/markdown; charset=UTF-8"}
41
+
42
+ [tool.setuptools.packages.find]
43
+ where = ["src"]
44
+ namespaces = false
45
+
46
+ [tool.pip-tools]
47
+ generate-hashes = true
48
+ strip-extras = true
49
+ upgrade = true
50
+
51
+ [tool.mypy]
52
+ python_version = 3.12
53
+ show_error_codes = true
54
+ pretty = true
55
+ files = ["src", "tests"]
56
+ plugins = ["pydantic.mypy"]
57
+
58
+ ignore_missing_imports = false
59
+ no_implicit_reexport = true
60
+ no_implicit_optional = true
61
+ strict_equality = true
62
+ strict_optional = true
63
+ check_untyped_defs = true
64
+ disallow_incomplete_defs = true
65
+ disallow_untyped_defs = true
66
+ disallow_untyped_calls = true
67
+ disallow_untyped_decorators = true
68
+ disallow_subclassing_any = true
69
+
70
+ warn_unused_configs = true
71
+ warn_redundant_casts = true
72
+ warn_unused_ignores = true
73
+ warn_return_any = true
74
+ warn_unreachable = true
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+