-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathtype-check.js
85 lines (66 loc) · 2.27 KB
/
type-check.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
import execa from 'execa'
import fs from 'mz/fs'
import path from 'path'
import supportsColor from 'supports-color'
import { getBabelPlugins, invokeBabel } from '../babel'
import type { Logger } from '../logger'
import run from '../run'
const DEFAULT_BABEL_PLUGINS = [
'@andywer/babel-plugin-transform-dctypes-to-flow'
]
const DEFAULT_BABEL_PRESETS = []
export default typeCheck
typeCheck :: (string[], Object, Logger) => Promise<*>
async function typeCheck (args, flags, logger) {
const [ sourceDirPath, ...unhandledSourceDirs ] = args
if (!sourceDirPath) {
throw new Error(`No source directory passed.`)
} else if (unhandledSourceDirs.length > 0) {
throw new Error(`Can only check a single source directory.`)
}
const plugins = DEFAULT_BABEL_PLUGINS.concat(getBabelPlugins(flags)).filter(noStripTypes)
const presets = DEFAULT_BABEL_PRESETS
const tempDirPath = path.join(sourceDirPath, '..', '.flowcheck')
if (!await exists(tempDirPath)) {
await fs.mkdir(tempDirPath)
}
if (!await exists(path.join(tempDirPath, '.flowconfig'))) {
await createFlowConfig(path.join(tempDirPath, '.flowconfig'))
}
await invokeBabel([ sourceDirPath, '-d', tempDirPath ], { plugins, presets })
// Dirty, dirty hack:
// It seems flow is sometimes still operating on the previous file contents, so we delay...
await new Promise(resolve => setTimeout(resolve, 250))
await invokeFlow(tempDirPath, logger)
logger.success(`Type check ok`)
}
noStripTypes :: string => bool
function noStripTypes (pluginName) {
return !pluginName.endsWith('flow-strip-types')
}
createFlowConfig :: string => Promise<*>
function createFlowConfig (filePath) {
// TODO: The node_modules/ path(s) should be rather dynamic
const content = `
[include]
../node_modules/
`
return fs.writeFile(filePath, content, { encoding: 'utf8' })
}
invokeFlow :: string => Promise<Object>
function invokeFlow (dirPath) {
// Flow's auto color detection will always disable colors when invoked using execa
const colorOptions = supportsColor
? [ '--color', 'always' ]
: [ ]
return run('flow', [ 'check', dirPath, ...colorOptions ])
}
exists :: string => Promise<bool>
async function exists (path) {
try {
await fs.access(path)
return true
} catch (error) {
return false
}
}