-
Notifications
You must be signed in to change notification settings - Fork 169
/
cli.ts
157 lines (138 loc) · 4.46 KB
/
cli.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
import { bold } from 'https://deno.land/std@0.106.0/fmt/colors.ts'
import { basename, resolve } from 'https://deno.land/std@0.106.0/path/mod.ts'
import { parse } from 'https://deno.land/std@0.106.0/flags/mod.ts'
import { loadImportMap } from './server/config.ts'
import { existsDir, findFile } from './shared/fs.ts'
import log from './shared/log.ts'
import util from './shared/util.ts'
import { VERSION } from './version.ts'
const commands = {
'init': 'Create a new app',
'dev': 'Start the app in development mode',
'start': 'Start the app in production mode',
'build': 'Build the app to a static site (SSG)',
'analyze': 'Analyze the app deps',
'upgrade': 'Upgrade Aleph.js command'
}
const helpMessage = `Aleph.js v${VERSION}
The Full-stack Framework in Deno.
Docs: https://alephjs.org/docs
Bugs: https://github.com/alephjs/aleph.js/issues
Usage:
aleph <command> [...options]
Commands:
${Object.entries(commands).map(([name, desc]) => `${name.padEnd(15)}${desc}`)
.join('\n ')
}
Options:
-v, --version Prints version number
-h, --help Prints help message
`
async function main() {
const { _: args, ...options } = parse(Deno.args)
// prints aleph.js version
if (options.v) {
console.log(`aleph.js v${VERSION}`)
Deno.exit(0)
}
// prints aleph.js and deno version
if (options.version) {
const { deno, v8, typescript } = Deno.version
console.log([
`aleph.js ${VERSION}`,
`deno ${deno}`,
`v8 ${v8}`,
`typescript ${typescript}`,
].join('\n'))
Deno.exit(0)
}
// prints help message when the command not found
if (!(args.length > 0 && args[0] in commands)) {
console.log(helpMessage)
Deno.exit(0)
}
const command = String(args.shift()) as keyof typeof commands
// prints command help message
if (options.h || options.help) {
const { helpMessage: cmdHelpMessage } = await import(`./commands/${command}.ts`)
console.log(commands[command])
console.log(cmdHelpMessage)
Deno.exit(0)
}
// execute `init` command
if (command === 'init') {
const { default: init } = await import(`./commands/init.ts`)
await init(options?.template, args[0])
return
}
// execute `upgrade` command
if (command === 'upgrade') {
const { default: upgrade } = await import(`./commands/upgrade.ts`)
await upgrade(options.v || options.version || args[0] || 'latest')
return
}
// check working dir
const workingDir = resolve(String(args[0] || '.'))
if (!await existsDir(workingDir)) {
log.fatal('No such directory:', workingDir)
}
// run the command if import maps exists
const importMapFile = await findFile(workingDir, ['import_map', 'import-map', 'importmap', 'importMap'].map(name => `${name}.json`))
if (importMapFile) {
const importMap = await loadImportMap(importMapFile)
let updateImportMaps: boolean | null = null
let verison = VERSION
for (const key in importMap.imports) {
const url = importMap.imports[key]
if (/\/\/deno\.land\/x\/aleph@v?\d+\.\d+\.\d+(-[a-z0-9\.]+)?\//.test(url)) {
const [prefix, rest] = util.splitBy(url, '@')
const [ver, suffix] = util.splitBy(rest, '/')
if (ver !== 'v' + VERSION && updateImportMaps === null) {
updateImportMaps = confirm(`You are using a different version of Aleph.js, expect ${ver} -> v${bold(VERSION)}, update '${basename(importMapFile)}'?`)
if (!updateImportMaps) {
verison = ver.slice(1)
}
}
if (updateImportMaps) {
importMap.imports[key] = `${prefix}@v${VERSION}/${suffix}`
}
}
}
if (updateImportMaps) {
await Deno.writeTextFile(importMapFile, JSON.stringify(importMap, undefined, 2))
}
await run(command, verison, importMapFile)
return
}
// run the command without import maps
await run(command, VERSION)
}
async function run(name: string, version: string, importMap?: string) {
const cmd: string[] = [
Deno.execPath(),
'run',
'-A',
'--unstable',
'--no-check',
'--location', 'http://localhost/'
]
if (importMap) {
cmd.push('--import-map', importMap)
}
if (Deno.env.get('ALEPH_DEV') && version === VERSION) {
cmd.push(`./commands/${name}.ts`)
} else {
cmd.push(`https://deno.land/x/aleph@v${version}/commands/${name}.ts`)
}
cmd.push(...Deno.args.slice(1))
const p = Deno.run({
cmd,
stdout: 'inherit',
stderr: 'inherit'
})
const c = await p.status()
p.close()
}
if (import.meta.main) {
main()
}