-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathscript.ts
77 lines (72 loc) · 2.26 KB
/
script.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
import { Migration, Rule, TaskPayload } from '../interfaces' // eslint-disable-line no-unused-vars
/**
* Adds a script to the target package's package.json
*/
export interface ScriptRule extends Rule {
strictCheck?: boolean
scriptName: string // 'test'
scriptCommand: string // 'tape --bail test/*.test.js'
}
export const create: (
partialScriptRule: Partial<ScriptRule> & {
name: string
scriptName: string
scriptCommand: string
}
) => ScriptRule = partialScriptRule =>
Object.keys(partialScriptRule).reduce(
(agg, key) => ({ ...agg, [key]: (partialScriptRule as any)[key] }),
{
plan,
check
}
) as ScriptRule
/**
* Plans to add the requested script to the package.json
* @note Rule's shall not to write the package.json file. counsel shall
* write the file on your behalf to not trash the disk and as rules are likely
* to update it.
*/
export async function plan (opts: TaskPayload<ScriptRule>): Promise<Migration> {
const { ctx, rule } = opts
const pkg = ctx.packageJson
const name = rule.scriptName
const cmd = rule.scriptCommand
const prexistingCmd = pkg.scripts ? pkg.scripts[name] : null
pkg.scripts = pkg.scripts || {}
if (!prexistingCmd) {
return () => {
pkg.scripts[name] = cmd
}
}
// script key already has cmd specified. handle it.
if (prexistingCmd.indexOf(cmd) >= 0) return null
if (!rule.strictCheck) return null
throw new Error(
`unable to create migration for rule ${
rule.name
}. script "${name}" already exists and strictCheck is enabled`
)
}
/**
* Asserts that the specified cmd exists in the corresponding script or that
* an approved variant is present
*/
export const check = async (opts: TaskPayload<ScriptRule>) => {
const {
ctx,
rule: { strictCheck, scriptCommand, scriptName }
} = opts
const pkg = ctx.packageJson
const missingScriptError = new Error(
`missing ${scriptName} script in package.json`
)
if (!pkg.scripts) throw missingScriptError
const actual = pkg.scripts[scriptName]
if (!actual) throw missingScriptError
if (!strictCheck) return // scriptName exists, loose check zen™
if (scriptCommand.trim() === actual.trim()) return
throw new Error(
`script ${scriptName} not found with requested command or variants`
)
}