fix(graphify): update CLI invocation from legacy flag form to subcommand
graphify . --update was removed in favor of graphify update . in v0.4.x. Also improves version detection to try `graphify --version` before falling back to python3 importlib query. Closes #2732
This commit is contained in:
@@ -153,7 +153,7 @@ gsd-tools path: $HOME/.claude/get-shit-done/bin/gsd-tools.cjs
|
||||
1. **Invoke graphify:**
|
||||
Run from the project root:
|
||||
```
|
||||
graphify . --update
|
||||
graphify update .
|
||||
```
|
||||
This builds the knowledge graph with SHA256 incremental caching.
|
||||
Timeout: up to 5 minutes (or as configured via graphify.build_timeout).
|
||||
|
||||
@@ -102,26 +102,55 @@ function checkGraphifyInstalled() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect graphify version via python3 importlib.metadata and check compatibility.
|
||||
* Detect graphify version and check compatibility.
|
||||
* Tested range: >=0.4.0,<1.0
|
||||
*
|
||||
* Detection strategy:
|
||||
* 1. Try `graphify --version` (works for most CLI installations, incl. venv installs)
|
||||
* 2. Fall back to python3 importlib.metadata (legacy / system Python path)
|
||||
* 3. Return null version gracefully if both fail
|
||||
*
|
||||
* @returns {{ version: string|null, compatible: boolean|null, warning: string|null }}
|
||||
*/
|
||||
function checkGraphifyVersion() {
|
||||
const result = childProcess.spawnSync('python3', [
|
||||
'-c',
|
||||
'from importlib.metadata import version; print(version("graphifyy"))',
|
||||
], {
|
||||
// Strategy 1: try `graphify --version` directly (2s timeout -- fast path)
|
||||
const versionResult = childProcess.spawnSync('graphify', ['--version'], {
|
||||
stdio: 'pipe',
|
||||
encoding: 'utf-8',
|
||||
timeout: 5000,
|
||||
timeout: 2000,
|
||||
});
|
||||
|
||||
if (result.status !== 0 || !result.stdout || !result.stdout.trim()) {
|
||||
let versionStr = null;
|
||||
|
||||
if (!versionResult.error && versionResult.status === 0) {
|
||||
const raw = (versionResult.stdout || '').trim();
|
||||
// graphify --version may emit "graphify 0.4.23" or just "0.4.23"
|
||||
const match = raw.match(/(\d+\.\d+(?:\.\d+)*)/);
|
||||
if (match) {
|
||||
versionStr = match[1];
|
||||
}
|
||||
}
|
||||
|
||||
// Strategy 2: fall back to python3 importlib.metadata
|
||||
if (!versionStr) {
|
||||
const pyResult = childProcess.spawnSync('python3', [
|
||||
'-c',
|
||||
'from importlib.metadata import version; print(version("graphifyy"))',
|
||||
], {
|
||||
stdio: 'pipe',
|
||||
encoding: 'utf-8',
|
||||
timeout: 5000,
|
||||
});
|
||||
|
||||
if (!pyResult.error && pyResult.status === 0 && pyResult.stdout && pyResult.stdout.trim()) {
|
||||
versionStr = pyResult.stdout.trim();
|
||||
}
|
||||
}
|
||||
|
||||
if (!versionStr) {
|
||||
return { version: null, compatible: null, warning: 'Could not determine graphify version' };
|
||||
}
|
||||
|
||||
const versionStr = result.stdout.trim();
|
||||
const parts = versionStr.split('.').map(Number);
|
||||
|
||||
if (parts.length < 2 || parts.some(isNaN)) {
|
||||
|
||||
@@ -384,18 +384,36 @@ describe('checkGraphifyVersion', () => {
|
||||
assert.ok(result.warning.includes('Could not parse'));
|
||||
});
|
||||
|
||||
test('calls python3 with importlib.metadata', () => {
|
||||
let capturedCmd;
|
||||
let capturedArgs;
|
||||
test('tries graphify --version first before python3', () => {
|
||||
const calls = [];
|
||||
mock.method(childProcess, 'spawnSync', (cmd, args) => {
|
||||
capturedCmd = cmd;
|
||||
capturedArgs = args;
|
||||
calls.push({ cmd, args });
|
||||
return { status: 0, stdout: '0.4.3\n', stderr: '', error: undefined, signal: null };
|
||||
});
|
||||
|
||||
checkGraphifyVersion();
|
||||
assert.strictEqual(capturedCmd, 'python3');
|
||||
assert.ok(capturedArgs.some(arg => arg.includes('importlib.metadata')));
|
||||
assert.ok(calls.length >= 1, 'at least one spawnSync call');
|
||||
assert.strictEqual(calls[0].cmd, 'graphify');
|
||||
assert.deepStrictEqual(calls[0].args, ['--version']);
|
||||
});
|
||||
|
||||
test('falls back to python3 importlib.metadata when graphify --version fails', () => {
|
||||
const calls = [];
|
||||
mock.method(childProcess, 'spawnSync', (cmd, args) => {
|
||||
calls.push({ cmd, args });
|
||||
if (cmd === 'graphify') {
|
||||
return { status: 1, stdout: '', stderr: 'unknown option', error: undefined, signal: null };
|
||||
}
|
||||
// python3 fallback
|
||||
return { status: 0, stdout: '0.4.3\n', stderr: '', error: undefined, signal: null };
|
||||
});
|
||||
|
||||
const result = checkGraphifyVersion();
|
||||
assert.strictEqual(result.version, '0.4.3');
|
||||
assert.strictEqual(result.compatible, true);
|
||||
const pythonCall = calls.find(c => c.cmd === 'python3');
|
||||
assert.ok(pythonCall, 'python3 should be called as fallback');
|
||||
assert.ok(pythonCall.args.some(arg => arg.includes('importlib.metadata')));
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user