UNPKG

@controlplane/cli

Version:

Control Plane Corporation CLI

201 lines 8.59 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.MiscCommand = void 0; const fs = require("fs"); const path = require("path"); const command_1 = require("./command"); const installer_1 = require("./completion/installer"); const cache_generator_1 = require("./completion/cache-generator"); const constants_1 = require("./completion/constants"); const logger_1 = require("../util/logger"); const options_1 = require("../commands/options"); const io_1 = require("../util/io"); class MiscCommand extends command_1.Command { constructor() { super(...arguments); this.command = 'misc'; this.describe = 'Miscellaneous helper commands'; } builder(yargs) { return yargs.demandCommand().command(new InstallCompletion().toYargs()).command(new UninstallCompletion().toYargs()); } handle() { } } exports.MiscCommand = MiscCommand; class InstallCompletion extends command_1.Command { constructor() { super(); this.command = 'install-completion'; this.describe = 'Install shell completion to your local profile'; this.installer = new installer_1.CompletionInstaller('cpln', 'cpln'); } builder(yargs) { return (0, options_1.withDebugOptions)(yargs.options({ batch: { alias: 'b', describe: 'Non-interactive (batch) mode', boolean: true, }, shell: { describe: `Shell to install completion for (${constants_1.SUPPORTED_SHELLS.join(', ')}). Only used with --batch`, choices: constants_1.SUPPORTED_SHELLS, type: 'string', }, })); } // Public Methods // async handle(args) { try { // Get shell (either from args or prompt) const shell = args.batch ? this.determineShell(args) : await this.promptForShell(); // Ensure cache exists and is fresh (handles fresh installs, upgrades, and repairs) cache_generator_1.CacheGenerator.regenerateIfStale(args, shell); // Perform installation await this.performInstallation(shell, args); // Show success message this.session.out('✓ Shell completion installed successfully'); this.showReloadInstructions(shell); } catch (e) { this.handleInstallationError(e); } } // Private Methods // async performInstallation(shell, args) { const mode = args.batch ? 'batch' : 'interactive'; logger_1.logger.debug(`Installing completion for ${shell} shell in ${mode} mode`); // Setup shell-specific requirements (pre-install) this.ensureShellRequirements(shell); // Install completion scripts const path = args.batch ? this.getShellPath(shell) : undefined; await this.installer.install(path, shell); } ensureShellRequirements(shell) { if (shell === 'zsh') { this.ensureZshCompinit(); } } async promptForShell() { const detectedShell = this.detectCurrentShell(); const defaultIndex = detectedShell ? constants_1.SHELL_CHOICES.findIndex((c) => c.value === detectedShell) : 0; const answers = await require('inquirer').prompt([ { type: 'list', name: 'shell', message: 'Which shell do you use?', choices: constants_1.SHELL_CHOICES, default: defaultIndex, }, ]); return answers.shell; } determineShell(args) { // Use explicit arg, detected shell, or fallback to bash const rawShell = args.shell || this.detectCurrentShell() || 'bash'; // Validate that the shell is supported if (!constants_1.SUPPORTED_SHELLS.includes(rawShell)) { this.session.abort({ message: `ERROR: Shell '${rawShell}' is not supported. Supported shells: ${constants_1.SUPPORTED_SHELLS.join(', ')}`, }); } return rawShell; } detectCurrentShell() { // Try to detect from parent process (most reliable for current shell) try { const { execSync } = require('child_process'); const ppid = process.ppid; const parentProcess = execSync(`ps -p ${ppid} -o comm=`, { encoding: 'utf8' }).trim(); // Extract shell name (handles paths like /bin/bash or just bash) const shellName = parentProcess.replace(/.*\//, '').replace(/^-/, ''); if (constants_1.SUPPORTED_SHELLS.includes(shellName)) { return shellName; } } catch (_a) { // Fall through to other detection methods } // Fallback to $SHELL (login shell, less reliable) const shellEnv = process.env.SHELL; if (!shellEnv) { return undefined; } const shellName = shellEnv.replace(/.*\//, ''); if (constants_1.SUPPORTED_SHELLS.includes(shellName)) { return shellName; } return undefined; } getShellPath(shell) { return constants_1.SHELL_CONFIGS[shell].path; } ensureZshCompinit() { const zshrcPath = path.join((0, io_1.getUserHome)(), '.zshrc'); // Create .zshrc if it doesn't exist if (!fs.existsSync(zshrcPath)) { fs.writeFileSync(zshrcPath, ''); logger_1.logger.debug('Created ~/.zshrc'); } const content = fs.readFileSync(zshrcPath, 'utf8'); // Check if compinit is already setup const hasCompinit = content.includes('compinit'); const hasAutoload = content.includes('autoload') && content.includes('compinit'); if (!hasCompinit || !hasAutoload) { // Add compinit setup at the beginning of the file const compInitSetup = `# Enable completion system (added by cpln)\nautoload -U compinit\ncompinit\n\n`; fs.writeFileSync(zshrcPath, compInitSetup + content); logger_1.logger.debug('Configured zsh completion system (compinit) in ~/.zshrc'); } } showReloadInstructions(shell) { const reloadCmd = constants_1.SHELL_CONFIGS[shell].reloadCommand; this.session.out(`\nTo activate the completion, restart your shell or run:\n ${reloadCmd}`); } handleInstallationError(error) { var _a; const errorMessage = (_a = error.message) !== null && _a !== void 0 ? _a : ''; let errorNote = 'Error installing shell completion:\n\n' + errorMessage; if (errorMessage.includes('profile')) { errorNote += '\n\nTry creating a default profile first, using:\n\ncpln profile login\n'; } else { errorNote += '\n\nIf the installation failed, try:\n\t1. Restarting the shell\n\t2. (on mac) Installing rosetta with:\n\n\tsoftwareupdate --install-rosetta\n'; } this.session.err(errorNote); process.exit(1); } } class UninstallCompletion extends command_1.Command { constructor() { super(); this.command = 'uninstall-completion'; this.describe = 'Uninstall shell completion from your local profile'; this.installer = new installer_1.CompletionInstaller('cpln', 'cpln'); } builder(yargs) { return (0, options_1.withDebugOptions)(yargs); } async handle() { try { // Get the shell that was used for installation const installedShell = cache_generator_1.CacheGenerator.getCachedShell(); logger_1.logger.debug(`Uninstalling completion (previously installed for: ${installedShell || 'unknown'})`); // Uninstall using CompletionInstaller (removes scripts and shell config) await this.installer.uninstall(); // Remove the cache file cache_generator_1.CacheGenerator.deleteCache(); this.session.out('✓ Shell completion uninstalled successfully'); // Only show zsh note if it was installed for zsh if (installedShell === 'zsh') { this.session.out('\nNote: The zsh completion system (compinit) remains configured as other tools may use it.'); } this.session.out('\nYou may need to restart your shell if completion is still active.'); } catch (e) { this.session.err('Error uninstalling shell completion'); process.exit(1); } } } //# sourceMappingURL=misc.js.map