mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-20 09:09:35 +02:00
Merge pull request #616 from opticon454/fix/deepseek-install-path
fix(deepseek): find pnpm when installing the terminal profile, and install it with dsh Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
commit
5eccaca3bc
7 files changed
+99
-8
No files matched your search
@@ -0,0 +1,76 @@
|
||||
import { describe, it, expect, afterEach } from 'vitest';
|
||||
import { chmodSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
|
||||
import { spawnSync } from 'node:child_process';
|
||||
import { tmpdir } from 'node:os';
|
||||
import { join, resolve } from 'node:path';
|
||||
import { STOCK_CLIS } from '../src/config/cli-registry/stock.js';
|
||||
|
||||
const root = resolve(import.meta.dirname, '..');
|
||||
const dirs: string[] = [];
|
||||
afterEach(() => {
|
||||
for (const dir of dirs.splice(0)) rmSync(dir, { recursive: true, force: true });
|
||||
});
|
||||
|
||||
function deepseekInstallCommand(platform: 'linux' | 'darwin'): string {
|
||||
const ds = STOCK_CLIS.find((c) => (c.id as string) === 'deepseek')!;
|
||||
return ds.discovery.install.command![platform]!;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the stock install command through `/bin/sh -c` (what CLI management does, `shell: true`)
|
||||
* with a fake `npm` that records each call, on a PATH that holds only the fake bins. So this
|
||||
* exercises the real string, not a copy of it.
|
||||
*/
|
||||
function runInstall(opts: { pnpmOnPath: boolean; npmFails?: boolean }): { status: number | null; npmCalls: string[] } {
|
||||
const dir = mkdtempSync(join(tmpdir(), 'dsh-install-'));
|
||||
dirs.push(dir);
|
||||
const npmBin = join(dir, 'npm-bin');
|
||||
const pnpmBin = join(dir, 'pnpm-bin');
|
||||
mkdirSync(npmBin);
|
||||
mkdirSync(pnpmBin);
|
||||
const log = join(dir, 'npm.log');
|
||||
writeFileSync(log, '');
|
||||
writeFileSync(join(npmBin, 'npm'), '#!/bin/sh\necho "$*" >> "$NPM_LOG"\nexit "${NPM_EXIT:-0}"\n');
|
||||
chmodSync(join(npmBin, 'npm'), 0o755);
|
||||
writeFileSync(join(pnpmBin, 'pnpm'), '#!/bin/sh\nexit 0\n');
|
||||
chmodSync(join(pnpmBin, 'pnpm'), 0o755);
|
||||
const result = spawnSync('/bin/sh', ['-c', deepseekInstallCommand('linux')], {
|
||||
env: {
|
||||
PATH: opts.pnpmOnPath ? `${npmBin}:${pnpmBin}` : npmBin,
|
||||
NPM_LOG: log,
|
||||
NPM_EXIT: opts.npmFails ? '1' : '0',
|
||||
},
|
||||
encoding: 'utf-8',
|
||||
});
|
||||
const npmCalls = readFileSync(log, 'utf-8').split('\n').filter(Boolean);
|
||||
return { status: result.status, npmCalls };
|
||||
}
|
||||
|
||||
describe('DeepSeek install', () => {
|
||||
it('is the same command on linux and darwin', () => {
|
||||
expect(deepseekInstallCommand('darwin')).toBe(deepseekInstallCommand('linux'));
|
||||
});
|
||||
|
||||
it('installs pnpm with dsh when none is on PATH, since `dsh plugin` spawns a literal pnpm', () => {
|
||||
const { status, npmCalls } = runInstall({ pnpmOnPath: false });
|
||||
expect(status).toBe(0);
|
||||
expect(npmCalls).toEqual(['install -g @deepseek-ai/dsh', 'install -g pnpm']);
|
||||
});
|
||||
|
||||
it('leaves an existing pnpm alone (a corepack shim makes `npm install -g pnpm` fail with EEXIST)', () => {
|
||||
const { status, npmCalls } = runInstall({ pnpmOnPath: true });
|
||||
expect(status).toBe(0);
|
||||
expect(npmCalls).toEqual(['install -g @deepseek-ai/dsh']);
|
||||
});
|
||||
|
||||
it('reports a failed dsh install and does not go on to pnpm', () => {
|
||||
const { status, npmCalls } = runInstall({ pnpmOnPath: false, npmFails: true });
|
||||
expect(status).not.toBe(0);
|
||||
expect(npmCalls).toEqual(['install -g @deepseek-ai/dsh']);
|
||||
});
|
||||
|
||||
it("puts dsh's own directory first on the profile install's PATH", () => {
|
||||
const src = readFileSync(resolve(root, 'src/web/routes/system-routes.ts'), 'utf8');
|
||||
expect(src).toMatch(/env: \{ \.\.\.process\.env, PATH: \[dir, process\.env\.PATH\]/);
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user