UNPKG

5.84 kBMarkdownView Raw
1# kopy
2
3[![NPM version](https://img.shields.io/npm/v/kopy.svg?style=flat)](https://npmjs.com/package/kopy) [![NPM downloads](https://img.shields.io/npm/dm/kopy.svg?style=flat)](https://npmjs.com/package/kopy) [![Build Status](https://img.shields.io/circleci/project/egoist/kopy/master.svg?style=flat)](https://circleci.com/gh/egoist/kopy)
4
5> Gracefully copy a directory and render templates.
6
7## Why is this useful?
8
9This could be used to build a scaffolding tool like [yeoman](https://github.com/yeoman/yeoman) or [vue-cli](https://github.com/vuejs/vue-cli), and it's actually used by [SAO](https://github.com/saojs/sao).
10
11## Install
12
13```bash
14$ npm install --save kopy
15```
16
17## Usage
18
19```js
20const copy = require('kopy')
21
22copy('./template', './dest', {
23 data: {
24 foo: 'bar'
25 }
26}).then(({files}) => {
27 console.log(files) // array of filenames in './dest'
28}).catch(err => {
29 console.log(err.stack)
30})
31```
32
33## Template Syntax
34
35Templates could use [ejs](http://ejs.co) syntax or any template engine supported by [jstransformer](https://github.com/jstransformers)
36
37## API
38
39### copy(src, dest, options)
40
41Returns a Promise resolving the [`majo`](https://github.com/egoist/majo) instance we use.
42
43```js
44copy(...args)
45 .then(stream => {
46 // stream is a majo instance
47 // answers for prompts (if any)
48 stream.meta.answers
49 // options.data basically
50 stream.meta.data
51 // merged 'answers' and 'data'
52 stream.meta.merged
53 })
54```
55
56#### src
57
58Type: `string`<br>
59Required: `true`
60
61Source directory. Could be a relative or absolute path.
62
63#### dest
64
65Type: `string`<br>
66Required: `true`
67
68Destination directory.
69
70#### options
71
72##### glob
73
74Type: `Array` `string`<br>
75Default: `['**', '!**/node_modules/**']`
76
77Use the glob pattern(s) to find files in `src` directory.
78
79##### template
80
81Type: `object`<br>
82Default: `require('jstransformer-ejs')`
83
84You can use a custom template engine, like [handlebars]:
85
86```js
87copy(src, dest, {
88 template: require('jstransformer-handlebars')
89})
90```
91
92##### templateOptions
93
94Type: `object` `function`
95
96The template engine options.
97
98If it's a function we use the return value as `templateOptions`, and the first argument is `{ answers, data, merged }`.
99
100##### clean
101
102Type: `boolean`<br>
103Default: `false`
104
105Whether to clean destination directory before writing to it.
106
107##### cwd
108
109Type: `string`<br>
110Default: `process.cwd()`
111
112Current working directory.
113
114##### data
115
116Type: `object` `function`<br>
117Default: `undefined`
118
119The data to be used in rendering templates in source directory, filter files etc.
120
121If it's a function, we use its return value as `data`, and the first arguments is `answers`.
122
123##### prompts
124
125Type: `Array<InquirerPrompt>`<br>
126Default: `undefined`
127
128[inquirer](https://github.com/SBoudrias/Inquirer.js) prompts, the answers of prompts will be assigned to `data`
129
130
131##### mockPrompts
132
133Type: `Object`
134
135An object of mocked prompt values, eg:
136
137```js
138{
139 prompts: [
140 { name: 'foo', message: 'type foo', validate: v => v === 'foo' },
141 { name: 'hey', message: 'type hey' }
142 ],
143 mockPrompts: {
144 foo: 'bar'
145 }
146}
147```
148
149In the above case, we will not run prompts to get answers from users, instead we use set `foo`'s value to `bar` and validate it. And in this case it will throw since `'bar' !== 'foo'`. The value of `hey` would be `undefined`.
150
151##### skipInterpolation
152
153Type: `string | Array<string> | function`<br>
154Default: `undefined` (we skip all [binary files](https://github.com/sindresorhus/is-binary-path) by default)
155
156Patterns([minimatch](https://github.com/isaacs/minimatch#features)) used to skip interpolation, eg: `./foo*/bar-*.js`
157
158It could also be a function, whose first arg is file path and second arg is file content, eg. we want to exclude all `.js` files:
159
160```js
161copy(src, dest, {
162 skipInterpolation(file, content) {
163 return /\.js$/.test(file)
164 }
165})
166```
167
168##### disableInterpolation
169
170Type: `boolean`<br>
171Default: `false`
172
173Similar to `skipInterpolation`, but `disableInterpolation` disables all template interpolation, template markup will remain the way it is.
174
175##### filters
176
177Type: `object` `function`<br>
178Default: `undefined`
179
180An object containing file filter rules, the key of each entry is a minimatch pattern, and its value is a JavaScript expression evaluated in the context of (prompt answers) data:
181
182```js
183copy(src, dest, {
184 filters: {
185 '**/*.js': 'useJavaScript',
186 '**/*.ts': '!useJavaScript'
187 }
188})
189```
190
191If it's a function, the first argument of it would be the result of `data` merging with prompt answers.
192
193##### move
194
195Type: `object` `function`<br>
196Default: `undefined`
197
198Similar to `filters`, but instead of filtering files, it just renames the file:
199
200```js
201copy(src, dest, {
202 move: {
203 'gitignore': '.gitignore',
204 'folder/file.js': 'another/file.ts'
205 }
206})
207```
208
209If it's a function, the first argument of it would be the result of `data` merging with prompt answers.
210
211The value of each entry should be a file path or a function will returns a file path:
212
213```js
214copy(src, dest, {
215 move: {
216 'foo.*': 'foo.js',
217 'bar-*.js': filepath => filepath.replace(/^bar-/, 'bar/')
218 }
219})
220```
221
222##### skipExisting
223
224Type: `function` `boolean`<br>
225Default: `undefined`
226
227Whether to skip existing file, it could be function that takes the path to existing file as argument.
228
229```js
230copy(src, dest, {
231 skipExisting(file) {
232 console.log(`${file} exists, skipped!`)
233 }
234})
235```
236
237##### write
238
239Type: `boolean`<br>
240Default: `true`
241
242Process files and write to disk.
243
244---
245
246**kopy** © [EGOIST](https://github.com/egoist), Released under the [MIT](https://egoist.mit-license.org/) License.<br>
247Authored and maintained by EGOIST with help from contributors ([list](https://github.com/egoist/kopy/contributors)).
248
249> [egoistian.com](https://egoistian.com) · GitHub [@egoist](https://github.com/egoist) · Twitter [@_egoistlily](https://twitter.com/_egoistlily)