forked from stkb/Rewrap
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdo
More file actions
199 lines (157 loc) · 5.94 KB
/
do
File metadata and controls
199 lines (157 loc) · 5.94 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
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
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
#!/usr/bin/env node
const CP = require('child_process')
const FS = require('fs')
const operations = ['clean', 'build', 'watch', 'test', 'package']
const components = ['core', 'vscode']
const testsDev = 'core/bin/Debug/js/Tests.js'
// Process input args
let args = process.argv.slice(2);
const supplied = (x) => args.includes(x)
const suppliedAny = (...xs) => xs.some(supplied)
const suppliedAll = (...xs) => xs.every(supplied)
const {production, verbose} = processArgs ()
/** Entry point */
function main () {
// Make sure base (tool) dependencies are installed
run ("", "dotnet tool restore")
if (notExists ('node_modules'))
run ("Installing NPM modules", "npm install")
// Clean
if (supplied ('clean')) {
if (supplied ('core')) rmDir ('core/bin')
if (supplied ('vscode')) rmDir ('vscode/bin', 'vscode/node_modules')
}
// Build Core
if (supplied ('build')) buildCore ()
// Test Core
if (supplied ('test'))
run ('Running Core tests', `node ${production ? 'core': testsDev}`, {showOutput: true})
// Build VS Code
if (suppliedAll ('build', 'vscode')) {
if (notExists ('vscode/node_modules'))
run ("Installing VS Code Extension NPM modules", 'npm install', {cwd:'./vscode'})
if (outdated ('vscode/bin/Extension.js', 'vscode/src')) {
run ("Typechecking TypeScript", npx `tsc -p vscode --noEmit`)
if (production) {
run ("Linting TypeScript", npx `eslint vscode --ext .ts`)
run ("Building TypeScript", npx `parcel build vscode --no-source-maps`)
}
else run ("Building TypeScript", npx `parcel build vscode --no-optimize`)
}
}
// Test VS Code
if (suppliedAll ('test', 'vscode') && process.env.TERM_PROGRAM != 'vscode')
run ("Running VS Code tests", 'node vscode.test/run')
// Package up VSIX
if (supplied ('package'))
run ('Creating VSIX', npx `vsce package -o Rewrap-VSCode.vsix`, {cwd:'./vscode'})
// Watch
if (supplied ('watch')) {
buildCore ({watch: true})
if (supplied ('vscode')) {
runAsync ("TypeScript watching...", npx `tsc -w -p vscode --noEmit`)
runAsync ("Parcel watching...", npx `parcel watch vscode`)
}
}
}
/** Builds the Core JS files */
function buildCore ({watch} = {}) {
const paj = x => `core/obj/${x}/project.assets.json`
if (notExists (paj ('core'), paj ('test')))
run ("Restoring Core dependencies", "dotnet restore core/Core.Test.fsproj")
const fableArgs = 'core/Core.Test.fsproj -o core/bin/Debug/js --noRestore'
if (outdated (testsDev, 'core')) run ("Fable building Core", `dotnet fable ${fableArgs}`)
if (watch) {
const cmd = `dotnet fable watch ${fableArgs} --runWatch "node ${testsDev}"`
runAsync ("Fable watching...", cmd)
}
else if (production && supplied ('test') && outdated ('core/bin/Release/js/index.js', testsDev))
run ("Parcel bundling Core", npx `parcel build core`)
}
/** If given file/folder(s) don't exist */
const notExists = (...ps) => ps.some(p => !FS.existsSync(p))
/** Runs a command under npx */
const npx = ([cmd], a1 = '') => 'npx --silent ' + cmd + a1
/** Checks if the target is outdated compared with the source */
function outdated (target, source) {
function lastModified (path) {
const s = FS.statSync(path, {throwIfNoEntry: false})
if (!s) return 0
if (s.isDirectory()) {
const times =
FS.readdirSync (path, {encoding: 'utf8', withFileTypes: true})
. filter(x => x.isFile())
. map (x => lastModified (path + "/" + x.name))
return Math.max(...times)
}
else return s.mtimeMs
}
return lastModified (target) < (source ? lastModified (source) : 1)
}
/** Processes the args given to this script. Returns production and verbose values */
function processArgs () {
if (suppliedAny ('-pv', '-vp')) args.push('-p', '-v')
const production =
suppliedAny ('--production', '-p') || process.env.NODE_ENV == 'production'
const verbose = suppliedAny ('--verbose', '-v')
// If not supplied any (valid) options, show help
if (!(production || suppliedAny (...operations) || suppliedAny (...components)))
showHelpAndExit ()
// If no other operations given then 'build' is default
if (! suppliedAny (...operations)) args.push(build)
// If no components given then do for all
if (! suppliedAny (...components)) args.push(...components)
if (supplied ('test')) args.push('build')
if (supplied ('package')) args.push('build', 'core', 'vscode')
return {production, verbose}
}
/** Removes given folder(s) */
function rmDir(...paths) {
for(let p of paths)
if (FS.existsSync (p)) run ('Cleaning ' + p, npx `rimraf ${p}`)
}
/** Runs a shell command (sync) */
function run (msg, cmd, {cwd, showOutput} = {}) {
console.log(msg)
try {
const output = CP.execSync(cmd, {encoding: 'utf8', cwd})
if (showOutput || verbose) console.log(output)
}
catch (err) {
console.error(err.stderr)
process.exit (1)
}
}
/** Runs a shell command (async) */
function runAsync (msg, cmd, {cwd, showOutput} = {}) {
console.log(msg)
const child = CP.exec(cmd, {encoding: 'utf8', cwd}, onExit)
if (showOutput || verbose) child.stdout.pipe(process.stdout, {end:false})
child.stderr.pipe(process.stderr, {end:false})
function onExit (error) {
if (error) {
console.error(error)
process.exit (1)
}
}
}
/** Shows help text and exits. For when invalid args are given */
function showHelpAndExit () {
const msg = [
"Usage: ./do (<operation> | <component> | <option>)...",
`- Operations: ${operations.join(", ")}`,
`- Components: ${components.join(", ")}`,
`- Options: --production (-p), --verbose (-v)`,
"",
"If no operations are given, does a 'build'. If no components are given, does all components.",
"Adding the --production flag does the operation in production mode.",
"",
"Examples:",
" ./do build core",
" ./do package --production",
]
console.log('\n' + msg.join('\n') + '\n')
process.exit(1)
}
// Run main function
main ()