@j-ulrich/release-it-regex-bumper 3.0.1 → 4.1.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/LICENSE +1 -1
- package/README.md +18 -5
- package/index.js +207 -166
- package/package.json +20 -14
- package/.github/workflows/CI.yml +0 -76
- package/.gitignore +0 -6
- package/.release-it.json +0 -29
- package/CHANGELOG.md +0 -166
- package/test.js +0 -686
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
> Regular expression based version read/write plugin for release-it
|
|
4
4
|
|
|
5
|
-

|
|
6
|
-
[](https://www.codacy.com/
|
|
7
|
-
[](https://www.codacy.com/
|
|
5
|
+
[](https://github.com/j-ulrich/release-it-regex-bumper/actions/workflows/CI.yml)
|
|
6
|
+
[](https://www.codacy.com/gh/j-ulrich/release-it-regex-bumper/dashboard?utm_source=github.com&utm_medium=referral&utm_content=j-ulrich/release-it-regex-bumper&utm_campaign=Badge_Coverage)
|
|
7
|
+
[](https://www.codacy.com/gh/j-ulrich/release-it-regex-bumper/dashboard?utm_source=github.com&utm_medium=referral&utm_content=j-ulrich/release-it-regex-bumper&utm_campaign=Badge_Grade)
|
|
8
8
|
|
|
9
9
|
This [release-it](https://github.com/release-it/release-it) plugin reads and/or writes versions
|
|
10
10
|
using regular expressions.
|
|
@@ -18,6 +18,10 @@ below for details.
|
|
|
18
18
|
|
|
19
19
|
# Installation #
|
|
20
20
|
|
|
21
|
+
> ⚠️ **Note:**
|
|
22
|
+
> Version 4 and later of release-it-regex-bumper require version 15 or later of release-it.
|
|
23
|
+
> When you are using release-it version 14.x or earlier, then use release-it-regex-bumper version 3.x or earlier.
|
|
24
|
+
|
|
21
25
|
```
|
|
22
26
|
npm install --save-dev @j-ulrich/release-it-regex-bumper
|
|
23
27
|
```
|
|
@@ -48,7 +52,7 @@ For example:
|
|
|
48
52
|
}
|
|
49
53
|
```
|
|
50
54
|
|
|
51
|
-
For a more complex example, see [
|
|
55
|
+
For a more complex example, see [here](https://gitlab.com/julrich/MockNetworkAccessManager/-/blob/main/.release-it.json).
|
|
52
56
|
|
|
53
57
|
|
|
54
58
|
## Regular Expressions ##
|
|
@@ -421,9 +425,18 @@ encodings are the ones supported by Node's `fs` module.
|
|
|
421
425
|
|
|
422
426
|
If this option is not defined or set to `null`, the default value is used.
|
|
423
427
|
|
|
428
|
+
## Tips ##
|
|
429
|
+
|
|
430
|
+
### Disable Output via Command-Line Parameter ###
|
|
431
|
+
To completely disable changing any files by the plugin, you can use the command-line parameter `--no-plugins.@j-ulrich/release-it-regex-bumper.out`.
|
|
432
|
+
For example:
|
|
433
|
+
```
|
|
434
|
+
npx release-it --no-plugins.@j-ulrich/release-it-regex-bumper.out
|
|
435
|
+
```
|
|
436
|
+
|
|
424
437
|
|
|
425
438
|
# License #
|
|
426
439
|
|
|
427
|
-
Copyright (c) 2020-
|
|
440
|
+
Copyright (c) 2020-2022 Jochen Ulrich
|
|
428
441
|
|
|
429
442
|
Licensed under [MIT license](LICENSE).
|
package/index.js
CHANGED
|
@@ -1,28 +1,24 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
const
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
const readFile = util.promisify( fs.readFile );
|
|
23
|
-
const writeFile = util.promisify( fs.writeFile );
|
|
24
|
-
|
|
25
|
-
const semanticVersionRegex = XRegExp( /(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)(?:-(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*)?(?:\+[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*)?/ );
|
|
1
|
+
|
|
2
|
+
import { readFile as fsReadFile, writeFile as fsWriteFile } from 'fs';
|
|
3
|
+
import { strict as assert } from 'assert';
|
|
4
|
+
import { promisify } from 'util';
|
|
5
|
+
import glob from 'fast-glob';
|
|
6
|
+
import chalk from 'chalk';
|
|
7
|
+
import _ from 'lodash';
|
|
8
|
+
import XRegExp from 'xregexp';
|
|
9
|
+
import semver from 'semver';
|
|
10
|
+
import { Plugin } from 'release-it';
|
|
11
|
+
import dateFormat from 'date-fns/format/index.js';
|
|
12
|
+
import dateFormatIso from 'date-fns/formatISO/index.js';
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
const readFile = promisify( fsReadFile );
|
|
16
|
+
const writeFile = promisify( fsWriteFile );
|
|
17
|
+
|
|
18
|
+
const semanticVersionRegex = XRegExp(
|
|
19
|
+
// eslint-disable-next-line security/detect-unsafe-regex
|
|
20
|
+
/(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)(?:-(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*)?(?:\+[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*)?/
|
|
21
|
+
);
|
|
26
22
|
const placeholderRegex = XRegExp( '\\{\\{(?<placeholder>(?:[a-z][a-z0-9_]*|\\{))(?::(?<format>.*))?\\}\\}', 'ig' );
|
|
27
23
|
|
|
28
24
|
const prereleasePrefix = '-';
|
|
@@ -35,38 +31,51 @@ const defaultReplace = '{{version}}';
|
|
|
35
31
|
|
|
36
32
|
|
|
37
33
|
|
|
38
|
-
class RegExBumper extends Plugin {
|
|
34
|
+
export default class RegExBumper extends Plugin {
|
|
39
35
|
|
|
40
|
-
constructor(...args) {
|
|
41
|
-
super(...args);
|
|
42
|
-
this.setContext({executionTime: new Date()});
|
|
36
|
+
constructor( ...args ) {
|
|
37
|
+
super( ...args );
|
|
38
|
+
this.setContext( { executionTime: new Date() } );
|
|
43
39
|
}
|
|
44
40
|
|
|
45
41
|
async getLatestVersion() {
|
|
46
42
|
|
|
47
43
|
const { in: inOptions, search: globalSearchOptions, encoding: globalEncoding } = this.options;
|
|
48
44
|
if ( _.isNil( inOptions ) ) {
|
|
49
|
-
return;
|
|
45
|
+
return undefined;
|
|
50
46
|
}
|
|
51
47
|
|
|
52
48
|
const context = Object.assign( {}, this.getContext(), this.config.contextOptions );
|
|
53
49
|
|
|
54
|
-
const {
|
|
55
|
-
|
|
50
|
+
const {
|
|
51
|
+
searchRegex: globalSearchRegex,
|
|
52
|
+
flags: globalSearchFlags,
|
|
53
|
+
versionCaptureGroup: globalVersionCaptureGroup,
|
|
54
|
+
} = parseSearchOptions( globalSearchOptions );
|
|
55
|
+
const { file, encoding, searchRegex, flags: searchFlags, versionCaptureGroup } = parseInOptions( inOptions );
|
|
56
56
|
|
|
57
57
|
const effectiveEncoding = firstNotNil( encoding, globalEncoding, defaultEncoding );
|
|
58
58
|
const fileContent = await readFile( file, { encoding: effectiveEncoding } );
|
|
59
|
-
const effectiveSearchRegex = mergeSearchRegExes(
|
|
59
|
+
const effectiveSearchRegex = mergeSearchRegExes(
|
|
60
|
+
[ searchRegex, globalSearchRegex, defaultSearchRegex ],
|
|
61
|
+
[ searchFlags, globalSearchFlags ]
|
|
62
|
+
);
|
|
60
63
|
const replacedSearchRegex = prepareSearch( effectiveSearchRegex, context );
|
|
61
|
-
const version = await extractVersion
|
|
62
|
-
|
|
64
|
+
const version = await extractVersion(
|
|
65
|
+
fileContent,
|
|
66
|
+
replacedSearchRegex,
|
|
67
|
+
firstNotNil( versionCaptureGroup, globalVersionCaptureGroup, defaultVersionCaptureGroup )
|
|
68
|
+
);
|
|
63
69
|
return version;
|
|
64
70
|
}
|
|
65
71
|
|
|
66
|
-
|
|
67
72
|
async bump( version ) {
|
|
68
|
-
|
|
69
|
-
|
|
73
|
+
const {
|
|
74
|
+
out: outOptions,
|
|
75
|
+
search: globalSearchOptions,
|
|
76
|
+
replace: globalReplace,
|
|
77
|
+
encoding: globalEncoding,
|
|
78
|
+
} = this.options;
|
|
70
79
|
const { isDryRun } = this.config;
|
|
71
80
|
if ( _.isNil( outOptions ) ) {
|
|
72
81
|
return;
|
|
@@ -76,15 +85,21 @@ class RegExBumper extends Plugin {
|
|
|
76
85
|
context.version = version;
|
|
77
86
|
}
|
|
78
87
|
|
|
79
|
-
const { searchRegex: globalSearchRegex, flags: globalSearchFlags } = parseSearchOptions.call(
|
|
88
|
+
const { searchRegex: globalSearchRegex, flags: globalSearchFlags } = parseSearchOptions.call(
|
|
89
|
+
this,
|
|
90
|
+
globalSearchOptions
|
|
91
|
+
);
|
|
80
92
|
const expandedOutOptions = await expandOutOptionFiles.call( this, parseOutOptions.call( this, outOptions ) );
|
|
81
93
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
const { files, encoding, searchRegex, flags: searchFlags, replace } =
|
|
94
|
+
/* eslint-disable no-await-in-loop */
|
|
95
|
+
for ( const outOption of expandedOutOptions ) {
|
|
96
|
+
const { files, encoding, searchRegex, flags: searchFlags, replace } = outOption;
|
|
85
97
|
|
|
86
98
|
const effectiveEncoding = firstNotNil( encoding, globalEncoding, defaultEncoding );
|
|
87
|
-
const effectiveSearchRegex = mergeSearchRegExes(
|
|
99
|
+
const effectiveSearchRegex = mergeSearchRegExes(
|
|
100
|
+
[ searchRegex, globalSearchRegex, defaultSearchRegex ],
|
|
101
|
+
[ searchFlags, globalSearchFlags ]
|
|
102
|
+
);
|
|
88
103
|
const effectiveReplacement = firstNotNil( replace, globalReplace, defaultReplace );
|
|
89
104
|
|
|
90
105
|
const replacedSearchRegex = prepareSearch( effectiveSearchRegex, context );
|
|
@@ -96,26 +111,105 @@ class RegExBumper extends Plugin {
|
|
|
96
111
|
const fileContent = await readFile( file, { encoding: effectiveEncoding } );
|
|
97
112
|
|
|
98
113
|
if ( isDryRun ) {
|
|
99
|
-
loadDiff
|
|
114
|
+
await this.loadDiff();
|
|
100
115
|
if ( this.diff ) {
|
|
101
|
-
const processedFileContent = replaceVersion
|
|
102
|
-
|
|
116
|
+
const processedFileContent = replaceVersion( fileContent, replacedSearchRegex,
|
|
117
|
+
effectiveReplacement, context );
|
|
118
|
+
await this.diffAndReport( fileContent, processedFileContent, file );
|
|
103
119
|
continue;
|
|
104
120
|
}
|
|
105
|
-
await searchAndReport
|
|
121
|
+
await this.searchAndReport( fileContent, replacedSearchRegex, file );
|
|
106
122
|
continue;
|
|
107
123
|
}
|
|
108
124
|
|
|
109
|
-
const processedFileContent = replaceVersion
|
|
125
|
+
const processedFileContent = replaceVersion(
|
|
126
|
+
fileContent,
|
|
127
|
+
replacedSearchRegex,
|
|
128
|
+
effectiveReplacement,
|
|
129
|
+
context
|
|
130
|
+
);
|
|
110
131
|
|
|
111
|
-
if ( processedFileContent
|
|
112
|
-
warnNoFileChange
|
|
132
|
+
if ( processedFileContent === fileContent ) {
|
|
133
|
+
this.warnNoFileChange( file );
|
|
113
134
|
}
|
|
114
135
|
else {
|
|
115
136
|
await writeFile( file, processedFileContent, effectiveEncoding );
|
|
116
137
|
}
|
|
117
138
|
}
|
|
118
139
|
}
|
|
140
|
+
/* eslint-enable no-await-in-loop */
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
async loadDiff() {
|
|
144
|
+
if ( this.diff ) {
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
try {
|
|
148
|
+
const diff = await import( 'diff' );
|
|
149
|
+
if ( !diff || !diff.structuredPatch ) {
|
|
150
|
+
throw new Error( 'diff module no available' );
|
|
151
|
+
}
|
|
152
|
+
this.diff = diff;
|
|
153
|
+
}
|
|
154
|
+
catch ( e ) {
|
|
155
|
+
this.log.info( 'Optional "diff" package not available' );
|
|
156
|
+
this.log.verbose( 'Exception was:', e );
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
diffAndReport( oldContent, newContent, filePath ) {
|
|
161
|
+
const { isDryRun } = this.config;
|
|
162
|
+
const diffResult = this.diff.structuredPatch( filePath, filePath, oldContent, newContent, undefined, undefined,
|
|
163
|
+
{
|
|
164
|
+
context: 0,
|
|
165
|
+
}
|
|
166
|
+
);
|
|
167
|
+
|
|
168
|
+
if ( _.isEmpty( diffResult.hunks ) ) {
|
|
169
|
+
this.warnNoFileChange( filePath );
|
|
170
|
+
}
|
|
171
|
+
diffResult.hunks.forEach( ( hunk ) => {
|
|
172
|
+
this.log.exec(
|
|
173
|
+
`Replacing at line ${hunk.oldStart}:\n` +
|
|
174
|
+
hunk.lines
|
|
175
|
+
.map( ( line ) => {
|
|
176
|
+
const lineText = '\t' + line;
|
|
177
|
+
if ( line.startsWith( '-' ) ) {
|
|
178
|
+
return chalk.red( lineText );
|
|
179
|
+
}
|
|
180
|
+
if ( line.startsWith( '+' ) ) {
|
|
181
|
+
return chalk.green( lineText );
|
|
182
|
+
}
|
|
183
|
+
return lineText;
|
|
184
|
+
} )
|
|
185
|
+
.join( '\n' ),
|
|
186
|
+
{ isDryRun }
|
|
187
|
+
);
|
|
188
|
+
} );
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
searchAndReport( content, searchRegex, filePath ) {
|
|
192
|
+
const { isDryRun } = this.config;
|
|
193
|
+
let foundMatch = false;
|
|
194
|
+
const lineCounter = new LineCounter( content );
|
|
195
|
+
XRegExp.forEach( content, searchRegex, ( match ) => {
|
|
196
|
+
const matchText = match[0];
|
|
197
|
+
const matchIndex = searchRegex.lastIndex - matchText.length;
|
|
198
|
+
this.log.exec(
|
|
199
|
+
`Replacing match at line ${lineCounter.lineOfIndex( matchIndex )}, ` +
|
|
200
|
+
`column ${lineCounter.columnOfIndex( matchIndex )}:\n\t` +
|
|
201
|
+
matchText,
|
|
202
|
+
{ isDryRun }
|
|
203
|
+
);
|
|
204
|
+
foundMatch = true;
|
|
205
|
+
} );
|
|
206
|
+
if ( !foundMatch ) {
|
|
207
|
+
this.warnNoFileChange( filePath );
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
warnNoFileChange( filePath ) {
|
|
212
|
+
this.log.warn( `File "${filePath}" did not change!` );
|
|
119
213
|
}
|
|
120
214
|
|
|
121
215
|
}
|
|
@@ -146,7 +240,7 @@ function parseSearchOptions( options ) {
|
|
|
146
240
|
return { searchRegex, versionCaptureGroup };
|
|
147
241
|
}
|
|
148
242
|
const { pattern, flags, versionCaptureGroup } = options;
|
|
149
|
-
const searchRegex = _.isNil(pattern) ? pattern : XRegExp( pattern, _.isNull( flags ) ? undefined : flags );
|
|
243
|
+
const searchRegex = _.isNil( pattern ) ? pattern : XRegExp( pattern, _.isNull( flags ) ? undefined : flags );
|
|
150
244
|
return { searchRegex, flags, versionCaptureGroup };
|
|
151
245
|
}
|
|
152
246
|
|
|
@@ -156,22 +250,27 @@ function extractVersion( content, versionRegex, versionCaptureGroup ) {
|
|
|
156
250
|
throw new Error( 'Could not extract version from file' );
|
|
157
251
|
}
|
|
158
252
|
if ( !_.isNil( versionCaptureGroup ) ) {
|
|
159
|
-
if( hasOwnProperty( match, versionCaptureGroup ) ) {
|
|
253
|
+
if ( typeof versionCaptureGroup === 'number' && hasOwnProperty( match, versionCaptureGroup ) ) {
|
|
160
254
|
// object injection mitigated by checking hasOwnProperty()
|
|
161
255
|
// eslint-disable-next-line security/detect-object-injection
|
|
162
|
-
return match[
|
|
256
|
+
return match[versionCaptureGroup];
|
|
257
|
+
}
|
|
258
|
+
if ( match.groups && hasOwnProperty( match.groups, versionCaptureGroup ) ) {
|
|
259
|
+
// object injection mitigated by checking hasOwnProperty()
|
|
260
|
+
// eslint-disable-next-line security/detect-object-injection
|
|
261
|
+
return match.groups[versionCaptureGroup];
|
|
163
262
|
}
|
|
164
263
|
}
|
|
165
264
|
else {
|
|
166
|
-
if ( hasOwnProperty( match, 'version' ) ) {
|
|
167
|
-
return match
|
|
265
|
+
if ( match.groups && hasOwnProperty( match.groups, 'version' ) ) {
|
|
266
|
+
return match.groups.version;
|
|
168
267
|
}
|
|
169
268
|
if ( hasOwnProperty( match, 1 ) ) {
|
|
170
|
-
return match[
|
|
269
|
+
return match[1];
|
|
171
270
|
}
|
|
172
271
|
}
|
|
173
272
|
|
|
174
|
-
return match[
|
|
273
|
+
return match[0];
|
|
175
274
|
}
|
|
176
275
|
|
|
177
276
|
function hasOwnProperty( obj, prop ) {
|
|
@@ -179,20 +278,20 @@ function hasOwnProperty( obj, prop ) {
|
|
|
179
278
|
}
|
|
180
279
|
|
|
181
280
|
function parseOutOptions( options ) {
|
|
182
|
-
return _.castArray( options ).map(
|
|
183
|
-
if ( _.isString(
|
|
281
|
+
return _.castArray( options ).map( ( option ) => {
|
|
282
|
+
if ( _.isString( option ) ) {
|
|
184
283
|
return {
|
|
185
|
-
files: [
|
|
284
|
+
files: [ option ],
|
|
186
285
|
encoding: null,
|
|
187
286
|
searchRegex: null,
|
|
188
287
|
replace: null,
|
|
189
288
|
};
|
|
190
289
|
}
|
|
191
|
-
const { encoding, replace } =
|
|
192
|
-
const { searchRegex, flags } = parseSearchOptions(
|
|
193
|
-
const files =
|
|
194
|
-
if(
|
|
195
|
-
files.unshift(
|
|
290
|
+
const { encoding, replace } = option;
|
|
291
|
+
const { searchRegex, flags } = parseSearchOptions( option.search );
|
|
292
|
+
const files = option.files ? _.castArray( option.files ) : [];
|
|
293
|
+
if ( option.file ) {
|
|
294
|
+
files.unshift( option.file );
|
|
196
295
|
}
|
|
197
296
|
return { files, encoding, searchRegex, flags, replace };
|
|
198
297
|
} );
|
|
@@ -215,55 +314,6 @@ async function expandOutOptionFiles( options ) {
|
|
|
215
314
|
return options;
|
|
216
315
|
}
|
|
217
316
|
|
|
218
|
-
function loadDiff() {
|
|
219
|
-
if ( !diff || diff instanceof Error ) {
|
|
220
|
-
this.log.info( 'Optional "diff" package not available' );
|
|
221
|
-
this.log.verbose( 'Exception was:', diff );
|
|
222
|
-
}
|
|
223
|
-
this.diff = diff;
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
function diffAndReport( oldContent, newContent, filePath ) {
|
|
227
|
-
const { isDryRun } = this.config;
|
|
228
|
-
const diffResult = this.diff.structuredPatch( filePath, filePath, oldContent, newContent, undefined, undefined, { context: 0 } );
|
|
229
|
-
|
|
230
|
-
if ( _.isEmpty( diffResult.hunks ) ) {
|
|
231
|
-
warnNoFileChange.call( this, filePath );
|
|
232
|
-
}
|
|
233
|
-
diffResult.hunks.forEach( hunk => {
|
|
234
|
-
this.log.exec( `Replacing at line ${hunk.oldStart}:\n` + hunk.lines.map( line => {
|
|
235
|
-
const lineText = '\t' + line;
|
|
236
|
-
if ( line.startsWith( '-' ) ) {
|
|
237
|
-
return chalk.red( lineText );
|
|
238
|
-
}
|
|
239
|
-
if ( line.startsWith( '+' ) ) {
|
|
240
|
-
return chalk.green( lineText );
|
|
241
|
-
}
|
|
242
|
-
return lineText;
|
|
243
|
-
} ).join( '\n' ), { isDryRun } );
|
|
244
|
-
} );
|
|
245
|
-
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
function searchAndReport( content, searchRegex, filePath ) {
|
|
249
|
-
const { isDryRun } = this.config;
|
|
250
|
-
let foundMatch = false;
|
|
251
|
-
const lineCounter = new LineCounter( content );
|
|
252
|
-
XRegExp.forEach( content, searchRegex, ( match ) => {
|
|
253
|
-
const matchText = match[ 0 ];
|
|
254
|
-
const matchIndex = searchRegex.lastIndex - matchText.length;
|
|
255
|
-
this.log.exec( `Replacing match at line ${lineCounter.lineOfIndex( matchIndex )}, column ${lineCounter.columnOfIndex( matchIndex )}:\n\t` + matchText, { isDryRun } );
|
|
256
|
-
foundMatch = true;
|
|
257
|
-
} );
|
|
258
|
-
if ( !foundMatch ) {
|
|
259
|
-
warnNoFileChange.call( this, filePath );
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
function warnNoFileChange( filePath ) {
|
|
264
|
-
this.log.warn( `File "${filePath}" did not change!` );
|
|
265
|
-
}
|
|
266
|
-
|
|
267
317
|
function mergeSearchRegExes( regExCandidates, flagCandidates ) {
|
|
268
318
|
const searchRegEx = firstNotNil( ...regExCandidates );
|
|
269
319
|
const flags = firstNotNil( ...flagCandidates );
|
|
@@ -273,36 +323,39 @@ function mergeSearchRegExes( regExCandidates, flagCandidates ) {
|
|
|
273
323
|
function prepareSearch( searchRegEx, context ) {
|
|
274
324
|
const pattern = searchRegEx.xregexp.source;
|
|
275
325
|
const placeholderMap = {
|
|
276
|
-
|
|
277
|
-
if( _.isNil( format ) ) {
|
|
326
|
+
now: ( format ) => {
|
|
327
|
+
if ( _.isNil( format ) ) {
|
|
278
328
|
throw new Error( "Missing required parameter 'format' for placeholder {{now}}" );
|
|
279
329
|
}
|
|
280
330
|
return XRegExp.escape( dateFormat( context.executionTime, format ) );
|
|
281
331
|
},
|
|
282
|
-
|
|
332
|
+
semver: `${semanticVersionRegex.xregexp.source || semanticVersionRegex.source}`,
|
|
283
333
|
};
|
|
284
334
|
const parsedVer = semver.parse( context.latestVersion );
|
|
285
|
-
if( parsedVer ) {
|
|
335
|
+
if ( parsedVer ) {
|
|
286
336
|
Object.assign( placeholderMap, {
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
337
|
+
version: XRegExp.escape( parsedVer.raw ),
|
|
338
|
+
major: parsedVer.major,
|
|
339
|
+
minor: parsedVer.minor,
|
|
340
|
+
patch: parsedVer.patch,
|
|
341
|
+
prerelease: XRegExp.escape( parsedVer.prerelease.join( '.' ) ),
|
|
342
|
+
prefixedPrerelease:
|
|
343
|
+
parsedVer.prerelease.length > 0
|
|
344
|
+
? XRegExp.escape( prereleasePrefix + parsedVer.prerelease.join( '.' ) )
|
|
345
|
+
: '',
|
|
346
|
+
build: XRegExp.escape( parsedVer.build.join( '.' ) ),
|
|
347
|
+
prefixedBuild:
|
|
348
|
+
parsedVer.build.length > 0 ? XRegExp.escape( buildPrefix + parsedVer.build.join( '.' ) ) : '',
|
|
349
|
+
versionWithoutBuild: XRegExp.escape( parsedVer.version ),
|
|
350
|
+
versionWithoutPrerelease: XRegExp.escape( `${parsedVer.major}.${parsedVer.minor}.${parsedVer.patch}` ),
|
|
298
351
|
} );
|
|
299
352
|
}
|
|
300
353
|
if ( context.latestTag ) {
|
|
301
|
-
Object.assign( placeholderMap, {
|
|
354
|
+
Object.assign( placeholderMap, { tag: XRegExp.escape( context.latestTag ) } );
|
|
302
355
|
}
|
|
303
356
|
|
|
304
357
|
if ( context.version ) {
|
|
305
|
-
Object.assign( placeholderMap, {
|
|
358
|
+
Object.assign( placeholderMap, { newVersion: XRegExp.escape( context.version ) } );
|
|
306
359
|
}
|
|
307
360
|
|
|
308
361
|
wrapSearchPatternPlaceholders( placeholderMap );
|
|
@@ -311,11 +364,11 @@ function prepareSearch( searchRegEx, context ) {
|
|
|
311
364
|
}
|
|
312
365
|
|
|
313
366
|
function wrapSearchPatternPlaceholders( placeholderMap ) {
|
|
314
|
-
for( const placeholder of Object.keys( placeholderMap ) ) {
|
|
367
|
+
for ( const placeholder of Object.keys( placeholderMap ) ) {
|
|
315
368
|
// object injection mitigated for placeholderMap since placeholder is from Object.keys( placeholderMap )
|
|
316
369
|
// eslint-disable-next-line security/detect-object-injection
|
|
317
370
|
const replacement = placeholderMap[ placeholder ];
|
|
318
|
-
if( _.isFunction( replacement ) ) {
|
|
371
|
+
if ( _.isFunction( replacement ) ) {
|
|
319
372
|
// eslint-disable-next-line security/detect-object-injection
|
|
320
373
|
placeholderMap[ placeholder ] = ( ...args ) => {
|
|
321
374
|
return wrapInRegexGroup( replacement( ...args ) );
|
|
@@ -332,7 +385,7 @@ function wrapInRegexGroup( pattern ) {
|
|
|
332
385
|
}
|
|
333
386
|
|
|
334
387
|
function replaceVersion( content, searchRegex, replace, context ) {
|
|
335
|
-
const processedReplace = prepareReplacement
|
|
388
|
+
const processedReplace = prepareReplacement( replace, context );
|
|
336
389
|
const processedContent = XRegExp.replace( content, searchRegex, processedReplace );
|
|
337
390
|
return processedContent;
|
|
338
391
|
}
|
|
@@ -340,24 +393,25 @@ function replaceVersion( content, searchRegex, replace, context ) {
|
|
|
340
393
|
function prepareReplacement( replace, context ) {
|
|
341
394
|
const parsedVer = semver.parse( context.version );
|
|
342
395
|
const placeholderMap = {
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
'
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
396
|
+
version: parsedVer.raw,
|
|
397
|
+
major: parsedVer.major,
|
|
398
|
+
minor: parsedVer.minor,
|
|
399
|
+
patch: parsedVer.patch,
|
|
400
|
+
prerelease: parsedVer.prerelease.join( '.' ),
|
|
401
|
+
prefixedPrerelease:
|
|
402
|
+
parsedVer.prerelease.length > 0 ? prereleasePrefix + parsedVer.prerelease.join( '.' ) : '',
|
|
403
|
+
build: parsedVer.build.join( '.' ),
|
|
404
|
+
prefixedBuild: parsedVer.build.length > 0 ? buildPrefix + parsedVer.build.join( '.' ) : '',
|
|
405
|
+
versionWithoutBuild: parsedVer.version,
|
|
406
|
+
versionWithoutPrerelease: `${parsedVer.major}.${parsedVer.minor}.${parsedVer.patch}`,
|
|
407
|
+
latestVersion: context.latestVersion || '',
|
|
408
|
+
latestTag: context.latestTag || '',
|
|
409
|
+
now: ( format ) => {
|
|
410
|
+
if ( _.isNil( format ) ) {
|
|
357
411
|
return dateFormatIso( context.executionTime );
|
|
358
412
|
}
|
|
359
413
|
return dateFormat( context.executionTime, format );
|
|
360
|
-
}
|
|
414
|
+
},
|
|
361
415
|
};
|
|
362
416
|
return replacePlaceholders( replace, placeholderMap );
|
|
363
417
|
}
|
|
@@ -381,34 +435,22 @@ function replacePlaceholders( template, placeholderMap ) {
|
|
|
381
435
|
} );
|
|
382
436
|
}
|
|
383
437
|
|
|
384
|
-
|
|
385
|
-
function optionalRequire( packageName ) {
|
|
386
|
-
try {
|
|
387
|
-
// eslint-disable-next-line security/detect-non-literal-require
|
|
388
|
-
return require( packageName );
|
|
389
|
-
}
|
|
390
|
-
/* c8 ignore next 4 */
|
|
391
|
-
/* rewiremock can't simulate the absence of a package so we can't test this case */
|
|
392
|
-
catch ( ex ) {
|
|
393
|
-
return ex;
|
|
394
|
-
}
|
|
395
|
-
}
|
|
396
|
-
|
|
397
438
|
function firstNotNil( ...args ) {
|
|
398
|
-
return args.find( ele => !_.isNil( ele ) );
|
|
439
|
+
return args.find( ( ele ) => !_.isNil( ele ) );
|
|
399
440
|
}
|
|
400
441
|
|
|
401
442
|
class LineCounter {
|
|
402
443
|
constructor( text ) {
|
|
403
444
|
let index = 0;
|
|
404
|
-
this.lineEndIndex = text.split( '\n' ).map( line => {
|
|
445
|
+
this.lineEndIndex = text.split( '\n' ).map( ( line ) => {
|
|
405
446
|
index += line.length + 1;
|
|
406
447
|
return index;
|
|
407
448
|
} );
|
|
408
449
|
}
|
|
409
450
|
|
|
410
451
|
lineOfIndex( index ) {
|
|
411
|
-
|
|
452
|
+
// eslint-disable-next-line no-extra-parens
|
|
453
|
+
const arrayIndex = this.lineEndIndex.findIndex( ( lineEndIndex ) => index <= lineEndIndex );
|
|
412
454
|
assert( arrayIndex >= 0 );
|
|
413
455
|
return arrayIndex + 1;
|
|
414
456
|
}
|
|
@@ -425,4 +467,3 @@ class LineCounter {
|
|
|
425
467
|
}
|
|
426
468
|
}
|
|
427
469
|
|
|
428
|
-
module.exports = RegExBumper;
|
package/package.json
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@j-ulrich/release-it-regex-bumper",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.1.0",
|
|
4
4
|
"description": "Regular expression based version read/write plugin for release-it",
|
|
5
5
|
"main": "index.js",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"files": [
|
|
8
|
+
"index.js"
|
|
9
|
+
],
|
|
6
10
|
"scripts": {
|
|
7
|
-
"test": "
|
|
8
|
-
"test+coverage": "npx c8
|
|
11
|
+
"test": "node --experimental-loader=testdouble ./node_modules/ava/entrypoints/cli.mjs --serial",
|
|
12
|
+
"test+coverage": "npx c8 node --experimental-loader=testdouble ./node_modules/ava/entrypoints/cli.mjs --serial",
|
|
9
13
|
"lint": "npx eslint .",
|
|
10
14
|
"release": "npx release-it"
|
|
11
15
|
},
|
|
@@ -35,30 +39,32 @@
|
|
|
35
39
|
"name": "Jochen Ulrich"
|
|
36
40
|
},
|
|
37
41
|
"dependencies": {
|
|
38
|
-
"chalk": "^
|
|
42
|
+
"chalk": "^5.0.0",
|
|
39
43
|
"date-fns": "^2.8.0",
|
|
40
44
|
"fast-glob": "^3.2.0",
|
|
41
45
|
"lodash": "^4.17.20",
|
|
42
46
|
"semver": "^7.3.0",
|
|
43
|
-
"xregexp": "^
|
|
47
|
+
"xregexp": "^5.0.0"
|
|
44
48
|
},
|
|
45
49
|
"peerDependencies": {
|
|
46
|
-
"release-it": "
|
|
50
|
+
"release-it": "15"
|
|
47
51
|
},
|
|
48
52
|
"optionalDependencies": {
|
|
49
|
-
"diff": "
|
|
53
|
+
"diff": "3 - 5"
|
|
50
54
|
},
|
|
51
55
|
"devDependencies": {
|
|
52
|
-
"
|
|
56
|
+
"@j-ulrich/eslint-config": "^1.0.0",
|
|
57
|
+
"@release-it/keep-a-changelog": "^3.0.0",
|
|
58
|
+
"ava": "^4.0.1",
|
|
53
59
|
"c8": "^7.3.0",
|
|
54
|
-
"eslint": "^8.0
|
|
60
|
+
"eslint": "^8.6.0",
|
|
55
61
|
"eslint-plugin-security": "^1.4.0",
|
|
56
|
-
"
|
|
57
|
-
"
|
|
58
|
-
"
|
|
59
|
-
"
|
|
62
|
+
"release-it": "^15.0.0",
|
|
63
|
+
"sinon": "^13.0.2",
|
|
64
|
+
"temp": "^0.9.4",
|
|
65
|
+
"testdouble": "^3.16.4"
|
|
60
66
|
},
|
|
61
67
|
"engines": {
|
|
62
|
-
"node": ">=
|
|
68
|
+
"node": ">=14.9"
|
|
63
69
|
}
|
|
64
70
|
}
|