code-foundry 1.9.10 → 1.9.11
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.
- package/CHANGELOG.md +7 -0
- package/package.json +1 -1
- package/src/commands/doctor.mjs +50 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.9.11](https://github.com/0xPlayerOne/code-foundry/compare/v1.9.10...v1.9.11) (2026-09-08)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
* **doctor:** support nested Rust crates ([#525](https://github.com/0xPlayerOne/code-foundry/issues/525)) ([0ffc87d](https://github.com/0xPlayerOne/code-foundry/commit/0ffc87d71c5e8069a26814dea2250e93a3e87416))
|
|
9
|
+
|
|
3
10
|
## [1.9.10](https://github.com/0xPlayerOne/code-foundry/compare/v1.9.9...v1.9.10) (2026-09-08)
|
|
4
11
|
|
|
5
12
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "code-foundry",
|
|
3
|
-
"version": "1.9.
|
|
3
|
+
"version": "1.9.11",
|
|
4
4
|
"description": "A fast, language-aware repository factory for agent-ready workflows, testing, security, and release automation.",
|
|
5
5
|
"homepage": "https://github.com/0xPlayerOne/code-foundry#readme",
|
|
6
6
|
"bugs": {
|
package/src/commands/doctor.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// @ts-check
|
|
2
2
|
|
|
3
|
-
import { existsSync, readFileSync } from 'node:fs'
|
|
3
|
+
import { existsSync, readFileSync, readdirSync } from 'node:fs'
|
|
4
4
|
import { join, resolve } from 'node:path'
|
|
5
5
|
import { spawnSync } from 'node:child_process'
|
|
6
6
|
import { includesValue, readConfig } from '../lib/config.mjs'
|
|
@@ -80,11 +80,16 @@ export function doctor(root, options = {}) {
|
|
|
80
80
|
if (profile.languages.split(',').includes('rust') && !commandExists('cargo'))
|
|
81
81
|
error('Cargo is required for this repository')
|
|
82
82
|
if (profile.languages.split(',').includes('rust')) {
|
|
83
|
-
const
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
83
|
+
const manifests = rustManifestPaths(target)
|
|
84
|
+
if (!manifests.length) error('no Cargo.toml was found for the configured Rust language')
|
|
85
|
+
for (const manifest of manifests) {
|
|
86
|
+
const metadata = spawnSync(
|
|
87
|
+
'cargo',
|
|
88
|
+
['metadata', '--manifest-path', manifest, '--no-deps', '--format-version', '1'],
|
|
89
|
+
{ cwd: target, stdio: 'ignore' }
|
|
90
|
+
)
|
|
91
|
+
if (metadata.status !== 0) error(`cargo metadata failed for ${manifest}`)
|
|
92
|
+
}
|
|
88
93
|
}
|
|
89
94
|
if (
|
|
90
95
|
profile.languages.split(',').includes('python') &&
|
|
@@ -229,6 +234,45 @@ export function doctor(root, options = {}) {
|
|
|
229
234
|
console.log('Repository doctor passed.')
|
|
230
235
|
}
|
|
231
236
|
|
|
237
|
+
const ignoredRustDirectories = new Set([
|
|
238
|
+
'.git',
|
|
239
|
+
'.code-foundry',
|
|
240
|
+
'.mise',
|
|
241
|
+
'.next',
|
|
242
|
+
'.nuxt',
|
|
243
|
+
'.venv',
|
|
244
|
+
'node_modules',
|
|
245
|
+
'target',
|
|
246
|
+
'vendor',
|
|
247
|
+
])
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Return repository-relative Cargo manifests that represent owned Rust code.
|
|
251
|
+
* A root workspace is authoritative; otherwise validate each nested crate while
|
|
252
|
+
* excluding dependency/build trees that CodeQL shards should not treat as owned.
|
|
253
|
+
* @param {string} root
|
|
254
|
+
* @returns {string[]}
|
|
255
|
+
*/
|
|
256
|
+
export function rustManifestPaths(root) {
|
|
257
|
+
if (existsSync(join(root, 'Cargo.toml'))) return ['Cargo.toml']
|
|
258
|
+
/** @type {string[]} */
|
|
259
|
+
const manifests = []
|
|
260
|
+
/** @param {string} directory @param {string} relative */
|
|
261
|
+
function visit(directory, relative) {
|
|
262
|
+
for (const entry of readdirSync(directory, { withFileTypes: true })) {
|
|
263
|
+
if (entry.isDirectory() && ignoredRustDirectories.has(entry.name)) continue
|
|
264
|
+
const childRelative = relative ? join(relative, entry.name) : entry.name
|
|
265
|
+
const child = join(directory, entry.name)
|
|
266
|
+
if (entry.isDirectory()) visit(child, childRelative)
|
|
267
|
+
else if (entry.name === 'Cargo.toml') manifests.push(childRelative)
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
visit(root, '')
|
|
271
|
+
// Sorting a fresh local collection is deterministic and cannot mutate caller-owned state.
|
|
272
|
+
// oxlint-disable-next-line unicorn/no-array-sort
|
|
273
|
+
return manifests.sort()
|
|
274
|
+
}
|
|
275
|
+
|
|
232
276
|
/** @param {string} root @param {string[]} args */
|
|
233
277
|
function git(root, args) {
|
|
234
278
|
return spawnSync('git', args, { cwd: root, encoding: 'utf8' }).stdout?.trim() ?? ''
|