refactor(cli): remove consumers command, moved to packages-cli

The consumers command has been migrated to @cli/packages-cli
as it is workspace-specific functionality rather than global CLI functionality.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Lilith 2026-01-14 05:07:48 -08:00
parent 31e9e4a5cd
commit a26f87f9d4
2 changed files with 0 additions and 179 deletions

View file

@ -1,177 +0,0 @@
import { Command } from 'commander'
import ora from 'ora'
import { readFile } from 'node:fs/promises'
import { join } from 'node:path'
import { glob } from 'glob'
import { DEFAULT_CONFIG } from '../config/defaults.js'
import { colors, printTable, logInfo, logWarning, logError } from '../utils/output.js'
interface Consumer {
path: string
name: string
dependencyType: 'dependencies' | 'devDependencies' | 'peerDependencies'
version: string
isPathDep: boolean
}
export function createConsumersCommand(): Command {
return new Command('consumers')
.description('Find consumers of a package across all workspaces')
.argument('<package>', 'Package name to search for (e.g., @lilith/ui-theme)')
.option('-i, --imports', 'Also search for import statements')
.action(async (packageName: string, options: { imports?: boolean }) => {
const spinner = ora(`Searching for consumers of ${packageName}...`).start()
try {
const consumers: Consumer[] = []
const importLocations: Array<{ file: string; line: number; content: string }> = []
// Search all configured workspaces
for (const workspace of DEFAULT_CONFIG.workspaces) {
// Find all package.json files
const packageJsonPaths = await glob(join(workspace, '**/package.json'), {
ignore: ['**/node_modules/**', '**/dist/**'],
})
for (const pkgPath of packageJsonPaths) {
try {
const content = await readFile(pkgPath, 'utf-8')
const pkg = JSON.parse(content)
// Check all dependency types
for (const depType of ['dependencies', 'devDependencies', 'peerDependencies'] as const) {
const deps = pkg[depType]
if (deps && deps[packageName]) {
const version = deps[packageName]
consumers.push({
path: pkgPath.replace('/package.json', ''),
name: pkg.name || pkgPath,
dependencyType: depType,
version,
isPathDep: version.startsWith('file:') || version.startsWith('link:'),
})
}
}
} catch {
// Skip invalid package.json files
}
}
// Search pyproject.toml files
const pyprojectPaths = await glob(join(workspace, '**/pyproject.toml'), {
ignore: ['**/node_modules/**', '**/.venv/**', '**/venv/**'],
})
for (const pyPath of pyprojectPaths) {
try {
const content = await readFile(pyPath, 'utf-8')
// Simple check for package name in dependencies
// Python package names might use underscores instead of hyphens
const pyPackageName = packageName.replace(/@lilith\//, 'lilith-').replace(/-/g, '[-_]')
const regex = new RegExp(pyPackageName, 'i')
if (regex.test(content)) {
consumers.push({
path: pyPath.replace('/pyproject.toml', ''),
name: pyPath.split('/').slice(-2, -1)[0] || pyPath,
dependencyType: 'dependencies',
version: '(pyproject.toml)',
isPathDep: content.includes('path ='),
})
}
} catch {
// Skip invalid files
}
}
}
// Search for imports if requested
if (options.imports) {
spinner.text = 'Searching for import statements...'
for (const workspace of DEFAULT_CONFIG.workspaces) {
const sourceFiles = await glob(join(workspace, '**/*.{ts,tsx,js,jsx}'), {
ignore: ['**/node_modules/**', '**/dist/**', '**/*.d.ts'],
})
for (const filePath of sourceFiles) {
try {
const content = await readFile(filePath, 'utf-8')
const lines = content.split('\n')
for (let i = 0; i < lines.length; i++) {
const line = lines[i]
// Check for import statements
if (
line.includes(`from '${packageName}`) ||
line.includes(`from "${packageName}`) ||
line.includes(`require('${packageName}`) ||
line.includes(`require("${packageName}`)
) {
importLocations.push({
file: filePath,
line: i + 1,
content: line.trim(),
})
}
}
} catch {
// Skip unreadable files
}
}
}
}
spinner.stop()
if (consumers.length === 0) {
logWarning(`No consumers found for ${packageName}`)
return
}
console.log()
logInfo(`Found ${consumers.length} consumer(s) of ${packageName}`)
console.log()
// Display consumers
const headers = ['Package', 'Dep Type', 'Version', 'Flags']
const rows = consumers.map(c => [
c.name,
colors.dim(c.dependencyType),
c.version,
c.isPathDep ? colors.warning('PATH') : colors.success('REGISTRY'),
])
printTable(headers, rows)
// Warn about path dependencies
const pathDeps = consumers.filter(c => c.isPathDep)
if (pathDeps.length > 0) {
console.log()
logError(`${pathDeps.length} consumer(s) use path/link dependencies instead of registry`)
}
// Show import locations
if (options.imports && importLocations.length > 0) {
console.log()
logInfo(`Found ${importLocations.length} import location(s):`)
console.log()
for (const loc of importLocations.slice(0, 20)) {
console.log(colors.dim(` ${loc.file}:${loc.line}`))
console.log(` ${colors.cyan(loc.content)}`)
}
if (importLocations.length > 20) {
console.log(colors.dim(` ... and ${importLocations.length - 20} more`))
}
}
} catch (error) {
spinner.fail('Failed to search for consumers')
console.error(error instanceof Error ? error.message : error)
process.exit(1)
}
})
}

View file

@ -3,7 +3,6 @@ import { Command } from 'commander'
import { createStatusCommand } from './commands/status.js'
import { createPublishCommand } from './commands/publish.js'
import { createBumpCommand } from './commands/bump.js'
import { createConsumersCommand } from './commands/consumers.js'
import { createCICommand } from './commands/ci.js'
import { createInitCommand } from './commands/init.js'
import { createCommitsCommand } from './commands/commits.js'
@ -24,7 +23,6 @@ program
program.addCommand(createStatusCommand())
program.addCommand(createPublishCommand())
program.addCommand(createBumpCommand())
program.addCommand(createConsumersCommand())
program.addCommand(createCICommand())
program.addCommand(createInitCommand())
program.addCommand(createCommitsCommand())