1 | import * as path from 'path'
|
2 | import * as fs from 'fs-extra'
|
3 | import * as memFs from 'mem-fs'
|
4 | import * as editor from 'mem-fs-editor'
|
5 | import * as _ from 'lodash'
|
6 |
|
7 | import { getRootPath } from '../util'
|
8 |
|
9 | interface IFile {
|
10 | contents: Buffer | NodeJS.ReadableStream | null;
|
11 | cwd: string;
|
12 | base: string | null | undefined;
|
13 | history: string[];
|
14 | relative: string;
|
15 | dirname: string;
|
16 | basename: string;
|
17 | stem: string;
|
18 | extname: string;
|
19 | symlink: string;
|
20 | stat: fs.Stats | null;
|
21 | }
|
22 |
|
23 | interface IReadOptions {
|
24 | raw?: boolean;
|
25 | }
|
26 |
|
27 | interface IAppendOptions {
|
28 | trimEnd?: boolean;
|
29 | separator?: string;
|
30 | }
|
31 |
|
32 | interface IMemFsEditor {
|
33 | store: {
|
34 | [key: string]: IFile;
|
35 | };
|
36 | read(filePath: string, options?: IReadOptions): string | Buffer;
|
37 | readJSON(filePath: string, defaults?: JSON): JSON;
|
38 | write(filePath: string, contents: string | Buffer): string;
|
39 | writeJSON(
|
40 | filepath: string,
|
41 | contents: JSON,
|
42 | replacer?: ((key: string, value: any) => any) | undefined,
|
43 | space?: string | number | undefined
|
44 | ): string;
|
45 | append(filePath: string, contents: string | Buffer, options?: IAppendOptions): string | Buffer;
|
46 | copyTpl(from: string, to: string, context: object, templateOptions: object);
|
47 | commit(cb: () => void);
|
48 | }
|
49 |
|
50 | export default class Creator {
|
51 | fs: IMemFsEditor
|
52 | protected _rootPath: string
|
53 | private _destinationRoot: string
|
54 |
|
55 | constructor (sourceRoot?: string) {
|
56 | const store = memFs.create()
|
57 | this.fs = editor.create(store)
|
58 | this.sourceRoot(sourceRoot || path.join(getRootPath()))
|
59 | this.init()
|
60 | }
|
61 |
|
62 | init () {}
|
63 |
|
64 | sourceRoot (rootPath?: string) {
|
65 | if (typeof rootPath === 'string') {
|
66 | this._rootPath = path.resolve(rootPath)
|
67 | }
|
68 | if (!fs.existsSync(this._rootPath)) {
|
69 | fs.ensureDirSync(this._rootPath)
|
70 | }
|
71 | return this._rootPath
|
72 | }
|
73 |
|
74 | templatePath (...args: string[]): string {
|
75 | let filepath = path.join.apply(path, args)
|
76 | if (!path.isAbsolute(filepath)) {
|
77 | filepath = path.join(this._rootPath, 'templates', filepath)
|
78 | }
|
79 | return filepath
|
80 | }
|
81 |
|
82 | destinationRoot (rootPath?: string): string {
|
83 | if (typeof rootPath === 'string') {
|
84 | this._destinationRoot = path.resolve(rootPath)
|
85 | if (!fs.existsSync(rootPath)) {
|
86 | fs.ensureDirSync(rootPath)
|
87 | }
|
88 | process.chdir(rootPath)
|
89 | }
|
90 | return this._destinationRoot || process.cwd()
|
91 | }
|
92 |
|
93 | destinationPath (...args: string[]): string {
|
94 | let filepath = path.join.apply(path, args)
|
95 | if (!path.isAbsolute(filepath)) {
|
96 | filepath = path.join(this.destinationRoot(), filepath)
|
97 | }
|
98 | if (filepath.endsWith('package.json.tmpl')) {
|
99 | filepath = filepath.replace('.tmpl', '')
|
100 | }
|
101 | const basename = path.basename(filepath)
|
102 | if (basename.startsWith('_')) {
|
103 | filepath = path.join(path.dirname(filepath), basename.replace(/^_/, '.'))
|
104 | }
|
105 | return filepath
|
106 | }
|
107 |
|
108 | template (template: string, source: string, dest: string, data?: object, options?) {
|
109 | if (typeof dest !== 'string') {
|
110 | options = data
|
111 | data = dest
|
112 | dest = source
|
113 | }
|
114 |
|
115 | const src = this.templatePath(template, source)
|
116 | if (!fs.existsSync(src)) return
|
117 |
|
118 | this.fs.copyTpl(src, this.destinationPath(dest), Object.assign({ _ }, this, data), options)
|
119 | return this
|
120 | }
|
121 |
|
122 | writeGitKeepFile (dirname: string) {
|
123 | dirname = path.resolve(dirname)
|
124 | fs.writeFileSync(path.join(dirname, '.gitkeep'), 'Place hold file', 'utf8')
|
125 | }
|
126 |
|
127 | write () {}
|
128 | }
|
129 |
|
\ | No newline at end of file |