muspe-cli
Version:
MusPE Advanced Framework v2.1.3 - Mobile User-friendly Simple Progressive Engine with Enhanced CLI Tools, Specialized E-Commerce Templates, Material Design 3, Progressive Enhancement, Mobile Optimizations, Performance Analysis, and Enterprise-Grade Develo
268 lines (223 loc) ⢠8.53 kB
JavaScript
const fs = require('fs');
const path = require('path');
const os = require('os');
const { execSync } = require('child_process');
function setupPath() {
try {
console.log('\nš§ Setting up MusPE CLI...');
// Platform detection
const platform = os.platform();
if (platform === 'win32') {
setupWindowsPath();
return;
}
setupUnixPath();
} catch (error) {
console.error('ā Error setting up PATH:', error.message);
showManualInstructions();
}
}
function setupWindowsPath() {
try {
console.log('šŖ Windows detected');
// Get npm global prefix for Windows
let npmPrefix;
try {
npmPrefix = execSync('npm config get prefix', { encoding: 'utf8' }).trim();
} catch (error) {
npmPrefix = path.join(os.homedir(), 'AppData', 'Roaming', 'npm');
}
console.log(`š npm global prefix: ${npmPrefix}`);
// Check if PATH already includes npm bin
const currentPath = process.env.PATH || '';
if (currentPath.includes(npmPrefix)) {
console.log('ā
npm global bin is already in PATH');
testCommand();
return;
}
console.log('š§ Please add the following directory to your system PATH:');
console.log(` ${npmPrefix}`);
console.log('\nš Instructions:');
console.log('1. Press Win + R, type "sysdm.cpl" and press Enter');
console.log('2. Click "Environment Variables"');
console.log('3. Under "User variables", select "Path" and click "Edit"');
console.log('4. Click "New" and add the path above');
console.log('5. Click "OK" to save');
console.log('6. Restart your command prompt');
console.log('\nš Then test with: muspe --version');
} catch (error) {
console.error('ā Windows PATH setup error:', error.message);
showManualInstructions();
}
}
function setupUnixPath() {
// Get npm global prefix
let npmPrefix;
try {
npmPrefix = execSync('npm config get prefix', { encoding: 'utf8' }).trim();
} catch (error) {
console.warn('ā ļø Could not get npm prefix, using default');
npmPrefix = path.join(os.homedir(), '.npm-global');
}
const npmBinPath = path.join(npmPrefix, 'bin');
// Detect shell
const shell = process.env.SHELL || '/bin/bash';
const isZsh = shell.includes('zsh');
const isBash = shell.includes('bash');
const isFish = shell.includes('fish');
let rcFile;
let pathExport;
if (isFish) {
rcFile = path.join(os.homedir(), '.config', 'fish', 'config.fish');
pathExport = `set -gx PATH ${npmBinPath} $PATH`;
} else if (isZsh) {
rcFile = path.join(os.homedir(), '.zshrc');
pathExport = `export PATH="${npmBinPath}:$PATH"`;
} else if (isBash) {
rcFile = path.join(os.homedir(), '.bashrc');
pathExport = `export PATH="${npmBinPath}:$PATH"`;
} else {
rcFile = path.join(os.homedir(), '.profile');
pathExport = `export PATH="${npmBinPath}:$PATH"`;
}
console.log(`š Shell detected: ${shell}`);
console.log(`š npm global prefix: ${npmPrefix}`);
// Check if PATH already includes npm bin
const currentPath = process.env.PATH || '';
if (currentPath.includes(npmBinPath)) {
console.log('ā
npm global bin is already in PATH');
testCommand();
return;
}
// Prepare PATH export line
const comment = '# Added by MusPE CLI';
const fullLine = `${comment}\n${pathExport}`;
// Create config directory for fish if needed
if (isFish) {
const configDir = path.dirname(rcFile);
if (!fs.existsSync(configDir)) {
fs.mkdirSync(configDir, { recursive: true });
}
}
// Check if rc file exists
if (!fs.existsSync(rcFile)) {
console.log(`š Creating ${rcFile}...`);
fs.writeFileSync(rcFile, '');
}
// Read current content
const currentContent = fs.readFileSync(rcFile, 'utf8');
// Check if already added
if (currentContent.includes('Added by MusPE CLI') || currentContent.includes(pathExport)) {
console.log('ā
PATH already configured in shell profile');
testCommand();
return;
}
// Add to rc file
console.log(`š Adding npm global bin to PATH in ${rcFile}...`);
fs.appendFileSync(rcFile, `\n${fullLine}\n`);
// Set up npm global directory if needed
setupNpmGlobal(npmPrefix);
console.log('ā
PATH configuration added successfully!');
console.log(`\nš Please restart your terminal or run:`);
console.log(` source ${rcFile}`);
console.log(`\nš Then test with: muspe --version`);
}
function setupNpmGlobal(npmPrefix) {
try {
// Check if npm prefix is set to a system directory
if (npmPrefix.includes('/usr/local') || npmPrefix.includes('root') || npmPrefix.includes('/opt')) {
console.log('š§ Setting up user-specific npm global directory...');
// Create .npm-global directory
const globalDir = path.join(os.homedir(), '.npm-global');
if (!fs.existsSync(globalDir)) {
fs.mkdirSync(globalDir, { recursive: true });
console.log(`š Created ${globalDir}`);
}
// Configure npm to use the new directory
try {
execSync(`npm config set prefix "${globalDir}"`, { stdio: 'pipe' });
console.log('ā
npm prefix configured to user directory');
console.log('ā¹ļø You may need to reinstall global packages');
} catch (error) {
console.warn('ā ļø Could not set npm prefix automatically');
console.log(`š” Manually run: npm config set prefix "${globalDir}"`);
}
}
} catch (error) {
console.warn('ā ļø Could not setup npm global directory:', error.message);
}
}
function testCommand() {
try {
// Test if muspe command is available
const npmPrefix = execSync('npm config get prefix', { encoding: 'utf8' }).trim();
let muspePath;
if (os.platform() === 'win32') {
muspePath = path.join(npmPrefix, 'muspe.cmd');
} else {
muspePath = path.join(npmPrefix, 'bin', 'muspe');
}
if (fs.existsSync(muspePath)) {
console.log('ā
MusPE CLI is properly installed and accessible');
// Try to run the command
try {
const pathEnv = os.platform() === 'win32' ?
`${npmPrefix};${process.env.PATH}` :
`${path.join(npmPrefix, 'bin')}:${process.env.PATH}`;
const version = execSync('muspe --version 2>/dev/null || muspe --version 2>nul', {
encoding: 'utf8',
env: { ...process.env, PATH: pathEnv }
}).trim();
if (version) {
console.log(`š MusPE CLI ${version.split('\n').pop()} is ready to use!`);
showQuickStart();
return;
}
} catch (error) {
// Command not in PATH yet, but binary exists
}
}
console.log('š MusPE CLI installed. You may need to restart your terminal.');
showQuickStart();
} catch (error) {
console.log('š MusPE CLI installation completed.');
showQuickStart();
}
}
function showQuickStart() {
console.log('\nš Quick start:');
console.log(' muspe create my-app');
console.log(' cd my-app');
console.log(' muspe serve');
console.log('\nš More info: https://github.com/bandeto45/muspe');
}
function showManualInstructions() {
console.log('\nš Manual setup instructions:');
if (os.platform() === 'win32') {
console.log(' Add npm global directory to your system PATH');
console.log(' Run: npm config get prefix (to see the directory)');
} else {
console.log(' Add this to your shell profile (~/.zshrc, ~/.bashrc, or ~/.profile):');
console.log(' export PATH="$(npm config get prefix)/bin:$PATH"');
}
}
// Only run if this script is executed directly (not required as module)
if (require.main === module) {
// Don't run PATH setup in CI environments
if (process.env.CI || process.env.CONTINUOUS_INTEGRATION) {
console.log('š¤ CI environment detected, skipping PATH setup');
process.exit(0);
}
// Check if this is a global installation
const isGlobal = process.env.npm_config_global === 'true' ||
process.argv.some(arg => arg === '-g' || arg === '--global') ||
__dirname.includes('node_modules');
if (isGlobal) {
setupPath();
} else {
console.log('š¦ Local installation detected, skipping PATH setup');
console.log('ā¹ļø For global access, install with: npm install -g muspe-cli');
}
}
module.exports = { setupPath, setupNpmGlobal };