-
Notifications
You must be signed in to change notification settings - Fork 26
/
bumpyear.js
113 lines (90 loc) · 3.14 KB
/
bumpyear.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
/**
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
* For licensing, see LICENSE.md.
*/
'use strict';
const chalk = require( 'chalk' );
const fs = require( 'fs' );
const { globSync } = require( 'glob' );
/**
* Updates year in all licenses in the provided directory, based on provided glob patterns.
*
* Replaces:
* Copyright (c) [initial year]-xxxx
*
* With:
* Copyright (c) [initial year]-[current year]
*
* @param {Object} params
* @param {String} params.cwd Current working directory from which all paths will be resolved.
* @param {Array} params.globPatterns An array of objects, where each object has string property `pattern`,
* and optionally `options` property for this `glob` pattern.
* @param {String} [params.initialYear='2003'] Year from which the licenses should begin.
*/
module.exports = function bumpYear( params ) {
if ( !params.initialYear ) {
params.initialYear = '2003';
}
console.log( chalk.cyan( 'Looking for files to update...' ) );
const filesToUpdate = params.globPatterns
.map( globPattern => {
const options = globPattern.options || {};
const defaultIgnore = [
'**/node_modules/**'
];
options.nodir = true;
options.ignore = options.ignore ? [ ...options.ignore, ...defaultIgnore ] : defaultIgnore;
return globSync( globPattern.pattern, options );
} )
.reduce( ( previous, current ) => [ ...previous, ...current ] );
console.log( chalk.cyan( 'Updating the files...' ) );
const currentYear = new Date().getFullYear();
const filesWithoutHeader = [];
const totalFiles = filesToUpdate.length;
let updatedFiles = 0;
filesToUpdate.forEach( fileName => {
const fileContent = fs.readFileSync( fileName, 'utf-8' );
const yearRegexp = new RegExp( `(?<=Copyright (?:\\(c\\)|©) ${ params.initialYear }[-–])\\d{4}`, 'g' );
const updatedFileContent = fileContent.replace( yearRegexp, currentYear );
if ( fileContent === updatedFileContent ) {
if ( isLicenseHeaderRequired( fileName ) && !fileContent.match( yearRegexp ) ) {
filesWithoutHeader.push( `${ params.cwd }/${ fileName }` );
}
} else {
fs.writeFileSync( fileName, updatedFileContent, 'utf-8' );
}
updatedFiles++;
const percent = ( ( updatedFiles / totalFiles ) * 100 ).toFixed( 2 );
const trimmedFileName = fileName.length < 50 ? fileName : '...' + fileName.slice( -47 );
const output = [
`[${ updatedFiles }/${ totalFiles }]`,
chalk.magenta( `(${ percent }%)` ),
`Processing: ${ chalk.underline( trimmedFileName ) }`
].join( ' ' );
process.stdout.clearLine( 1 );
process.stdout.cursorTo( 0 );
process.stdout.write( output );
} );
console.log( '\n' + chalk.green( 'Done.' ) );
if ( filesWithoutHeader.length ) {
console.warn( chalk.red( 'Following files are missing their license headers:' ) );
for ( const file of filesWithoutHeader ) {
console.log( file );
}
}
};
/**
* License headers are only required in JS and TS files.
*
* @param {String} fileName
* @returns {Boolean}
*/
function isLicenseHeaderRequired( fileName ) {
if ( fileName.endsWith( '.js' ) ) {
return true;
}
if ( fileName.endsWith( '.ts' ) ) {
return true;
}
return false;
}