release-it 19.0.0-next.0 → 19.0.0-next.2

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/util.js CHANGED
@@ -1,25 +1,57 @@
1
1
  import fs, { close, openSync, statSync, utimesSync, accessSync } from 'node:fs'; // need import fs here due to test stubbing
2
2
  import util from 'node:util';
3
3
  import { EOL } from 'node:os';
4
- import _ from 'lodash';
5
4
  import gitUrlParse from 'git-url-parse';
6
5
  import semver from 'semver';
7
6
  import osName from 'os-name';
7
+ import { Eta } from 'eta';
8
8
  import Log from './log.js';
9
9
 
10
+ const debug = util.debug('release-it:shell');
11
+
12
+ const eta = new Eta({
13
+ autoEscape: false,
14
+ useWith: true,
15
+ tags: ['${', '}'],
16
+ parse: { interpolate: '' },
17
+ rmWhitespace: false,
18
+ autoTrim: false
19
+ });
20
+ const wait = ms => new Promise(resolve => setTimeout(resolve, ms));
21
+ const before = (n, func) => {
22
+ var result;
23
+ if (typeof func != 'function') {
24
+ throw new TypeError('Missing argument for `func`');
25
+ }
26
+ n = parseInt(n);
27
+ return function () {
28
+ if (--n > 0) {
29
+ result = func.apply(this, arguments);
30
+ }
31
+ if (n <= 1) {
32
+ func = undefined;
33
+ }
34
+ return result;
35
+ };
36
+ };
37
+ const tryStatFile = filePath => {
38
+ try {
39
+ return statSync(filePath);
40
+ } catch (e) {
41
+ debug(e);
42
+ return null;
43
+ }
44
+ };
45
+
10
46
  export const execOpts = {
11
47
  stdio: process.env.NODE_DEBUG && process.env.NODE_DEBUG.indexOf('release-it') === 0 ? 'pipe' : []
12
48
  };
13
49
 
14
- const debug = util.debug('release-it:shell');
15
-
16
- const readJSON = file => JSON.parse(fs.readFileSync(file, 'utf8'));
50
+ export const readJSON = file => JSON.parse(fs.readFileSync(file, 'utf8'));
17
51
 
18
52
  const pkg = readJSON(new URL('../package.json', import.meta.url));
19
53
 
20
- const log = new Log();
21
-
22
- const getSystemInfo = () => {
54
+ export const getSystemInfo = () => {
23
55
  return {
24
56
  'release-it': pkg.version,
25
57
  node: process.version,
@@ -27,9 +59,11 @@ const getSystemInfo = () => {
27
59
  };
28
60
  };
29
61
 
30
- const format = (template = '', context = {}) => {
62
+ export const format = (template = '', context = {}) => {
63
+ if (!context || context === null || !template || template === null || template.indexOf('${') === -1) return template;
64
+ const log = new Log();
31
65
  try {
32
- return _.template(template)(context);
66
+ return eta.renderString(template, context);
33
67
  } catch (error) {
34
68
  log.error(`Unable to render template with context:\n${template}\n${JSON.stringify(context)}`);
35
69
  log.error(error);
@@ -37,21 +71,19 @@ const format = (template = '', context = {}) => {
37
71
  }
38
72
  };
39
73
 
40
- const truncateLines = (input, maxLines = 10, surplusText = null) => {
74
+ export const truncateLines = (input, maxLines = 10, surplusText = null) => {
41
75
  const lines = input.split(EOL);
42
76
  const surplus = lines.length - maxLines;
43
77
  const output = lines.slice(0, maxLines).join(EOL);
44
78
  return surplus > 0 ? (surplusText ? `${output}${surplusText}` : `${output}${EOL}...and ${surplus} more`) : output;
45
79
  };
46
80
 
47
- const wait = ms => new Promise(resolve => setTimeout(resolve, ms));
48
-
49
- const rejectAfter = (ms, error) =>
81
+ export const rejectAfter = (ms, error) =>
50
82
  wait(ms).then(() => {
51
83
  throw error;
52
84
  });
53
85
 
54
- const parseGitUrl = remoteUrl => {
86
+ export const parseGitUrl = remoteUrl => {
55
87
  if (!remoteUrl) return { host: null, owner: null, project: null, protocol: null, remote: null, repository: null };
56
88
  const normalizedUrl = (remoteUrl || '')
57
89
  .replace(/^[A-Z]:\\\\/, 'file://') // Assume file protocol for Windows drive letters
@@ -59,12 +91,12 @@ const parseGitUrl = remoteUrl => {
59
91
  .replace(/\\+/g, '/'); // Replace forward with backslashes
60
92
  const parsedUrl = gitUrlParse(normalizedUrl);
61
93
  const { resource: host, name: project, protocol, href: remote } = parsedUrl;
62
- const owner = protocol === 'file' ? _.last(parsedUrl.owner.split('/')) : parsedUrl.owner; // Fix owner for file protocol
94
+ const owner = protocol === 'file' ? parsedUrl.owner.split('/').at(-1) : parsedUrl.owner; // Fix owner for file protocol
63
95
  const repository = `${owner}/${project}`;
64
96
  return { host, owner, project, protocol, remote, repository };
65
97
  };
66
98
 
67
- const reduceUntil = async (collection, fn) => {
99
+ export const reduceUntil = async (collection, fn) => {
68
100
  let result;
69
101
  for (const item of collection) {
70
102
  if (result) break;
@@ -73,7 +105,7 @@ const reduceUntil = async (collection, fn) => {
73
105
  return result;
74
106
  };
75
107
 
76
- const hasAccess = path => {
108
+ export const hasAccess = path => {
77
109
  try {
78
110
  accessSync(path);
79
111
  return true;
@@ -82,7 +114,7 @@ const hasAccess = path => {
82
114
  }
83
115
  };
84
116
 
85
- const parseVersion = raw => {
117
+ export const parseVersion = raw => {
86
118
  if (raw == null) return { version: raw, isPreRelease: false, preReleaseId: null };
87
119
  const version = semver.valid(raw) ? raw : semver.coerce(raw);
88
120
  if (!version) return { version: raw, isPreRelease: false, preReleaseId: null };
@@ -96,14 +128,14 @@ const parseVersion = raw => {
96
128
  };
97
129
  };
98
130
 
99
- const e = (message, docs, fail = true) => {
131
+ export const e = (message, docs, fail = true) => {
100
132
  const error = new Error(docs ? `${message}${EOL}Documentation: ${docs}${EOL}` : message);
101
133
  error.code = fail ? 1 : 0;
102
134
  error.cause = fail ? 'ERROR' : 'INFO';
103
135
  return error;
104
136
  };
105
137
 
106
- const touch = (path, callback) => {
138
+ export const touch = (path, callback) => {
107
139
  const stat = tryStatFile(path);
108
140
  if (stat && stat.isDirectory()) {
109
141
  // don't error just exit
@@ -121,28 +153,25 @@ const touch = (path, callback) => {
121
153
  }
122
154
  };
123
155
 
124
- const tryStatFile = filePath => {
125
- try {
126
- return statSync(filePath);
127
- } catch (e) {
128
- debug(e);
129
- return null;
130
- }
156
+ export const fixArgs = args => (args ? (typeof args === 'string' ? args.split(' ') : args) : []);
157
+
158
+ export const upperFirst = string => {
159
+ return string ? string.charAt(0).toUpperCase() + string.slice(1) : '';
160
+ };
161
+
162
+ export const castArray = arr => {
163
+ return Array.isArray(arr) ? arr : [arr];
164
+ };
165
+
166
+ export const once = fn => {
167
+ return before(2, fn);
131
168
  };
132
169
 
133
- const fixArgs = args => (args ? (typeof args === 'string' ? args.split(' ') : args) : []);
134
-
135
- export {
136
- getSystemInfo,
137
- format,
138
- truncateLines,
139
- rejectAfter,
140
- reduceUntil,
141
- parseGitUrl,
142
- hasAccess,
143
- parseVersion,
144
- readJSON,
145
- fixArgs,
146
- e,
147
- touch
170
+ export const pick = (object, keys) => {
171
+ return keys.reduce((obj, key) => {
172
+ if (object && Object.prototype.hasOwnProperty.call(object, key)) {
173
+ obj[key] = object[key];
174
+ }
175
+ return obj;
176
+ }, {});
148
177
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "release-it",
3
- "version": "19.0.0-next.0",
3
+ "version": "19.0.0-next.2",
4
4
  "description": "Generic CLI tool to automate versioning and package publishing-related tasks.",
5
5
  "keywords": [
6
6
  "build",
@@ -48,9 +48,9 @@
48
48
  "type": "module",
49
49
  "exports": {
50
50
  ".": {
51
+ "types": "./types/index.d.ts",
51
52
  "import": "./lib/index.js",
52
- "require": "./lib/index.js",
53
- "types": "./types/index.d.ts"
53
+ "require": "./lib/index.js"
54
54
  },
55
55
  "./package.json": "./package.json",
56
56
  "./test/util/index.js": "./test/util/index.js"
@@ -69,7 +69,7 @@
69
69
  "lint": "eslint lib test",
70
70
  "format": "prettier --write eslint.config.mjs \"{lib,test}/**/*.js\"",
71
71
  "docs": "remark README.md 'docs/**/*.md' '.github/*.md' -o",
72
- "test": "ava --no-worker-threads && installed-check --ignore ava --ignore nock",
72
+ "test": "node --env-file=.env.test --test && installed-check",
73
73
  "release": "./bin/release-it.js"
74
74
  },
75
75
  "author": {
@@ -79,17 +79,21 @@
79
79
  "license": "MIT",
80
80
  "dependencies": {
81
81
  "@iarna/toml": "2.2.5",
82
- "@octokit/rest": "21.1.0",
82
+ "@nodeutils/defaults-deep": "1.1.0",
83
+ "@octokit/rest": "21.1.1",
84
+ "@phun-ky/typeof": "1.2.3",
83
85
  "async-retry": "1.3.3",
84
86
  "chalk": "5.4.1",
85
- "ci-info": "^4.1.0",
87
+ "ci-info": "^4.2.0",
86
88
  "cosmiconfig": "9.0.0",
89
+ "eta": "3.5.0",
87
90
  "execa": "9.5.2",
88
- "git-url-parse": "16.0.0",
91
+ "git-url-parse": "16.0.1",
89
92
  "globby": "14.1.0",
90
- "inquirer": "12.4.1",
93
+ "inquirer": "12.5.0",
91
94
  "issue-parser": "7.0.1",
92
- "lodash": "4.17.21",
95
+ "lodash.get": "4.4.2",
96
+ "lodash.merge": "4.6.2",
93
97
  "mime-types": "2.1.35",
94
98
  "new-github-release-url": "2.0.0",
95
99
  "open": "10.1.0",
@@ -104,30 +108,24 @@
104
108
  "yargs-parser": "21.1.1"
105
109
  },
106
110
  "devDependencies": {
107
- "@eslint/compat": "1.2.6",
108
- "@eslint/eslintrc": "3.2.0",
109
- "@eslint/js": "9.20.0",
110
- "@octokit/request-error": "6.1.6",
111
- "@types/node": "20.17.17",
112
- "ava": "6.2.0",
113
- "eslint": "9.20.1",
114
- "eslint-config-prettier": "10.0.1",
115
- "eslint-plugin-ava": "15.0.1",
116
- "eslint-plugin-import-x": "4.6.1",
117
- "eslint-plugin-prettier": "5.2.3",
118
- "fs-monkey": "1.0.6",
119
- "globals": "15.14.0",
111
+ "@eslint/compat": "1.2.7",
112
+ "@eslint/eslintrc": "3.3.1",
113
+ "@eslint/js": "9.23.0",
114
+ "@octokit/request-error": "6.1.7",
115
+ "@types/node": "20.17.24",
116
+ "eslint": "9.23.0",
117
+ "eslint-config-prettier": "10.1.1",
118
+ "eslint-plugin-import-x": "4.9.3",
119
+ "eslint-plugin-prettier": "5.2.5",
120
+ "globals": "16.0.0",
120
121
  "installed-check": "9.3.0",
121
- "knip": "5.44.0",
122
- "memfs": "4.17.0",
122
+ "knip": "5.46.1",
123
+ "mentoss": "0.9.0",
123
124
  "mock-stdio": "1.0.3",
124
- "nock": "14.0.1",
125
- "prettier": "3.5.0",
125
+ "prettier": "3.5.3",
126
126
  "remark-cli": "12.0.1",
127
127
  "remark-preset-webpro": "1.1.1",
128
- "sinon": "19.0.2",
129
- "strip-ansi": "7.1.0",
130
- "typescript": "5.7.3"
128
+ "typescript": "5.8.2"
131
129
  },
132
130
  "overrides": {
133
131
  "pac-resolver": "7.0.1",
@@ -46,6 +46,10 @@
46
46
  "certificateAuthorityFile": {
47
47
  "default": null
48
48
  },
49
+ "certificateAuthorityFileRef": {
50
+ "type": "string",
51
+ "default": "CI_SERVER_TLS_CA_FILE"
52
+ },
49
53
  "secure": {
50
54
  "default": null
51
55
  },
@@ -9,6 +9,10 @@
9
9
  "type": "string",
10
10
  "description": "The JSON schema version used to validate this configuration file"
11
11
  },
12
+ "extends": {
13
+ "type": "string",
14
+ "description": "URL that specifies a configuration to extend"
15
+ },
12
16
  "hooks": {
13
17
  "type": "object",
14
18
  "additionalProperties": true,
package/test/cli.js CHANGED
@@ -1,20 +1,21 @@
1
- import test from 'ava';
1
+ import test from 'node:test';
2
+ import assert from 'node:assert/strict';
2
3
  import mockStdIo from 'mock-stdio';
3
4
  import { version, help } from '../lib/cli.js';
4
5
  import { readJSON } from '../lib/util.js';
5
6
 
6
7
  const pkg = readJSON(new URL('../package.json', import.meta.url));
7
8
 
8
- test('should print version', t => {
9
+ test('should print version', () => {
9
10
  mockStdIo.start();
10
11
  version();
11
12
  const { stdout } = mockStdIo.end();
12
- t.is(stdout, `v${pkg.version}\n`);
13
+ assert.equal(stdout, `v${pkg.version}\n`);
13
14
  });
14
15
 
15
- test('should print help', t => {
16
+ test('should print help', () => {
16
17
  mockStdIo.start();
17
18
  help();
18
19
  const { stdout } = mockStdIo.end();
19
- t.regex(stdout, RegExp(`Release It!.+${pkg.version}`));
20
+ assert.match(stdout, new RegExp(`Release It!.+${pkg.version}`));
20
21
  });