claude-task-master/scripts/prepare-package.js

195 lines
5.6 KiB
JavaScript
Raw Normal View History

2025-03-04 13:55:17 -05:00
#!/usr/bin/env node
/**
* This script prepares the package for publication to NPM.
* It ensures all necessary files are included and properly configured.
*
* Additional options:
* --patch: Increment patch version (default)
* --minor: Increment minor version
* --major: Increment major version
* --version=x.y.z: Set specific version
2025-03-04 13:55:17 -05:00
*/
import fs from 'fs';
import path from 'path';
import { execSync } from 'child_process';
import { fileURLToPath } from 'url';
import { dirname } from 'path';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
2025-03-04 13:55:17 -05:00
// Define colors for console output
const COLORS = {
reset: '\x1b[0m',
bright: '\x1b[1m',
dim: '\x1b[2m',
red: '\x1b[31m',
green: '\x1b[32m',
yellow: '\x1b[33m',
blue: '\x1b[34m',
magenta: '\x1b[35m',
cyan: '\x1b[36m'
};
// Parse command line arguments
const args = process.argv.slice(2);
const versionBump = args.includes('--major') ? 'major' :
args.includes('--minor') ? 'minor' :
'patch';
// Check for explicit version
const versionArg = args.find(arg => arg.startsWith('--version='));
const explicitVersion = versionArg ? versionArg.split('=')[1] : null;
2025-03-04 13:55:17 -05:00
// Log function with color support
function log(level, ...args) {
const prefix = {
info: `${COLORS.blue}[INFO]${COLORS.reset}`,
warn: `${COLORS.yellow}[WARN]${COLORS.reset}`,
error: `${COLORS.red}[ERROR]${COLORS.reset}`,
success: `${COLORS.green}[SUCCESS]${COLORS.reset}`
}[level.toLowerCase()];
console.log(prefix, ...args);
}
// Function to check if a file exists
function fileExists(filePath) {
return fs.existsSync(filePath);
}
// Function to ensure a file is executable
function ensureExecutable(filePath) {
try {
fs.chmodSync(filePath, '755');
log('info', `Made ${filePath} executable`);
} catch (error) {
log('error', `Failed to make ${filePath} executable:`, error.message);
return false;
}
return true;
}
// Function to sync template files
function syncTemplateFiles() {
// We no longer need to sync files since we're using them directly
log('info', 'Template syncing has been deprecated - using source files directly');
return true;
}
// Function to increment version
function incrementVersion(currentVersion, type = 'patch') {
const [major, minor, patch] = currentVersion.split('.').map(Number);
switch (type) {
case 'major':
return `${major + 1}.0.0`;
case 'minor':
return `${major}.${minor + 1}.0`;
case 'patch':
default:
return `${major}.${minor}.${patch + 1}`;
}
}
2025-03-04 13:55:17 -05:00
// Main function to prepare the package
function preparePackage() {
const rootDir = path.join(__dirname, '..');
log('info', `Preparing package in ${rootDir}`);
// Update version in package.json
const packageJsonPath = path.join(rootDir, 'package.json');
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
const currentVersion = packageJson.version;
let newVersion;
if (explicitVersion) {
newVersion = explicitVersion;
log('info', `Setting version to specified ${newVersion} (was ${currentVersion})`);
} else {
newVersion = incrementVersion(currentVersion, versionBump);
log('info', `Incrementing ${versionBump} version to ${newVersion} (was ${currentVersion})`);
}
packageJson.version = newVersion;
fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2));
log('success', `Updated package.json version to ${newVersion}`);
2025-03-04 13:55:17 -05:00
// Check for required files
const requiredFiles = [
'package.json',
'README-task-master.md',
2025-03-04 13:55:17 -05:00
'index.js',
'scripts/init.js',
'scripts/dev.js',
'assets/env.example',
'assets/gitignore',
'assets/example_prd.txt',
'.cursor/rules/dev_workflow.mdc',
'.cursor/rules/cursor_rules.mdc',
'.cursor/rules/self_improve.mdc'
2025-03-04 13:55:17 -05:00
];
let allFilesExist = true;
for (const file of requiredFiles) {
const filePath = path.join(rootDir, file);
if (!fileExists(filePath)) {
log('error', `Required file ${file} does not exist`);
allFilesExist = false;
}
}
if (!allFilesExist) {
log('error', 'Some required files are missing. Package preparation failed.');
process.exit(1);
}
// Ensure scripts are executable
const executableScripts = [
'scripts/init.js',
'scripts/dev.js'
];
let allScriptsExecutable = true;
for (const script of executableScripts) {
const scriptPath = path.join(rootDir, script);
if (!ensureExecutable(scriptPath)) {
allScriptsExecutable = false;
}
}
if (!allScriptsExecutable) {
log('warn', 'Some scripts could not be made executable. This may cause issues.');
}
// Run npm pack to test package creation
try {
log('info', 'Running npm pack to test package creation...');
const output = execSync('npm pack --dry-run', { cwd: rootDir }).toString();
log('info', output);
} catch (error) {
log('error', 'Failed to run npm pack:', error.message);
process.exit(1);
}
// Make scripts executable
log('info', 'Making scripts executable...');
try {
execSync('chmod +x scripts/init.js', { stdio: 'ignore' });
log('info', 'Made scripts/init.js executable');
execSync('chmod +x scripts/dev.js', { stdio: 'ignore' });
log('info', 'Made scripts/dev.js executable');
} catch (error) {
log('error', 'Failed to make scripts executable:', error.message);
}
log('success', `Package preparation completed successfully! 🎉`);
log('success', `Version updated to ${newVersion}`);
2025-03-04 13:55:17 -05:00
log('info', 'You can now publish the package with:');
log('info', ' npm publish');
}
// Run the preparation
preparePackage();