-
Notifications
You must be signed in to change notification settings - Fork 0
/
common.js
125 lines (104 loc) · 2.98 KB
/
common.js
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
import path from 'node:path'
import * as fs from 'node:fs'
import { spawn } from 'node:child_process'
export function buildCopyOptions(baseOptions, meadow) {
const copyOptions = { ...baseOptions }
// note: subtle bug: if meadow has a filter, it loses the default !node_modules filter
if (meadow.filter) {
copyOptions.filter = meadow.filter
}
return copyOptions
}
export const logNoSuchFile = (error) => {
if (error.errno === -2 && error.code === 'ENOENT') {
console.error('Did not find file', error.path)
} else {
throw error
}
}
export function fixInstalledPath(filepath) {
if (filepath[0] === '~') {
filepath = path.join(process.env['HOME'], filepath.slice(1))
}
return filepath
}
export function fixSourceControlPath(filepath) {
// transform ~/ into ~~/ for safety
if (filepath.length && filepath[0] == `~`) filepath = `~${filepath}`
return path.join(process.cwd(), '/meadows', filepath)
}
export async function bash(cmd, {
// https://www.gnu.org/software/bash/manual/html_node/Bash-Startup-Files.html
sources = [`~/.bashrc`],
...options
} = {}) {
return shell(cmd, { shell: 'bash', sources, ...options })
}
export async function zsh(cmd, {
// https://zsh.sourceforge.io/Intro/intro_3.html
sources = [`~/.zshenv`, `~/.zshrc`],
...options
} = {}) {
return shell(cmd, { shell: 'zsh', sources, ...options })
}
export async function shell(cmd, {
sources = [],
sourceSuffix = ' >/dev/null',
shell = 'sh',
flags = ['-c'],
...options
} = {}) {
let sourcedFiles = sources.map(file => `. ${file}${sourceSuffix}`).join('\n')
return run([shell, ...flags, `${sourcedFiles}\n${cmd}`], options)
}
/**
*
* @param {string[]} commandFlags An array of commands and arguments provided to spawn. The first is the cmd, the rest are provided as flags.
* @param {*} options Any option you want to provide to spawn.
* @returns
*/
export async function run(
[cmd, ...flags] = [],
options
) {
return new Promise((resolve) => {
const command = spawn(
cmd,
flags,
{
stdio: ['pipe', 'pipe', 'pipe'],
...options
}
);
process.stdin.pipe(command.stdin)
command.stdout.pipe(process.stdout)
command.stderr.pipe(process.stderr)
let out = ''
let stdout = ''
let stderr = ''
command.stdout.on('data', (data) => {
out += data
stdout += data
});
command.stderr.on('data', (data) => {
out += data
stderr += data
});
command.on('close', (code) => {
resolve({ out, stdout, stderr, code })
});
})
}
export async function parseMeadows(filePath = `./meadows.mjs`) {
global.bash = bash
global.zsh = zsh
global.shell = shell
global.run = run
const { meadows } = await import(path.resolve(process.cwd(), filePath))
return { meadows }
}
export function runDirectly() {
const runLocally = process.argv[1].split('/').pop() === 'wildflower.js'
const runGlobally = process.argv[1].split('/').pop() === 'wildflower'
return !runLocally && !runGlobally
}