Commit 4231fc8
go_modules: Add go.work workspace support (#14909)
* Add go.work workspace support to Go modules updater
Dependabot can now detect and process go.work files, enabling
dependency updates across multi-module Go workspaces.
- FileFetcher: detect go.work, fetch all workspace module go.mod/go.sum
- FileParser: parse dependencies from all workspace modules; DependencySet
handles deduplication across modules automatically
- FileUpdater: dispatch to workspace vs. single-module update paths
- GoModUpdater: run `go get dep@version` in each module directory so
every go.mod that requires the dep gets updated; follow with
`go work sync` then per-module `go mod tidy -e`
- GoWorkParser: shared utility for parsing `use` directives from go.work
content, including inline comment stripping and `use .` (root module)
- PackageDetailsFetcher: fall back to any sub-module go.mod when no root
go.mod exists
- ecosystem_versions: read Go version from go.work or first workspace
module when no root go.mod is present
Fixes #6012
* Add specs and fixtures for go.work workspace support
- GoWorkParser: unit tests for block/single-line use directives, inline
comments, deduplication, bare `use .`, empty content, toolchain and
godebug directives
- FileFetcher: workspace with root module, workspace with no root go.mod,
root-only workspace (use .)
- FileParser: workspace dependency parsing and cross-module deduplication
- FileUpdater: workspace update dispatch, all-module go get, go work sync
failure propagation, no-root-mod workspace
- Fixtures: workspace/ (root + libs + services), workspace_no_root_mod/
(api + worker), workspace_root_only/ (use . only)
* Fix Sorbet, lint, and ecosystem_versions regressions caught by CI
- Restore T.nilable in T.let memoization for @all_go_mods and
@updated_workspace_module_files — required Sorbet idiom for ||=
memoized ivars not declared in initialize
- Revert go_version_from_file regex to \d+\.\d+ (major.minor only)
to match original ecosystem_versions behaviour and fix e2e tests
- Wrap two over-length lines in file_parser_spec.rb
- Use %w() literals and explicit subject in go_work_parser_spec.rb
- Add file_updater_spec.rb to RSpec/AnyInstance todo exclusion list
(same treatment as bundler, bun, and other ecosystems)
* Remove go.env and .ruby-version (local development artifacts)
* Address Copilot review feedback
- Reject absolute paths and traversals in GoModUpdater#workspace_module_paths
as a defence-in-depth guard (paths already validated by FileFetcher, but
worth being explicit in the updater too)
- Pass mod_file.path to handle_parser_error when parsing workspace modules
so DependencyFileNotParseable points at the failing go.mod, not go.work
- Fetch go.work.sum when present; return updated version after go work sync
* chore: bump go_work_parser.rb to typed: strong
Sorbet typing mode check (spoom) detected all methods have complete
signatures, qualifying for the stricter strong level.
* fix: select go.mod by requirement file in PackageDetailsFetcher
In workspace repos there is no root go.mod, so the fallback to the first
nested go.mod could apply exclude directives from an unrelated module.
For direct dependencies, use the requirement file path to find the
correct go.mod. Indirect deps (empty requirements) retain the existing
fallback behaviour.
* fix: align fetch/parse scope with go.work use directives
Previously, the fetcher unconditionally appended the root go.mod/go.sum
whenever they existed, even in workspace repos where go.work does not
include ".". The parser then ingested those out-of-scope modules via
all_go_mods, surfacing dependencies that the updater would never touch.
Fix the fetcher so workspace mode is fully handled by workspace_module_files
(which now fetches "go.mod"/"go.sum" directly for the root "." path when
present in the use list) and removes the unconditional root fallback.
Fix the parser so all_go_mods derives its list from GoWorkParser.use_paths
in workspace mode, keeping parse scope in lockstep with update scope.
Addresses maintainer feedback from @thavaahariharangit.
* fix: harden workspace_module_paths against missing dirs and false-positive path rejection
- Replace substring `include?("..")` check with Pathname.cleanpath-based
traversal guard, matching FileFetcher#valid_module_path? and avoiding
false rejections on dirs whose names contain ".." (e.g. "tools..v2")
- Filter use-paths against fetched go.mod dependency_files so Dir.chdir
never runs against a module directory that wasn't fetched, preventing
an unhandled Errno::ENOENT if go.work has a stale or missing use entry
* fix: resolve RuboCop offenses in workspace_module_paths
Extract valid_workspace_path? and workspace_mod_name helpers to bring
Metrics/PerceivedComplexity back under threshold, and use to_set(&:name)
to satisfy Style/MapToSet.
* fix: fail fast when a go.work workspace module has a vendor directory
Workspace vendoring is not yet supported — the workspace update path
only updates go.mod/go.sum files and does not invoke vendor_updater,
which would leave vendor/modules.txt and vendored sources stale.
Detect vendor/modules.txt in any workspace module (root or submodule)
before proceeding and raise DependencyFileNotResolvable with a clear
message rather than silently producing an inconsistent vendor directory.
* fix: wrap long line in check_workspace_not_vendored! to satisfy LineLength cop
* fix: each File.join argument on its own line to satisfy multiline argument cops
---------
Co-authored-by: Jamie Magee <jamagee@microsoft.com>
Co-authored-by: Hariharan Thavachelvam <164553783+thavaahariharangit@users.noreply.github.com>1 parent a7b8ee8 commit 4231fc8
33 files changed
Lines changed: 1143 additions & 43 deletions
File tree
- go_modules
- lib/dependabot/go_modules
- file_updater
- package
- spec
- dependabot/go_modules
- fixtures/projects
- workspace_no_root_mod
- api
- worker
- workspace_root_only
- workspace
- libs
- services
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
51 | 51 | | |
52 | 52 | | |
53 | 53 | | |
| 54 | + | |
54 | 55 | | |
55 | 56 | | |
56 | 57 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
| 7 | + | |
7 | 8 | | |
8 | 9 | | |
9 | 10 | | |
| |||
13 | 14 | | |
14 | 15 | | |
15 | 16 | | |
16 | | - | |
| 17 | + | |
17 | 18 | | |
18 | 19 | | |
19 | 20 | | |
20 | 21 | | |
21 | | - | |
| 22 | + | |
22 | 23 | | |
23 | 24 | | |
24 | 25 | | |
25 | 26 | | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
26 | 32 | | |
27 | 33 | | |
28 | | - | |
| 34 | + | |
29 | 35 | | |
30 | 36 | | |
31 | 37 | | |
32 | 38 | | |
33 | 39 | | |
34 | 40 | | |
35 | | - | |
36 | | - | |
37 | | - | |
38 | | - | |
39 | | - | |
40 | | - | |
41 | | - | |
42 | | - | |
43 | | - | |
44 | | - | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
45 | 44 | | |
46 | 45 | | |
47 | 46 | | |
48 | 47 | | |
49 | 48 | | |
50 | 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 | + | |
51 | 79 | | |
52 | 80 | | |
53 | 81 | | |
| |||
58 | 86 | | |
59 | 87 | | |
60 | 88 | | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
61 | 94 | | |
62 | 95 | | |
63 | 96 | | |
64 | 97 | | |
65 | 98 | | |
66 | 99 | | |
67 | 100 | | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
68 | 161 | | |
69 | 162 | | |
70 | 163 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
6 | 6 | | |
7 | 7 | | |
8 | 8 | | |
| 9 | + | |
9 | 10 | | |
10 | 11 | | |
11 | 12 | | |
| |||
52 | 53 | | |
53 | 54 | | |
54 | 55 | | |
55 | | - | |
56 | | - | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
57 | 61 | | |
58 | | - | |
59 | | - | |
| 62 | + | |
60 | 63 | | |
61 | 64 | | |
62 | 65 | | |
| |||
190 | 193 | | |
191 | 194 | | |
192 | 195 | | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
| 269 | + | |
| 270 | + | |
| 271 | + | |
| 272 | + | |
| 273 | + | |
| 274 | + | |
| 275 | + | |
| 276 | + | |
| 277 | + | |
| 278 | + | |
| 279 | + | |
| 280 | + | |
| 281 | + | |
| 282 | + | |
| 283 | + | |
| 284 | + | |
193 | 285 | | |
194 | 286 | | |
195 | | - | |
| 287 | + | |
196 | 288 | | |
197 | 289 | | |
198 | 290 | | |
| |||
264 | 356 | | |
265 | 357 | | |
266 | 358 | | |
267 | | - | |
268 | | - | |
| 359 | + | |
| 360 | + | |
269 | 361 | | |
270 | | - | |
| 362 | + | |
| 363 | + | |
271 | 364 | | |
272 | 365 | | |
273 | 366 | | |
| |||
0 commit comments