Files
huly-platform/foundations/utils/packages/platform-rig/bin/sync-eslint-deps.js
T
Denis Bykhov 16b1109180 Add 'foundations/utils/' from commit '063b52c1cac395319e99d017986c35abe6b79deb'
git-subtree-dir: foundations/utils
git-subtree-mainline: 6ea92dd409
git-subtree-split: 063b52c1ca
2025-11-26 22:56:34 +05:00

210 lines
6.0 KiB
JavaScript
Executable File

#!/usr/bin/env node
//
// Copyright © 2025 Hardcore Engineering Inc.
//
// Script to sync ESLint dev dependencies from platform-rig to all Rush packages
//
const fs = require('fs')
const path = require('path')
const { execSync } = require('child_process')
// ESLint related dependency prefixes to sync
const ESLINT_PATTERNS = ['eslint', '@typescript-eslint/', 'eslint-plugin-', 'eslint-config-']
/**
* Get list of Rush projects using 'rush list --json'
*/
function getRushProjects() {
try {
const output = execSync('rush list --json', {
encoding: 'utf-8',
stdio: ['pipe', 'pipe', 'pipe']
})
const data = JSON.parse(output)
const projects = data.projects || data
if (!Array.isArray(projects)) {
throw new Error('Expected rush list --json to return an array of projects')
}
return projects
} catch (err) {
if (err.message.includes('rush') || err.code === 'ENOENT') {
throw new Error('Failed to run "rush list --json". Make sure you are in a Rush workspace and Rush is installed.')
}
throw new Error(`Failed to get Rush projects: ${err.message}`)
}
}
/**
* Check if a dependency name matches ESLint patterns
*/
function isEslintDependency(depName) {
return ESLINT_PATTERNS.some((pattern) => depName.startsWith(pattern))
}
/**
* Find platform-rig in node_modules
*/
function findPlatformRigPath() {
// Try to find platform-rig in node_modules
const cwd = process.cwd()
const possiblePaths = [path.join(cwd, 'common', 'scripts', 'node_modules', '@hcengineering', 'platform-rig')]
for (const platformRigPath of possiblePaths) {
const packageJsonPath = path.join(platformRigPath, 'package.json')
if (fs.existsSync(packageJsonPath)) {
return platformRigPath
}
}
return null
}
/**
* Get ESLint dev dependencies from platform-rig package.json
*/
function getEslintDepsFromPlatformRig(platformRigPath) {
const packageJsonPath = path.join(platformRigPath, 'package.json')
if (!fs.existsSync(packageJsonPath)) {
throw new Error(`platform-rig package.json not found at: ${packageJsonPath}`)
}
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'))
const dependencies = packageJson.dependencies || {}
const eslintDeps = {}
for (const [name, version] of Object.entries(dependencies)) {
if (isEslintDependency(name)) {
eslintDeps[name] = version
}
}
return eslintDeps
}
/**
* Update package.json with ESLint dependencies
*/
function updatePackageJson(packagePath, eslintDeps) {
const packageJsonPath = path.join(packagePath, 'package.json')
if (!fs.existsSync(packageJsonPath)) {
console.warn(`⚠️ package.json not found at: ${packageJsonPath}`)
return { updated: false, changes: [] }
}
const content = fs.readFileSync(packageJsonPath, 'utf-8')
const packageJson = JSON.parse(content)
// Skip if this is the platform-rig package itself
if (packageJson.name === '@hcengineering/platform-rig') {
return { updated: false, changes: [] }
}
// Initialize devDependencies if it doesn't exist
if (!packageJson.devDependencies) {
packageJson.devDependencies = {}
}
const changes = []
let hasChanges = false
// Add or update ESLint dependencies
for (const [name, version] of Object.entries(eslintDeps)) {
const currentVersion = packageJson.devDependencies[name]
if (currentVersion !== version) {
packageJson.devDependencies[name] = version
hasChanges = true
if (currentVersion) {
changes.push(` ${name}: ${currentVersion}${version}`)
} else {
changes.push(` ${name}: (new) → ${version}`)
}
}
}
if (hasChanges) {
// Preserve original formatting by maintaining indent detection
const indent = content.match(/^(\s+)/m)?.[1]?.length || 2
const newContent = JSON.stringify(packageJson, null, indent) + '\n'
fs.writeFileSync(packageJsonPath, newContent, 'utf-8')
}
return { updated: hasChanges, changes }
}
/**
* Main execution
*/
function main() {
console.log('🔍 Syncing ESLint dependencies from platform-rig to all packages...\n')
try {
// Find platform-rig in node_modules
const platformRigPath = findPlatformRigPath()
if (!platformRigPath) {
console.log('⚠️ platform-rig package not found in node_modules. Skipping sync.')
console.log(' Make sure @hcengineering/platform-rig is installed as a dependency.')
return
}
console.log(`📍 Found platform-rig at: ${platformRigPath}\n`)
// Get ESLint dependencies from platform-rig
const eslintDeps = getEslintDepsFromPlatformRig(platformRigPath)
if (Object.keys(eslintDeps).length === 0) {
console.log('⚠️ No ESLint dependencies found in platform-rig')
return
}
console.log('📦 ESLint dependencies from platform-rig:')
for (const [name, version] of Object.entries(eslintDeps)) {
console.log(` ${name}: ${version}`)
}
console.log()
// Get all Rush projects
const projects = getRushProjects()
console.log(`Found ${projects.length} projects in Rush workspace\n`)
// Update all packages
let updatedCount = 0
let skippedCount = 0
for (const project of projects) {
const result = updatePackageJson(project.fullPath, eslintDeps)
if (result.updated) {
updatedCount++
console.log(`✅ Updated ${project.name}`)
result.changes.forEach((change) => console.log(change))
console.log()
} else if (result.changes.length === 0 && project.name !== '@hcengineering/platform-rig') {
skippedCount++
}
}
console.log('━'.repeat(50))
console.log(`✨ Sync complete!`)
console.log(` Updated: ${updatedCount} package(s)`)
console.log(` Skipped: ${skippedCount} package(s) (already up-to-date)`)
if (updatedCount > 0) {
console.log('\n💡 Don\'t forget to run "rush update" to install the updated dependencies')
}
} catch (error) {
console.error(`\n❌ Error: ${error.message}`)
process.exit(1)
}
}
// Run the script
main()