@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 CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2020-2021 Jochen Ulrich
3
+ Copyright (c) 2020-2022 Jochen Ulrich
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -3,8 +3,8 @@
3
3
  > Regular expression based version read/write plugin for release-it
4
4
 
5
5
  ![CI](https://github.com/j-ulrich/release-it-regex-bumper/workflows/CI/badge.svg)
6
- [![Test Coverage](https://app.codacy.com/project/badge/Coverage/bf3c6e8740a9472b9acd7dac231adf4e)](https://www.codacy.com/manual/j-ulrich/release-it-regex-bumper?utm_source=github.com&utm_medium=referral&utm_content=j-ulrich/release-it-regex-bumper&utm_campaign=Badge_Coverage)
7
- [![Code Quality](https://app.codacy.com/project/badge/Grade/bf3c6e8740a9472b9acd7dac231adf4e)](https://www.codacy.com/manual/j-ulrich/release-it-regex-bumper?utm_source=github.com&utm_medium=referral&utm_content=j-ulrich/release-it-regex-bumper&utm_campaign=Badge_Grade)
6
+ [![Test Coverage](https://app.codacy.com/project/badge/Coverage/bf3c6e8740a9472b9acd7dac231adf4e)](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
+ [![Code Quality](https://app.codacy.com/project/badge/Grade/bf3c6e8740a9472b9acd7dac231adf4e)](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 [.release-it.json](.release-it.json).
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-2021 Jochen Ulrich
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( /(?: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-]+)*)?/ );
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 { searchRegex: globalSearchRegex, flags: globalSearchFlags, versionCaptureGroup: globalVersionCaptureGroup } = parseSearchOptions.call( this, globalSearchOptions );
55
- const { file, encoding, searchRegex, flags: searchFlags, versionCaptureGroup } = parseInOptions.call( this, inOptions );
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( [searchRegex, globalSearchRegex, defaultSearchRegex], [searchFlags, globalSearchFlags] );
68
+ const effectiveSearchRegex = mergeSearchRegExes(
69
+ [ searchRegex, globalSearchRegex, defaultSearchRegex ],
70
+ [ searchFlags, globalSearchFlags ]
71
+ );
60
72
  const replacedSearchRegex = prepareSearch( effectiveSearchRegex, context );
61
- const version = await extractVersion.call( this, fileContent, replacedSearchRegex,
62
- firstNotNil( versionCaptureGroup, globalVersionCaptureGroup, defaultVersionCaptureGroup ) );
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
- const { out: outOptions, search: globalSearchOptions, replace: globalReplace, encoding: globalEncoding } = this.options;
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( this, globalSearchOptions );
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
- for ( const outOptions of expandedOutOptions ) {
83
-
84
- const { files, encoding, searchRegex, flags: searchFlags, replace } = outOptions;
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( [searchRegex, globalSearchRegex, defaultSearchRegex], [searchFlags, globalSearchFlags] );
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.call( this );
123
+ this.loadDiff();
100
124
  if ( this.diff ) {
101
- const processedFileContent = replaceVersion.call( this, fileContent, replacedSearchRegex, effectiveReplacement, context );
102
- await diffAndReport.call( this, fileContent, processedFileContent, file );
125
+ const processedFileContent = replaceVersion( fileContent, replacedSearchRegex,
126
+ effectiveReplacement, context );
127
+ await this.diffAndReport( fileContent, processedFileContent, file );
103
128
  continue;
104
129
  }
105
- await searchAndReport.call( this, fileContent, replacedSearchRegex, file );
130
+ await this.searchAndReport( fileContent, replacedSearchRegex, file );
106
131
  continue;
107
132
  }
108
133
 
109
- const processedFileContent = replaceVersion.call( this, fileContent, replacedSearchRegex, effectiveReplacement, context );
134
+ const processedFileContent = replaceVersion(
135
+ fileContent,
136
+ replacedSearchRegex,
137
+ effectiveReplacement,
138
+ context
139
+ );
110
140
 
111
- if ( processedFileContent == fileContent ) {
112
- warnNoFileChange.call( this, file );
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[ versionCaptureGroup ];
256
+ return match[versionCaptureGroup];
163
257
  }
164
258
  }
165
259
  else {
166
260
  if ( hasOwnProperty( match, 'version' ) ) {
167
- return match[ 'version' ];
261
+ return match['version'];
168
262
  }
169
263
  if ( hasOwnProperty( match, 1 ) ) {
170
- return match[ 1 ];
264
+ return match[1];
171
265
  }
172
266
  }
173
267
 
174
- return match[ 0 ];
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( options => {
183
- if ( _.isString( options ) ) {
276
+ return _.castArray( options ).map( ( option ) => {
277
+ if ( _.isString( option ) ) {
184
278
  return {
185
- files: [ options ],
279
+ files: [ option ],
186
280
  encoding: null,
187
281
  searchRegex: null,
188
282
  replace: null,
189
283
  };
190
284
  }
191
- const { encoding, replace } = options;
192
- const { searchRegex, flags } = parseSearchOptions( options.search );
193
- const files = options.files ? _.castArray( options.files ) : [];
194
- if( options.file ) {
195
- files.unshift( options.file );
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
- 'now': ( format ) => {
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
- 'semver': `${semanticVersionRegex.xregexp.source || semanticVersionRegex.source}`
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
- 'version': XRegExp.escape( parsedVer.raw ),
288
- 'major': parsedVer.major,
289
- 'minor': parsedVer.minor,
290
- 'patch': parsedVer.patch,
291
- 'prerelease': XRegExp.escape( parsedVer.prerelease.join( '.' ) ),
292
- 'prefixedPrerelease': parsedVer.prerelease.length > 0 ? XRegExp.escape( prereleasePrefix + parsedVer.prerelease.join( '.' ) ) : '',
293
- 'build': XRegExp.escape( parsedVer.build.join( '.' ) ),
294
- 'prefixedBuild': parsedVer.build.length > 0 ? XRegExp.escape( buildPrefix + parsedVer.build.join( '.' ) ) : '',
295
- 'versionWithoutBuild': XRegExp.escape( parsedVer.version ),
296
- 'versionWithoutPrerelease': XRegExp.escape( `${parsedVer.major}.${parsedVer.minor}.${parsedVer.patch}` ),
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, { 'tag': XRegExp.escape( context.latestTag ) } );
349
+ Object.assign( placeholderMap, { tag: XRegExp.escape( context.latestTag ) } );
302
350
  }
303
351
 
304
352
  if ( context.version ) {
305
- Object.assign( placeholderMap, { 'newVersion': XRegExp.escape( context.version ) } );
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.call( this, replace, context );
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
- 'version': parsedVer.raw,
344
- 'major': parsedVer.major,
345
- 'minor': parsedVer.minor,
346
- 'patch': parsedVer.patch,
347
- 'prerelease': parsedVer.prerelease.join( '.' ),
348
- 'prefixedPrerelease': parsedVer.prerelease.length > 0 ? prereleasePrefix + parsedVer.prerelease.join( '.' ) : '',
349
- 'build': parsedVer.build.join( '.' ),
350
- 'prefixedBuild': parsedVer.build.length > 0 ? buildPrefix + parsedVer.build.join( '.' ) : '',
351
- 'versionWithoutBuild': parsedVer.version,
352
- 'versionWithoutPrerelease': `${parsedVer.major}.${parsedVer.minor}.${parsedVer.patch}`,
353
- 'latestVersion': context.latestVersion || '',
354
- 'latestTag': context.latestTag || '',
355
- 'now': ( format ) => {
356
- if( _.isNil( format ) ) {
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
- const arrayIndex = this.lineEndIndex.findIndex( lineEndIndex => ( index <= lineEndIndex ) );
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.1",
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.1",
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"
@@ -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
package/.gitignore DELETED
@@ -1,6 +0,0 @@
1
- coverage/
2
- .*
3
- !.github
4
- !.gitignore
5
- !.release-it.json
6
- node_modules/