release-it 18.1.2 → 19.0.0-next.1
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/lib/config.js +10 -7
- package/lib/index.js +4 -5
- package/lib/log.js +9 -8
- package/lib/plugin/GitBase.js +2 -1
- package/lib/plugin/GitRelease.js +5 -5
- package/lib/plugin/Plugin.js +6 -4
- package/lib/plugin/factory.js +11 -11
- package/lib/plugin/git/Git.js +5 -7
- package/lib/plugin/github/GitHub.js +15 -14
- package/lib/plugin/gitlab/GitLab.js +5 -6
- package/lib/plugin/npm/npm.js +1 -3
- package/lib/shell.js +5 -6
- package/lib/util.js +97 -30
- package/package.json +26 -23
- package/test/git.init.js +56 -53
- package/test/git.js +106 -80
- package/test/npm.js +1 -0
- package/test/plugins.js +44 -39
- package/test/shell.js +2 -3
- package/test/tasks.interactive.js +13 -12
- package/test/tasks.js +40 -33
- package/test/util/helpers.js +10 -8
- package/test/util/index.js +2 -4
- package/test/util/setup.js +0 -2
- package/test/util/sh.js +18 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
|
+
import { renameSync } from 'node:fs';
|
|
3
|
+
import childProcess from 'node:child_process';
|
|
2
4
|
import test from 'ava';
|
|
3
|
-
import sh from 'shelljs';
|
|
4
|
-
import _ from 'lodash';
|
|
5
5
|
import sinon from 'sinon';
|
|
6
6
|
import Log from '../lib/log.js';
|
|
7
7
|
import Spinner from '../lib/spinner.js';
|
|
@@ -9,6 +9,7 @@ import Prompt from '../lib/prompt.js';
|
|
|
9
9
|
import Config from '../lib/config.js';
|
|
10
10
|
import runTasks from '../lib/index.js';
|
|
11
11
|
import Git from '../lib/plugin/git/Git.js';
|
|
12
|
+
import { execOpts } from '../lib/util.js';
|
|
12
13
|
import { mkTmpDir, gitAdd } from './util/helpers.js';
|
|
13
14
|
import ShellStub from './stub/shell.js';
|
|
14
15
|
import { interceptPublish as interceptGitLabPublish } from './stub/gitlab.js';
|
|
@@ -68,10 +69,10 @@ test.before(t => {
|
|
|
68
69
|
test.serial.beforeEach(t => {
|
|
69
70
|
const bare = mkTmpDir();
|
|
70
71
|
const target = mkTmpDir();
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
72
|
+
process.chdir(bare);
|
|
73
|
+
childProcess.execSync(`git init --bare .`, execOpts);
|
|
74
|
+
childProcess.execSync(`git clone ${bare} ${target}`, execOpts);
|
|
75
|
+
process.chdir(target);
|
|
75
76
|
gitAdd('line', 'file', 'Add file');
|
|
76
77
|
t.context = { bare, target };
|
|
77
78
|
});
|
|
@@ -81,7 +82,7 @@ test.serial.afterEach(() => {
|
|
|
81
82
|
});
|
|
82
83
|
|
|
83
84
|
test.serial('should run tasks without throwing errors', async t => {
|
|
84
|
-
|
|
85
|
+
renameSync('.git', 'foo');
|
|
85
86
|
const { name, latestVersion, version } = await runTasks({}, getContainer());
|
|
86
87
|
t.is(version, '0.0.1');
|
|
87
88
|
t.true(log.obtrusive.firstCall.args[0].includes(`release ${name} (currently at ${latestVersion})`));
|
|
@@ -103,7 +104,7 @@ test.serial('should not run hooks for disabled release-cycle methods', async t =
|
|
|
103
104
|
|
|
104
105
|
await runTasks({}, container);
|
|
105
106
|
|
|
106
|
-
const commands =
|
|
107
|
+
const commands = exec.args.flat().filter(arg => typeof arg === 'string' && arg.startsWith('echo'));
|
|
107
108
|
|
|
108
109
|
t.true(commands.includes('echo before:init'));
|
|
109
110
|
t.true(commands.includes('echo after:afterRelease'));
|
|
@@ -118,7 +119,7 @@ test.serial('should not run hooks for cancelled release-cycle methods', async t
|
|
|
118
119
|
const { target } = t.context;
|
|
119
120
|
const pkgName = path.basename(target);
|
|
120
121
|
gitAdd(`{"name":"${pkgName}","version":"1.0.0"}`, 'package.json', 'Add package.json');
|
|
121
|
-
|
|
122
|
+
childProcess.execSync('git tag 1.0.0', execOpts);
|
|
122
123
|
|
|
123
124
|
const hooks = getHooks(['version', 'git', 'github', 'gitlab', 'npm']);
|
|
124
125
|
const inquirer = { prompt: sandbox.stub().callsFake(([options]) => ({ [options.name]: false })) };
|
|
@@ -138,7 +139,7 @@ test.serial('should not run hooks for cancelled release-cycle methods', async t
|
|
|
138
139
|
|
|
139
140
|
await runTasks({}, container);
|
|
140
141
|
|
|
141
|
-
const commands =
|
|
142
|
+
const commands = exec.args.flat().filter(arg => typeof arg === 'string' && arg.startsWith('echo'));
|
|
142
143
|
|
|
143
144
|
t.true(commands.includes('echo before:init'));
|
|
144
145
|
t.true(commands.includes('echo after:afterRelease'));
|
|
@@ -159,7 +160,7 @@ test.serial('should run "after:*:release" plugin hooks', async t => {
|
|
|
159
160
|
const pkgName = path.basename(target);
|
|
160
161
|
const owner = path.basename(path.dirname(bare));
|
|
161
162
|
gitAdd(`{"name":"${pkgName}","version":"1.0.0"}`, 'package.json', 'Add package.json');
|
|
162
|
-
|
|
163
|
+
childProcess.execSync('git tag 1.0.0', execOpts);
|
|
163
164
|
const sha = gitAdd('line', 'file', 'More file');
|
|
164
165
|
|
|
165
166
|
const git = factory(Git);
|
|
@@ -197,7 +198,7 @@ test.serial('should run "after:*:release" plugin hooks', async t => {
|
|
|
197
198
|
|
|
198
199
|
await runTasks({}, container);
|
|
199
200
|
|
|
200
|
-
const commands =
|
|
201
|
+
const commands = exec.args.flat().filter(arg => typeof arg === 'string' && arg.startsWith('echo'));
|
|
201
202
|
|
|
202
203
|
t.true(commands.includes('echo after:git:bump'));
|
|
203
204
|
t.true(commands.includes('echo after:npm:bump'));
|
package/test/tasks.js
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
|
+
import childProcess from 'node:child_process';
|
|
3
|
+
import { appendFileSync, mkdirSync, renameSync } from 'node:fs';
|
|
2
4
|
import test from 'ava';
|
|
3
5
|
import semver from 'semver';
|
|
4
|
-
import sh from 'shelljs';
|
|
5
|
-
import _ from 'lodash';
|
|
6
6
|
import sinon from 'sinon';
|
|
7
7
|
import Log from '../lib/log.js';
|
|
8
8
|
import Spinner from '../lib/spinner.js';
|
|
9
9
|
import Config from '../lib/config.js';
|
|
10
10
|
import runTasks from '../lib/index.js';
|
|
11
11
|
import Git from '../lib/plugin/git/Git.js';
|
|
12
|
+
import { execOpts } from '../lib/util.js';
|
|
12
13
|
import { mkTmpDir, gitAdd, getArgs } from './util/helpers.js';
|
|
13
14
|
import ShellStub from './stub/shell.js';
|
|
14
15
|
import {
|
|
@@ -60,10 +61,10 @@ test.before(t => {
|
|
|
60
61
|
test.serial.beforeEach(t => {
|
|
61
62
|
const bare = mkTmpDir();
|
|
62
63
|
const target = mkTmpDir();
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
64
|
+
process.chdir(bare);
|
|
65
|
+
childProcess.execSync(`git init --bare .`, execOpts);
|
|
66
|
+
childProcess.execSync(`git clone ${bare} ${target}`, execOpts);
|
|
67
|
+
process.chdir(target);
|
|
67
68
|
gitAdd('line', 'file', 'Add file');
|
|
68
69
|
t.context = { bare, target };
|
|
69
70
|
});
|
|
@@ -73,28 +74,30 @@ test.serial.afterEach(() => {
|
|
|
73
74
|
});
|
|
74
75
|
|
|
75
76
|
test.serial('should run tasks without throwing errors', async t => {
|
|
76
|
-
|
|
77
|
+
renameSync('.git', 'foo');
|
|
77
78
|
const { name, latestVersion, version } = await runTasks({}, getContainer());
|
|
78
79
|
t.true(log.obtrusive.firstCall.args[0].includes(`release ${name} (${latestVersion}...${version})`));
|
|
79
80
|
t.regex(log.log.lastCall.args[0], /Done \(in [0-9]+s\.\)/);
|
|
80
81
|
});
|
|
81
82
|
|
|
82
83
|
test.serial('should run tasks without package.json', async t => {
|
|
83
|
-
|
|
84
|
+
childProcess.execSync('git tag 1.0.0', execOpts);
|
|
84
85
|
gitAdd('line', 'file', 'Add file');
|
|
85
86
|
const { name } = await runTasks({}, getContainer({ increment: 'major', git: { commit: false } }));
|
|
86
87
|
t.true(log.obtrusive.firstCall.args[0].includes(`release ${name} (1.0.0...2.0.0)`));
|
|
87
88
|
t.regex(log.log.lastCall.args[0], /Done \(in [0-9]+s\.\)/);
|
|
88
89
|
t.is(log.warn.callCount, 0);
|
|
89
90
|
{
|
|
90
|
-
const
|
|
91
|
+
const stdout = childProcess.execSync('git describe --tags --match=* --abbrev=0', {
|
|
92
|
+
encoding: 'utf-8'
|
|
93
|
+
});
|
|
91
94
|
t.is(stdout.trim(), '2.0.0');
|
|
92
95
|
}
|
|
93
96
|
});
|
|
94
97
|
|
|
95
98
|
test.serial('should disable plugins', async t => {
|
|
96
99
|
gitAdd('{"name":"my-package","version":"1.2.3"}', 'package.json', 'Add package.json');
|
|
97
|
-
|
|
100
|
+
childProcess.execSync('git tag 1.2.3', execOpts);
|
|
98
101
|
gitAdd('line', 'file', 'Add file');
|
|
99
102
|
const container = getContainer({ increment: 'minor', git: false, npm: false });
|
|
100
103
|
const { latestVersion, version } = await runTasks({}, container);
|
|
@@ -105,12 +108,12 @@ test.serial('should disable plugins', async t => {
|
|
|
105
108
|
|
|
106
109
|
test.serial('should run tasks with minimal config and without any warnings/errors', async t => {
|
|
107
110
|
gitAdd('{"name":"my-package","version":"1.2.3"}', 'package.json', 'Add package.json');
|
|
108
|
-
|
|
111
|
+
childProcess.execSync('git tag 1.2.3', execOpts);
|
|
109
112
|
gitAdd('line', 'file', 'More file');
|
|
110
113
|
await runTasks({}, getContainer({ increment: 'patch' }));
|
|
111
114
|
t.true(log.obtrusive.firstCall.args[0].includes('release my-package (1.2.3...1.2.4)'));
|
|
112
115
|
t.regex(log.log.lastCall.args[0], /Done \(in [0-9]+s\.\)/);
|
|
113
|
-
const
|
|
116
|
+
const stdout = childProcess.execSync('git describe --tags --match=* --abbrev=0', { encoding: 'utf-8' });
|
|
114
117
|
t.is(stdout.trim(), '1.2.4');
|
|
115
118
|
});
|
|
116
119
|
|
|
@@ -119,22 +122,22 @@ test.serial('should use pkg.version', async t => {
|
|
|
119
122
|
await runTasks({}, getContainer({ increment: 'minor' }));
|
|
120
123
|
t.true(log.obtrusive.firstCall.args[0].includes('release my-package (1.2.3...1.3.0)'));
|
|
121
124
|
t.regex(log.log.lastCall.args[0], /Done \(in [0-9]+s\.\)/);
|
|
122
|
-
const
|
|
125
|
+
const stdout = childProcess.execSync('git describe --tags --match=* --abbrev=0', { encoding: 'utf-8' });
|
|
123
126
|
t.is(stdout.trim(), '1.3.0');
|
|
124
127
|
});
|
|
125
128
|
|
|
126
129
|
test.serial('should use pkg.version (in sub dir) w/o tagging repo', async t => {
|
|
127
130
|
gitAdd('{"name":"root-package","version":"1.0.0"}', 'package.json', 'Add package.json');
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
+
childProcess.execSync('git tag 1.0.0', execOpts);
|
|
132
|
+
mkdirSync('my-package');
|
|
133
|
+
process.chdir('my-package');
|
|
131
134
|
gitAdd('{"name":"my-package","version":"1.2.3"}', 'package.json', 'Add package.json');
|
|
132
135
|
const container = getContainer({ increment: 'minor', git: { tag: false } });
|
|
133
136
|
const exec = sinon.spy(container.shell, 'exec');
|
|
134
137
|
await runTasks({}, container);
|
|
135
138
|
t.true(log.obtrusive.firstCall.args[0].endsWith('release my-package (1.2.3...1.3.0)'));
|
|
136
139
|
t.regex(log.log.lastCall.args[0], /Done \(in [0-9]+s\.\)/);
|
|
137
|
-
const
|
|
140
|
+
const stdout = childProcess.execSync('git describe --tags --match=* --abbrev=0', { encoding: 'utf-8' });
|
|
138
141
|
t.is(stdout.trim(), '1.0.0');
|
|
139
142
|
const npmArgs = getArgs(exec.args, 'npm');
|
|
140
143
|
t.is(npmArgs[5], 'npm version 1.3.0 --no-git-tag-version');
|
|
@@ -143,12 +146,12 @@ test.serial('should use pkg.version (in sub dir) w/o tagging repo', async t => {
|
|
|
143
146
|
|
|
144
147
|
test.serial('should ignore version in pkg.version and use git tag instead', async t => {
|
|
145
148
|
gitAdd('{"name":"my-package","version":"0.0.0"}', 'package.json', 'Add package.json');
|
|
146
|
-
|
|
149
|
+
childProcess.execSync('git tag 1.1.1', execOpts);
|
|
147
150
|
gitAdd('line', 'file', 'More file');
|
|
148
151
|
await runTasks({}, getContainer({ increment: 'minor', npm: { ignoreVersion: true } }));
|
|
149
152
|
t.true(log.obtrusive.firstCall.args[0].includes('release my-package (1.1.1...1.2.0)'));
|
|
150
153
|
t.regex(log.log.lastCall.args[0], /Done \(in [0-9]+s\.\)/);
|
|
151
|
-
const
|
|
154
|
+
const stdout = childProcess.execSync('git describe --tags --match=* --abbrev=0', { encoding: 'utf-8' });
|
|
152
155
|
t.is(stdout.trim(), '1.2.0');
|
|
153
156
|
});
|
|
154
157
|
|
|
@@ -158,7 +161,7 @@ test.serial('should release all the things (basic)', async t => {
|
|
|
158
161
|
const pkgName = path.basename(target);
|
|
159
162
|
const owner = path.basename(path.dirname(bare));
|
|
160
163
|
gitAdd(`{"name":"${pkgName}","version":"1.0.0"}`, 'package.json', 'Add package.json');
|
|
161
|
-
|
|
164
|
+
childProcess.execSync('git tag 1.0.0', execOpts);
|
|
162
165
|
const sha = gitAdd('line', 'file', 'More file');
|
|
163
166
|
|
|
164
167
|
interceptGitHubAuthentication();
|
|
@@ -201,10 +204,10 @@ test.serial('should release with correct tag name', async t => {
|
|
|
201
204
|
const project = path.basename(bare);
|
|
202
205
|
const pkgName = path.basename(target);
|
|
203
206
|
const owner = path.basename(path.dirname(bare));
|
|
204
|
-
const
|
|
207
|
+
const stdout = childProcess.execSync('git rev-parse --abbrev-ref HEAD', { encoding: 'utf-8' });
|
|
205
208
|
const branchName = stdout.trim();
|
|
206
209
|
gitAdd(`{"name":"${pkgName}","version":"1.0.0"}`, 'package.json', 'Add package.json');
|
|
207
|
-
|
|
210
|
+
childProcess.execSync(`git tag ${pkgName}-${branchName}-1.0.0`, execOpts);
|
|
208
211
|
const sha = gitAdd('line', 'file', 'More file');
|
|
209
212
|
|
|
210
213
|
interceptGitHubCreate({
|
|
@@ -246,9 +249,9 @@ test.serial('should release all the things (pre-release, github, gitlab)', async
|
|
|
246
249
|
const owner = path.basename(path.dirname(bare));
|
|
247
250
|
const url = `https://gitlab.com/${owner}/${project}`;
|
|
248
251
|
gitAdd(`{"name":"${pkgName}","version":"1.0.0"}`, 'package.json', 'Add package.json');
|
|
249
|
-
|
|
252
|
+
childProcess.execSync('git tag v1.0.0', execOpts);
|
|
250
253
|
const sha = gitAdd('line', 'file', 'More file');
|
|
251
|
-
|
|
254
|
+
childProcess.execSync('git push --follow-tags', execOpts);
|
|
252
255
|
const git = factory(Git);
|
|
253
256
|
const ref = (await git.getBranchName()) ?? 'HEAD';
|
|
254
257
|
|
|
@@ -327,13 +330,17 @@ test.serial('should release all the things (pre-release, github, gitlab)', async
|
|
|
327
330
|
'npm publish . --tag alpha'
|
|
328
331
|
]);
|
|
329
332
|
|
|
330
|
-
const
|
|
333
|
+
const commitMessage = childProcess.execSync('git log --oneline --format=%B -n 1 HEAD', {
|
|
334
|
+
encoding: 'utf-8'
|
|
335
|
+
});
|
|
331
336
|
t.is(commitMessage.trim(), `Release 1.1.0-alpha.0 for ${pkgName} (from 1.0.0)`);
|
|
332
337
|
|
|
333
|
-
const
|
|
338
|
+
const tagName = childProcess.execSync('git describe --tags --match=* --abbrev=0', { encoding: 'utf-8' });
|
|
334
339
|
t.is(tagName.trim(), 'v1.1.0-alpha.0');
|
|
335
340
|
|
|
336
|
-
const
|
|
341
|
+
const tagAnnotation = childProcess.execSync('git for-each-ref refs/tags/v1.1.0-alpha.0 --format="%(contents)"', {
|
|
342
|
+
encoding: 'utf-8'
|
|
343
|
+
});
|
|
337
344
|
t.is(tagAnnotation.trim(), `${owner} ${owner}/${project} ${project}`);
|
|
338
345
|
|
|
339
346
|
t.true(log.obtrusive.firstCall.args[0].endsWith(`release ${pkgName} (1.0.0...1.1.0-alpha.0)`));
|
|
@@ -349,7 +356,7 @@ test.serial('should publish pre-release without pre-id with different npm.tag',
|
|
|
349
356
|
const { target } = t.context;
|
|
350
357
|
const pkgName = path.basename(target);
|
|
351
358
|
gitAdd(`{"name":"${pkgName}","version":"1.0.0"}`, 'package.json', 'Add package.json');
|
|
352
|
-
|
|
359
|
+
childProcess.execSync('git tag v1.0.0', execOpts);
|
|
353
360
|
|
|
354
361
|
const container = getContainer({ increment: 'major', preRelease: true, npm: { name: pkgName, tag: 'next' } });
|
|
355
362
|
const exec = sinon.spy(container.shell, 'exec');
|
|
@@ -367,7 +374,7 @@ test.serial('should publish pre-release without pre-id with different npm.tag',
|
|
|
367
374
|
'npm publish . --tag next'
|
|
368
375
|
]);
|
|
369
376
|
|
|
370
|
-
const
|
|
377
|
+
const stdout = childProcess.execSync('git describe --tags --match=* --abbrev=0', { encoding: 'utf-8' });
|
|
371
378
|
t.is(stdout.trim(), 'v2.0.0-0');
|
|
372
379
|
t.true(log.obtrusive.firstCall.args[0].endsWith(`release ${pkgName} (1.0.0...2.0.0-0)`));
|
|
373
380
|
t.true(log.log.firstCall.args[0].endsWith(`https://www.npmjs.com/package/${pkgName}`));
|
|
@@ -459,7 +466,7 @@ test.serial('should use custom changelog command with context', async t => {
|
|
|
459
466
|
const { bare } = t.context;
|
|
460
467
|
const project = path.basename(bare);
|
|
461
468
|
const owner = path.basename(path.dirname(bare));
|
|
462
|
-
|
|
469
|
+
childProcess.execSync('git tag v1.0.0', execOpts);
|
|
463
470
|
gitAdd('line', 'file', 'More file');
|
|
464
471
|
|
|
465
472
|
interceptGitHubAuthentication();
|
|
@@ -499,10 +506,10 @@ test.serial('should use custom changelog command with context', async t => {
|
|
|
499
506
|
{
|
|
500
507
|
test.serial('should run all hooks', async t => {
|
|
501
508
|
gitAdd(`{"name":"hooked","version":"1.0.0","type":"module"}`, 'package.json', 'Add package.json');
|
|
502
|
-
|
|
509
|
+
childProcess.execSync(`npm install ${rootDir}`, execOpts);
|
|
503
510
|
const plugin = "import { Plugin } from 'release-it'; class MyPlugin extends Plugin {}; export default MyPlugin;";
|
|
504
|
-
sh.ShellString(plugin).toEnd('my-plugin.js');
|
|
505
511
|
|
|
512
|
+
appendFileSync('my-plugin.js', plugin);
|
|
506
513
|
const hooks = {};
|
|
507
514
|
['before', 'after'].forEach(prefix => {
|
|
508
515
|
['version', 'git', 'npm', 'my-plugin'].forEach(ns => {
|
|
@@ -521,7 +528,7 @@ test.serial('should use custom changelog command with context', async t => {
|
|
|
521
528
|
|
|
522
529
|
await runTasks({}, container);
|
|
523
530
|
|
|
524
|
-
const commands =
|
|
531
|
+
const commands = exec.args.flat().filter(arg => typeof arg === 'string' && arg.startsWith('echo'));
|
|
525
532
|
|
|
526
533
|
t.deepEqual(commands, [
|
|
527
534
|
'echo before:init',
|
package/test/util/helpers.js
CHANGED
|
@@ -1,24 +1,26 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { appendFileSync, mkdirSync, mkdtempSync, promises } from 'node:fs';
|
|
2
2
|
import os from 'node:os';
|
|
3
3
|
import path from 'node:path';
|
|
4
|
-
import
|
|
4
|
+
import childProcess from 'node:child_process';
|
|
5
|
+
import { execOpts } from '../../lib/util.js';
|
|
5
6
|
|
|
6
7
|
const mkTmpDir = () => {
|
|
7
|
-
const dir =
|
|
8
|
+
const dir = mkdtempSync(path.join(os.tmpdir(), 'release-it-'));
|
|
8
9
|
return dir;
|
|
9
10
|
};
|
|
10
11
|
|
|
11
|
-
const readFile = file =>
|
|
12
|
+
const readFile = file => promises.readFile(path.resolve(file), 'utf8');
|
|
12
13
|
|
|
13
14
|
const gitAdd = (content, filePath, message) => {
|
|
14
15
|
const pathSegments = filePath.split('/').filter(Boolean);
|
|
15
16
|
pathSegments.pop();
|
|
16
17
|
if (pathSegments.length) {
|
|
17
|
-
|
|
18
|
+
mkdirSync(path.resolve(pathSegments.join('/')), { mode: parseInt('0777', 8), recursive: true });
|
|
18
19
|
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
|
|
21
|
+
appendFileSync(filePath, content);
|
|
22
|
+
childProcess.execSync(`git add ${filePath}`, execOpts);
|
|
23
|
+
const stdout = childProcess.execSync(`git commit -m "${message}"`, { encoding: 'utf-8' });
|
|
22
24
|
const match = stdout.match(/\[.+([a-z0-9]{7})\]/);
|
|
23
25
|
return match ? match[1] : null;
|
|
24
26
|
};
|
package/test/util/index.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import _ from 'lodash';
|
|
2
1
|
import sinon from 'sinon';
|
|
3
2
|
import semver from 'semver';
|
|
4
3
|
import { parseVersion } from '../../lib/util.js';
|
|
@@ -9,10 +8,8 @@ import Spinner from '../../lib/spinner.js';
|
|
|
9
8
|
import Prompt from '../../lib/prompt.js';
|
|
10
9
|
|
|
11
10
|
export let factory = (Definition, { namespace, options = {}, container = {} } = {}) => {
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
options = Object.assign({}, { ci: true, verbose: false, 'dry-run': false, debug: false }, options);
|
|
14
12
|
const ns = namespace || Definition.name.toLowerCase();
|
|
15
|
-
|
|
16
13
|
container.config = container.config || new Config(Object.assign({ config: false }, options));
|
|
17
14
|
container.log = container.log || sinon.createStubInstance(Log);
|
|
18
15
|
|
|
@@ -20,6 +17,7 @@ export let factory = (Definition, { namespace, options = {}, container = {} } =
|
|
|
20
17
|
spinner.show.callsFake(({ enabled = true, task }) => (enabled ? task() : () => {}));
|
|
21
18
|
container.spinner = spinner;
|
|
22
19
|
container.shell = container.shell || new ShellStub({ container });
|
|
20
|
+
|
|
23
21
|
container.prompt = container.prompt || new Prompt({ container });
|
|
24
22
|
container.shell.cache = { set: () => {}, has: () => false };
|
|
25
23
|
|
package/test/util/setup.js
CHANGED
package/test/util/sh.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { spawnSync } from 'node:child_process';
|
|
2
|
+
|
|
3
|
+
const getCommandAndArgs = input => {
|
|
4
|
+
if (typeof input !== 'string' || !input.trim()) {
|
|
5
|
+
throw new Error('Invalid input: expected a non-empty string.');
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
const [command, ...args] = input.trim().split(/\s+/);
|
|
9
|
+
|
|
10
|
+
return [command, args];
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
const exec = (command, opts = { stdio: 'inherit' }) => {
|
|
14
|
+
const [cmd, args] = getCommandAndArgs(command);
|
|
15
|
+
return spawnSync(cmd, args, opts);
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export default { getCommandAndArgs, exec };
|