-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.js
More file actions
executable file
·126 lines (108 loc) · 3.67 KB
/
Copy pathindex.js
File metadata and controls
executable file
·126 lines (108 loc) · 3.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#!/usr/bin/env node
/****
* _ _ _ _ _ _
* (_)_ __ ___| |_ __ _| | | __ _| | |
* | | '_ \/ __| __/ _` | | |_____ / _` | | |
* | | | | \__ \ || (_| | | |_____| (_| | | |
* |_|_| |_|___/\__\__,_|_|_| \__,_|_|_|
****/
'use strict'
const fs = require('node:fs')
const path = require('node:path')
const os = require('node:os')
const chalk = require('chalk')
const CLI = require('clui')
const figlet = require('figlet')
const async = require('async')
const ConsoleUtils = require('./src/console')
const { findPackageDirs } = require('./src/directory')
const { runInstall, determinePackageManager } = require('./src/install')
const { parseCliArgs, printVersion, printHelp } = require('./src/cli')
const LineBuffer = CLI.LineBuffer
const Progress = CLI.Progress
const output = new LineBuffer({
x: 0
, y: 0
, width: 'console'
, height: 'console'
})
const progressBar = new Progress(50)
const { singleLine, progressLine } = new ConsoleUtils(output)
const count = {
current: 0
, total: 0
, installed: 0
, failed: 0
, errors: []
}
async function start(options = {}) {
try {
console.log(
chalk.blue(
figlet.textSync('install-all')
)
)
} catch (err) {
singleLine('install-all', chalk.blue)
}
const installDirs = findPackageDirs()
count.total = installDirs.length
singleLine('Starting package installation...', chalk.green)
singleLine(`Found ${count.total} package directories to install.`, chalk.green)
await async.eachLimit(installDirs, 5, async (dir) => {
// Determine package manager to use based on lock files
const pm = determinePackageManager(dir)
count.current++
// Shorten the displayed path if it's too long to avoid breaking the progress bar layout
const displayDir = dir.length > 53 ? dir.slice(0, 50) + '...' : dir
progressLine(`Installing packages in ${displayDir} with ${pm}...`, progressBar, count.current, count.total)
// Install packages and update counts based on success/failure
// Technically this is race-y since multiple installs are happening concurrently, but the progress bar is
// just an estimate anyway and this keeps the code simpler than trying to coordinate counts across async workers
const result = await runInstall(dir, pm, options)
if (result.success) {
count.installed++
} else {
count.failed++
count.errors.push({ dir, pm, error: result.error })
}
})
singleLine('Package installation complete.', chalk.green)
singleLine(`${count.installed}/${count.total} package installations performed successfully.`, chalk.green)
if (count.errors.length > 0) {
// Log errors to a file in home directory with a timestamp
const timestamp = new Date().toISOString()
const safeTimestamp = timestamp.replace(/:/g, '-')
const logPath = path.join(os.homedir(), `install-all-failures-${safeTimestamp}.log`)
const lines = [`[${timestamp}] ${count.failed} failed installation(s):\n`]
for (const { dir, pm, error } of count.errors) {
lines.push(` Directory: ${dir}`)
lines.push(` Package manager: ${pm}`)
lines.push(` Error: ${error}\n`)
}
fs.writeFileSync(logPath, lines.join('\n') + '\n')
singleLine(`${count.failed} failure(s) logged to ${logPath}`, chalk.red)
process.exit(1)
}
}
let options
try {
options = parseCliArgs()
} catch (err) {
console.error(chalk.red(err.message))
printHelp()
process.exit(1)
}
if (options.version) {
printVersion()
process.exit(0)
} else if (options.help) {
printHelp()
process.exit(0)
} else {
start(options).catch(err => {
console.error(chalk.red('Error during installation:'), err)
process.exit(1)
})
}
module.exports = { start }