1 | import fs from 'fs';
|
2 | import path from 'path';
|
3 | import handleBars from 'handlebars';
|
4 | import fse from 'fs-extra';
|
5 | import {
|
6 | exec
|
7 | } from 'child_process';
|
8 | import watch from 'watch';
|
9 | import glob from 'glob';
|
10 | import {
|
11 | argv
|
12 | } from 'yargs';
|
13 | import chalk from 'chalk';
|
14 | import prompt from "prompt";
|
15 | var isDebug = !!argv.debug;
|
16 | prompt.start();
|
17 |
|
18 | export async function checkCommandAvailableAsync(command) {
|
19 | const whereResult = await execAsync(`which ${command}`);
|
20 | if (whereResult.stderr || whereResult.err) {
|
21 | return false;
|
22 | } else {
|
23 | return true;
|
24 | }
|
25 | }
|
26 | export function promptAsync(property) {
|
27 | return new Promise((resolve, reject) => {
|
28 | prompt.get(property, (err, result) => {
|
29 | if (err) {
|
30 | reject(err);
|
31 | } else {
|
32 | resolve(result);
|
33 | }
|
34 | });
|
35 | });
|
36 | }
|
37 |
|
38 | export function readFileAsync(filePath) {
|
39 | return new Promise((resolve, reject) => {
|
40 | fs.readFile(filePath, 'utf-8', (err, txt) => {
|
41 | if (err) {
|
42 | reject(err);
|
43 | } else {
|
44 | resolve(txt);
|
45 | }
|
46 | });
|
47 | });
|
48 | }
|
49 |
|
50 |
|
51 | export async function templateAsync(filePath, args) {
|
52 | const template = await readFileAsync(filePath);
|
53 | return handleBars.compile(template, {
|
54 | noEscape: true
|
55 | })(args);
|
56 | }
|
57 |
|
58 | export function copyDirAsync(src, dest, clobber = false, filter) {
|
59 | if (!filter) {
|
60 | filter = () => {
|
61 | return true;
|
62 | };
|
63 | }
|
64 | return new Promise((resolve, reject) => {
|
65 | fse.copy(src, dest, {
|
66 | clobber: clobber,
|
67 | filter: filter
|
68 | }, (err) => {
|
69 | if (err) {
|
70 | reject(err);
|
71 | return;
|
72 | }
|
73 | resolve();
|
74 | });
|
75 | });
|
76 | }
|
77 |
|
78 | export function writeFileAsync(filePath, content) {
|
79 | return new Promise((resolve, reject) => {
|
80 | fse.outputFile(filePath, content, (err) => {
|
81 | if (err) {
|
82 | reject(err);
|
83 | return;
|
84 | }
|
85 | resolve();
|
86 | });
|
87 | });
|
88 | }
|
89 |
|
90 | export function unlinkAsync(filePath) {
|
91 | return new Promise((resolve, reject) => {
|
92 | fs.unlink(filePath, (err) => {
|
93 | if (err) {
|
94 | reject(err);
|
95 | return;
|
96 | }
|
97 | resolve();
|
98 | });
|
99 | });
|
100 | }
|
101 |
|
102 | export function execAsync(command) {
|
103 | if (isDebug) {
|
104 | console.log(chalk.green(`Executing:${command}`));
|
105 | console.log(chalk.cyan(`PATH:${process.env.PATH}`));
|
106 | }
|
107 | return new Promise((resolve) => {
|
108 | exec(command, (err, stdout, stderr) => {
|
109 | resolve({
|
110 | stdout: stdout,
|
111 | stderr: stderr,
|
112 | err: err
|
113 | });
|
114 | });
|
115 | });
|
116 | }
|
117 |
|
118 | export function* watchItr(src, options) {
|
119 | let resolver = {};
|
120 | watch.watchTree(src, options, (f, curr, prev) => {
|
121 | let result = {};
|
122 | if (typeof f === "object" && prev == null && curr == null) {
|
123 | result = {
|
124 | state: "TREE_WALKED",
|
125 | hash: f
|
126 | };
|
127 | } else if (prev === null) {
|
128 | result = {
|
129 | state: "CREATED",
|
130 | stat: curr
|
131 | };
|
132 | } else if (curr.nlink === 0) {
|
133 | result = {
|
134 | state: "REMOVED",
|
135 | prevStat: prev
|
136 | };
|
137 | } else {
|
138 | result = {
|
139 | state: "MODIFIED",
|
140 | prevStat: prev,
|
141 | currStat: curr
|
142 | };
|
143 | }
|
144 | resolver.resolve(result);
|
145 | });
|
146 | while (true) {
|
147 | const p = new Promise((resolve) => {
|
148 | resolver.resolve = resolve;
|
149 | });
|
150 | yield p;
|
151 | }
|
152 | }
|
153 |
|
154 | export async function getEntities(path) {
|
155 | return new Promise((resolve, reject) => {
|
156 | fs.readdir(path, (err, files) => {
|
157 | if (err) {
|
158 | reject(err);
|
159 | } else {
|
160 | resolve(files);
|
161 | }
|
162 | });
|
163 | });
|
164 | }
|
165 |
|
166 | export async function isDirectory(path) {
|
167 | return new Promise((resolve, reject) => {
|
168 | fs.stat(path, (err, stat) => {
|
169 | if (err) {
|
170 | reject(err);
|
171 | } else {
|
172 | resolve(stat.isDirectory());
|
173 | }
|
174 | });
|
175 | });
|
176 | }
|
177 |
|
178 | export async function getDirectories(srcPath) {
|
179 | const files = await getEntities(srcPath);
|
180 | const directories = [];
|
181 | for (let i = 0; i < files.length; i++) {
|
182 | const dirName = path.join(srcPath, files[i]);
|
183 | if (await isDirectory(dirName)) {
|
184 | directories.push(files[i]);
|
185 | }
|
186 | }
|
187 | return directories;
|
188 | }
|
189 |
|
190 | export function emptyDirAsync(src) {
|
191 | return new Promise((resolve, reject) => {
|
192 | fse.emptyDir(src, (err) => {
|
193 | if (err) {
|
194 | reject(err);
|
195 | return;
|
196 | }
|
197 | resolve();
|
198 | });
|
199 | });
|
200 | }
|
201 |
|
202 | export function globAsync(globRegex) {
|
203 | return new Promise((resolve, reject) => {
|
204 | glob(globRegex, (err, files) => {
|
205 | if (err) {
|
206 | reject(err);
|
207 | return;
|
208 | }
|
209 | resolve(files);
|
210 | });
|
211 | });
|
212 | }
|
213 |
|
214 | export function ensureDirAsync(path) {
|
215 | return new Promise((resolve, reject) => {
|
216 | fse.ensureDir(path, err => {
|
217 | if (err) {
|
218 | reject(err);
|
219 | } else {
|
220 | resolve();
|
221 | }
|
222 | });
|
223 | });
|
224 | }
|
225 |
|
226 | export function ensureFileAsync(path) {
|
227 | return new Promise((resolve, reject) => {
|
228 | fse.ensureFile(path, err => {
|
229 | if (err) {
|
230 | reject(err);
|
231 | } else {
|
232 | resolve();
|
233 | }
|
234 | });
|
235 | });
|
236 | }
|
237 |
|
238 | export function existsAsync(path) {
|
239 | return new Promise((resolve, reject) => {
|
240 | fs.stat(path, err => {
|
241 | if (err === null) {
|
242 | resolve(true);
|
243 | } else if (err.code == 'ENOENT') {
|
244 |
|
245 | resolve(false)
|
246 | } else {
|
247 | reject('Some other error: ', err.code);
|
248 | }
|
249 | });
|
250 | });
|
251 | }
|