@gkalpak/aliases 0.9.4 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -4
- package/bin/aio/__a-builds-dir.js +5 -7
- package/bin/aio/aioall.js +5 -5
- package/bin/aio/aioatt.js +5 -5
- package/bin/aio/aiobd.js +5 -5
- package/bin/aio/aiord.js +5 -5
- package/bin/aio/aiorm.js +5 -5
- package/bin/config/cfgbash.js +3 -4
- package/bin/config/cfgbash.wsl.js +3 -4
- package/bin/config/cfggit.js +3 -4
- package/bin/config/cfggit.wsl.js +4 -5
- package/bin/config/cfgvim.js +5 -3
- package/bin/docker/dkrall.js +5 -5
- package/bin/docker/dkratt.js +5 -5
- package/bin/docker/dkrbd.js +5 -5
- package/bin/docker/dkrrd.js +5 -5
- package/bin/docker/dkrrm.js +5 -5
- package/bin/git/__g-pick-branch.js +5 -7
- package/bin/git/__g-pick-commit.js +5 -7
- package/bin/git/gaa.js +5 -5
- package/bin/git/gb.js +5 -5
- package/bin/git/gbc.js +5 -5
- package/bin/git/gbcm.js +5 -5
- package/bin/git/gbd.js +5 -5
- package/bin/git/gcl.js +5 -5
- package/bin/git/gcm.js +5 -5
- package/bin/git/gcma.js +5 -5
- package/bin/git/gcmane.js +5 -5
- package/bin/git/gcmf.js +5 -5
- package/bin/git/gcmfc.js +5 -5
- package/bin/git/gcmfs.js +5 -5
- package/bin/git/gcmi.js +5 -5
- package/bin/git/gcmia.js +5 -5
- package/bin/git/gcmiane.js +5 -5
- package/bin/git/gcmif.js +5 -5
- package/bin/git/gcmifc.js +5 -5
- package/bin/git/gcmifs.js +5 -5
- package/bin/git/gco.js +5 -5
- package/bin/git/gcoghpr-cleanup.js +5 -5
- package/bin/git/gcoghpr.js +5 -7
- package/bin/git/gcom.js +5 -5
- package/bin/git/gcopr.js +5 -5
- package/bin/git/gcp.js +5 -5
- package/bin/git/gcpa.js +5 -5
- package/bin/git/gcpc.js +5 -5
- package/bin/git/gcpx.js +5 -5
- package/bin/git/gcpxl.js +5 -5
- package/bin/git/gd.js +5 -5
- package/bin/git/gd1.js +5 -5
- package/bin/git/gdefb.js +5 -5
- package/bin/git/gdh.js +5 -5
- package/bin/git/gdn.js +5 -5
- package/bin/git/gdn1.js +5 -5
- package/bin/git/gdnh.js +5 -5
- package/bin/git/gl.js +5 -5
- package/bin/git/gl1.js +5 -5
- package/bin/git/gl1g.js +5 -5
- package/bin/git/gmt.js +5 -5
- package/bin/git/gngprh.js +5 -5
- package/bin/git/gngprm.js +5 -5
- package/bin/git/gp.js +5 -5
- package/bin/git/gp1.js +5 -5
- package/bin/git/gpf.js +5 -5
- package/bin/git/gpr.js +5 -5
- package/bin/git/gpro.js +5 -5
- package/bin/git/gprom.js +5 -5
- package/bin/git/gpru.js +5 -5
- package/bin/git/gprum.js +5 -5
- package/bin/git/grb.js +5 -5
- package/bin/git/grba.js +5 -5
- package/bin/git/grbc.js +5 -5
- package/bin/git/grbi.js +5 -5
- package/bin/git/grbia.js +5 -5
- package/bin/git/grbin.js +5 -5
- package/bin/git/grbm.js +5 -5
- package/bin/git/grs.js +5 -5
- package/bin/git/grs1.js +5 -5
- package/bin/git/gs.js +5 -5
- package/bin/git/gsh.js +5 -5
- package/bin/git/gshn.js +5 -5
- package/bin/git/gst.js +5 -5
- package/bin/git/gstk.js +5 -5
- package/bin/git/gstl.js +5 -5
- package/bin/git/gstp.js +5 -5
- package/bin/git/gsync.js +5 -5
- package/bin/misc/alv.js +1 -2
- package/bin/misc/halp.js +2 -2
- package/bin/misc/ll.darwin.js +5 -5
- package/bin/misc/ll.js +5 -5
- package/bin/misc/lla.darwin.js +5 -5
- package/bin/misc/lla.js +5 -5
- package/bin/misc/osv.darwin.js +5 -5
- package/bin/misc/osv.js +5 -5
- package/bin/misc/osv.win32.js +5 -5
- package/bin/misc/salfup.js +5 -5
- package/bin/node/nad.js +5 -5
- package/bin/node/naga.js +5 -5
- package/bin/node/nap.js +5 -5
- package/bin/node/niin.js +5 -5
- package/bin/node/nls.js +5 -5
- package/bin/node/nls1.js +5 -5
- package/bin/node/nlsg.js +5 -5
- package/bin/node/nlsg1.js +5 -5
- package/bin/node/nr.js +5 -5
- package/bin/node/nrd.js +5 -5
- package/bin/node/nrin.js +5 -5
- package/bin/node/nrp.js +5 -5
- package/bin/node/nrx.js +5 -5
- package/bin/node/ns.js +5 -5
- package/bin/node/nsin.js +5 -5
- package/bin/node/nsx.js +5 -5
- package/bin/node/nt.js +5 -5
- package/bin/node/ntin.js +5 -5
- package/bin/node/ntx.js +5 -5
- package/bin/node/nua.js +5 -5
- package/bin/node/nud.js +5 -5
- package/bin/node/nup.js +5 -5
- package/bin/node/nv.js +5 -5
- package/bin/node/nvls.js +5 -5
- package/bin/node/nvls.win32.js +5 -5
- package/bin/node/nvlsa.js +5 -5
- package/bin/node/nvlsa.win32.js +5 -5
- package/bin/node/nvmup.js +5 -5
- package/bin/node/nvmup.win32.js +5 -5
- package/bin/node/nvu.js +5 -7
- package/bin/node/srv.js +5 -5
- package/bin/node/srvw.js +5 -5
- package/bin/node/yad.js +5 -5
- package/bin/node/yaga.js +5 -5
- package/bin/node/yap.js +5 -5
- package/bin/node/yiin.js +5 -5
- package/bin/node/yls.js +5 -5
- package/bin/node/yls1.js +5 -5
- package/bin/node/ylsg.js +5 -5
- package/bin/node/ylsg1.js +5 -5
- package/bin/node/yr.js +5 -5
- package/bin/node/yrd.js +5 -5
- package/bin/node/yrin.js +5 -5
- package/bin/node/yrp.js +5 -5
- package/bin/node/yrx.js +5 -5
- package/bin/node/ys.js +5 -5
- package/bin/node/ysin.js +5 -5
- package/bin/node/ysx.js +5 -5
- package/bin/node/yt.js +5 -5
- package/bin/node/ytin.js +5 -5
- package/bin/node/ytx.js +5 -5
- package/bin/node/yua.js +5 -5
- package/bin/node/yud.js +5 -5
- package/bin/node/yup.js +5 -5
- package/lib/alias-scripts/a-builds-dir.js +65 -45
- package/lib/alias-scripts/g-pick-branch.js +44 -25
- package/lib/alias-scripts/g-pick-commit.js +44 -25
- package/lib/alias-scripts/gcoghpr.js +182 -195
- package/lib/alias-scripts/nvu.js +57 -49
- package/lib/alias.js +4 -5
- package/lib/constants.js +68 -47
- package/lib/helper.js +96 -88
- package/lib/utils.js +111 -60
- package/package.json +8 -6
- package/scripts/build.js +11 -10
- package/scripts/platformize-bin.js +7 -7
- package/scripts/test-pkg.js +14 -12
|
@@ -1,19 +1,73 @@
|
|
|
1
1
|
/* eslint-disable max-classes-per-file */
|
|
2
|
-
'use strict';
|
|
3
|
-
|
|
4
2
|
// Imports
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
import {get as httpsGet} from 'node:https';
|
|
4
|
+
import {basename} from 'node:path';
|
|
5
|
+
import {createInterface} from 'node:readline';
|
|
6
|
+
|
|
7
|
+
import {commandUtils} from '@gkalpak/cli-utils';
|
|
8
|
+
import chalk from 'chalk';
|
|
9
|
+
|
|
10
|
+
import {ALIASES, PR_LOCAL_BRANCH_PREFIX, PR_REMOTE_ALIAS_PREFIX, VERSION_STAMP} from '../constants.js';
|
|
7
11
|
|
|
8
|
-
// Constants
|
|
9
|
-
const _PR_REMOTE_ALIAS_PREFIX = 'gcoghpr';
|
|
10
|
-
const _PR_LOCAL_BRANCH_PREFIX = 'gcoghpr';
|
|
11
12
|
|
|
12
|
-
|
|
13
|
-
const
|
|
14
|
-
|
|
13
|
+
// Constants
|
|
14
|
+
const internal = {
|
|
15
|
+
_GH_TOKEN_NAME: 'GITHUB_ACCESS_TOKEN',
|
|
16
|
+
_PR_LOCAL_BRANCH_BASE: `${PR_LOCAL_BRANCH_PREFIX}-base`,
|
|
17
|
+
_PR_LOCAL_BRANCH_TOP: `${PR_LOCAL_BRANCH_PREFIX}-top`,
|
|
18
|
+
get _Executor() { return Executor; },
|
|
19
|
+
get _GitHubUtils() { return GitHubUtils; },
|
|
20
|
+
get _Logger() { return Logger; },
|
|
21
|
+
|
|
22
|
+
_httpsGet,
|
|
23
|
+
_rlCreateInterface,
|
|
24
|
+
};
|
|
15
25
|
|
|
16
26
|
// Classes
|
|
27
|
+
class Executor {
|
|
28
|
+
constructor(logger, baseConfig = {}, debugMode = false) {
|
|
29
|
+
this._logger = logger;
|
|
30
|
+
this._baseConfig = baseConfig;
|
|
31
|
+
this._debugMode = debugMode;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
exec(cmd, config) {
|
|
35
|
+
config = Object.assign({}, this._baseConfig, config);
|
|
36
|
+
|
|
37
|
+
const cmdSep = ' && ';
|
|
38
|
+
const printableCmd = cmd.
|
|
39
|
+
split(cmdSep).
|
|
40
|
+
filter(c => !/^(?:echo|node (?:-p|--print)) /.test(c)).
|
|
41
|
+
join(cmdSep);
|
|
42
|
+
|
|
43
|
+
if (this._debugMode) {
|
|
44
|
+
this._logger.debug(`Running command '${cmd}' (config: ${JSON.stringify(config)})...`);
|
|
45
|
+
}
|
|
46
|
+
this._logger.info(`RUN: ${printableCmd}`);
|
|
47
|
+
|
|
48
|
+
return commandUtils.spawnAsPromised(cmd, config);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
async execForOutput(cmd, config) {
|
|
52
|
+
config = Object.assign({}, config, {returnOutput: true});
|
|
53
|
+
const output = await this.exec(cmd, config);
|
|
54
|
+
|
|
55
|
+
return output.trim();
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
async execWithStyle(color, cmd, config) {
|
|
59
|
+
const tempStyle = this._logger.getTempStyle(color);
|
|
60
|
+
const preCmd = `node --print ${JSON.stringify(`'\b${tempStyle.open}'`)}`;
|
|
61
|
+
const resetStyle = () => process.stdout.write(tempStyle.close);
|
|
62
|
+
|
|
63
|
+
try {
|
|
64
|
+
return await this.exec(`${preCmd} && ${cmd}`, config);
|
|
65
|
+
} finally {
|
|
66
|
+
resetStyle();
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
17
71
|
/**
|
|
18
72
|
* @class Gcoghpr
|
|
19
73
|
*
|
|
@@ -25,14 +79,10 @@ const PR_LOCAL_BRANCH_BASE = `${_PR_LOCAL_BRANCH_PREFIX}-base`;
|
|
|
25
79
|
* new Gcoghpr().run(['12345'])
|
|
26
80
|
* ```
|
|
27
81
|
*/
|
|
28
|
-
class
|
|
29
|
-
get _rl() { return this._lazyLoader.get('readline'); }
|
|
30
|
-
get _constants() { return this._lazyLoader.get('../constants'); }
|
|
31
|
-
|
|
82
|
+
class Gcoghpr {
|
|
32
83
|
constructor() {
|
|
33
|
-
this._logger = new
|
|
34
|
-
this.
|
|
35
|
-
this._ghUtils = new exps._GitHubUtils(this._logger, this._lazyLoader);
|
|
84
|
+
this._logger = new internal._Logger();
|
|
85
|
+
this._ghUtils = new internal._GitHubUtils(this._logger);
|
|
36
86
|
this._remoteUrlRe = /^https:\/\/github\.com\/([^/]+)\/([^/]+?)(?:\.git|\/)?$/i;
|
|
37
87
|
}
|
|
38
88
|
|
|
@@ -65,67 +115,77 @@ class _Gcoghpr {
|
|
|
65
115
|
*
|
|
66
116
|
* @return {Promise<void>} - A promise that resolves once all operations have completed.
|
|
67
117
|
*/
|
|
68
|
-
run(runtimeArgs, config = {}) {
|
|
118
|
+
async run(runtimeArgs, config = {}) {
|
|
69
119
|
if (config.dryrun) {
|
|
70
120
|
this._logger.log('Check out a GitHub pull request on a local branch.');
|
|
71
|
-
return
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const executor = new internal._Executor(this._logger, Object.assign({sapVersion: 2}, config), config.debug);
|
|
125
|
+
const {prId = null} = this._validateInput(runtimeArgs);
|
|
126
|
+
|
|
127
|
+
if (prId === null) {
|
|
128
|
+
return;
|
|
72
129
|
}
|
|
73
130
|
|
|
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
|
-
|
|
131
|
+
try {
|
|
132
|
+
this._logger.forceColor('gray');
|
|
133
|
+
|
|
134
|
+
const upstreamUrl = await executor.execForOutput('git remote get-url upstream || git remote get-url origin');
|
|
135
|
+
const [, upstreamUser, upstreamRepo] = this._remoteUrlRe.exec(upstreamUrl);
|
|
136
|
+
const upstreamInfo = {user: upstreamUser, repo: upstreamRepo, url: upstreamUrl};
|
|
137
|
+
|
|
138
|
+
if (config.debug) {
|
|
139
|
+
this._logger.debug(`Upstream info: ${JSON.stringify(upstreamInfo)}`);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const prInfo = await this._getPrInfo(upstreamInfo, prId);
|
|
143
|
+
const localBranchSuffix = (prId.indexOf(':') !== -1) ? prInfo.branch : `pr${prId}`;
|
|
144
|
+
const localBranch = `${PR_LOCAL_BRANCH_PREFIX}-${localBranchSuffix}`;
|
|
145
|
+
const remoteAlias = `${PR_REMOTE_ALIAS_PREFIX}-${prInfo.author}`;
|
|
146
|
+
|
|
147
|
+
if (config.debug) {
|
|
148
|
+
this._logger.debug(`PR info: ${JSON.stringify(prInfo)}`);
|
|
149
|
+
this._logger.debug(`Local branch: ${localBranch}`);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
let localBranchExists;
|
|
153
|
+
|
|
154
|
+
try {
|
|
155
|
+
await executor.exec(`git show-ref --heads --quiet ${localBranch}`);
|
|
156
|
+
localBranchExists = true;
|
|
157
|
+
} catch {
|
|
158
|
+
localBranchExists = false;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
if (localBranchExists) {
|
|
162
|
+
await this._confirmOverwriteBranch(localBranch);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
const currentBranch = await executor.execForOutput('git rev-parse --abbrev-ref HEAD');
|
|
166
|
+
|
|
167
|
+
if (currentBranch === localBranch) {
|
|
168
|
+
const defaultBranch = await executor.execForOutput(ALIASES.git.gdefb.getSpec().command);
|
|
169
|
+
await executor.exec(`git checkout ${defaultBranch}`);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
await executor.exec(`git remote remove ${remoteAlias} || true`);
|
|
173
|
+
await executor.exec(`git remote add ${remoteAlias} ${prInfo.originUrl}`);
|
|
174
|
+
await executor.exec(`git fetch --no-tags ${remoteAlias} ${prInfo.branch}`);
|
|
175
|
+
await executor.exec(`git branch --force --track ${localBranch} ${remoteAlias}/${prInfo.branch}`);
|
|
176
|
+
await executor.exec(`git branch --force ${internal._PR_LOCAL_BRANCH_TOP} ${localBranch}`);
|
|
177
|
+
await executor.exec(`git branch --force ${internal._PR_LOCAL_BRANCH_BASE} ${localBranch}~${prInfo.commits || 0}`);
|
|
178
|
+
await executor.exec(`git checkout ${localBranch}`);
|
|
179
|
+
|
|
180
|
+
await this._reportSuccess(localBranch, prInfo.commits, executor);
|
|
181
|
+
} finally {
|
|
182
|
+
this._logger.forceColor(null);
|
|
183
|
+
}
|
|
124
184
|
}
|
|
125
185
|
|
|
126
186
|
_confirmOverwriteBranch(branch) {
|
|
127
187
|
return new Promise((resolve, reject) => {
|
|
128
|
-
const rlInstance =
|
|
188
|
+
const rlInstance = internal._rlCreateInterface(process.stdin, process.stdout);
|
|
129
189
|
const question = chalk.yellow(
|
|
130
190
|
`Branch '${branch}' does already exist.\n` +
|
|
131
191
|
`Overwrite it? ${chalk.white('[y/N]')} `);
|
|
@@ -137,18 +197,17 @@ class _Gcoghpr {
|
|
|
137
197
|
});
|
|
138
198
|
}
|
|
139
199
|
|
|
140
|
-
_getPrInfo(upstreamInfo, prId) {
|
|
141
|
-
const
|
|
200
|
+
async _getPrInfo(upstreamInfo, prId) {
|
|
201
|
+
const {commits, label} = prId.includes(':') ?
|
|
142
202
|
// `author:branch`
|
|
143
|
-
|
|
203
|
+
{commits: 0, label: prId} :
|
|
144
204
|
// `12345`
|
|
145
|
-
this._ghUtils.getPr(upstreamInfo, prId).then(({commits, head}) => ({commits, label: head.label}));
|
|
205
|
+
await this._ghUtils.getPr(upstreamInfo, prId).then(({commits, head}) => ({commits, label: head.label}));
|
|
146
206
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
});
|
|
207
|
+
const [author, branch] = label.split(':');
|
|
208
|
+
const originUrl = `https://github.com/${author}/${upstreamInfo.repo}.git`;
|
|
209
|
+
|
|
210
|
+
return {author, branch, originUrl, commits};
|
|
152
211
|
}
|
|
153
212
|
|
|
154
213
|
_getPrintCommand(message) {
|
|
@@ -158,20 +217,21 @@ class _Gcoghpr {
|
|
|
158
217
|
join(' && ');
|
|
159
218
|
}
|
|
160
219
|
|
|
161
|
-
_reportSuccess(localBranch, commits, executor) {
|
|
220
|
+
async _reportSuccess(localBranch, commits, executor) {
|
|
162
221
|
let ready = Promise.resolve();
|
|
163
222
|
const commands = [];
|
|
164
223
|
|
|
165
224
|
const messageMain = `\nFetched PR into local branch '${chalk.green(localBranch)}'`;
|
|
166
225
|
const messageExt = !commits ?
|
|
167
226
|
'.' :
|
|
168
|
-
|
|
227
|
+
' (and also branch range ' +
|
|
228
|
+
`'${chalk.cyan(internal._PR_LOCAL_BRANCH_BASE)}..${chalk.cyan(internal._PR_LOCAL_BRANCH_TOP)}').\n` +
|
|
169
229
|
'\n' +
|
|
170
230
|
`PR commits (${commits})\\n---`;
|
|
171
231
|
commands.push(this._getPrintCommand(`${messageMain}${messageExt}`));
|
|
172
232
|
|
|
173
233
|
if (commits) {
|
|
174
|
-
const gl1RawCmd =
|
|
234
|
+
const gl1RawCmd = ALIASES.git.gl1.getSpec().command;
|
|
175
235
|
const gl1Args = [`-${commits + 1}`];
|
|
176
236
|
|
|
177
237
|
ready = ready.
|
|
@@ -179,11 +239,12 @@ class _Gcoghpr {
|
|
|
179
239
|
then(gl1Cmd => commands.push(gl1Cmd));
|
|
180
240
|
}
|
|
181
241
|
|
|
182
|
-
|
|
242
|
+
await ready;
|
|
243
|
+
return executor.execWithStyle(null, commands.join(' && '));
|
|
183
244
|
}
|
|
184
245
|
|
|
185
246
|
_usage() {
|
|
186
|
-
const scriptName =
|
|
247
|
+
const scriptName = basename(import.meta.url).replace(/\.js$/, '');
|
|
187
248
|
const command = chalk.bgBlack.green(`${scriptName} @(<pr-number>|<author>:<branch>)`);
|
|
188
249
|
const usageMessage = `${chalk.cyan('Usage:')} ${command}`;
|
|
189
250
|
|
|
@@ -203,7 +264,7 @@ class _Gcoghpr {
|
|
|
203
264
|
this._usage();
|
|
204
265
|
return {};
|
|
205
266
|
case 1:
|
|
206
|
-
if (
|
|
267
|
+
if (!prId.includes(':') && !/^\d+$/.test(prId)) {
|
|
207
268
|
onError(`Unexpected PR identifier: ${prId}`);
|
|
208
269
|
break;
|
|
209
270
|
}
|
|
@@ -216,84 +277,38 @@ class _Gcoghpr {
|
|
|
216
277
|
}
|
|
217
278
|
}
|
|
218
279
|
|
|
219
|
-
class Executor {
|
|
220
|
-
constructor(logger, baseConfig = {}, debugMode = false) {
|
|
221
|
-
this._logger = logger;
|
|
222
|
-
this._baseConfig = baseConfig;
|
|
223
|
-
this._debugMode = debugMode;
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
exec(cmd, config) {
|
|
227
|
-
config = Object.assign({}, this._baseConfig, config);
|
|
228
|
-
|
|
229
|
-
const cmdSep = ' && ';
|
|
230
|
-
const printableCmd = cmd.
|
|
231
|
-
split(cmdSep).
|
|
232
|
-
filter(c => !/^(?:echo|node (?:-p|--print)) /.test(c)).
|
|
233
|
-
join(cmdSep);
|
|
234
|
-
|
|
235
|
-
if (this._debugMode) {
|
|
236
|
-
this._logger.debug(`Running command '${cmd}' (config: ${JSON.stringify(config)})...`);
|
|
237
|
-
}
|
|
238
|
-
this._logger.info(`RUN: ${printableCmd}`);
|
|
239
|
-
|
|
240
|
-
return commandUtils.spawnAsPromised(cmd, config);
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
execForOutput(cmd, config) {
|
|
244
|
-
config = Object.assign({}, config, {returnOutput: true});
|
|
245
|
-
return this.exec(cmd, config).then(output => output.trim());
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
execWithStyle(color, cmd, config) {
|
|
249
|
-
const tempStyle = this._logger.getTempStyle(color);
|
|
250
|
-
const preCmd = `node --print ${JSON.stringify(`'\b${tempStyle.open}'`)}`;
|
|
251
|
-
const resetStyle = () => process.stdout.write(tempStyle.close);
|
|
252
|
-
|
|
253
|
-
const promise = this.exec(`${preCmd} && ${cmd}`, config);
|
|
254
|
-
promise.then(resetStyle, resetStyle);
|
|
255
|
-
|
|
256
|
-
return promise;
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
|
|
260
280
|
class GitHubUtils {
|
|
261
|
-
|
|
262
|
-
get _url() { return this._lazyLoader.get('url'); }
|
|
263
|
-
get _constants() { return this._lazyLoader.get('../constants'); }
|
|
264
|
-
|
|
265
|
-
constructor(logger, lazyLoader) {
|
|
281
|
+
constructor(logger) {
|
|
266
282
|
this._logger = logger;
|
|
267
|
-
this._lazyLoader = lazyLoader;
|
|
268
283
|
this._baseUrl = 'https://api.github.com/';
|
|
269
284
|
this._shownTokenWarning = false;
|
|
270
285
|
}
|
|
271
286
|
|
|
272
|
-
get(path) {
|
|
273
|
-
const url = this._baseUrl
|
|
274
|
-
const ghToken = process.env[
|
|
287
|
+
async get(path) {
|
|
288
|
+
const url = `${this._baseUrl}${path}`;
|
|
289
|
+
const ghToken = process.env[internal._GH_TOKEN_NAME] || '';
|
|
275
290
|
const options = {
|
|
276
291
|
headers: {
|
|
277
292
|
Authorization: ghToken && `token ${ghToken}`,
|
|
278
|
-
'User-Agent':
|
|
293
|
+
'User-Agent': VERSION_STAMP.replace(/\s/g, '_'),
|
|
279
294
|
},
|
|
280
295
|
};
|
|
281
296
|
|
|
282
297
|
if (!ghToken && !this._shownTokenWarning) {
|
|
283
298
|
this._shownTokenWarning = true;
|
|
284
299
|
this._logger.warn(
|
|
285
|
-
`No GitHub access token found in \`${
|
|
300
|
+
`No GitHub access token found in \`${internal._GH_TOKEN_NAME}\` environment variable.\n` +
|
|
286
301
|
'Proceeding anonymously (and subject to rate-limiting)...');
|
|
287
302
|
}
|
|
288
303
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
}
|
|
304
|
+
const responseText = await this._httpsGet(url, options);
|
|
305
|
+
|
|
306
|
+
try {
|
|
307
|
+
return JSON.parse(responseText);
|
|
308
|
+
} catch (err) {
|
|
309
|
+
this._logger.error(`Response:\n${responseText}`);
|
|
310
|
+
throw err;
|
|
311
|
+
}
|
|
297
312
|
}
|
|
298
313
|
|
|
299
314
|
getPr({user: upstreamUser, repo: upstreamRepo}, prNumber) {
|
|
@@ -303,32 +318,19 @@ class GitHubUtils {
|
|
|
303
318
|
_httpsGet(url, options = {}) {
|
|
304
319
|
return new Promise((resolve, reject) => {
|
|
305
320
|
this._logger.info(`GET: ${url} (options: {${Object.keys(options).join(', ')}})`);
|
|
306
|
-
|
|
307
321
|
let data = '';
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
resolve(data) :
|
|
316
|
-
reject(`Request to '${url}' failed (status: ${res.statusCode}):\n${data}`))).
|
|
322
|
+
|
|
323
|
+
internal._httpsGet(url, options, res => res.
|
|
324
|
+
on('error', reject).
|
|
325
|
+
on('data', d => data += d).
|
|
326
|
+
on('end', () => ((200 <= res.statusCode) && (res.statusCode < 300)) ?
|
|
327
|
+
resolve(data) :
|
|
328
|
+
reject(`Request to '${url}' failed (status: ${res.statusCode}):\n${data}`))).
|
|
317
329
|
on('error', reject);
|
|
318
330
|
});
|
|
319
331
|
}
|
|
320
332
|
}
|
|
321
333
|
|
|
322
|
-
class LazyLoader {
|
|
323
|
-
constructor() {
|
|
324
|
-
this._loaded = Object.create(null);
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
get(dep) {
|
|
328
|
-
return this._loaded[dep] || (this._loaded[dep] = require(dep));
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
|
|
332
334
|
class Logger {
|
|
333
335
|
constructor() {
|
|
334
336
|
this._forcedStyle = {
|
|
@@ -380,38 +382,23 @@ class Logger {
|
|
|
380
382
|
}
|
|
381
383
|
|
|
382
384
|
// Exports
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
PR_REMOTE_ALIAS_PREFIX: _PR_REMOTE_ALIAS_PREFIX,
|
|
387
|
-
|
|
388
|
-
Gcoghpr: _Gcoghpr,
|
|
389
|
-
|
|
390
|
-
main: __main,
|
|
391
|
-
|
|
392
|
-
/** Exposed for testing purposes only. */
|
|
393
|
-
_GH_TOKEN_NAME: GH_TOKEN_NAME,
|
|
385
|
+
export {
|
|
386
|
+
Gcoghpr,
|
|
387
|
+
main,
|
|
394
388
|
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
/** Exposed for testing purposes only. */
|
|
399
|
-
_PR_LOCAL_BRANCH_TOP: PR_LOCAL_BRANCH_TOP,
|
|
400
|
-
|
|
401
|
-
/** Exposed for testing purposes only. */
|
|
402
|
-
_Executor: Executor,
|
|
403
|
-
|
|
404
|
-
/** Exposed for testing purposes only. */
|
|
405
|
-
_GitHubUtils: GitHubUtils,
|
|
389
|
+
// Exposed for testing purposes only.
|
|
390
|
+
internal as _testing,
|
|
391
|
+
};
|
|
406
392
|
|
|
407
|
-
|
|
408
|
-
|
|
393
|
+
// Helpers
|
|
394
|
+
function _httpsGet(...args) {
|
|
395
|
+
return httpsGet(...args);
|
|
396
|
+
}
|
|
409
397
|
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
}
|
|
398
|
+
function _rlCreateInterface(...args) {
|
|
399
|
+
return createInterface(...args);
|
|
400
|
+
}
|
|
413
401
|
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
return new exps.Gcoghpr().run(runtimeArgs, config);
|
|
402
|
+
function main(runtimeArgs, config) {
|
|
403
|
+
return new Gcoghpr().run(runtimeArgs, config);
|
|
417
404
|
}
|
package/lib/alias-scripts/nvu.js
CHANGED
|
@@ -1,15 +1,21 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
1
|
// Imports
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
import {commandUtils} from '@gkalpak/cli-utils';
|
|
3
|
+
import chalk from 'chalk';
|
|
4
|
+
|
|
5
|
+
import {ALIASES} from '../constants.js';
|
|
6
|
+
import {getPlatform, stripIndentation} from '../utils.js';
|
|
7
|
+
|
|
7
8
|
|
|
8
9
|
// Constants
|
|
9
10
|
const PLATFORM_WINDOWS = 'win32';
|
|
11
|
+
const internal = {
|
|
12
|
+
_nvu,
|
|
13
|
+
};
|
|
10
14
|
|
|
11
15
|
// Exports
|
|
12
|
-
|
|
16
|
+
export {
|
|
17
|
+
main,
|
|
18
|
+
|
|
13
19
|
/**
|
|
14
20
|
* @function nvu
|
|
15
21
|
*
|
|
@@ -41,32 +47,29 @@ const exps = module.exports = {
|
|
|
41
47
|
*
|
|
42
48
|
* @return {Promise<void>} - A promise that resolves once switched to the new Node.js version.
|
|
43
49
|
*/
|
|
44
|
-
nvu
|
|
50
|
+
nvu,
|
|
45
51
|
|
|
46
|
-
|
|
52
|
+
// Exposed for testing purposes only.
|
|
53
|
+
internal as _testing,
|
|
47
54
|
};
|
|
48
55
|
|
|
49
|
-
//
|
|
50
|
-
function
|
|
51
|
-
return exps.nvu(runtimeArgs, config);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
function _nvu(runtimeArgs, config) {
|
|
56
|
+
// Helpers
|
|
57
|
+
async function _nvu(runtimeArgs, config) {
|
|
55
58
|
const branch = runtimeArgs[0];
|
|
56
59
|
const nvmRuntimeArgs = runtimeArgs.slice(1);
|
|
57
|
-
const buildCmd = getBuildCmdFn(
|
|
60
|
+
const buildCmd = getBuildCmdFn(getPlatform(), config.dryrun);
|
|
58
61
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
62
|
+
const cmd = await buildCmd(branch, nvmRuntimeArgs, config);
|
|
63
|
+
|
|
64
|
+
if (config.dryrun) {
|
|
65
|
+
console.log(cmd);
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
64
68
|
|
|
65
|
-
|
|
66
|
-
});
|
|
69
|
+
return commandUtils.run(cmd, nvmRuntimeArgs, config);
|
|
67
70
|
}
|
|
68
71
|
|
|
69
|
-
function buildCmdDefault(branch, runtimeArgs) {
|
|
72
|
+
async function buildCmdDefault(branch, runtimeArgs) {
|
|
70
73
|
const hasChainedCmd = runtimeArgs.indexOf('&&') !== -1;
|
|
71
74
|
|
|
72
75
|
const nvuCmd = `nvu ${branch} "&&" <some-command>`;
|
|
@@ -74,8 +77,8 @@ function buildCmdDefault(branch, runtimeArgs) {
|
|
|
74
77
|
let warnCmd = '';
|
|
75
78
|
|
|
76
79
|
if (!hasChainedCmd) {
|
|
77
|
-
//
|
|
78
|
-
const warning = chalk.yellow(
|
|
80
|
+
// 1|0 2|0 3|0 4|0 5|0 6|0 7|0
|
|
81
|
+
const warning = chalk.yellow(stripIndentation(`
|
|
79
82
|
WARNING:
|
|
80
83
|
Running 'nvu' like this will not affect the current proccess, only the
|
|
81
84
|
spawned child process. You can still execute a single command using
|
|
@@ -90,40 +93,37 @@ function buildCmdDefault(branch, runtimeArgs) {
|
|
|
90
93
|
warnCmd = `node --print ${JSON.stringify(JSON.stringify(warning))} && `;
|
|
91
94
|
}
|
|
92
95
|
|
|
93
|
-
return
|
|
96
|
+
return `${warnCmd}. $NVM_DIR/nvm.sh && ${nvmCmd} $*`;
|
|
94
97
|
}
|
|
95
98
|
|
|
96
|
-
function buildCmdDryrun(platform, branch, nvmRuntimeArgs) {
|
|
99
|
+
async function buildCmdDryrun(platform, branch, nvmRuntimeArgs) {
|
|
97
100
|
const getVersionArgs = (platform === PLATFORM_WINDOWS) ? `${branch}, {{nvls}}` : branch;
|
|
98
101
|
const getVersionSubCmd = `getVersion(${getVersionArgs})`;
|
|
99
102
|
|
|
100
|
-
return
|
|
103
|
+
return `nvm use {{${getVersionSubCmd}}} ${nvmRuntimeArgs.join(' ')}`.trim();
|
|
101
104
|
}
|
|
102
105
|
|
|
103
|
-
function buildCmdForWindows(branch,
|
|
104
|
-
const {ALIASES} = require('../constants');
|
|
106
|
+
async function buildCmdForWindows(branch, _runtimeArgs, config) {
|
|
105
107
|
const nvlsCmd = ALIASES.node.nvls.getSpec().command;
|
|
106
108
|
const nvlsConfig = Object.assign({}, config, {returnOutput: true});
|
|
107
109
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
return `nvm use ${versionArr.join('.')} $*`;
|
|
126
|
-
});
|
|
110
|
+
const nvlsOutput = await commandUtils.run(nvlsCmd, [], nvlsConfig);
|
|
111
|
+
|
|
112
|
+
const subVersionCount = 3 - branch.split('.').length;
|
|
113
|
+
const versionRe = new RegExp(`(?:^|\\D)(${branch}(?:\\.\\d+){${subVersionCount}})`);
|
|
114
|
+
const versionArr = nvlsOutput.
|
|
115
|
+
split('\n').
|
|
116
|
+
map(line => versionRe.exec(line)).
|
|
117
|
+
filter(Boolean).
|
|
118
|
+
map(match => match[1].split('.').map(Number)).
|
|
119
|
+
sort(sortVersionArrays).
|
|
120
|
+
pop();
|
|
121
|
+
|
|
122
|
+
if (!versionArr) {
|
|
123
|
+
throw new Error(`No installed Node.js version found for '${branch}'.`);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return `nvm use ${versionArr.join('.')} $*`;
|
|
127
127
|
}
|
|
128
128
|
|
|
129
129
|
function getBuildCmdFn(platform, dryrun) {
|
|
@@ -137,6 +137,14 @@ function getBuildCmdFn(platform, dryrun) {
|
|
|
137
137
|
}
|
|
138
138
|
}
|
|
139
139
|
|
|
140
|
+
function main(runtimeArgs, config) {
|
|
141
|
+
return nvu(runtimeArgs, config);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function nvu(runtimeArgs, config) {
|
|
145
|
+
return internal._nvu(runtimeArgs, config);
|
|
146
|
+
}
|
|
147
|
+
|
|
140
148
|
function sortVersionArrays(a, b) {
|
|
141
149
|
for (let i = 0, ii = a.length; i < ii; ++i) {
|
|
142
150
|
const diff = a[i] - b[i];
|