Last active
October 1, 2024 20:06
-
-
Save nicholasadamou/1aa7204bbe658a26adeeed3281bc78cb to your computer and use it in GitHub Desktop.
This script, version-pin-and-clean.js, automates the process of pinning and cleaning dependency versions in a package.json file. It reads version information from a pnpm-lock.yaml file and updates both dependencies and devDependencies in package.json to match the versions specified in the lock file, removing any leading version specifiers like ^…
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const fs = require('fs'); | |
const path = require('path'); | |
const yaml = require('js-yaml'); | |
console.log('Starting the version pinning and cleaning process...'); | |
// Utility function to determine which package manager is used | |
const determinePackageManager = () => { | |
if (fs.existsSync(path.join(__dirname, 'pnpm-lock.yaml'))) { | |
return 'pnpm'; | |
} else if (fs.existsSync(path.join(__dirname, 'package-lock.json'))) { | |
return 'npm'; | |
} else if (fs.existsSync(path.join(__dirname, 'yarn.lock'))) { | |
return 'yarn'; | |
} else if (fs.existsSync(path.join(__dirname, 'bun.lockb'))) { | |
return 'bun'; | |
} | |
return null; | |
}; | |
// Utility function to clean version strings | |
const cleanVersion = (version) => { | |
// Remove everything from the first parenthesis till the end of the string | |
return version.replace(/\(.*$/, '').trim(); | |
}; | |
// Main logic | |
const packageManager = determinePackageManager(); | |
if (!packageManager) { | |
console.error('No known package manager lock file found. Aborting...'); | |
process.exit(1); | |
} | |
console.log(`Detected package manager: ${packageManager}`); | |
const packageJsonPath = path.join(__dirname, 'package.json'); | |
let lockFilePath; | |
try { | |
// Load the corresponding lock file based on the detected package manager | |
let lockFile; | |
switch (packageManager) { | |
case 'pnpm': | |
lockFilePath = path.join(__dirname, 'pnpm-lock.yaml'); | |
console.log('Loading pnpm-lock.yaml...'); | |
lockFile = yaml.load(fs.readFileSync(lockFilePath, 'utf8')); | |
console.log('Successfully loaded pnpm-lock.yaml'); | |
break; | |
case 'npm': | |
lockFilePath = path.join(__dirname, 'package-lock.json'); | |
console.log('Loading package-lock.json...'); | |
lockFile = JSON.parse(fs.readFileSync(lockFilePath, 'utf8')); | |
console.log('Successfully loaded package-lock.json'); | |
break; | |
case 'yarn': | |
lockFilePath = path.join(__dirname, 'yarn.lock'); | |
console.log('Loading yarn.lock...'); | |
console.log('Note: Parsing yarn.lock directly is complex. Consider using an appropriate parser.'); | |
process.exit(1); | |
break; | |
case 'bun': | |
lockFilePath = path.join(__dirname, 'bun.lockb'); | |
console.log('Loading bun.lockb...'); | |
console.log('Note: Parsing bun.lockb directly is not yet implemented.'); | |
process.exit(1); | |
break; | |
default: | |
throw new Error('Unsupported package manager'); | |
} | |
// Load package.json | |
console.log('Loading package.json...'); | |
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')); | |
console.log('Successfully loaded package.json'); | |
// Update dependencies and devDependencies with pinned versions | |
const updateDependencies = (dependencies, lockDeps, sectionName) => { | |
if (!dependencies) return; | |
Object.keys(dependencies).forEach((depName) => { | |
if (lockDeps[depName]) { | |
console.log(`Found ${depName} in ${sectionName}, pinning version to ${lockDeps[depName].version || lockDeps[depName]}`); | |
dependencies[depName] = cleanVersion(lockDeps[depName].version || lockDeps[depName]); | |
} else { | |
console.warn(`Warning: ${depName} found in ${sectionName} of package.json but not in ${packageManager} lock file`); | |
// Clean the version if extra info exists | |
dependencies[depName] = cleanVersion(dependencies[depName]); | |
} | |
}); | |
}; | |
console.log('Updating dependencies...'); | |
if (packageManager === 'pnpm') { | |
updateDependencies(packageJson.dependencies, lockFile.importers['.'].dependencies, 'dependencies'); | |
updateDependencies(packageJson.devDependencies, lockFile.importers['.'].devDependencies, 'devDependencies'); | |
} else if (packageManager === 'npm') { | |
updateDependencies(packageJson.dependencies, lockFile.dependencies, 'dependencies'); | |
updateDependencies(packageJson.devDependencies, lockFile.dependencies, 'devDependencies'); | |
} | |
// Write the updated package.json back to file | |
console.log('Writing the updated package.json back to file...'); | |
fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2), 'utf8'); | |
console.log('Successfully updated package.json with pinned and cleaned versions.'); | |
} catch (e) { | |
console.error('An error occurred:', e); | |
} | |
console.log('Version pinning and cleaning process completed.'); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment