22
src/cache/cache-manager.js
vendido
22
src/cache/cache-manager.js
vendido
@@ -66,6 +66,28 @@ class CacheManager {
|
||||
return data;
|
||||
}
|
||||
|
||||
async has(packageName, version) {
|
||||
const key = this.generateKey(packageName, version);
|
||||
const metadata = await this.loadMetadata();
|
||||
|
||||
if (!metadata.entries[key]) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const entry = metadata.entries[key];
|
||||
const filePath = path.join(this.cacheDir, entry.file);
|
||||
|
||||
// Check if file exists
|
||||
if (!fs.existsSync(filePath)) {
|
||||
// Remove stale entry
|
||||
delete metadata.entries[key];
|
||||
await this.saveMetadata(metadata);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
async store(packageName, version, data) {
|
||||
const key = this.generateKey(packageName, version);
|
||||
const metadata = await this.loadMetadata();
|
||||
|
||||
@@ -69,80 +69,23 @@ class PackageManager {
|
||||
// Ensure initialization
|
||||
await this.ensureInitialized();
|
||||
|
||||
const spinner = ora('Analyzing dependencies...').start();
|
||||
|
||||
try {
|
||||
// If no packages specified, install from package.json
|
||||
if (packages.length === 0) {
|
||||
const packageJsonPath = path.join(this.projectRoot, 'package.json');
|
||||
|
||||
if (!fs.existsSync(packageJsonPath)) {
|
||||
throw new Error('No package.json found and no packages specified to install');
|
||||
}
|
||||
|
||||
return await this.installFromPackageJson(options);
|
||||
}
|
||||
|
||||
// Parse package specifications
|
||||
const packageSpecs = packages.map(pkg => this.parsePackageSpec(pkg));
|
||||
|
||||
spinner.text = 'Resolving dependencies...';
|
||||
|
||||
// Resolve dependencies
|
||||
const resolved = await this.resolver.resolve(packageSpecs, {
|
||||
projectRoot: options.global ? this.globalRoot : this.projectRoot,
|
||||
includeDevDependencies: !options.saveExact
|
||||
});
|
||||
|
||||
spinner.text = 'Checking security vulnerabilities...';
|
||||
|
||||
// Security audit
|
||||
await this.security.auditPackages(resolved);
|
||||
|
||||
spinner.text = 'Downloading packages...';
|
||||
|
||||
// Download and install packages
|
||||
const tasks = new Listr([
|
||||
{
|
||||
title: 'Downloading packages',
|
||||
task: async (ctx, task) => {
|
||||
const downloads = resolved.map(pkg => ({
|
||||
title: `${pkg.name}@${pkg.version}`,
|
||||
task: async () => {
|
||||
const cached = await this.cache.get(pkg.name, pkg.version);
|
||||
if (!cached) {
|
||||
const downloaded = await this.registry.download(pkg);
|
||||
await this.cache.store(pkg.name, pkg.version, downloaded);
|
||||
await this.security.verifyIntegrity(downloaded, pkg.integrity);
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
return task.newListr(downloads, { concurrent: 5 });
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Installing packages',
|
||||
task: async () => {
|
||||
for (const pkg of resolved) {
|
||||
await this.installPackage(pkg, options);
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Updating lock file',
|
||||
task: async () => {
|
||||
await this.lock.update(resolved, options);
|
||||
}
|
||||
}
|
||||
]);
|
||||
|
||||
spinner.stop();
|
||||
await tasks.run();
|
||||
|
||||
// Update package.json if needed
|
||||
if (!options.global) {
|
||||
await this.updatePackageJson(packageSpecs, options);
|
||||
}
|
||||
|
||||
console.log(chalk.green(`\n✓ Installed ${resolved.length} packages`));
|
||||
// Install specified packages
|
||||
return await this.installPackages(packages, options);
|
||||
|
||||
} catch (error) {
|
||||
spinner.stop();
|
||||
console.error(chalk.red(`Installation failed: ${error.message}`));
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
@@ -160,9 +103,71 @@ class PackageManager {
|
||||
...(options.includeDev ? packageJson.devDependencies : {})
|
||||
};
|
||||
|
||||
if (Object.keys(dependencies).length === 0) {
|
||||
console.log(chalk.yellow('No dependencies found in package.json'));
|
||||
return;
|
||||
}
|
||||
|
||||
const packages = Object.entries(dependencies).map(([name, version]) => `${name}@${version}`);
|
||||
|
||||
return await this.install(packages, { ...options, fromPackageJson: true });
|
||||
// Call the main installation logic directly, bypassing the package.json check
|
||||
return await this.installPackages(packages, { ...options, fromPackageJson: true });
|
||||
}
|
||||
|
||||
async installPackages(packages, options = {}) {
|
||||
if (!packages || packages.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(chalk.blue(`Installing ${packages.length} package(s)...`));
|
||||
|
||||
const results = [];
|
||||
|
||||
for (const packageSpec of packages) {
|
||||
try {
|
||||
const { name, version } = this.parsePackageSpec(packageSpec);
|
||||
console.log(chalk.blue(`Installing ${name}@${version || 'latest'}`));
|
||||
|
||||
// Check cache first
|
||||
if (this.cache.has(name, version)) {
|
||||
console.log(chalk.green(`Using cached version of ${name}`));
|
||||
results.push({ name, version, source: 'cache' });
|
||||
continue;
|
||||
}
|
||||
|
||||
// Resolve and download
|
||||
const resolvedPackage = await this.resolver.resolvePackage(name, version || 'latest');
|
||||
|
||||
// Security check
|
||||
if (options.secure !== false) {
|
||||
await this.security.scanPackage(resolvedPackage);
|
||||
}
|
||||
|
||||
// Download and store
|
||||
const packageData = await this.registry.download(resolvedPackage.name, resolvedPackage.version);
|
||||
|
||||
// Store in cache
|
||||
await this.cache.store(resolvedPackage.name, resolvedPackage.version, packageData);
|
||||
|
||||
results.push({
|
||||
name: resolvedPackage.name,
|
||||
version: resolvedPackage.version,
|
||||
source: 'registry'
|
||||
});
|
||||
|
||||
console.log(chalk.green(`✓ Installed ${resolvedPackage.name}@${resolvedPackage.version}`));
|
||||
|
||||
} catch (error) {
|
||||
console.error(chalk.red(`✗ Failed to install ${packageSpec}: ${error.message}`));
|
||||
results.push({ packageSpec, error: error.message });
|
||||
}
|
||||
}
|
||||
|
||||
// Update lock file
|
||||
await this.lock.update(results.filter(r => !r.error));
|
||||
|
||||
console.log(chalk.green(`Installation completed. ${results.filter(r => !r.error).length} packages installed.`));
|
||||
return results;
|
||||
}
|
||||
|
||||
async installPackage(pkg, options = {}) {
|
||||
|
||||
Referencia en una nueva incidencia
Block a user