workset 0.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.
@@ -0,0 +1,33 @@
1
+ One sentence explaining what this PR does.
2
+
3
+ Follow this format by default, but you can deviate if that makes the PR
4
+ clearer, for example for an unusually large PR.
5
+
6
+ ## Related:
7
+ Optional. Use only if truly needed. Link related issues, docs, PRs, or
8
+ discussion.
9
+ - ...
10
+
11
+ ## Changes:
12
+ What changed in the final state of the PR. Describe the current behavior the
13
+ reader needs to know. Do not narrate the whole implementation history of the PR.
14
+ Be concise.
15
+ - ...
16
+ - ...
17
+
18
+ ## Why:
19
+ What problem this solves and why the changes were needed.
20
+ Be concise.
21
+ - ...
22
+ - ...
23
+
24
+ ## Details:
25
+ Optional. Use only if truly needed. Use this for important details or gotchas
26
+ that would clutter the changes section.
27
+ - ...
28
+
29
+ ## How To Try It:
30
+ Optional. Use only if truly needed. Use this when a reviewer would benefit
31
+ from commands, paths, task ids, or links to inspect the change directly. Do
32
+ not repeat generic CI or test output.
33
+ - ...
@@ -0,0 +1,137 @@
1
+ name: Checks
2
+
3
+ on:
4
+ pull_request:
5
+ push:
6
+ branches: [main]
7
+ workflow_dispatch:
8
+
9
+ concurrency:
10
+ group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
11
+ cancel-in-progress: true
12
+
13
+ permissions:
14
+ contents: read
15
+
16
+ jobs:
17
+ ruff:
18
+ name: Ruff
19
+ runs-on: ubuntu-latest
20
+ timeout-minutes: 5
21
+
22
+ steps:
23
+ - name: Check out repository
24
+ uses: actions/checkout@v6
25
+
26
+ - name: Set up Python
27
+ uses: actions/setup-python@v6
28
+ with:
29
+ python-version: "3.11"
30
+ cache: pip
31
+ cache-dependency-path: pyproject.toml
32
+
33
+ - name: Install Ruff
34
+ run: python -m pip install ruff==0.15.9
35
+
36
+ - name: Ruff format
37
+ run: python -m ruff format --check --diff .
38
+
39
+ - name: Ruff lint
40
+ run: python -m ruff check --output-format=full .
41
+
42
+ python-checks:
43
+ name: Ruff + Mypy + Pytest
44
+ runs-on: ubuntu-latest
45
+ timeout-minutes: 10
46
+ strategy:
47
+ fail-fast: false
48
+ matrix:
49
+ python-version: ["3.11", "3.12", "3.13"]
50
+
51
+ steps:
52
+ - name: Check out repository
53
+ uses: actions/checkout@v6
54
+
55
+ - name: Set up Python
56
+ uses: actions/setup-python@v6
57
+ with:
58
+ python-version: ${{ matrix.python-version }}
59
+ cache: pip
60
+ cache-dependency-path: pyproject.toml
61
+
62
+ - name: Install Python dependencies
63
+ run: |
64
+ python -m pip install --upgrade pip
65
+ python -m pip install -e ".[dev]"
66
+
67
+ - name: Ruff format
68
+ run: python -m ruff format --check --diff .
69
+
70
+ - name: Ruff lint
71
+ run: python -m ruff check --output-format=full .
72
+
73
+ - name: Mypy static type checks
74
+ run: python -m mypy
75
+
76
+ - name: Pytest tests
77
+ run: python -m pytest
78
+
79
+ package-pip:
80
+ name: Package Build (pip)
81
+ runs-on: ubuntu-latest
82
+ timeout-minutes: 10
83
+
84
+ steps:
85
+ - name: Check out repository
86
+ uses: actions/checkout@v6
87
+
88
+ - name: Set up Python
89
+ uses: actions/setup-python@v6
90
+ with:
91
+ python-version: "3.11"
92
+ cache: pip
93
+ cache-dependency-path: pyproject.toml
94
+
95
+ - name: Install Python dependencies
96
+ run: |
97
+ python -m pip install --upgrade pip
98
+ python -m pip install -e ".[dev]"
99
+
100
+ - name: Build package
101
+ run: python -m build
102
+
103
+ - name: Install built wheel
104
+ run: python -m pip install --force-reinstall dist/*.whl
105
+
106
+ - name: Smoke test installed package
107
+ run: python -c "import workset; print('ok')"
108
+
109
+ package-uv:
110
+ name: Package Build (uv)
111
+ runs-on: ubuntu-latest
112
+ timeout-minutes: 10
113
+
114
+ steps:
115
+ - name: Check out repository
116
+ uses: actions/checkout@v6
117
+
118
+ - name: Set up uv
119
+ uses: astral-sh/setup-uv@v6
120
+ with:
121
+ enable-cache: true
122
+ cache-dependency-glob: uv.lock
123
+
124
+ - name: Set up Python
125
+ run: uv python install 3.11
126
+
127
+ - name: Install Python dependencies
128
+ run: uv sync --extra dev --locked
129
+
130
+ - name: Build package
131
+ run: uv build
132
+
133
+ - name: Install built wheel
134
+ run: uv pip install --force-reinstall dist/*.whl
135
+
136
+ - name: Smoke test installed package
137
+ run: uv run python -c "import workset; print('ok')"
@@ -0,0 +1,36 @@
1
+ name: Release
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+ workflow_dispatch:
7
+
8
+ permissions:
9
+ contents: read
10
+
11
+ jobs:
12
+ publish:
13
+ name: Publish to PyPI
14
+ runs-on: ubuntu-latest
15
+ environment: pypi
16
+ permissions:
17
+ contents: read
18
+ id-token: write
19
+
20
+ steps:
21
+ - name: Check out repository
22
+ uses: actions/checkout@v6
23
+
24
+ - name: Set up Python
25
+ uses: actions/setup-python@v6
26
+ with:
27
+ python-version: "3.11"
28
+
29
+ - name: Build package
30
+ run: |
31
+ python -m pip install --upgrade pip
32
+ python -m pip install build
33
+ python -m build
34
+
35
+ - name: Publish package distributions to PyPI
36
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,27 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ *$py.class
4
+
5
+ .Python
6
+ .venv/
7
+ venv/
8
+ env/
9
+ ENV/
10
+
11
+ build/
12
+ dist/
13
+ *.egg-info/
14
+ .eggs/
15
+
16
+ .pytest_cache/
17
+ .mypy_cache/
18
+ .ruff_cache/
19
+ .coverage
20
+ htmlcov/
21
+
22
+ .env
23
+ .env.*
24
+
25
+ .DS_Store
26
+ .idea/
27
+ .vscode/
@@ -0,0 +1,39 @@
1
+ repos:
2
+ - repo: https://github.com/astral-sh/ruff-pre-commit
3
+ rev: v0.15.9
4
+ hooks:
5
+ - id: ruff
6
+ - id: ruff-format
7
+ args: ["--check"]
8
+
9
+ - repo: https://github.com/pre-commit/pre-commit-hooks
10
+ rev: v6.0.0
11
+ hooks:
12
+ - id: trailing-whitespace
13
+ - id: check-symlinks
14
+ - id: destroyed-symlinks
15
+ - id: end-of-file-fixer
16
+ - id: check-yaml
17
+ - id: check-toml
18
+ - id: check-merge-conflict
19
+ - id: check-case-conflict
20
+ - id: check-executables-have-shebangs
21
+ - id: check-added-large-files
22
+ args: ["--maxkb=2000"]
23
+ - id: check-shebang-scripts-are-executable
24
+ - id: detect-private-key
25
+ - id: debug-statements
26
+
27
+ - repo: https://github.com/codespell-project/codespell
28
+ rev: v2.4.1
29
+ hooks:
30
+ - id: codespell
31
+ additional_dependencies:
32
+ - tomli
33
+
34
+ - repo: https://github.com/pre-commit/pygrep-hooks
35
+ rev: v1.10.0
36
+ hooks:
37
+ - id: rst-backticks
38
+ - id: rst-directive-colons
39
+ - id: rst-inline-touching-normal
@@ -0,0 +1 @@
1
+ 3.11
@@ -0,0 +1,22 @@
1
+ # AGENTS.md
2
+
3
+ Repo-specific instructions for agents working with the `workset` package.
4
+
5
+ ## Package Conventions
6
+
7
+ - Keep importable package code under `src/workset/`.
8
+ - Put CLI entrypoint behavior in `src/workset/cli.py`.
9
+
10
+ ## Validation
11
+
12
+ - Run checks relevant to the files changed.
13
+ - For README/docs-only changes, run formatting and pre-commit hygiene.
14
+ - For Python or packaging changes, also run Ruff, mypy, pytest, and build
15
+ checks.
16
+
17
+ ## Pull Requests
18
+
19
+ - Use `.github/PULL_REQUEST_TEMPLATE.md` for PR descriptions.
20
+ - Do not commit secrets, credentials, local runtime config, or scratch notes.
21
+ - Keep `AGENTS.md` updated when recurring agent instructions become
22
+ repo-specific.
workset-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,65 @@
1
+ Metadata-Version: 2.4
2
+ Name: workset
3
+ Version: 0.1.0
4
+ Summary: Create and initialize isolated git worktree worksets.
5
+ Project-URL: Homepage, https://github.com/alik-git/workset
6
+ Project-URL: Repository, https://github.com/alik-git/workset
7
+ Project-URL: Issues, https://github.com/alik-git/workset/issues
8
+ Author-email: Ali K <akuwajerwala@minervahumanoids.com>
9
+ Maintainer-email: Ali K <akuwajerwala@minervahumanoids.com>
10
+ Keywords: devtools,git,python,workset,worktree
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.11
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Classifier: Programming Language :: Python :: 3.13
15
+ Classifier: Typing :: Typed
16
+ Requires-Python: >=3.11
17
+ Requires-Dist: colorlog>=6.10
18
+ Provides-Extra: dev
19
+ Requires-Dist: build>=1.2; extra == 'dev'
20
+ Requires-Dist: mypy>=1.15; extra == 'dev'
21
+ Requires-Dist: pre-commit>=4.0; extra == 'dev'
22
+ Requires-Dist: pytest>=8.0; extra == 'dev'
23
+ Requires-Dist: ruff>=0.11; extra == 'dev'
24
+ Description-Content-Type: text/markdown
25
+
26
+ # workset
27
+
28
+ Create and initialize isolated git worktree worksets in one command.
29
+
30
+ A workset is a directory containing one or more git worktrees for related
31
+ repos, each on their own branch, with submodules initialized and the Python
32
+ environment ready to go. `workset` automates the setup so you can go from
33
+ "I have a task" to a working environment without the manual back-and-forth.
34
+
35
+ ## Installation
36
+
37
+ ```bash
38
+ uv tool install workset
39
+ ```
40
+
41
+ Or install from source:
42
+
43
+ ```bash
44
+ uv tool install --editable path/to/workset
45
+ ```
46
+
47
+ ## Usage
48
+
49
+ ```bash
50
+ workset --help
51
+ ```
52
+
53
+ ## Development
54
+
55
+ ```bash
56
+ uv sync --extra dev
57
+ uv run ruff format --check .
58
+ uv run ruff check .
59
+ uv run mypy
60
+ uv run pytest
61
+ ```
62
+
63
+ ## Publishing
64
+
65
+ Releases are published to PyPI automatically when a GitHub Release is created.
@@ -0,0 +1,40 @@
1
+ # workset
2
+
3
+ Create and initialize isolated git worktree worksets in one command.
4
+
5
+ A workset is a directory containing one or more git worktrees for related
6
+ repos, each on their own branch, with submodules initialized and the Python
7
+ environment ready to go. `workset` automates the setup so you can go from
8
+ "I have a task" to a working environment without the manual back-and-forth.
9
+
10
+ ## Installation
11
+
12
+ ```bash
13
+ uv tool install workset
14
+ ```
15
+
16
+ Or install from source:
17
+
18
+ ```bash
19
+ uv tool install --editable path/to/workset
20
+ ```
21
+
22
+ ## Usage
23
+
24
+ ```bash
25
+ workset --help
26
+ ```
27
+
28
+ ## Development
29
+
30
+ ```bash
31
+ uv sync --extra dev
32
+ uv run ruff format --check .
33
+ uv run ruff check .
34
+ uv run mypy
35
+ uv run pytest
36
+ ```
37
+
38
+ ## Publishing
39
+
40
+ Releases are published to PyPI automatically when a GitHub Release is created.
@@ -0,0 +1,15 @@
1
+ # API
2
+
3
+ Document the package's public Python API here.
4
+
5
+ ## `do_useful_thing`
6
+
7
+ ```python
8
+ import workset
9
+
10
+ result = workset.do_useful_thing("world")
11
+ ```
12
+
13
+ `do_useful_thing` is the starter public function exposed by this template.
14
+ Replace it with the functions or classes that should make up the package's
15
+ public API.
@@ -0,0 +1,67 @@
1
+ # CI Private Submodules
2
+
3
+ If a package created from this template uses private GitHub submodules, the
4
+ default [`GITHUB_TOKEN`](https://docs.github.com/en/actions/security-for-github-actions/security-guides/automatic-token-authentication)
5
+ may not be able to clone them in GitHub Actions.
6
+
7
+ Use a [GitHub App](https://docs.github.com/en/apps/overview) token pattern for
8
+ private submodules. The
9
+ [`actions/create-github-app-token`](https://github.com/actions/create-github-app-token)
10
+ action creates a short-lived installation access token that can be scoped to the
11
+ parent repo and the private submodule repos:
12
+
13
+ ```yaml
14
+ - name: Create GitHub App token
15
+ id: app-token
16
+ uses: actions/create-github-app-token@v3
17
+ with:
18
+ client-id: ${{ vars.CI_APP_CLIENT_ID }}
19
+ private-key: ${{ secrets.CI_APP_PRIVATE_KEY }}
20
+ owner: your-org
21
+ repositories: |
22
+ your_repo
23
+ private_submodule_repo
24
+ permission-contents: read
25
+
26
+ - name: Check out repository
27
+ uses: actions/checkout@v6
28
+ with:
29
+ token: ${{ steps.app-token.outputs.token }}
30
+ submodules: recursive
31
+ persist-credentials: false
32
+ ```
33
+
34
+ Required repository settings:
35
+
36
+ - Variable: `CI_APP_CLIENT_ID`
37
+ - Secret: `CI_APP_PRIVATE_KEY`
38
+
39
+ Create these under the repository's
40
+ [Actions variables and secrets settings](https://docs.github.com/en/actions/how-tos/write-workflows/choose-what-workflows-do/use-variables)
41
+ and
42
+ [Actions secrets settings](https://docs.github.com/en/actions/how-tos/security-for-github-actions/security-guides/using-secrets-in-github-actions).
43
+
44
+ The GitHub App must be installed on the parent repo and each private submodule
45
+ repo listed under `repositories`. See GitHub's docs for
46
+ [installing your own GitHub App](https://docs.github.com/en/apps/using-github-apps/installing-your-own-github-app).
47
+
48
+ Replace the variable and secret names in the YAML with whatever naming
49
+ convention your repository uses.
50
+
51
+ `actions/create-github-app-token` still accepts the older `app-id` input, but
52
+ the upstream action now recommends `client-id`. Prefer `client-id` in new
53
+ workflows to avoid deprecation/legacy-input warnings. GitHub documents where to
54
+ find a GitHub App's client ID in the
55
+ [GitHub App settings](https://docs.github.com/en/apps/maintaining-github-apps/modifying-a-github-app).
56
+
57
+ Symptoms when this is missing:
58
+
59
+ - PR checks stay queued and then fail during checkout.
60
+ - [`actions/checkout`](https://github.com/actions/checkout) reports that it
61
+ cannot clone a private submodule.
62
+ - SSH submodule URLs like `git@github.com:org/private_repo.git` fail in CI even
63
+ though they work locally.
64
+
65
+ When adapting the template, either avoid private submodules in CI or add the
66
+ token step before every `actions/checkout` step that uses `submodules:
67
+ recursive`.
@@ -0,0 +1,148 @@
1
+ [build-system]
2
+ requires = ["hatchling>=1.25"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "workset"
7
+ version = "0.1.0"
8
+ description = "Create and initialize isolated git worktree worksets."
9
+ readme = "README.md"
10
+ requires-python = ">=3.11"
11
+ authors = [
12
+ { name = "Ali K", email = "akuwajerwala@minervahumanoids.com" },
13
+ ]
14
+ maintainers = [
15
+ { name = "Ali K", email = "akuwajerwala@minervahumanoids.com" },
16
+ ]
17
+ keywords = ["python", "git", "worktree", "workset", "devtools"]
18
+ classifiers = [
19
+ "Programming Language :: Python :: 3",
20
+ "Programming Language :: Python :: 3.11",
21
+ "Programming Language :: Python :: 3.12",
22
+ "Programming Language :: Python :: 3.13",
23
+ "Typing :: Typed",
24
+ ]
25
+ dependencies = [
26
+ "colorlog>=6.10",
27
+ ]
28
+
29
+ [project.optional-dependencies]
30
+ dev = [
31
+ "build>=1.2",
32
+ "mypy>=1.15",
33
+ "pre-commit>=4.0",
34
+ "pytest>=8.0",
35
+ "ruff>=0.11",
36
+ ]
37
+
38
+ [tool.hatch.build.targets.wheel]
39
+ packages = ["src/workset"]
40
+
41
+ [project.scripts]
42
+ workset = "workset.cli:main"
43
+
44
+ [project.urls]
45
+ Homepage = "https://github.com/alik-git/workset"
46
+ Repository = "https://github.com/alik-git/workset"
47
+ Issues = "https://github.com/alik-git/workset/issues"
48
+
49
+ [tool.ruff]
50
+ line-length = 88
51
+ target-version = "py311"
52
+ src = ["src", "tests"]
53
+
54
+ [tool.ruff.lint]
55
+ # This template uses a fairly strict Ruff setup by default. The less universal
56
+ # rule families are marked below; comment them out if they are too noisy for a
57
+ # new project.
58
+ extend-select = [
59
+ # Core Python style and modernization.
60
+ "E", # pycodestyle errors
61
+ "W", # pycodestyle warnings
62
+ "I", # import sorting
63
+ "UP", # Python modernization
64
+ # Bug-risk checks.
65
+ "B", # flake8-bugbear bug patterns
66
+ "BLE", # blind except / bare except
67
+ "PLE", # pylint errors
68
+ "PLW", # pylint warnings
69
+ "S", # Bandit security checks; comment out if too noisy.
70
+ # Maintainability checks.
71
+ "A", # flake8-builtins: avoid shadowing id/list/input/etc.
72
+ "ARG", # unused function arguments
73
+ "C4", # cleaner comprehensions
74
+ "DTZ", # timezone-aware datetimes
75
+ "FBT003", # boolean positional values in function calls
76
+ "NPY", # NumPy-specific checks
77
+ "PERF", # performance footguns
78
+ "PTH", # prefer pathlib over os.path
79
+ "RET", # return control-flow simplification
80
+ "SIM", # flake8-simplify
81
+ # Logging and import hygiene.
82
+ "G", # logging format strings
83
+ "LOG", # logging anti-patterns
84
+ "TC", # type-checking import hygiene
85
+ # Strict docs/annotations/tests. Comment these out for a looser template.
86
+ "ANN201", # public function return annotations
87
+ "ANN202", # private function return annotations
88
+ "ANN204", # special-method return annotations
89
+ "D100", # module docstrings
90
+ "D104", # package docstrings
91
+ "D102", # public method docstrings
92
+ "D103", # public function docstrings
93
+ "D2", # docstring whitespace/placement conventions
94
+ "D4", # docstring content conventions
95
+ "PT", # pytest style
96
+ # Ruff suppression hygiene and narrow style correctness rules.
97
+ "RUF100", # unused noqa
98
+ "RUF102", # invalid noqa rule code
99
+ "RUF104", # unmatched ruff suppression comments
100
+ "PLR0402", # prefer from-module imports for aliased submodule imports
101
+ "PLR1722", # prefer sys.exit() over the interactive exit() helper
102
+ "TRY203", # useless try/except blocks that immediately re-raise
103
+ ]
104
+
105
+ ignore = [
106
+ # typing.cast(SomeType, value) is clearer than quoted type names.
107
+ "TC006",
108
+ ]
109
+
110
+ [tool.ruff.lint.per-file-ignores]
111
+ # Do not flag assert statements in tests.
112
+ "tests/**/*.py" = ["S101"]
113
+
114
+ [tool.ruff.lint.isort]
115
+ known-first-party = ["workset"]
116
+
117
+ [tool.ruff.lint.pydocstyle]
118
+ convention = "google"
119
+
120
+ [tool.ruff.format]
121
+ docstring-code-format = true
122
+
123
+ [tool.mypy]
124
+ python_version = "3.11"
125
+ files = ["src/workset"]
126
+
127
+ # Type-check function bodies even before every function is fully annotated.
128
+ check_untyped_defs = true
129
+ no_implicit_optional = true
130
+ strict_equality = true
131
+
132
+ # High-signal warnings without full mypy strict mode.
133
+ warn_redundant_casts = true
134
+ warn_return_any = true
135
+ warn_unreachable = true
136
+ warn_unused_configs = true
137
+ warn_unused_ignores = true
138
+
139
+ # Missing packages still fail as import-not-found. This only suppresses the
140
+ # weaker "installed but has no stubs/py.typed marker" error for third-party
141
+ # packages.
142
+ ignore_missing_imports = false
143
+ follow_imports = "silent"
144
+ disable_error_code = ["import-untyped"]
145
+
146
+ # Make local and CI output easier to read and easier to suppress precisely.
147
+ show_error_codes = true
148
+ pretty = true
@@ -0,0 +1,10 @@
1
+ """Workset — create and initialize isolated git worktree worksets."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from workset.config import WorksetError
6
+ from workset.core import RepoResult, WorksetResult, create_workset
7
+
8
+ __all__ = ["WorksetError", "RepoResult", "WorksetResult", "create_workset"]
9
+
10
+ __version__ = "0.1.0"