Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ program
.version(VERSION)
.option('-y, --yes', 'Skip prompts and install all tools automatically')
.option('--dry-run', 'Show what would be installed without actually installing')
.option('--verbose', 'Show raw install output from package manager commands')
.option('--list', 'List all available tools grouped by category and exit')
.option('--category <cat>','Install only tools from a specific category')
.parse(process.argv);
Expand Down Expand Up @@ -212,7 +213,7 @@ async function main() {
}

// ── Step 6: Install ───────────────────────────
await runInstaller(os, selectedToolNames);
await runInstaller(os, selectedToolNames, { verbose: options.verbose });

// ── Step 7: Done ──────────────────────────────
console.log('');
Expand Down
8 changes: 5 additions & 3 deletions src/installer.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,11 @@ const logger = require('./logger');
*
* @param {{ id: string, label: string, scriptPath: string }} osInfo - OS descriptor from detectOS()
* @param {string[]} selectedTools - Array of tool names to install (e.g. ['git', 'nodejs'])
* @param {{ verbose?: boolean }} [options] - Installer behavior flags
*/
async function runInstaller(osInfo, selectedTools) {
async function runInstaller(osInfo, selectedTools, options = {}) {
const scriptPath = path.join(__dirname, '..', osInfo.scriptPath);
const stdio = options.verbose ? 'inherit' : 'pipe';

logger.info(`Running installer for ${chalk.bold(osInfo.label)}`);
logger.info(`Package manager: ${chalk.bold(osInfo.packageManager)}\n`);
Expand All @@ -41,12 +43,12 @@ async function runInstaller(osInfo, selectedTools) {
'-ExecutionPolicy', 'Bypass',
'-File', scriptPath,
'-Tool', tool,
], { stdio: 'pipe' });
], { stdio });
} else {
// macOS / Linux: run shell script
// Ensure the script is executable first
await execa('chmod', ['+x', scriptPath]);
await execa('bash', [scriptPath, tool], { stdio: 'pipe' });
await execa('bash', [scriptPath, tool], { stdio });
}

spinner.succeed(chalk.green(`Installed: ${chalk.bold(tool)}`));
Expand Down
12 changes: 12 additions & 0 deletions tests/installer.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,18 @@ describe('runInstaller — Windows', () => {
expect(args).toContain('-Tool');
expect(args).toContain('nodejs');
});

test('uses inherited stdio when verbose mode is enabled', async () => {
await runInstaller(windowsOS, ['git'], { verbose: true });
const psCalls = execa.mock.calls.filter((c) => c[0] === 'powershell');
expect(psCalls[0][2]).toMatchObject({ stdio: 'inherit' });
});

test('uses piped stdio by default', async () => {
await runInstaller(windowsOS, ['git']);
const psCalls = execa.mock.calls.filter((c) => c[0] === 'powershell');
expect(psCalls[0][2]).toMatchObject({ stdio: 'pipe' });
});
});

// ─────────────────────────────────────────────────────────────────────────────
Expand Down
Loading