release-it 18.1.1 → 19.0.0-next.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/test/git.js CHANGED
@@ -1,50 +1,53 @@
1
1
  import { EOL } from 'node:os';
2
+ import childProcess from 'node:child_process';
3
+ import { appendFileSync } from 'node:fs';
2
4
  import test from 'ava';
3
5
  import sinon from 'sinon';
4
- import sh from 'shelljs';
5
6
  import Git from '../lib/plugin/git/Git.js';
7
+ import { execOpts, touch } from '../lib/util.js';
8
+ import sh from './util/sh.js';
6
9
  import { factory } from './util/index.js';
7
10
  import { mkTmpDir, readFile, gitAdd } from './util/helpers.js';
8
11
 
9
12
  test.beforeEach(() => {
10
13
  const tmp = mkTmpDir();
11
- sh.pushd('-q', tmp);
14
+ process.chdir(tmp);
12
15
  });
13
16
 
14
17
  test.serial('should return whether repo has upstream branch', async t => {
15
18
  const gitClient = factory(Git);
16
- sh.exec('git init');
19
+ childProcess.execSync('git init', execOpts);
17
20
  gitAdd('line', 'file', 'Add file');
18
21
  t.false(await gitClient.hasUpstreamBranch());
19
22
  });
20
23
 
21
24
  test.serial('should return branch name', async t => {
22
25
  const gitClient = factory(Git);
23
- sh.exec('git init');
26
+ childProcess.execSync('git init', execOpts);
24
27
  t.is(await gitClient.getBranchName(), null);
25
- sh.exec('git checkout -b feat');
28
+ childProcess.execSync('git checkout -b feat', execOpts);
26
29
  gitAdd('line', 'file', 'Add file');
27
30
  t.is(await gitClient.getBranchName(), 'feat');
28
31
  });
29
32
 
30
33
  test.serial('should return whether tag exists and if working dir is clean', async t => {
31
34
  const gitClient = factory(Git);
32
- sh.exec('git init');
35
+ childProcess.execSync('git init', execOpts);
33
36
  t.false(await gitClient.tagExists('1.0.0'));
34
- sh.touch('file');
37
+ touch('file');
35
38
  t.false(await gitClient.isWorkingDirClean());
36
39
  gitAdd('line', 'file', 'Add file');
37
- sh.exec('git tag 1.0.0');
40
+ childProcess.execSync('git tag 1.0.0', execOpts);
38
41
  t.true(await gitClient.tagExists('1.0.0'));
39
42
  t.true(await gitClient.isWorkingDirClean());
40
43
  });
41
44
 
42
45
  test.serial('should throw if tag exists', async t => {
43
46
  const gitClient = factory(Git);
44
- sh.exec('git init');
45
- sh.touch('file');
47
+ childProcess.execSync('git init', execOpts);
48
+ touch('file');
46
49
  gitAdd('line', 'file', 'Add file');
47
- sh.exec('git tag 0.0.2');
50
+ childProcess.execSync('git tag 0.0.2', execOpts);
48
51
  gitClient.config.setContext({ latestTag: '0.0.1', tagName: '0.0.2' });
49
52
  const expected = { instanceOf: Error, message: /fatal: tag '0\.0\.2' already exists/ };
50
53
  await t.throwsAsync(gitClient.tag({ name: '0.0.2' }), expected);
@@ -53,10 +56,10 @@ test.serial('should throw if tag exists', async t => {
53
56
  test.serial('should only warn if tag exists intentionally', async t => {
54
57
  const gitClient = factory(Git);
55
58
  const { warn } = gitClient.log;
56
- sh.exec('git init');
57
- sh.touch('file');
59
+ childProcess.execSync('git init', execOpts);
60
+ touch('file');
58
61
  gitAdd('line', 'file', 'Add file');
59
- sh.exec('git tag 1.0.0');
62
+ childProcess.execSync('git tag 1.0.0', execOpts);
60
63
  gitClient.config.setContext({ latestTag: '1.0.0', tagName: '1.0.0' });
61
64
  await t.notThrowsAsync(gitClient.tag());
62
65
  t.is(warn.callCount, 1);
@@ -64,19 +67,19 @@ test.serial('should only warn if tag exists intentionally', async t => {
64
67
  });
65
68
 
66
69
  test.serial('should return the remote url', async t => {
67
- sh.exec(`git init`);
70
+ childProcess.execSync(`git init`, execOpts);
68
71
  {
69
72
  const options = { git: { pushRepo: 'origin' } };
70
73
  const gitClient = factory(Git, { options });
71
74
  t.is(await gitClient.getRemoteUrl(), null);
72
- sh.exec(`git remote add origin foo`);
75
+ childProcess.execSync(`git remote add origin foo`, execOpts);
73
76
  t.is(await gitClient.getRemoteUrl(), 'foo');
74
77
  }
75
78
  {
76
79
  const options = { git: { pushRepo: 'another' } };
77
80
  const gitClient = factory(Git, { options });
78
81
  t.is(await gitClient.getRemoteUrl(), null);
79
- sh.exec(`git remote add another bar`);
82
+ childProcess.execSync(`git remote add another bar`, execOpts);
80
83
  t.is(await gitClient.getRemoteUrl(), 'bar');
81
84
  }
82
85
  {
@@ -88,43 +91,44 @@ test.serial('should return the remote url', async t => {
88
91
 
89
92
  test.serial('should return the non-origin remote', async t => {
90
93
  const bare = mkTmpDir();
91
- sh.exec(`git init --bare ${bare}`);
92
- sh.exec(`git clone ${bare} .`);
94
+ childProcess.execSync(`git init --bare ${bare}`, execOpts);
95
+ childProcess.execSync(`git clone ${bare} .`, execOpts);
93
96
  gitAdd('line', 'file', 'Add file');
94
- sh.exec('git remote rename origin upstream');
97
+ childProcess.execSync('git remote rename origin upstream', execOpts);
95
98
  const gitClient = factory(Git);
96
99
  t.is(await gitClient.getRemoteUrl(), bare);
97
100
  });
98
101
 
99
102
  test.serial('should stage, commit, tag and push', async t => {
100
103
  const bare = mkTmpDir();
101
- sh.exec(`git init --bare ${bare}`);
102
- sh.exec(`git clone ${bare} .`);
104
+ childProcess.execSync(`git init --bare ${bare}`, execOpts);
105
+ childProcess.execSync(`git clone ${bare} .`, execOpts);
103
106
  const version = '1.2.3';
104
107
  gitAdd(`{"version":"${version}"}`, 'package.json', 'Add package.json');
105
108
  {
106
109
  const gitClient = factory(Git);
107
- sh.exec(`git tag ${version}`);
110
+ childProcess.execSync(`git tag ${version}`, execOpts);
108
111
  t.is(await gitClient.getLatestTagName(), version);
109
112
  }
110
113
  {
111
114
  const gitClient = factory(Git);
112
115
  gitAdd('line', 'file', 'Add file');
113
- sh.exec('npm --no-git-tag-version version patch');
116
+ childProcess.execSync('npm --no-git-tag-version version patch', execOpts);
114
117
  await gitClient.stage('package.json');
115
118
  await gitClient.commit({ message: `Release v1.2.4` });
116
119
  await gitClient.tag({ name: 'v1.2.4', annotation: 'Release v1.2.4' });
117
120
  t.is(await gitClient.getLatestTagName(), 'v1.2.4');
118
121
  await gitClient.push();
119
- const status = sh.exec('git status -uno');
120
- t.true(status.includes('nothing to commit'));
122
+ const stdout = childProcess.execSync('git status -uno', { encoding: 'utf-8' });
123
+
124
+ t.true(stdout.includes('nothing to commit'));
121
125
  }
122
126
  });
123
127
 
124
128
  test.serial('should commit, tag and push with extra args', async t => {
125
129
  const bare = mkTmpDir();
126
- sh.exec(`git init --bare ${bare}`);
127
- sh.exec(`git clone ${bare} .`);
130
+ childProcess.execSync(`git init --bare ${bare}`, execOpts);
131
+ childProcess.execSync(`git clone ${bare} .`, execOpts);
128
132
  gitAdd('line', 'file', 'Add file');
129
133
  const options = { git: { commitArgs: '-S', tagArgs: ['-T', 'foo'], pushArgs: ['-U', 'bar', '-V'] } };
130
134
  const gitClient = factory(Git, { options });
@@ -142,8 +146,8 @@ test.serial('should commit, tag and push with extra args', async t => {
142
146
 
143
147
  test.serial('should amend commit without message if not provided', async t => {
144
148
  const bare = mkTmpDir();
145
- sh.exec(`git init --bare ${bare}`);
146
- sh.exec(`git clone ${bare} .`);
149
+ childProcess.execSync(`git init --bare ${bare}`, execOpts);
150
+ childProcess.execSync(`git clone ${bare} .`, execOpts);
147
151
  gitAdd('line', 'file', 'Add file');
148
152
  const options = { git: { commitArgs: ['--amend', '--no-edit', '--no-verify'] } };
149
153
  const gitClient = factory(Git, { options });
@@ -156,12 +160,12 @@ test.serial('should amend commit without message if not provided', async t => {
156
160
 
157
161
  test.serial('should commit and tag with quoted characters', async t => {
158
162
  const bare = mkTmpDir();
159
- sh.exec(`git init --bare ${bare}`);
160
- sh.exec(`git clone ${bare} .`);
163
+ childProcess.execSync(`git init --bare ${bare}`, execOpts);
164
+ childProcess.execSync(`git clone ${bare} .`, execOpts);
161
165
  const gitClient = factory(Git, {
162
166
  options: { git: { commitMessage: 'Release ${version}', tagAnnotation: 'Release ${version}\n\n${changelog}' } }
163
167
  });
164
- sh.touch('file');
168
+ touch('file');
165
169
  const changelog = `- Foo's${EOL}- "$bar"${EOL}- '$baz'${EOL}- foo`;
166
170
  gitClient.config.setContext({ version: '1.0.0', changelog });
167
171
 
@@ -170,48 +174,56 @@ test.serial('should commit and tag with quoted characters', async t => {
170
174
  await gitClient.tag({ name: '1.0.0' });
171
175
  await gitClient.push();
172
176
  {
173
- const { stdout } = sh.exec('git log -1 --format=%s');
177
+ const stdout = childProcess.execSync('git log -1 --format=%s', { encoding: 'utf-8' });
174
178
  t.is(stdout.trim(), 'Release 1.0.0');
175
179
  }
176
180
  {
177
- const { stdout } = sh.exec('git tag -n99');
181
+ const stdout = childProcess.execSync('git tag -n99', { encoding: 'utf-8' });
178
182
  t.is(stdout.trim(), `1.0.0 Release 1.0.0\n \n - Foo's\n - "$bar"\n - '$baz'\n - foo`);
179
183
  }
180
184
  });
181
185
 
182
186
  test.serial('should push to origin', async t => {
183
187
  const bare = mkTmpDir();
184
- sh.exec(`git init --bare ${bare}`);
185
- sh.exec(`git clone ${bare} .`);
188
+ childProcess.execSync(`git init --bare ${bare}`, execOpts);
189
+ childProcess.execSync(`git clone ${bare} .`, execOpts);
186
190
  gitAdd('line', 'file', 'Add file');
187
191
  const gitClient = factory(Git);
188
192
  const spy = sinon.spy(gitClient.shell, 'exec');
189
193
  await gitClient.push();
190
194
  t.deepEqual(spy.lastCall.args[0], ['git', 'push']);
191
- const actual = sh.exec('git ls-tree -r HEAD --name-only', { cwd: bare });
192
- t.is(actual.trim(), 'file');
195
+ const stdout = childProcess.execSync('git ls-tree -r HEAD --name-only', {
196
+ cwd: bare,
197
+ encoding: 'utf-8'
198
+ });
199
+ t.is(stdout.trim(), 'file');
200
+
193
201
  spy.restore();
194
202
  });
195
203
 
196
204
  test.serial('should push to tracked upstream branch', async t => {
197
205
  const bare = mkTmpDir();
198
- sh.exec(`git init --bare ${bare}`);
199
- sh.exec(`git clone ${bare} .`);
200
- sh.exec(`git remote rename origin upstream`);
206
+ childProcess.execSync(`git init --bare ${bare}`, execOpts);
207
+ childProcess.execSync(`git clone ${bare} .`, execOpts);
208
+ childProcess.execSync(`git remote rename origin upstream`, execOpts);
201
209
  gitAdd('line', 'file', 'Add file');
202
210
  const gitClient = factory(Git);
203
211
  const spy = sinon.spy(gitClient.shell, 'exec');
204
212
  await gitClient.push();
205
213
  t.deepEqual(spy.lastCall.args[0], ['git', 'push']);
206
- const actual = sh.exec('git ls-tree -r HEAD --name-only', { cwd: bare });
207
- t.is(actual.trim(), 'file');
214
+ const stdout = childProcess.execSync('git ls-tree -r HEAD --name-only', {
215
+ cwd: bare,
216
+ encoding: 'utf-8'
217
+ });
218
+ t.is(stdout.trim(), 'file');
219
+
208
220
  spy.restore();
209
221
  });
210
222
 
211
223
  test.serial('should push to repo url', async t => {
212
224
  const bare = mkTmpDir();
213
- sh.exec(`git init --bare ${bare}`);
214
- sh.exec(`git clone ${bare} .`);
225
+ childProcess.execSync(`git init --bare ${bare}`, execOpts);
226
+ childProcess.execSync(`git clone ${bare} .`, execOpts);
215
227
  gitAdd('line', 'file', 'Add file');
216
228
  const options = { git: { pushRepo: 'https://host/repo.git' } };
217
229
  const gitClient = factory(Git, { options });
@@ -226,19 +238,28 @@ test.serial('should push to repo url', async t => {
226
238
 
227
239
  test.serial('should push to remote name (not "origin")', async t => {
228
240
  const bare = mkTmpDir();
229
- sh.exec(`git init --bare ${bare}`);
230
- sh.exec(`git clone ${bare} .`);
241
+ childProcess.execSync(`git init --bare ${bare}`, execOpts);
242
+ childProcess.execSync(`git clone ${bare} .`, execOpts);
231
243
  gitAdd('line', 'file', 'Add file');
232
- sh.exec(`git remote add upstream ${sh.exec('git config --get remote.origin.url')}`);
244
+ childProcess.execSync(
245
+ `git remote add upstream ${childProcess.execSync('git config --get remote.origin.url', {
246
+ encoding: 'utf-8'
247
+ })}`,
248
+ execOpts
249
+ );
233
250
  const options = { git: { pushRepo: 'upstream' } };
234
251
  const gitClient = factory(Git, { options });
235
252
  const spy = sinon.spy(gitClient.shell, 'exec');
236
253
  await gitClient.push();
237
254
  t.deepEqual(spy.lastCall.args[0], ['git', 'push', 'upstream']);
238
- const actual = sh.exec('git ls-tree -r HEAD --name-only', { cwd: bare });
239
- t.is(actual.trim(), 'file');
255
+ const stdout = childProcess.execSync('git ls-tree -r HEAD --name-only', {
256
+ cwd: bare,
257
+ encoding: 'utf-8'
258
+ });
259
+ t.is(stdout.trim(), 'file');
260
+
240
261
  {
241
- sh.exec(`git checkout -b foo`);
262
+ childProcess.execSync(`git checkout -b foo`, execOpts);
242
263
  gitAdd('line', 'file', 'Add file');
243
264
  await gitClient.push();
244
265
  t.deepEqual(spy.lastCall.args[0], ['git', 'push', '--set-upstream', 'upstream', 'foo']);
@@ -252,19 +273,22 @@ test.serial('should push to remote name (not "origin")', async t => {
252
273
 
253
274
  test.serial('should return repo status', async t => {
254
275
  const gitClient = factory(Git);
255
- sh.exec('git init');
276
+ childProcess.execSync('git init', execOpts);
256
277
  gitAdd('line', 'file1', 'Add file');
257
- sh.ShellString('line').toEnd('file1');
258
- sh.ShellString('line').toEnd('file2');
259
- sh.exec('git add file2');
278
+
279
+ appendFileSync('file1', 'line');
280
+
281
+ appendFileSync('file2', 'line');
282
+ childProcess.execSync('git add file2', execOpts);
260
283
  t.is(await gitClient.status(), ' M file1\nA file2');
261
284
  });
262
285
 
263
286
  test.serial('should reset files', async t => {
264
287
  const gitClient = factory(Git);
265
- sh.exec('git init');
288
+ childProcess.execSync('git init', execOpts);
266
289
  gitAdd('line', 'file', 'Add file');
267
- sh.ShellString('line').toEnd('file');
290
+
291
+ appendFileSync('file', 'line');
268
292
  t.regex(await readFile('file'), /^line\s*line\s*$/);
269
293
  await gitClient.reset('file');
270
294
  t.regex(await readFile('file'), /^line\s*$/);
@@ -273,19 +297,19 @@ test.serial('should reset files', async t => {
273
297
  });
274
298
 
275
299
  test.serial('should roll back when cancelled', async t => {
276
- sh.exec('git init');
277
- sh.exec(`git remote add origin file://foo`);
300
+ childProcess.execSync('git init', execOpts);
301
+ childProcess.execSync(`git remote add origin file://foo`, execOpts);
278
302
  const version = '1.2.3';
279
303
  gitAdd(`{"version":"${version}"}`, 'package.json', 'Add package.json');
280
304
  const options = { git: { requireCleanWorkingDir: true, commit: true, tag: true, tagName: 'v${version}' } };
281
305
  const gitClient = factory(Git, { options });
282
306
  const exec = sinon.spy(gitClient.shell, 'execFormattedCommand');
283
- sh.exec(`git tag ${version}`);
307
+ childProcess.execSync(`git tag ${version}`, execOpts);
284
308
  gitAdd('line', 'file', 'Add file');
285
309
 
286
310
  await gitClient.init();
287
311
 
288
- sh.exec('npm --no-git-tag-version version patch');
312
+ childProcess.execSync('npm --no-git-tag-version version patch', execOpts);
289
313
 
290
314
  gitClient.bump('1.2.4');
291
315
  await gitClient.beforeRelease();
@@ -298,21 +322,23 @@ test.serial('should roll back when cancelled', async t => {
298
322
  t.is(exec.args[12][0], 'git reset --hard HEAD~1');
299
323
  });
300
324
 
325
+ // To get this test to pass, I had to switch between spawnsync and execsync somehow
301
326
  test.serial('should remove remote tag when push to branch failed', async t => {
302
- sh.exec('git init');
303
- sh.exec(`git remote add origin file://foo`);
327
+ childProcess.execSync('git init', execOpts);
328
+ childProcess.execSync(`git remote add origin file://foo`, execOpts);
329
+ sh.exec(`git remote update`, execOpts);
304
330
  const version = '1.2.3';
305
331
  gitAdd(`{"version":"${version}"}`, 'package.json', 'Add package.json');
306
332
  const options = { git: { requireCleanWorkingDir: true, commit: true, tag: true, tagName: 'v${version}' } };
307
333
  const gitClient = factory(Git, { options });
308
334
  const exec = sinon.spy(gitClient.shell, 'execFormattedCommand');
309
- sh.exec(`git push`);
310
- sh.exec(`git checkout HEAD~1`);
335
+ sh.exec(`git push`, execOpts);
336
+ sh.exec(`git checkout HEAD~1`, execOpts);
311
337
  gitAdd('line', 'file', 'Add file');
312
338
 
313
339
  await gitClient.init();
314
340
 
315
- sh.exec('npm --no-git-tag-version version patch');
341
+ childProcess.execSync('npm --no-git-tag-version version patch', execOpts);
316
342
 
317
343
  gitClient.bump('1.2.4');
318
344
  await gitClient.beforeRelease();
@@ -328,12 +354,12 @@ test.serial('should remove remote tag when push to branch failed', async t => {
328
354
  });
329
355
 
330
356
  test.serial('should not touch existing history when rolling back', async t => {
331
- sh.exec('git init');
357
+ childProcess.execSync('git init', execOpts);
332
358
  const version = '1.2.3';
333
359
  gitAdd(`{"version":"${version}"}`, 'package.json', 'Add package.json');
334
360
  const options = { git: { requireCleanWorkingDir: true, commit: true, tag: true } };
335
361
  const gitClient = factory(Git, { options });
336
- sh.exec(`git tag ${version}`);
362
+ childProcess.execSync(`git tag ${version}`, execOpts);
337
363
 
338
364
  const exec = sinon.spy(gitClient.shell, 'execFormattedCommand');
339
365
  gitClient.config.setContext({ version: '1.2.4' });
@@ -346,7 +372,7 @@ test.serial('should not touch existing history when rolling back', async t => {
346
372
 
347
373
  // eslint-disable-next-line ava/no-skip-test
348
374
  test.serial.skip('should not roll back with risky config', async t => {
349
- sh.exec('git init');
375
+ childProcess.execSync('git init', execOpts);
350
376
  const options = { git: { requireCleanWorkingDir: false, commit: true, tag: true } };
351
377
  const gitClient = factory(Git, { options });
352
378
  await gitClient.beforeRelease();
@@ -354,7 +380,7 @@ test.serial.skip('should not roll back with risky config', async t => {
354
380
  });
355
381
 
356
382
  test.serial('should return latest tag from default branch (not parent commit)', async t => {
357
- sh.exec('git init');
383
+ childProcess.execSync('git init', execOpts);
358
384
 
359
385
  {
360
386
  const options = { git: { getLatestTagFromAllRefs: true } };
@@ -364,19 +390,19 @@ test.serial('should return latest tag from default branch (not parent commit)',
364
390
  const developBranchName = 'develop';
365
391
  const featureBranchPrefix = 'feature';
366
392
  await gitClient.tag({ name: '1.0.0' });
367
- sh.exec(`git branch ${developBranchName} ${defaultBranchName}`);
368
- sh.exec(`git checkout -b ${featureBranchPrefix}/first ${developBranchName}`);
393
+ childProcess.execSync(`git branch ${developBranchName} ${defaultBranchName}`, execOpts);
394
+ childProcess.execSync(`git checkout -b ${featureBranchPrefix}/first ${developBranchName}`, execOpts);
369
395
  gitAdd('feature/1', 'file', 'Update file in feature branch (1)');
370
- sh.exec(`git checkout ${developBranchName}`);
371
- sh.exec(`git merge --no-ff ${featureBranchPrefix}/first`);
396
+ childProcess.execSync(`git checkout ${developBranchName}`, execOpts);
397
+ childProcess.execSync(`git merge --no-ff ${featureBranchPrefix}/first`, execOpts);
372
398
  await gitClient.tag({ name: '1.1.0-rc.1' });
373
- sh.exec(`git checkout ${defaultBranchName}`);
374
- sh.exec(`git merge --no-ff ${developBranchName}`);
399
+ childProcess.execSync(`git checkout ${defaultBranchName}`, execOpts);
400
+ childProcess.execSync(`git merge --no-ff ${developBranchName}`, execOpts);
375
401
  await gitClient.tag({ name: '1.1.0' });
376
- sh.exec(`git checkout -b ${featureBranchPrefix}/second ${developBranchName}`);
402
+ childProcess.execSync(`git checkout -b ${featureBranchPrefix}/second ${developBranchName}`, execOpts);
377
403
  gitAdd('feature/2', 'file', 'Update file again, in feature branch (2)');
378
- sh.exec(`git checkout ${developBranchName}`);
379
- sh.exec(`git merge --no-ff ${featureBranchPrefix}/second`);
404
+ childProcess.execSync(`git checkout ${developBranchName}`, execOpts);
405
+ childProcess.execSync(`git merge --no-ff ${featureBranchPrefix}/second`, execOpts);
380
406
  t.is(await gitClient.getLatestTagName(), '1.1.0');
381
407
  }
382
408
 
package/test/npm.js CHANGED
@@ -372,6 +372,7 @@ test('should not publish when `npm version` fails', async t => {
372
372
  const options = { npm };
373
373
  const npmClient = factory(npm, { options });
374
374
  const exec = sinon.stub(npmClient.shell, 'exec').resolves();
375
+
375
376
  exec.withArgs('npm whoami').resolves('john');
376
377
  exec
377
378
  .withArgs(/npm access (list collaborators --json|ls-collaborators) @my-scope\/my-pkg/)
package/test/plugins.js CHANGED
@@ -1,11 +1,12 @@
1
- import { join } from 'node:path';
1
+ import { resolve, join } from 'node:path';
2
+ import childProcess from 'node:child_process';
3
+ import fs, { appendFileSync, mkdirSync } from 'node:fs';
2
4
  import test from 'ava';
3
- import sh from 'shelljs';
4
5
  import sinon from 'sinon';
5
6
  import Log from '../lib/log.js';
6
7
  import Spinner from '../lib/spinner.js';
7
8
  import Config from '../lib/config.js';
8
- import { parseGitUrl } from '../lib/util.js';
9
+ import { execOpts, parseGitUrl } from '../lib/util.js';
9
10
  import runTasks from '../lib/index.js';
10
11
  import MyPlugin from './stub/plugin.js';
11
12
  import ReplacePlugin from './stub/plugin-replace.js';
@@ -39,12 +40,12 @@ const getContainer = options => {
39
40
 
40
41
  test.before(t => {
41
42
  t.timeout(60 * 1000);
42
- sh.exec('npm link');
43
+ childProcess.execSync('npm link', execOpts);
43
44
  });
44
45
 
45
46
  test.serial.beforeEach(t => {
46
47
  const dir = mkTmpDir();
47
- sh.pushd('-q', dir);
48
+ process.chdir(dir);
48
49
  t.context = { dir };
49
50
  });
50
51
 
@@ -56,25 +57,26 @@ test.serial('should instantiate plugins and execute all release-cycle methods',
56
57
  const { dir } = t.context;
57
58
 
58
59
  const pluginDir = mkTmpDir();
59
- sh.pushd('-q', pluginDir);
60
- sh.ShellString(JSON.stringify({ name: 'my-plugin', version: '1.0.0', type: 'module' })).toEnd(
61
- join(pluginDir, 'package.json')
60
+ process.chdir(pluginDir);
61
+
62
+ appendFileSync(
63
+ join(pluginDir, 'package.json'),
64
+ JSON.stringify({ name: 'my-plugin', version: '1.0.0', type: 'module' })
62
65
  );
63
- sh.exec(`npm link release-it`);
66
+ childProcess.execSync(`npm link release-it`, execOpts);
64
67
  const content = "import { Plugin } from 'release-it'; " + MyPlugin.toString() + '; export default MyPlugin;';
65
- sh.ShellString(content).toEnd(join(pluginDir, 'index.js'));
66
68
 
67
- sh.pushd('-q', dir);
68
- sh.mkdir('-p', 'my/plugin');
69
- sh.pushd('-q', 'my/plugin');
70
- sh.ShellString(content).toEnd(join(dir, 'my', 'plugin', 'index.js'));
69
+ appendFileSync(join(pluginDir, 'index.js'), content);
70
+ process.chdir(dir);
71
+ mkdirSync(resolve('my/plugin'), { recursive: true });
72
+ process.chdir('my/plugin');
71
73
 
72
- sh.pushd('-q', dir);
73
- sh.ShellString(JSON.stringify({ name: 'project', version: '1.0.0', type: 'module' })).toEnd(
74
- join(dir, 'package.json')
75
- );
76
- sh.exec(`npm install ${pluginDir}`);
77
- sh.exec(`npm link release-it`);
74
+ appendFileSync(join(dir, 'my', 'plugin', 'index.js'), content);
75
+ process.chdir(dir);
76
+
77
+ appendFileSync(join(dir, 'package.json'), JSON.stringify({ name: 'project', version: '1.0.0', type: 'module' }));
78
+ childProcess.execSync(`npm install ${pluginDir}`, execOpts);
79
+ childProcess.execSync(`npm link release-it`, execOpts);
78
80
 
79
81
  const config = {
80
82
  plugins: {
@@ -125,20 +127,21 @@ test.serial('should instantiate plugins and execute all release-cycle methods fo
125
127
  const { dir } = t.context;
126
128
 
127
129
  const pluginDir = mkTmpDir();
128
- sh.pushd('-q', pluginDir);
129
- sh.ShellString(JSON.stringify({ name: '@scoped/my-plugin', version: '1.0.0', type: 'module' })).toEnd(
130
- join(pluginDir, 'package.json')
130
+ process.chdir(pluginDir);
131
+
132
+ fs.writeFileSync(
133
+ join(pluginDir, 'package.json'),
134
+ JSON.stringify({ name: '@scoped/my-plugin', version: '1.0.0', type: 'module' })
131
135
  );
132
- sh.exec(`npm link release-it`);
136
+ childProcess.execSync(`npm link release-it`, execOpts);
133
137
  const content = "import { Plugin } from 'release-it'; " + MyPlugin.toString() + '; export default MyPlugin;';
134
- sh.ShellString(content).toEnd(join(pluginDir, 'index.js'));
135
138
 
136
- sh.pushd('-q', dir);
137
- sh.ShellString(JSON.stringify({ name: 'project', version: '1.0.0', type: 'module' })).toEnd(
138
- join(dir, 'package.json')
139
- );
140
- sh.exec(`npm install ${pluginDir}`);
141
- sh.exec(`npm link release-it`);
139
+ fs.writeFileSync(join(pluginDir, 'index.js'), content);
140
+ process.chdir(dir);
141
+
142
+ fs.writeFileSync(join(dir, 'package.json'), JSON.stringify({ name: 'project', version: '1.0.0', type: 'module' }));
143
+ childProcess.execSync(`npm install ${pluginDir}`, execOpts);
144
+ childProcess.execSync(`npm link release-it`, execOpts);
142
145
 
143
146
  const config = {
144
147
  plugins: {
@@ -174,11 +177,13 @@ test.serial('should instantiate plugins and execute all release-cycle methods fo
174
177
 
175
178
  test.serial('should disable core plugins', async t => {
176
179
  const { dir } = t.context;
177
- sh.ShellString(JSON.stringify({ name: 'project', version: '1.0.0' })).toEnd(join(dir, 'package.json'));
180
+
181
+ fs.appendFileSync(join(dir, 'package.json'), JSON.stringify({ name: 'project', version: '1.0.0' }));
178
182
  const content =
179
183
  "import { Plugin } from 'release-it'; " + ReplacePlugin.toString() + '; export default ReplacePlugin;';
180
- sh.ShellString(content).toEnd(join(dir, 'replace-plugin.mjs'));
181
- sh.exec(`npm link release-it`);
184
+
185
+ fs.appendFileSync(join(dir, 'replace-plugin.mjs'), content);
186
+ childProcess.execSync(`npm link release-it`, execOpts);
182
187
 
183
188
  const config = {
184
189
  plugins: {
@@ -199,13 +204,13 @@ test.serial('should disable core plugins', async t => {
199
204
 
200
205
  test.serial('should expose context to execute commands', async t => {
201
206
  const { dir } = t.context;
202
- sh.ShellString(JSON.stringify({ name: 'pkg-name', version: '1.0.0', type: 'module' })).toEnd(
203
- join(dir, 'package.json')
204
- );
207
+
208
+ fs.appendFileSync(join(dir, 'package.json'), JSON.stringify({ name: 'pkg-name', version: '1.0.0', type: 'module' }));
205
209
  const content =
206
210
  "import { Plugin } from 'release-it'; " + ContextPlugin.toString() + '; export default ContextPlugin;';
207
- sh.ShellString(content).toEnd(join(dir, 'context-plugin.js'));
208
- sh.exec(`npm link release-it`);
211
+
212
+ fs.appendFileSync(join(dir, 'context-plugin.js'), content);
213
+ childProcess.execSync(`npm link release-it`, execOpts);
209
214
 
210
215
  const repo = parseGitUrl('https://github.com/user/pkg');
211
216
 
package/test/shell.js CHANGED
@@ -1,12 +1,11 @@
1
+ import childProcess from 'node:child_process';
1
2
  import test from 'ava';
2
- import sh from 'shelljs';
3
3
  import sinon from 'sinon';
4
4
  import Shell from '../lib/shell.js';
5
5
  import Log from '../lib/log.js';
6
6
  import { factory } from './util/index.js';
7
7
 
8
- const { stdout } = sh.exec('pwd');
9
- const cwd = stdout.trim();
8
+ const cwd = childProcess.execSync('pwd', { encoding: 'utf8' }).trim();
10
9
 
11
10
  const shell = factory(Shell);
12
11