docker-pilot
Version:
A powerful, scalable Docker CLI library for managing containerized applications of any size
294 lines (289 loc) ⢠13.1 kB
JavaScript
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.ConfigCommand = void 0;
const BaseCommand_1 = require("./BaseCommand");
const path = __importStar(require("path"));
const fs = __importStar(require("fs"));
const util_1 = require("util");
const writeFileAsync = (0, util_1.promisify)(fs.writeFile);
const existsAsync = (0, util_1.promisify)(fs.exists);
class ConfigCommand extends BaseCommand_1.BaseCommand {
constructor(context) {
super('config', 'View and manage Docker Pilot configuration', 'docker-pilot config <action> [options]', context);
}
async execute(args, _options) {
const { args: parsedArgs, options: parsedOptions } = this.parseOptions(args);
const action = parsedArgs[0];
try {
switch (action) {
case 'show':
case 'view':
return await this.showConfig(parsedOptions);
case 'validate':
case 'check':
return await this.validateConfig(parsedOptions);
case 'init':
case 'create':
return await this.initConfig(parsedOptions);
case 'path':
return await this.showConfigPath(parsedOptions);
case 'edit':
return await this.editConfig(parsedOptions);
default:
return this.createErrorResult(this.i18n.t('error.generic', {
message: `Unknown action: ${action}. Available actions: show, validate, init, path, edit`
}));
}
}
catch (error) {
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
this.logger.error(this.i18n.t('cmd.config.failed', { error: errorMessage }));
return this.createErrorResult(errorMessage);
}
}
async showConfig(options) {
this.logger.info(this.i18n.t('cmd.config.title'));
const config = this.context.config;
if (options['json']) {
console.log(JSON.stringify(config, null, 2));
}
else {
this.displayConfigSummary(config);
}
return this.createSuccessResult('Configuration displayed');
}
async validateConfig(_options) {
this.logger.loading('š Validating configuration...');
const config = this.context.config;
const errors = [];
const warnings = [];
// Basic validation
if (!config.projectName || config.projectName.trim() === '') {
errors.push('Project name is required');
}
if (!config.services || Object.keys(config.services).length === 0) {
warnings.push('No services defined');
}
// Validate services
for (const [serviceName, serviceConfig] of Object.entries(config.services || {})) {
if (serviceConfig.port && (serviceConfig.port < 1 || serviceConfig.port > 65535)) {
errors.push(`Service '${serviceName}': Invalid port ${serviceConfig.port}`);
}
if (serviceConfig.scale && serviceConfig.scale < 1) {
errors.push(`Service '${serviceName}': Scale must be at least 1`);
}
}
// Display results
if (errors.length > 0) {
this.logger.error('ā Configuration validation failed:');
errors.forEach(error => this.logger.error(` ⢠${error}`));
}
if (warnings.length > 0) {
this.logger.warn('ā ļø Configuration warnings:');
warnings.forEach(warning => this.logger.warn(` ⢠${warning}`));
}
if (errors.length === 0) {
this.logger.success('ā
Configuration is valid');
if (warnings.length === 0) {
this.logger.info('š No warnings found');
}
}
return errors.length > 0
? this.createErrorResult(`Configuration validation failed with ${errors.length} error(s)`)
: this.createSuccessResult('Configuration is valid');
}
async initConfig(options) {
const configPath = path.join(this.context.workingDirectory, 'docker-pilot.config.json');
// Check if config already exists
if (await existsAsync(configPath)) {
const forceCreate = options['force'] || options['f'];
if (!forceCreate) {
return this.createErrorResult(`Configuration file already exists at ${configPath}. Use --force to overwrite.`);
}
this.logger.warn('ā ļø Overwriting existing configuration file');
}
this.logger.loading('š Creating new configuration file...');
const projectName = options['name'] || path.basename(this.context.workingDirectory);
const newConfig = {
projectName,
dockerCompose: 'docker compose',
configVersion: '1.0',
language: 'en',
services: {},
plugins: [],
cli: {
version: '1.0.0',
welcomeMessage: `Welcome to ${projectName} Docker Pilot! š³`,
goodbyeMessage: `Thank you for using ${projectName} Docker Pilot!`,
interactiveMode: true,
colorOutput: true,
verboseLogging: false,
confirmDestructiveActions: true
},
backup: {
enabled: false,
schedule: '0 2 * * *',
retention: 7,
compression: true,
location: './backups'
},
monitoring: {
enabled: false,
interval: 30,
healthChecks: true,
notifications: false
},
development: {
hotReload: true,
debugMode: false,
logLevel: 'info',
autoMigrate: false,
seedData: false,
testMode: false,
watchFiles: [],
environment: 'development'
},
networks: {},
volumes: {}
};
try {
// Actually write the configuration file
await writeFileAsync(configPath, JSON.stringify(newConfig, null, 2), 'utf8');
this.logger.success(`ā
Configuration file created at: ${configPath}`);
if (!options['quiet']) {
this.logger.info('š§ Configuration structure:');
this.displayConfigSummary(newConfig);
}
this.logger.info('š” Edit the configuration file to customize your setup');
this.logger.info('ļæ½ Run "docker-pilot config validate" to check your configuration');
return this.createSuccessResult('Configuration file created successfully');
}
catch (error) {
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
this.logger.error(`Failed to create configuration file: ${errorMessage}`);
return this.createErrorResult(`Failed to create configuration file: ${errorMessage}`);
}
}
async showConfigPath(_options) {
const configPath = path.join(this.context.workingDirectory, 'docker-pilot.config.json');
const configExists = await existsAsync(configPath);
this.logger.info('š Configuration file location:');
console.log(configPath);
if (configExists) {
this.logger.success('ā
Configuration file exists');
try {
const stats = fs.statSync(configPath);
this.logger.info(`š File size: ${this.formatFileSize(stats.size)}`);
this.logger.info(`š
Last modified: ${stats.mtime.toLocaleString()}`);
}
catch (error) {
this.logger.debug('Could not read file stats');
}
}
else {
this.logger.warn('ā ļø Configuration file does not exist');
this.logger.info('š” Run "docker-pilot config init" to create one');
}
return this.createSuccessResult('Configuration path displayed');
}
async editConfig(_options) {
const configPath = path.join(this.context.workingDirectory, 'docker-pilot.config.json');
const configExists = await existsAsync(configPath);
if (!configExists) {
this.logger.error('ā Configuration file does not exist');
this.logger.info('š” Run "docker-pilot config init" to create one');
return this.createErrorResult('Configuration file not found');
}
this.logger.info('āļø Edit configuration:');
this.logger.info(`š File: ${configPath}`);
this.logger.info('š” Use your preferred editor to modify the configuration');
this.logger.info('š Run "docker-pilot config validate" after making changes');
// Show some helpful editing tips
this.logger.newLine();
this.logger.info('š Editing tips:');
this.logger.info(' ⢠Use a JSON-aware editor for syntax highlighting');
this.logger.info(' ⢠Backup the file before making major changes');
this.logger.info(' ⢠Validate JSON syntax with your editor');
this.logger.info(' ⢠Check the documentation for available options');
return this.createSuccessResult('Configuration edit information displayed');
}
/**
* Format file size in human readable format
*/
formatFileSize(bytes) {
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
if (bytes === 0)
return '0 Bytes';
const i = Math.floor(Math.log(bytes) / Math.log(1024));
return Math.round(bytes / Math.pow(1024, i) * 100) / 100 + ' ' + sizes[i];
}
displayConfigSummary(config) {
console.log(`
š Project: ${config.projectName}
š³ Docker Compose: ${config.dockerCompose}
š Version: ${config.configVersion}
š§ Services: ${Object.keys(config.services || {}).length}
${Object.keys(config.services || {}).map(name => ` ⢠${name}`).join('\n')}
š Plugins: ${config.plugins?.length || 0}
${config.plugins?.map((plugin) => ` ⢠${plugin}`).join('\n') || ' (none)'}
š Networks: ${Object.keys(config.networks || {}).length}
š¾ Volumes: ${Object.keys(config.volumes || {}).length}
āļø CLI Configuration:
⢠Interactive Mode: ${config.cli?.interactiveMode ? 'enabled' : 'disabled'}
⢠Color Output: ${config.cli?.colorOutput ? 'enabled' : 'disabled'}
⢠Verbose Logging: ${config.cli?.verboseLogging ? 'enabled' : 'disabled'}
š Development Mode:
⢠Hot Reload: ${config.development?.hotReload ? 'enabled' : 'disabled'}
⢠Debug Mode: ${config.development?.debugMode ? 'enabled' : 'disabled'}
⢠Log Level: ${config.development?.logLevel || 'info'}
`.trim());
}
showExamples() {
this.logger.info(`
Examples:
docker-pilot config show # Display current configuration
docker-pilot config show --json # Display configuration as JSON
docker-pilot config validate # Validate configuration
docker-pilot config init # Create new configuration
docker-pilot config init --name myapp # Create config with project name
docker-pilot config init --force # Overwrite existing configuration
docker-pilot config path # Show configuration file path
docker-pilot config edit # Show edit instructions
`);
}
}
exports.ConfigCommand = ConfigCommand;
//# sourceMappingURL=ConfigCommand.js.map