@j-ulrich/release-it-regex-bumper 3.0.1 → 3.0.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/LICENSE +1 -1
- package/README.md +13 -4
- package/index.js +177 -128
- package/package.json +9 -3
- 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
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
> Regular expression based version read/write plugin for release-it
|
|
4
4
|
|
|
5
5
|

|
|
6
|
-
[](https://www.codacy.com/
|
|
7
|
-
[](https://www.codacy.com/
|
|
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.
|
|
@@ -48,7 +48,7 @@ For example:
|
|
|
48
48
|
}
|
|
49
49
|
```
|
|
50
50
|
|
|
51
|
-
For a more complex example, see [
|
|
51
|
+
For a more complex example, see [here](https://gitlab.com/julrich/MockNetworkAccessManager/-/blob/main/.release-it.json).
|
|
52
52
|
|
|
53
53
|
|
|
54
54
|
## Regular Expressions ##
|
|
@@ -421,9 +421,18 @@ encodings are the ones supported by Node's `fs` module.
|
|
|
421
421
|
|
|
422
422
|
If this option is not defined or set to `null`, the default value is used.
|
|
423
423
|
|
|
424
|
+
## Tips ##
|
|
425
|
+
|
|
426
|
+
### Disable Output via Command-Line Parameter ###
|
|
427
|
+
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`.
|
|
428
|
+
For example:
|
|
429
|
+
```
|
|
430
|
+
npx release-it --no-plugins.@j-ulrich/release-it-regex-bumper.out
|
|
431
|
+
```
|
|
432
|
+
|
|
424
433
|
|
|
425
434
|
# License #
|
|
426
435
|
|
|
427
|
-
Copyright (c) 2020-
|
|
436
|
+
Copyright (c) 2020-2022 Jochen Ulrich
|
|
428
437
|
|
|
429
438
|
Licensed under [MIT license](LICENSE).
|
package/index.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
1
3
|
const fs = require( 'fs' );
|
|
2
4
|
const assert = require( 'assert' ).strict;
|
|
3
5
|
const util = require( 'util' );
|
|
@@ -9,7 +11,7 @@ const _ = {
|
|
|
9
11
|
isNull: require( 'lodash/isNull' ),
|
|
10
12
|
isString: require( 'lodash/isString' ),
|
|
11
13
|
isFunction: require( 'lodash/isFunction' ),
|
|
12
|
-
castArray: require( 'lodash/castArray' )
|
|
14
|
+
castArray: require( 'lodash/castArray' ),
|
|
13
15
|
};
|
|
14
16
|
const XRegExp = require( 'xregexp' );
|
|
15
17
|
const semver = require( 'semver' );
|
|
@@ -22,7 +24,10 @@ const diff = optionalRequire( 'diff' );
|
|
|
22
24
|
const readFile = util.promisify( fs.readFile );
|
|
23
25
|
const writeFile = util.promisify( fs.writeFile );
|
|
24
26
|
|
|
25
|
-
const semanticVersionRegex = XRegExp(
|
|
27
|
+
const semanticVersionRegex = XRegExp(
|
|
28
|
+
// eslint-disable-next-line security/detect-unsafe-regex
|
|
29
|
+
/(?: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-]+)*)?/
|
|
30
|
+
);
|
|
26
31
|
const placeholderRegex = XRegExp( '\\{\\{(?<placeholder>(?:[a-z][a-z0-9_]*|\\{))(?::(?<format>.*))?\\}\\}', 'ig' );
|
|
27
32
|
|
|
28
33
|
const prereleasePrefix = '-';
|
|
@@ -37,36 +42,49 @@ const defaultReplace = '{{version}}';
|
|
|
37
42
|
|
|
38
43
|
class RegExBumper extends Plugin {
|
|
39
44
|
|
|
40
|
-
constructor(...args) {
|
|
41
|
-
super(...args);
|
|
42
|
-
this.setContext({executionTime: new Date()});
|
|
45
|
+
constructor( ...args ) {
|
|
46
|
+
super( ...args );
|
|
47
|
+
this.setContext( { executionTime: new Date() } );
|
|
43
48
|
}
|
|
44
49
|
|
|
45
50
|
async getLatestVersion() {
|
|
46
51
|
|
|
47
52
|
const { in: inOptions, search: globalSearchOptions, encoding: globalEncoding } = this.options;
|
|
48
53
|
if ( _.isNil( inOptions ) ) {
|
|
49
|
-
return;
|
|
54
|
+
return undefined;
|
|
50
55
|
}
|
|
51
56
|
|
|
52
57
|
const context = Object.assign( {}, this.getContext(), this.config.contextOptions );
|
|
53
58
|
|
|
54
|
-
const {
|
|
55
|
-
|
|
59
|
+
const {
|
|
60
|
+
searchRegex: globalSearchRegex,
|
|
61
|
+
flags: globalSearchFlags,
|
|
62
|
+
versionCaptureGroup: globalVersionCaptureGroup,
|
|
63
|
+
} = parseSearchOptions( globalSearchOptions );
|
|
64
|
+
const { file, encoding, searchRegex, flags: searchFlags, versionCaptureGroup } = parseInOptions( inOptions );
|
|
56
65
|
|
|
57
66
|
const effectiveEncoding = firstNotNil( encoding, globalEncoding, defaultEncoding );
|
|
58
67
|
const fileContent = await readFile( file, { encoding: effectiveEncoding } );
|
|
59
|
-
const effectiveSearchRegex = mergeSearchRegExes(
|
|
68
|
+
const effectiveSearchRegex = mergeSearchRegExes(
|
|
69
|
+
[ searchRegex, globalSearchRegex, defaultSearchRegex ],
|
|
70
|
+
[ searchFlags, globalSearchFlags ]
|
|
71
|
+
);
|
|
60
72
|
const replacedSearchRegex = prepareSearch( effectiveSearchRegex, context );
|
|
61
|
-
const version = await extractVersion
|
|
62
|
-
|
|
73
|
+
const version = await extractVersion(
|
|
74
|
+
fileContent,
|
|
75
|
+
replacedSearchRegex,
|
|
76
|
+
firstNotNil( versionCaptureGroup, globalVersionCaptureGroup, defaultVersionCaptureGroup )
|
|
77
|
+
);
|
|
63
78
|
return version;
|
|
64
79
|
}
|
|
65
80
|
|
|
66
|
-
|
|
67
81
|
async bump( version ) {
|
|
68
|
-
|
|
69
|
-
|
|
82
|
+
const {
|
|
83
|
+
out: outOptions,
|
|
84
|
+
search: globalSearchOptions,
|
|
85
|
+
replace: globalReplace,
|
|
86
|
+
encoding: globalEncoding,
|
|
87
|
+
} = this.options;
|
|
70
88
|
const { isDryRun } = this.config;
|
|
71
89
|
if ( _.isNil( outOptions ) ) {
|
|
72
90
|
return;
|
|
@@ -76,15 +94,21 @@ class RegExBumper extends Plugin {
|
|
|
76
94
|
context.version = version;
|
|
77
95
|
}
|
|
78
96
|
|
|
79
|
-
const { searchRegex: globalSearchRegex, flags: globalSearchFlags } = parseSearchOptions.call(
|
|
97
|
+
const { searchRegex: globalSearchRegex, flags: globalSearchFlags } = parseSearchOptions.call(
|
|
98
|
+
this,
|
|
99
|
+
globalSearchOptions
|
|
100
|
+
);
|
|
80
101
|
const expandedOutOptions = await expandOutOptionFiles.call( this, parseOutOptions.call( this, outOptions ) );
|
|
81
102
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
const { files, encoding, searchRegex, flags: searchFlags, replace } =
|
|
103
|
+
/* eslint-disable no-await-in-loop */
|
|
104
|
+
for ( const outOption of expandedOutOptions ) {
|
|
105
|
+
const { files, encoding, searchRegex, flags: searchFlags, replace } = outOption;
|
|
85
106
|
|
|
86
107
|
const effectiveEncoding = firstNotNil( encoding, globalEncoding, defaultEncoding );
|
|
87
|
-
const effectiveSearchRegex = mergeSearchRegExes(
|
|
108
|
+
const effectiveSearchRegex = mergeSearchRegExes(
|
|
109
|
+
[ searchRegex, globalSearchRegex, defaultSearchRegex ],
|
|
110
|
+
[ searchFlags, globalSearchFlags ]
|
|
111
|
+
);
|
|
88
112
|
const effectiveReplacement = firstNotNil( replace, globalReplace, defaultReplace );
|
|
89
113
|
|
|
90
114
|
const replacedSearchRegex = prepareSearch( effectiveSearchRegex, context );
|
|
@@ -96,26 +120,96 @@ class RegExBumper extends Plugin {
|
|
|
96
120
|
const fileContent = await readFile( file, { encoding: effectiveEncoding } );
|
|
97
121
|
|
|
98
122
|
if ( isDryRun ) {
|
|
99
|
-
loadDiff
|
|
123
|
+
this.loadDiff();
|
|
100
124
|
if ( this.diff ) {
|
|
101
|
-
const processedFileContent = replaceVersion
|
|
102
|
-
|
|
125
|
+
const processedFileContent = replaceVersion( fileContent, replacedSearchRegex,
|
|
126
|
+
effectiveReplacement, context );
|
|
127
|
+
await this.diffAndReport( fileContent, processedFileContent, file );
|
|
103
128
|
continue;
|
|
104
129
|
}
|
|
105
|
-
await searchAndReport
|
|
130
|
+
await this.searchAndReport( fileContent, replacedSearchRegex, file );
|
|
106
131
|
continue;
|
|
107
132
|
}
|
|
108
133
|
|
|
109
|
-
const processedFileContent = replaceVersion
|
|
134
|
+
const processedFileContent = replaceVersion(
|
|
135
|
+
fileContent,
|
|
136
|
+
replacedSearchRegex,
|
|
137
|
+
effectiveReplacement,
|
|
138
|
+
context
|
|
139
|
+
);
|
|
110
140
|
|
|
111
|
-
if ( processedFileContent
|
|
112
|
-
warnNoFileChange
|
|
141
|
+
if ( processedFileContent === fileContent ) {
|
|
142
|
+
this.warnNoFileChange( file );
|
|
113
143
|
}
|
|
114
144
|
else {
|
|
115
145
|
await writeFile( file, processedFileContent, effectiveEncoding );
|
|
116
146
|
}
|
|
117
147
|
}
|
|
118
148
|
}
|
|
149
|
+
/* eslint-enable no-await-in-loop */
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
loadDiff() {
|
|
153
|
+
if ( !diff || diff instanceof Error ) {
|
|
154
|
+
this.log.info( 'Optional "diff" package not available' );
|
|
155
|
+
this.log.verbose( 'Exception was:', diff );
|
|
156
|
+
}
|
|
157
|
+
this.diff = diff;
|
|
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,22 @@ 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 ( 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];
|
|
163
257
|
}
|
|
164
258
|
}
|
|
165
259
|
else {
|
|
166
260
|
if ( hasOwnProperty( match, 'version' ) ) {
|
|
167
|
-
return match[
|
|
261
|
+
return match['version'];
|
|
168
262
|
}
|
|
169
263
|
if ( hasOwnProperty( match, 1 ) ) {
|
|
170
|
-
return match[
|
|
264
|
+
return match[1];
|
|
171
265
|
}
|
|
172
266
|
}
|
|
173
267
|
|
|
174
|
-
return match[
|
|
268
|
+
return match[0];
|
|
175
269
|
}
|
|
176
270
|
|
|
177
271
|
function hasOwnProperty( obj, prop ) {
|
|
@@ -179,20 +273,20 @@ function hasOwnProperty( obj, prop ) {
|
|
|
179
273
|
}
|
|
180
274
|
|
|
181
275
|
function parseOutOptions( options ) {
|
|
182
|
-
return _.castArray( options ).map(
|
|
183
|
-
if ( _.isString(
|
|
276
|
+
return _.castArray( options ).map( ( option ) => {
|
|
277
|
+
if ( _.isString( option ) ) {
|
|
184
278
|
return {
|
|
185
|
-
files: [
|
|
279
|
+
files: [ option ],
|
|
186
280
|
encoding: null,
|
|
187
281
|
searchRegex: null,
|
|
188
282
|
replace: null,
|
|
189
283
|
};
|
|
190
284
|
}
|
|
191
|
-
const { encoding, replace } =
|
|
192
|
-
const { searchRegex, flags } = parseSearchOptions(
|
|
193
|
-
const files =
|
|
194
|
-
if(
|
|
195
|
-
files.unshift(
|
|
285
|
+
const { encoding, replace } = option;
|
|
286
|
+
const { searchRegex, flags } = parseSearchOptions( option.search );
|
|
287
|
+
const files = option.files ? _.castArray( option.files ) : [];
|
|
288
|
+
if ( option.file ) {
|
|
289
|
+
files.unshift( option.file );
|
|
196
290
|
}
|
|
197
291
|
return { files, encoding, searchRegex, flags, replace };
|
|
198
292
|
} );
|
|
@@ -215,55 +309,6 @@ async function expandOutOptionFiles( options ) {
|
|
|
215
309
|
return options;
|
|
216
310
|
}
|
|
217
311
|
|
|
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
312
|
function mergeSearchRegExes( regExCandidates, flagCandidates ) {
|
|
268
313
|
const searchRegEx = firstNotNil( ...regExCandidates );
|
|
269
314
|
const flags = firstNotNil( ...flagCandidates );
|
|
@@ -273,36 +318,39 @@ function mergeSearchRegExes( regExCandidates, flagCandidates ) {
|
|
|
273
318
|
function prepareSearch( searchRegEx, context ) {
|
|
274
319
|
const pattern = searchRegEx.xregexp.source;
|
|
275
320
|
const placeholderMap = {
|
|
276
|
-
|
|
277
|
-
if( _.isNil( format ) ) {
|
|
321
|
+
now: ( format ) => {
|
|
322
|
+
if ( _.isNil( format ) ) {
|
|
278
323
|
throw new Error( "Missing required parameter 'format' for placeholder {{now}}" );
|
|
279
324
|
}
|
|
280
325
|
return XRegExp.escape( dateFormat( context.executionTime, format ) );
|
|
281
326
|
},
|
|
282
|
-
|
|
327
|
+
semver: `${semanticVersionRegex.xregexp.source || semanticVersionRegex.source}`,
|
|
283
328
|
};
|
|
284
329
|
const parsedVer = semver.parse( context.latestVersion );
|
|
285
|
-
if( parsedVer ) {
|
|
330
|
+
if ( parsedVer ) {
|
|
286
331
|
Object.assign( placeholderMap, {
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
332
|
+
version: XRegExp.escape( parsedVer.raw ),
|
|
333
|
+
major: parsedVer.major,
|
|
334
|
+
minor: parsedVer.minor,
|
|
335
|
+
patch: parsedVer.patch,
|
|
336
|
+
prerelease: XRegExp.escape( parsedVer.prerelease.join( '.' ) ),
|
|
337
|
+
prefixedPrerelease:
|
|
338
|
+
parsedVer.prerelease.length > 0
|
|
339
|
+
? XRegExp.escape( prereleasePrefix + parsedVer.prerelease.join( '.' ) )
|
|
340
|
+
: '',
|
|
341
|
+
build: XRegExp.escape( parsedVer.build.join( '.' ) ),
|
|
342
|
+
prefixedBuild:
|
|
343
|
+
parsedVer.build.length > 0 ? XRegExp.escape( buildPrefix + parsedVer.build.join( '.' ) ) : '',
|
|
344
|
+
versionWithoutBuild: XRegExp.escape( parsedVer.version ),
|
|
345
|
+
versionWithoutPrerelease: XRegExp.escape( `${parsedVer.major}.${parsedVer.minor}.${parsedVer.patch}` ),
|
|
298
346
|
} );
|
|
299
347
|
}
|
|
300
348
|
if ( context.latestTag ) {
|
|
301
|
-
Object.assign( placeholderMap, {
|
|
349
|
+
Object.assign( placeholderMap, { tag: XRegExp.escape( context.latestTag ) } );
|
|
302
350
|
}
|
|
303
351
|
|
|
304
352
|
if ( context.version ) {
|
|
305
|
-
Object.assign( placeholderMap, {
|
|
353
|
+
Object.assign( placeholderMap, { newVersion: XRegExp.escape( context.version ) } );
|
|
306
354
|
}
|
|
307
355
|
|
|
308
356
|
wrapSearchPatternPlaceholders( placeholderMap );
|
|
@@ -311,11 +359,11 @@ function prepareSearch( searchRegEx, context ) {
|
|
|
311
359
|
}
|
|
312
360
|
|
|
313
361
|
function wrapSearchPatternPlaceholders( placeholderMap ) {
|
|
314
|
-
for( const placeholder of Object.keys( placeholderMap ) ) {
|
|
362
|
+
for ( const placeholder of Object.keys( placeholderMap ) ) {
|
|
315
363
|
// object injection mitigated for placeholderMap since placeholder is from Object.keys( placeholderMap )
|
|
316
364
|
// eslint-disable-next-line security/detect-object-injection
|
|
317
365
|
const replacement = placeholderMap[ placeholder ];
|
|
318
|
-
if( _.isFunction( replacement ) ) {
|
|
366
|
+
if ( _.isFunction( replacement ) ) {
|
|
319
367
|
// eslint-disable-next-line security/detect-object-injection
|
|
320
368
|
placeholderMap[ placeholder ] = ( ...args ) => {
|
|
321
369
|
return wrapInRegexGroup( replacement( ...args ) );
|
|
@@ -332,7 +380,7 @@ function wrapInRegexGroup( pattern ) {
|
|
|
332
380
|
}
|
|
333
381
|
|
|
334
382
|
function replaceVersion( content, searchRegex, replace, context ) {
|
|
335
|
-
const processedReplace = prepareReplacement
|
|
383
|
+
const processedReplace = prepareReplacement( replace, context );
|
|
336
384
|
const processedContent = XRegExp.replace( content, searchRegex, processedReplace );
|
|
337
385
|
return processedContent;
|
|
338
386
|
}
|
|
@@ -340,24 +388,25 @@ function replaceVersion( content, searchRegex, replace, context ) {
|
|
|
340
388
|
function prepareReplacement( replace, context ) {
|
|
341
389
|
const parsedVer = semver.parse( context.version );
|
|
342
390
|
const placeholderMap = {
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
'
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
391
|
+
version: parsedVer.raw,
|
|
392
|
+
major: parsedVer.major,
|
|
393
|
+
minor: parsedVer.minor,
|
|
394
|
+
patch: parsedVer.patch,
|
|
395
|
+
prerelease: parsedVer.prerelease.join( '.' ),
|
|
396
|
+
prefixedPrerelease:
|
|
397
|
+
parsedVer.prerelease.length > 0 ? prereleasePrefix + parsedVer.prerelease.join( '.' ) : '',
|
|
398
|
+
build: parsedVer.build.join( '.' ),
|
|
399
|
+
prefixedBuild: parsedVer.build.length > 0 ? buildPrefix + parsedVer.build.join( '.' ) : '',
|
|
400
|
+
versionWithoutBuild: parsedVer.version,
|
|
401
|
+
versionWithoutPrerelease: `${parsedVer.major}.${parsedVer.minor}.${parsedVer.patch}`,
|
|
402
|
+
latestVersion: context.latestVersion || '',
|
|
403
|
+
latestTag: context.latestTag || '',
|
|
404
|
+
now: ( format ) => {
|
|
405
|
+
if ( _.isNil( format ) ) {
|
|
357
406
|
return dateFormatIso( context.executionTime );
|
|
358
407
|
}
|
|
359
408
|
return dateFormat( context.executionTime, format );
|
|
360
|
-
}
|
|
409
|
+
},
|
|
361
410
|
};
|
|
362
411
|
return replacePlaceholders( replace, placeholderMap );
|
|
363
412
|
}
|
|
@@ -381,7 +430,6 @@ function replacePlaceholders( template, placeholderMap ) {
|
|
|
381
430
|
} );
|
|
382
431
|
}
|
|
383
432
|
|
|
384
|
-
|
|
385
433
|
function optionalRequire( packageName ) {
|
|
386
434
|
try {
|
|
387
435
|
// eslint-disable-next-line security/detect-non-literal-require
|
|
@@ -395,20 +443,21 @@ function optionalRequire( packageName ) {
|
|
|
395
443
|
}
|
|
396
444
|
|
|
397
445
|
function firstNotNil( ...args ) {
|
|
398
|
-
return args.find( ele => !_.isNil( ele ) );
|
|
446
|
+
return args.find( ( ele ) => !_.isNil( ele ) );
|
|
399
447
|
}
|
|
400
448
|
|
|
401
449
|
class LineCounter {
|
|
402
450
|
constructor( text ) {
|
|
403
451
|
let index = 0;
|
|
404
|
-
this.lineEndIndex = text.split( '\n' ).map( line => {
|
|
452
|
+
this.lineEndIndex = text.split( '\n' ).map( ( line ) => {
|
|
405
453
|
index += line.length + 1;
|
|
406
454
|
return index;
|
|
407
455
|
} );
|
|
408
456
|
}
|
|
409
457
|
|
|
410
458
|
lineOfIndex( index ) {
|
|
411
|
-
|
|
459
|
+
// eslint-disable-next-line no-extra-parens
|
|
460
|
+
const arrayIndex = this.lineEndIndex.findIndex( ( lineEndIndex ) => index <= lineEndIndex );
|
|
412
461
|
assert( arrayIndex >= 0 );
|
|
413
462
|
return arrayIndex + 1;
|
|
414
463
|
}
|
package/package.json
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@j-ulrich/release-it-regex-bumper",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.2",
|
|
4
4
|
"description": "Regular expression based version read/write plugin for release-it",
|
|
5
5
|
"main": "index.js",
|
|
6
|
+
"files": [
|
|
7
|
+
"index.js"
|
|
8
|
+
],
|
|
6
9
|
"scripts": {
|
|
7
10
|
"test": "npx bron test.js",
|
|
8
11
|
"test+coverage": "npx c8 npx bron test.js",
|
|
@@ -49,14 +52,17 @@
|
|
|
49
52
|
"diff": "^3.0.0 || ^4.0.0"
|
|
50
53
|
},
|
|
51
54
|
"devDependencies": {
|
|
55
|
+
"@j-ulrich/eslint-config": "^1.0.0",
|
|
56
|
+
"@release-it/keep-a-changelog": "^2.5.0",
|
|
52
57
|
"bron": "^1.1.0",
|
|
53
58
|
"c8": "^7.3.0",
|
|
54
|
-
"eslint": "^8.0
|
|
59
|
+
"eslint": "^8.6.0",
|
|
55
60
|
"eslint-plugin-security": "^1.4.0",
|
|
56
61
|
"mock-fs": "^5.1.1",
|
|
57
62
|
"release-it": "^14.0.0",
|
|
58
63
|
"rewiremock": "^3.14.3",
|
|
59
|
-
"sinon": "^9.0.3"
|
|
64
|
+
"sinon": "^9.0.3",
|
|
65
|
+
"temp": "^0.9.4"
|
|
60
66
|
},
|
|
61
67
|
"engines": {
|
|
62
68
|
"node": ">=10.12.0"
|
package/.github/workflows/CI.yml
DELETED
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node
|
|
2
|
-
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
|
|
3
|
-
|
|
4
|
-
name: CI
|
|
5
|
-
|
|
6
|
-
on: [ push, pull_request ]
|
|
7
|
-
|
|
8
|
-
jobs:
|
|
9
|
-
compatibility-test-node:
|
|
10
|
-
name: Test Node Version Compatibility
|
|
11
|
-
runs-on: ubuntu-latest
|
|
12
|
-
|
|
13
|
-
strategy:
|
|
14
|
-
matrix:
|
|
15
|
-
node-version: [ 10.x, 12.x, 14.x ]
|
|
16
|
-
|
|
17
|
-
steps:
|
|
18
|
-
- uses: actions/checkout@v2
|
|
19
|
-
- name: Use Node.js ${{ matrix.node-version }}
|
|
20
|
-
uses: actions/setup-node@v1
|
|
21
|
-
with:
|
|
22
|
-
node-version: ${{ matrix.node-version }}
|
|
23
|
-
- run: npm ci
|
|
24
|
-
- run: npm install release-it
|
|
25
|
-
- run: npm run build --if-present
|
|
26
|
-
- run: npm run test
|
|
27
|
-
|
|
28
|
-
compatibility-test-release:
|
|
29
|
-
name: Test Release-it Version Compatibility
|
|
30
|
-
runs-on: ubuntu-latest
|
|
31
|
-
|
|
32
|
-
strategy:
|
|
33
|
-
matrix:
|
|
34
|
-
release-it-version: [ 11.x, 12.x, 13.x, 14.x ]
|
|
35
|
-
|
|
36
|
-
steps:
|
|
37
|
-
- uses: actions/checkout@v2
|
|
38
|
-
- uses: actions/setup-node@v1
|
|
39
|
-
with:
|
|
40
|
-
node-version: 16.x
|
|
41
|
-
- run: npm ci
|
|
42
|
-
- run: npm install release-it@${{ matrix.release-it-version }}
|
|
43
|
-
- run: npm run build --if-present
|
|
44
|
-
- run: npm run test
|
|
45
|
-
|
|
46
|
-
coverage:
|
|
47
|
-
name: Coverage
|
|
48
|
-
runs-on: ubuntu-latest
|
|
49
|
-
|
|
50
|
-
steps:
|
|
51
|
-
- uses: actions/checkout@v2
|
|
52
|
-
- uses: actions/setup-node@v1
|
|
53
|
-
with:
|
|
54
|
-
node-version: 16.x
|
|
55
|
-
- run: npm ci
|
|
56
|
-
- run: npm install release-it
|
|
57
|
-
- run: npm run build --if-present
|
|
58
|
-
- run: npm run test+coverage
|
|
59
|
-
- run: npx c8 report --reporter lcov
|
|
60
|
-
- name: Upload coverage to Codacy
|
|
61
|
-
uses: codacy/codacy-coverage-reporter-action@v1
|
|
62
|
-
with:
|
|
63
|
-
project-token: ${{ secrets.CODACY_PROJECT_TOKEN }}
|
|
64
|
-
coverage-reports: coverage/lcov.info
|
|
65
|
-
|
|
66
|
-
lint:
|
|
67
|
-
name: Lint
|
|
68
|
-
runs-on: ubuntu-latest
|
|
69
|
-
|
|
70
|
-
steps:
|
|
71
|
-
- uses: actions/checkout@v2
|
|
72
|
-
- uses: actions/setup-node@v1
|
|
73
|
-
with:
|
|
74
|
-
node-version: 16.x
|
|
75
|
-
- run: npm ci
|
|
76
|
-
- run: npm run lint
|