mirror of
https://github.com/affaan-m/ECC.git
synced 2026-09-29 04:55:12 +02:00
feat(profiles): add opt-in Lean/Full and hybrid Auto selection
This commit is contained in:
+43
-12
@@ -78,6 +78,35 @@ function runSetup(fixture, args, options = {}) {
|
||||
function quoteShellArgument(value) {
|
||||
return `'${String(value).replace(/'/g, `'\\''`)}'`;
|
||||
}
|
||||
|
||||
// Answer only after the PTY displays a prompt. Fixed-delay pipes can deliver
|
||||
// blank defaults and EOF before the wizard creates its readline interface.
|
||||
function driveInteractiveTerminal() {
|
||||
const { spawn } = require('child_process');
|
||||
const { pseudoTerminalCommand, answers } = JSON.parse(process.argv[1]);
|
||||
// Node pipes are sockets on macOS; script requires a real pipe for stdin.
|
||||
const child = spawn('sh', ['-c', `cat | ${pseudoTerminalCommand}`], { stdio: ['pipe', 'pipe', 'pipe'] });
|
||||
let pending = '';
|
||||
let answerIndex = 0;
|
||||
child.stdout.on('data', chunk => {
|
||||
process.stdout.write(chunk);
|
||||
pending += chunk.toString('utf8');
|
||||
const prompt = /Choose(?: \[\d+\])?: |\[y\/N\] /.exec(pending);
|
||||
if (!prompt) return;
|
||||
pending = pending.slice(prompt.index + prompt[0].length);
|
||||
if (answerIndex >= answers.length) { child.stdin.end(); return; }
|
||||
const answer = answers[answerIndex++];
|
||||
child.stdin.write(answer === '\u0004' ? answer : `${answer}\n`);
|
||||
if (answerIndex === answers.length) child.stdin.end();
|
||||
});
|
||||
child.stderr.on('data', chunk => process.stderr.write(chunk));
|
||||
child.stdin.on('error', error => {
|
||||
if (error.code !== 'EPIPE') { process.stderr.write(error.message); process.exitCode = 1; }
|
||||
});
|
||||
child.on('error', error => { process.stderr.write(error.message); process.exitCode = 1; });
|
||||
child.on('close', code => { process.exitCode = code ?? 1; });
|
||||
}
|
||||
|
||||
function runInteractiveEccSetup(fixture, options = {}) {
|
||||
if (process.platform === 'win32') {
|
||||
return null;
|
||||
@@ -85,12 +114,18 @@ function runInteractiveEccSetup(fixture, options = {}) {
|
||||
|
||||
const args = options.args || ['--dry-run'];
|
||||
const answers = options.answers || ['3', '3'];
|
||||
const command = [
|
||||
const setupCommand = [
|
||||
process.execPath,
|
||||
eccScript,
|
||||
'setup',
|
||||
...args,
|
||||
];
|
||||
const command = options.delayedStartup
|
||||
? [process.execPath, '-e', `setTimeout(() => {
|
||||
const result = require('child_process').spawnSync(process.argv[1], process.argv.slice(2), { stdio: 'inherit' });
|
||||
process.exitCode = result.status ?? 1;
|
||||
}, 1250);`, ...setupCommand]
|
||||
: setupCommand;
|
||||
const scriptArgs = process.platform === 'darwin'
|
||||
? ['-q', '-e', '/dev/null', ...command]
|
||||
: [
|
||||
@@ -100,16 +135,11 @@ function runInteractiveEccSetup(fixture, options = {}) {
|
||||
command.map(quoteShellArgument).join(' '),
|
||||
'/dev/null',
|
||||
];
|
||||
const pseudoTerminalCommand = ['script', ...scriptArgs]
|
||||
.map(quoteShellArgument)
|
||||
.join(' ');
|
||||
const answerCommands = answers
|
||||
.map(answer => `sleep 0.5; printf '%s\\n' ${quoteShellArgument(answer)}`)
|
||||
.join('; ');
|
||||
|
||||
return spawnSync('sh', [
|
||||
'-c',
|
||||
`(${answerCommands}; sleep 0.1) | ${pseudoTerminalCommand}`,
|
||||
const pseudoTerminalCommand = ['script', ...scriptArgs].map(quoteShellArgument).join(' ');
|
||||
return spawnSync(process.execPath, [
|
||||
'-e',
|
||||
`(${driveInteractiveTerminal.toString()})();`,
|
||||
JSON.stringify({ pseudoTerminalCommand, answers }),
|
||||
], {
|
||||
cwd: fixture.projectRoot,
|
||||
env: {
|
||||
@@ -386,8 +416,8 @@ test('setup automatically migrates an existing install to the selected scope and
|
||||
const calls = readCalls(fixture);
|
||||
assert.ok(calls.some(argv => (
|
||||
argv.join(' ') === 'plugin install ecc@ecc --scope user'
|
||||
+ ' --config hooks_enabled=true --config hook_profile=minimal'
|
||||
)));
|
||||
assert.ok(calls.every(argv => !argv.includes('--config')));
|
||||
assert.ok(calls.some(argv => (
|
||||
argv.join(' ') === 'plugin uninstall ecc@ecc --scope local --keep-data'
|
||||
)));
|
||||
@@ -914,6 +944,7 @@ test('interactive defaults preserve an existing install scope and hook preferenc
|
||||
const result = runInteractiveEccSetup(fixture, {
|
||||
args: ['--dry-run'],
|
||||
answers: ['', ''],
|
||||
delayedStartup: true,
|
||||
});
|
||||
assert.ifError(result.error);
|
||||
assert.strictEqual(result.status, 0, `${result.stdout}\n${result.stderr}`);
|
||||
|
||||
Reference in New Issue
Block a user