-
Notifications
You must be signed in to change notification settings - Fork 15
/
Copy pathyo.ts
151 lines (122 loc) · 3.76 KB
/
yo.ts
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
import {window, StatusBarItem, StatusBarAlignment} from 'vscode';
import {EOL} from 'os';
import * as fs from 'fs';
import * as _ from 'lodash';
import createEnvironment from './environment';
import EscapeException from '../utils/EscapeException';
const readPkgUp = require('read-pkg-up');
const semver = require('semver');
const elegantSpinner = require('elegant-spinner');
const figures = require('figures');
const frame = elegantSpinner();
export default class Yeoman {
private _options: any;
private _env: any;
private _status: StatusBarItem;
private _interval: any;
public constructor(options?: any) {
this._options = options;
this._env = createEnvironment(undefined, options);
this._status = window.createStatusBarItem(StatusBarAlignment.Left);
this._interval;
}
public getEnvironment(): any {
return this._env;
}
public getGenerators(): any[] {
const generatorsMeta = this._env.store.getGeneratorsMeta();
// Remove sub generators from list
let list = Object.keys(generatorsMeta).filter((key: any) => key.split(':')[1] === 'app');
list = list.map(key => {
const item = generatorsMeta[key];
const name = key.split(':')[0];
const pkgPath = readPkgUp.sync({cwd: item.resolved});
if (!pkgPath.pkg) {
return null;
}
const pkg = pkgPath.pkg;
const generatorVersion: any = pkg.dependencies['yeoman-generator'];
const generatorMeta: any = _.pick(pkg, 'name', 'version', 'description');
// Ignore the generator if does not depend on `yeoman-generator`
if (!generatorVersion) {
return null;
}
// Flag generator to indecate if the generator version is fully supported or not.
// https://github.com/yeoman/yeoman-app/issues/16#issuecomment-121054821
generatorMeta.isCompatible = semver.ltr('0.17.6', generatorVersion);
// Indicator to verify official generators
generatorMeta.officialGenerator = false;
if (generatorMeta.repository && generatorMeta.repository.url) {
generatorMeta.officialGenerator = generatorMeta.repository.url.indexOf('github.com/yeoman/') > -1;
}
// Add subgenerators
generatorMeta.subGenerators = Object.keys(generatorsMeta).reduce((result, key: any) => {
const split = key.split(':');
if (split[0] === name) {
result.push(split[1]);
}
return result;
}, []);
return generatorMeta;
});
return _.compact(list);
}
public run(generator: string, cwd: string) {
if (!cwd) {
throw new Error('Please open a workspace directory first.');
}
process.chdir(cwd);
const prefix = 'generator-';
if (generator.indexOf(prefix) === 0) {
generator = generator.slice(prefix.length);
}
return new Promise((resolve, reject) => {
Promise.resolve(window.showQuickPick(new Promise((res, rej) => {
setImmediate(() => {
try {
this._env.run(generator, this.done)
.on('npmInstall', () => {
this.setState('install node dependencies');
})
.on('bowerInstall', () => {
this.setState('install bower dependencies');
})
.on('error', err => {
if (!(err instanceof EscapeException)) {
window.showErrorMessage(err.message);
throw err;
}
})
.on('end', () => {
this.clearState();
console.log(`${EOL}${figures.tick} done`);
});
resolve();
} catch (err) {
reject(err);
}
rej();
});
}))).catch(err => {
// do nothing because the input is always rejected
});
});
}
private setState(state: string) {
console.log(state);
this._status.show();
this._status.tooltip = state;
this._interval = setInterval(() => {
this._status.text = `${frame()} yo`;
}, 50);
}
private clearState() {
clearInterval(this._interval);
this._status.dispose();
}
private done(err) {
if (err) {
// handle error
}
}
}