fastws-cli 0.0.8__tar.gz → 0.0.9__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.
@@ -1,5 +1,17 @@
1
1
  <!-- do not remove -->
2
2
 
3
+ ## 0.0.9
4
+
5
+ ### New Features
6
+
7
+ - Add ws-build: build sdists of all workspace projects into a dists dir, skipping unchanged projects and pruning old versions ([#23](https://github.com/AnswerDotAI/fastws/issues/23))
8
+ - detect project from cwd, add --nodeps to skip the dependency closure, and map dir names to packages ([#22](https://github.com/AnswerDotAI/fastws/issues/22))
9
+ - Move `dep_key`, member graph, and closure helpers to ghapi (>=2.0.6) and use `dep_key`/`local_dep_graph`/`dep_closure` in core and releases ([#21](https://github.com/AnswerDotAI/fastws/issues/21))
10
+ - ws-sync: write content-hashed .git/fastws-cargo-key per crate, covering Cargo.lock and locally patched git deps, for uv cache-keys ([#20](https://github.com/AnswerDotAI/fastws/issues/20))
11
+ - Run cargo update before uv sync in `ws_sync` so Rust deps refresh first ([#19](https://github.com/AnswerDotAI/fastws/issues/19))
12
+ - Add out-of-tree repo support, auto-managed workspace excludes, and uv.sources preservation to ws-sync ([#18](https://github.com/AnswerDotAI/fastws/issues/18))
13
+
14
+
3
15
  ## 0.0.8
4
16
 
5
17
  ### New Features
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fastws-cli
3
- Version: 0.0.8
3
+ Version: 0.0.9
4
4
  Summary: Fast workspace tools for multi-repo management
5
5
  Author: Jeremy Howard
6
6
  License: Apache-2.0
@@ -12,7 +12,7 @@ Description-Content-Type: text/markdown
12
12
  License-File: LICENSE
13
13
  Requires-Dist: fastcore>=1.14.3
14
14
  Requires-Dist: fastgit>=0.0.7
15
- Requires-Dist: ghapi>=1.0.7
15
+ Requires-Dist: ghapi>=2.0.6
16
16
  Requires-Dist: packaging
17
17
  Requires-Dist: tomli; python_version < "3.11"
18
18
  Provides-Extra: dev
@@ -42,6 +42,17 @@ AnswerDotAI/fastship
42
42
  AnswerDotAI/fastws
43
43
  ```
44
44
 
45
+ A line may add a checkout location after the repo, for repos that live outside
46
+ the workspace root (`~` ok). Every command then reads and writes them there, and
47
+ `ws-sync` editable-installs each Python project found inside (the repo root if it
48
+ has a `pyproject.toml`, else its immediate subdirectories), so one out-of-tree
49
+ repo can hold several small packages alongside non-Python content:
50
+
51
+ ```
52
+ AnswerDotAI/fastcore
53
+ jph00/private ~/private
54
+ ```
55
+
45
56
  ## Commands
46
57
 
47
58
  ### `ws-clone`
@@ -80,6 +91,18 @@ ws-branches
80
91
  ws-branches --expected develop
81
92
  ```
82
93
 
94
+ ### `ws-build`
95
+
96
+ Build an sdist of each workspace project (including `repos.txt` checkouts outside the root) into a dists directory, `.dists` by default. A project is rebuilt only when a file in it is newer than its existing sdist, and older versions of a rebuilt package are pruned, so the directory always holds one current sdist per project. A failing project gets a warning without stopping the others, but the command then exits 1.
97
+
98
+ Progress goes to stderr; on success the dists path prints to stdout, so `$(ws-build)` in a script both refreshes the pool and yields its location. The result suits any resolver that takes a candidate pool, e.g. `uv pip install --find-links` or a docker build context for images that must test unreleased workspace packages:
99
+
100
+ ```bash
101
+ ws-build
102
+ ws-build --force # rebuild everything
103
+ ws-build --out /tmp/dists
104
+ ```
105
+
83
106
  ### `ws-sync`
84
107
 
85
108
  Sync the workspace metadata, pull local repos, and install updates.
@@ -88,11 +111,21 @@ It respects `tool.uv.workspace.members` and `exclude` when scanning local projec
88
111
  member directory isn't a Python project yet (no `pyproject.toml`, e.g. a fresh empty clone), it
89
112
  warns and skips the `uv sync` step instead of letting uv fail on the whole workspace.
90
113
 
114
+ The workspace `exclude` list is auto-managed: a top-level directory that isn't a valid Python
115
+ project and isn't a `repos.txt` checkout gets excluded automatically, and is un-excluded once it
116
+ gains a real `pyproject.toml`. Globs, entries for missing directories, and entries for `repos.txt`
117
+ checkouts are always kept, and `exclude = [...]` under `[tool.fastws]` in the workspace
118
+ `pyproject.toml` declares intent the scan can't infer (e.g. keeping a real project out of the
119
+ workspace). Hand-written `[tool.uv.sources]` entries (path, git, ...) are preserved when syncing
120
+ adds new members.
121
+
91
122
  At most once per day (tracked by a stamp file inside the workspace's `.git`, so git never
92
123
  sees it), the sync also floats dependencies: `uv sync -U` instead of plain `uv sync`, plus
93
124
  a parallel `cargo update` in every member with a `Cargo.toml`, printing what moved. Pass
94
125
  `--upgrade` to force that pass regardless of when it last ran.
95
126
 
127
+ Before every uv sync, `ws-sync` writes `.git/fastws-cargo-key` for each member crate. The key hashes `Cargo.lock` contents and the workspace Cargo patch configuration. For Git dependencies redirected to local paths by `[patch."<url>"]`, it also hashes each patched crate's `Cargo.toml`, `build.rs`, and `src` tree, recursively. The file is rewritten only when that content changes, so projects can use `{ file = ".git/fastws-cargo-key" }` in `tool.uv.cache-keys` without rebuilding after a timestamp-only `Cargo.lock` write.
128
+
96
129
  ```bash
97
130
  ws-sync
98
131
  ws-sync --workspace ~/aai-ws
@@ -104,12 +137,15 @@ ws-sync --upgrade
104
137
  Add a repo to `repos.txt`, then run `ws-sync`. Given `owner/repo`, it clones; given the
105
138
  name of an existing local folder (e.g. one just scaffolded with `nbdev-new` or `ship-new`),
106
139
  it resolves `owner/repo` from the folder's `origin` remote instead, telling you exactly
107
- what's missing if the folder has no git repo, no GitHub origin, or no `pyproject.toml`:
140
+ what's missing if the folder has no git repo, no GitHub origin, or no `pyproject.toml`.
141
+ Given a path outside the workspace root, the repo stays where it is and its location is
142
+ recorded in `repos.txt` (no root `pyproject.toml` needed: its packages are discovered on sync):
108
143
 
109
144
  ```bash
110
145
  ws-add AnswerDotAI/fastws
111
146
  ws-add answerdotai/fastws
112
147
  ws-add fastws # existing local folder, resolved via its origin remote
148
+ ws-add ~/private # a path outside the workspace: stays where it is, recorded in repos.txt with its location
113
149
  ```
114
150
 
115
151
  ### `ws-remove`
@@ -129,11 +165,14 @@ ws-remove fastws # bare folder name also works if the directory exists
129
165
  Report repos with commits since their newest GitHub release, so nothing reviewed sits unshipped:
130
166
 
131
167
  ```bash
132
- ws-releases # sweep every repo in repos.txt
168
+ ws-releases # at the workspace root: sweep every repo in repos.txt
133
169
  ws-releases solveit # only solveit's transitive workspace dependencies
170
+ ws-releases --nodeps # inside a repo: just that repo
134
171
  ws-releases --skip 'wip' # extra start-of-message regex for commits that need no release
135
172
  ```
136
173
 
174
+ Run from inside a workspace checkout, the sweep narrows to that repo and its transitive workspace dependencies; `--nodeps` narrows it to the repo alone (an error when no project is in play).
175
+
137
176
  Each pending repo lists its unreleased commit summaries; repos with no releases yet get one quiet `no releases:` line, and fully-released repos appear in `up to date:`. The newest release is picked by version number (publish timestamps can be out of order), and repos whose default branch isn't `main` are handled automatically.
138
177
 
139
178
  Commits whose message matches a start-anchored regex from the skip set need no release and aren't reported. The built-in set covers version bumps and housekeeping (`bump`, `nbdev regen`, `.gitignore`, `docs`, `CI`, ...: `DEFAULT_SKIP` in `fastws.releases`); `[tool.fastws]` in the workspace root `pyproject.toml` adds to it, and names repos that should never be swept (apps that deploy rather than release):
@@ -19,6 +19,17 @@ AnswerDotAI/fastship
19
19
  AnswerDotAI/fastws
20
20
  ```
21
21
 
22
+ A line may add a checkout location after the repo, for repos that live outside
23
+ the workspace root (`~` ok). Every command then reads and writes them there, and
24
+ `ws-sync` editable-installs each Python project found inside (the repo root if it
25
+ has a `pyproject.toml`, else its immediate subdirectories), so one out-of-tree
26
+ repo can hold several small packages alongside non-Python content:
27
+
28
+ ```
29
+ AnswerDotAI/fastcore
30
+ jph00/private ~/private
31
+ ```
32
+
22
33
  ## Commands
23
34
 
24
35
  ### `ws-clone`
@@ -57,6 +68,18 @@ ws-branches
57
68
  ws-branches --expected develop
58
69
  ```
59
70
 
71
+ ### `ws-build`
72
+
73
+ Build an sdist of each workspace project (including `repos.txt` checkouts outside the root) into a dists directory, `.dists` by default. A project is rebuilt only when a file in it is newer than its existing sdist, and older versions of a rebuilt package are pruned, so the directory always holds one current sdist per project. A failing project gets a warning without stopping the others, but the command then exits 1.
74
+
75
+ Progress goes to stderr; on success the dists path prints to stdout, so `$(ws-build)` in a script both refreshes the pool and yields its location. The result suits any resolver that takes a candidate pool, e.g. `uv pip install --find-links` or a docker build context for images that must test unreleased workspace packages:
76
+
77
+ ```bash
78
+ ws-build
79
+ ws-build --force # rebuild everything
80
+ ws-build --out /tmp/dists
81
+ ```
82
+
60
83
  ### `ws-sync`
61
84
 
62
85
  Sync the workspace metadata, pull local repos, and install updates.
@@ -65,11 +88,21 @@ It respects `tool.uv.workspace.members` and `exclude` when scanning local projec
65
88
  member directory isn't a Python project yet (no `pyproject.toml`, e.g. a fresh empty clone), it
66
89
  warns and skips the `uv sync` step instead of letting uv fail on the whole workspace.
67
90
 
91
+ The workspace `exclude` list is auto-managed: a top-level directory that isn't a valid Python
92
+ project and isn't a `repos.txt` checkout gets excluded automatically, and is un-excluded once it
93
+ gains a real `pyproject.toml`. Globs, entries for missing directories, and entries for `repos.txt`
94
+ checkouts are always kept, and `exclude = [...]` under `[tool.fastws]` in the workspace
95
+ `pyproject.toml` declares intent the scan can't infer (e.g. keeping a real project out of the
96
+ workspace). Hand-written `[tool.uv.sources]` entries (path, git, ...) are preserved when syncing
97
+ adds new members.
98
+
68
99
  At most once per day (tracked by a stamp file inside the workspace's `.git`, so git never
69
100
  sees it), the sync also floats dependencies: `uv sync -U` instead of plain `uv sync`, plus
70
101
  a parallel `cargo update` in every member with a `Cargo.toml`, printing what moved. Pass
71
102
  `--upgrade` to force that pass regardless of when it last ran.
72
103
 
104
+ Before every uv sync, `ws-sync` writes `.git/fastws-cargo-key` for each member crate. The key hashes `Cargo.lock` contents and the workspace Cargo patch configuration. For Git dependencies redirected to local paths by `[patch."<url>"]`, it also hashes each patched crate's `Cargo.toml`, `build.rs`, and `src` tree, recursively. The file is rewritten only when that content changes, so projects can use `{ file = ".git/fastws-cargo-key" }` in `tool.uv.cache-keys` without rebuilding after a timestamp-only `Cargo.lock` write.
105
+
73
106
  ```bash
74
107
  ws-sync
75
108
  ws-sync --workspace ~/aai-ws
@@ -81,12 +114,15 @@ ws-sync --upgrade
81
114
  Add a repo to `repos.txt`, then run `ws-sync`. Given `owner/repo`, it clones; given the
82
115
  name of an existing local folder (e.g. one just scaffolded with `nbdev-new` or `ship-new`),
83
116
  it resolves `owner/repo` from the folder's `origin` remote instead, telling you exactly
84
- what's missing if the folder has no git repo, no GitHub origin, or no `pyproject.toml`:
117
+ what's missing if the folder has no git repo, no GitHub origin, or no `pyproject.toml`.
118
+ Given a path outside the workspace root, the repo stays where it is and its location is
119
+ recorded in `repos.txt` (no root `pyproject.toml` needed: its packages are discovered on sync):
85
120
 
86
121
  ```bash
87
122
  ws-add AnswerDotAI/fastws
88
123
  ws-add answerdotai/fastws
89
124
  ws-add fastws # existing local folder, resolved via its origin remote
125
+ ws-add ~/private # a path outside the workspace: stays where it is, recorded in repos.txt with its location
90
126
  ```
91
127
 
92
128
  ### `ws-remove`
@@ -106,11 +142,14 @@ ws-remove fastws # bare folder name also works if the directory exists
106
142
  Report repos with commits since their newest GitHub release, so nothing reviewed sits unshipped:
107
143
 
108
144
  ```bash
109
- ws-releases # sweep every repo in repos.txt
145
+ ws-releases # at the workspace root: sweep every repo in repos.txt
110
146
  ws-releases solveit # only solveit's transitive workspace dependencies
147
+ ws-releases --nodeps # inside a repo: just that repo
111
148
  ws-releases --skip 'wip' # extra start-of-message regex for commits that need no release
112
149
  ```
113
150
 
151
+ Run from inside a workspace checkout, the sweep narrows to that repo and its transitive workspace dependencies; `--nodeps` narrows it to the repo alone (an error when no project is in play).
152
+
114
153
  Each pending repo lists its unreleased commit summaries; repos with no releases yet get one quiet `no releases:` line, and fully-released repos appear in `up to date:`. The newest release is picked by version number (publish timestamps can be out of order), and repos whose default branch isn't `main` are handled automatically.
115
154
 
116
155
  Commits whose message matches a start-anchored regex from the skip set need no release and aren't reported. The built-in set covers version bumps and housekeeping (`bump`, `nbdev regen`, `.gitignore`, `docs`, `CI`, ...: `DEFAULT_SKIP` in `fastws.releases`); `[tool.fastws]` in the workspace root `pyproject.toml` adds to it, and names repos that should never be swept (apps that deploy rather than release):
@@ -1,4 +1,5 @@
1
- __version__ = "0.0.8"
1
+ __version__ = "0.0.9"
2
+
2
3
 
3
4
 
4
5