UNPKG

4.84 kBJavaScriptView Raw
1const path = require('path')
2const majo = require('majo')
3const matcher = require('micromatch')
4const { glob, fs } = require('majo')
5const logger = require('./logger')
6const getGlobPatterns = require('./utils/getGlobPatterns')
7
8module.exports = async (config, context) => {
9 const actions =
10 typeof config.actions === 'function'
11 ? await config.actions.call(context, context)
12 : config.actions
13
14 for (const action of actions) {
15 logger.debug('Running action:', action)
16 if (action.type === 'add' && action.files) {
17 const stream = majo()
18 stream.source(['!**/node_modules/**'].concat(action.files), {
19 baseDir: path.resolve(
20 context.generator.path,
21 config.templateDir || 'template'
22 )
23 })
24
25 if (action.filters) {
26 const excludedPatterns = getGlobPatterns(
27 action.filters,
28 context.answers,
29 true
30 )
31
32 if (excludedPatterns.length > 0) {
33 stream.use(() => {
34 const excludedFiles = matcher(stream.fileList, excludedPatterns)
35 for (const file of excludedFiles) {
36 stream.deleteFile(file)
37 }
38 })
39 }
40 }
41
42 const shouldTransform =
43 typeof action.transform === 'boolean'
44 ? action.transform
45 : config.transform !== false
46 if (shouldTransform) {
47 stream.use(({ files }) => {
48 let fileList = Object.keys(stream.files)
49
50 if (action.transformInclude) {
51 fileList = matcher(fileList, action.transformInclude)
52 }
53 if (action.transformExclude) {
54 fileList = matcher.not(fileList, action.transformExclude)
55 }
56
57 fileList.forEach(relativePath => {
58 const contents = files[relativePath].contents.toString()
59 const transformer = require('jstransformer')(
60 require(`jstransformer-${config.transformer || 'ejs'}`)
61 )
62 stream.writeContents(
63 relativePath,
64 transformer.render(
65 contents,
66 config.transformerOptions,
67 Object.assign({}, context.answers, {
68 context
69 })
70 ).body
71 )
72 })
73 })
74 }
75 stream.on('write', (_, targetPath) => {
76 logger.fileAction('magenta', 'Created', targetPath)
77 })
78 await stream.dest(context.outDir)
79 } else if (action.type === 'modify' && action.handler) {
80 const stream = majo()
81 stream.source(action.files, { baseDir: context.outDir })
82 stream.use(async ({ files }) => {
83 await Promise.all(
84 // eslint-disable-next-line array-callback-return
85 Object.keys(files).map(async relativePath => {
86 const isJson = relativePath.endsWith('.json')
87 let contents = stream.fileContents(relativePath)
88 if (isJson) {
89 contents = JSON.parse(contents)
90 }
91 let result = await action.handler(contents, relativePath)
92 if (isJson) {
93 result = JSON.stringify(result, null, 2)
94 }
95 stream.writeContents(relativePath, result)
96 logger.fileAction(
97 'yellow',
98 'Modified',
99 path.join(context.outDir, relativePath)
100 )
101 })
102 )
103 })
104 await stream.dest(context.outDir)
105 } else if (action.type === 'move' && action.patterns) {
106 await Promise.all(
107 Object.keys(action.patterns).map(async pattern => {
108 const files = await glob(pattern, {
109 cwd: context.outDir,
110 absolute: true,
111 onlyFiles: false
112 })
113 if (files.length > 1) {
114 throw new Error('"move" pattern can only match one file!')
115 } else if (files.length === 1) {
116 const from = files[0]
117 const to = path.join(context.outDir, action.patterns[pattern])
118 await fs.move(from, to, {
119 overwrite: true
120 })
121 logger.fileMoveAction(from, to)
122 }
123 })
124 )
125 } else if (action.type === 'remove' && action.files) {
126 let patterns
127 if (typeof action.files === 'function') {
128 action.files = action.files(context.answers)
129 }
130 if (typeof action.files === 'string' || Array.isArray(action.files)) {
131 patterns = [].concat(action.files)
132 } else if (typeof action.files === 'object') {
133 patterns = getGlobPatterns(action.files, context.answers)
134 }
135 const files = await glob(patterns, {
136 cwd: context.outDir,
137 absolute: true
138 })
139 await Promise.all(
140 files.map(file => {
141 logger.fileAction('red', 'Removed', file)
142 return fs.remove(file)
143 })
144 )
145 }
146 }
147}