-
-
Notifications
You must be signed in to change notification settings - Fork 622
/
add.ts
157 lines (131 loc) · 4.26 KB
/
add.ts
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
/*
* @adonisjs/core
*
* (c) AdonisJS
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import { detectPackageManager, installPackage } from '@antfu/install-pkg'
import { CommandOptions } from '../types/ace.js'
import { args, BaseCommand, flags } from '../modules/ace/main.js'
/**
* The install command is used to `npm install` and `node ace configure` a new package
* in one go.
*/
export default class Add extends BaseCommand {
static commandName = 'add'
static description = 'Install and configure a package'
static options: CommandOptions = {
allowUnknownFlags: true,
}
@args.string({ description: 'Package name' })
declare name: string
@flags.boolean({ description: 'Display logs in verbose mode' })
declare verbose?: boolean
@flags.string({ description: 'Select the package manager you want to use' })
declare packageManager?: 'npm' | 'pnpm' | 'yarn'
@flags.boolean({ description: 'Should we install the package as a dev dependency', alias: 'D' })
declare dev?: boolean
@flags.boolean({ description: 'Forcefully overwrite existing files' })
declare force?: boolean
/**
* Detect the package manager to use
*/
async #getPackageManager() {
const pkgManager =
this.packageManager || (await detectPackageManager(this.app.makePath())) || 'npm'
if (['npm', 'pnpm', 'yarn'].includes(pkgManager)) {
return pkgManager as 'npm' | 'pnpm' | 'yarn'
}
throw new Error('Invalid package manager. Must be one of npm, pnpm or yarn')
}
/**
* Configure the package by delegating the work to the `node ace configure` command
*/
async #configurePackage() {
/**
* Sending unknown flags to the configure command
*/
const flagValueArray = this.parsed.unknownFlags
.filter((flag) => !!this.parsed.flags[flag])
.map((flag) => `--${flag}=${this.parsed.flags[flag]}`)
const configureArgs = [
this.name,
this.force ? '--force' : undefined,
this.verbose ? '--verbose' : undefined,
...flagValueArray,
].filter(Boolean) as string[]
return await this.kernel.exec('configure', configureArgs)
}
/**
* Install the package using the selected package manager
*/
async #installPackage(npmPackageName: string) {
const colors = this.colors
const spinner = this.logger
.await(`installing ${colors.green(this.name)} using ${colors.grey(this.packageManager!)}`)
.start()
spinner.start()
try {
await installPackage(npmPackageName, {
dev: this.dev,
silent: this.verbose === true ? false : true,
cwd: this.app.makePath(),
packageManager: this.packageManager,
})
spinner.update('package installed successfully')
spinner.stop()
return true
} catch (error) {
spinner.update('unable to install the package')
spinner.stop()
this.logger.fatal(error)
this.exitCode = 1
return false
}
}
/**
* Run method is invoked by ace automatically
*/
async run() {
const colors = this.colors
this.packageManager = await this.#getPackageManager()
/**
* Handle special packages to configure
*/
let npmPackageName = this.name
if (this.name === 'vinejs') {
npmPackageName = '@vinejs/vine'
} else if (this.name === 'edge') {
npmPackageName = 'edge.js'
}
/**
* Prompt the user to confirm the installation
*/
const cmd = colors.grey(`${this.packageManager} add ${this.dev ? '-D ' : ''}${this.name}`)
this.logger.info(`Installing the package using the following command : ${cmd}`)
const shouldInstall = await this.prompt.confirm('Continue ?', { name: 'install' })
if (!shouldInstall) {
this.logger.info('Installation cancelled')
return
}
/**
* Install package
*/
const pkgWasInstalled = await this.#installPackage(npmPackageName)
if (!pkgWasInstalled) {
return
}
/**
* Configure package
*/
const { exitCode } = await this.#configurePackage()
this.exitCode = exitCode
if (exitCode === 0) {
this.logger.success(`Installed and configured ${colors.green(this.name)}`)
} else {
this.logger.fatal(`Unable to configure ${colors.green(this.name)}`)
}
}
}