distinguish a dev-tree clide from a packaged install (T-256)
CliInstaller.inspect() gains a devTree state: when `clide` on PATH resolves to a dev-tree build artifact (native/<plat>/clide, the Makefile's CLIDE_CLI_BIN output) it's classified separately from a packaged install rather than silently treated as "installed". needsInstall stays false for a dev build (it's intentional on a checkout, not a reinstall prompt), and the launch-time check surfaces it as an info note. install() flags fromDevTree + notes it in the result message when the copied source is a dev build. Closes the last open child of the T-208 "give Claude hands" initiative. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -108,6 +108,34 @@ void main() {
|
||||
);
|
||||
expect(i.inspect().state, CliInstallState.staleGui);
|
||||
});
|
||||
|
||||
test('devTree when clide resolves to a native/<plat>/clide build (T-256)', () {
|
||||
final dev = touchExec('${tmp.path}/native/linux-x64/clide').path;
|
||||
final binDir = Directory('${tmp.path}/bin')..createSync();
|
||||
Link('${binDir.path}/clide').createSync(dev);
|
||||
final i = installer(
|
||||
resolvedExecutable: '${tmp.path}/gui/clide',
|
||||
env: {'PATH': binDir.path},
|
||||
);
|
||||
final s = i.inspect();
|
||||
expect(s.state, CliInstallState.devTree);
|
||||
// A dev build is intentional — it doesn't prompt a reinstall.
|
||||
expect(s.needsInstall, isFalse);
|
||||
});
|
||||
});
|
||||
|
||||
group('isDevTreeClient', () {
|
||||
test('matches the native/<platform>/clide build artifacts', () {
|
||||
expect(isDevTreeClient('/repo/native/linux-x64/clide'), isTrue);
|
||||
expect(isDevTreeClient('/repo/native/macos-arm64/clide'), isTrue);
|
||||
expect(isDevTreeClient('native/linux-arm64/clide'), isTrue);
|
||||
});
|
||||
|
||||
test('does not match installed or bundled paths', () {
|
||||
expect(isDevTreeClient('/home/x/.local/bin/clide'), isFalse);
|
||||
expect(isDevTreeClient('/usr/local/bin/clide'), isFalse);
|
||||
expect(isDevTreeClient('/opt/clide/bundle/clide-cli'), isFalse);
|
||||
});
|
||||
});
|
||||
|
||||
group('defaults', () {
|
||||
@@ -191,6 +219,33 @@ void main() {
|
||||
}
|
||||
});
|
||||
|
||||
test('flags fromDevTree when the source is a dev-tree build (T-256)', () {
|
||||
final src = touchExec('${tmp.path}/native/linux-x64/clide');
|
||||
final binDir = '${tmp.path}/bin';
|
||||
final i = installer(
|
||||
resolvedExecutable: '${tmp.path}/gui/clide',
|
||||
env: {'PATH': binDir},
|
||||
candidates: [src.path],
|
||||
installDir: binDir,
|
||||
);
|
||||
final r = i.install();
|
||||
expect(r.ok, isTrue);
|
||||
expect(r.fromDevTree, isTrue);
|
||||
expect(r.message, contains('dev-tree build'));
|
||||
});
|
||||
|
||||
test('a bundled (non-dev) source is not flagged fromDevTree', () {
|
||||
final src = touchExec('${tmp.path}/bundle/clide-cli');
|
||||
final binDir = '${tmp.path}/bin';
|
||||
final i = installer(
|
||||
resolvedExecutable: '${tmp.path}/gui/clide',
|
||||
env: {'PATH': binDir},
|
||||
candidates: [src.path],
|
||||
installDir: binDir,
|
||||
);
|
||||
expect(i.install().fromDevTree, isFalse);
|
||||
});
|
||||
|
||||
test('overwrites a stale symlink rather than following it', () {
|
||||
final src = touchExec('${tmp.path}/bundle/clide-cli', contents: 'NEW');
|
||||
final gui = touchExec('${tmp.path}/gui/clide', contents: 'GUI').path;
|
||||
|
||||
Reference in New Issue
Block a user