Last active
October 1, 2024 20:19
-
-
Save nicholasadamou/3344967b896979f52baac282916c3de6 to your computer and use it in GitHub Desktop.
A utility script that determines the appropriate pnpm version based on the Node.js version used in your project. It reads from .nvmrc, package.json, or defaults to the currently installed Node.js version, ensuring compatibility and simplifying dependency management. Optionally, it can also install the recommended pnpm version automatically.
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
import os | |
import json | |
import subprocess | |
import requests | |
# Compatibility table for pnpm versions based on Node.js versions (only the major versions) | |
pnpm_compatibility = { | |
'14': '6', # PNPM 6 for Node 14 | |
'16': '7', # PNPM 7 for Node 16 | |
'18': '8', # PNPM 8 for Node 18 | |
'20': '9', # PNPM 9 for Node 20 | |
# Extend this mapping as needed | |
} | |
# Function to read Node version from .nvmrc file | |
def get_node_version_from_nvmrc(): | |
nvmrc_path = os.path.join(os.getcwd(), '.nvmrc') | |
try: | |
if os.path.exists(nvmrc_path): | |
with open(nvmrc_path, 'r') as file: | |
return file.read().strip() | |
except Exception as e: | |
print(f"Error reading .nvmrc: {e}") | |
return None | |
# Function to read Node version from package.json file | |
def get_node_version_from_package_json(): | |
package_json_path = os.path.join(os.getcwd(), 'package.json') | |
try: | |
if os.path.exists(package_json_path): | |
with open(package_json_path, 'r') as file: | |
package_json = json.load(file) | |
if 'engines' in package_json and 'node' in package_json['engines']: | |
# Remove any non-numeric characters (like ^, ~, >=) from version | |
return ''.join(filter(str.isdigit, package_json['engines']['node'])) | |
except Exception as e: | |
print(f"Error reading package.json: {e}") | |
return None | |
# Function to get the currently installed Node.js version | |
def get_current_node_version(): | |
try: | |
result = subprocess.run(['node', '-v'], capture_output=True, text=True) | |
if result.returncode == 0: | |
return result.stdout.strip().lstrip('v') | |
except FileNotFoundError: | |
print("Node.js is not installed or not found in PATH.") | |
return None | |
# Function to determine the Node.js version | |
def get_node_version(): | |
return get_node_version_from_nvmrc() or get_node_version_from_package_json() or get_current_node_version() | |
# Function to determine appropriate pnpm version | |
def determine_pnpm_version(node_version): | |
major_version = node_version.split('.')[0] | |
target_pnpm_major = pnpm_compatibility.get(major_version) | |
if not target_pnpm_major: | |
return 'latest' | |
# Get the latest compatible pnpm version from the npm registry | |
try: | |
response = requests.get('https://registry.npmjs.org/pnpm') | |
if response.status_code == 200: | |
data = response.json() | |
versions = data.get('versions', {}) | |
latest_version = None | |
for version in versions.keys(): | |
if version.startswith(f'{target_pnpm_major}.'): | |
latest_version = version # Keep updating to get the latest version in this major line | |
return latest_version if latest_version else 'latest' | |
except Exception as e: | |
print(f"Error fetching pnpm versions: {e}") | |
return 'latest' | |
def main(): | |
node_version = get_node_version() | |
if not node_version: | |
print("Could not determine Node.js version.") | |
return | |
print(f"Node version: {node_version}") | |
pnpm_version = determine_pnpm_version(node_version) | |
print(f"Recommended pnpm version: {pnpm_version}") | |
# Install the required pnpm version | |
try: | |
subprocess.run(['npm', 'install', '-g', f'pnpm@{pnpm_version}'], check=True) | |
except subprocess.CalledProcessError as e: | |
print(f"Failed to install pnpm version {pnpm_version}: {e}") | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment