Skip to content

Commit c6c059f

Browse files
committedMar 9, 2024
refactor: extract readFile helper
1 parent ca6b6d9 commit c6c059f

File tree

3 files changed

+141
-23
lines changed

3 files changed

+141
-23
lines changed
 

‎src/license-plugin.js

+4-23
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,13 @@ import {mkdirp} from 'mkdirp';
2828
import _ from 'lodash';
2929
import moment from 'moment';
3030
import MagicString from 'magic-string';
31-
import glob from 'glob';
3231
import packageNameRegex from 'package-name-regex';
3332

3433
import {Dependency} from './dependency.js';
3534
import {generateBlockComment} from './generate-block-comment.js';
3635
import {licensePluginOptions} from './license-plugin-option.js';
3736
import {licenseValidator} from './license-validator';
37+
import {readFile} from './read-file';
3838
import {PLUGIN_NAME} from './license-plugin-name.js';
3939
import {EOL} from './eol.js';
4040

@@ -196,14 +196,9 @@ class LicensePlugin {
196196

197197
// Read license file, if it exists.
198198
const cwd = this._cwd || process.cwd();
199-
const absolutePath = path.join(dir, '[lL][iI][cC][eE][nN][cCsS][eE]*');
200-
const relativeToCwd = path.relative(cwd, absolutePath);
201-
const licenseFile = this._findGlob(relativeToCwd, cwd).find((file) => (
202-
fs.existsSync(file) && fs.lstatSync(file).isFile()
203-
));
204-
205-
if (licenseFile) {
206-
pkg.licenseText = fs.readFileSync(licenseFile, 'utf-8');
199+
const licenseText = readFile(dir, cwd, ['license', 'licence']);
200+
if (licenseText) {
201+
pkg.licenseText = licenseText;
207202
}
208203

209204
// Add the new dependency to the set of third-party dependencies.
@@ -349,20 +344,6 @@ class LicensePlugin {
349344
console.warn(`[${this.name}] -- ${msg}`);
350345
}
351346

352-
/**
353-
* Find given file, matching given pattern.
354-
*
355-
* @param {string} pattern Pattern to look for.
356-
* @param {string} cwd Working directory.
357-
* @returns {*} All match.
358-
* @private
359-
*/
360-
_findGlob(pattern, cwd) {
361-
return glob.sync(pattern, {
362-
cwd,
363-
});
364-
}
365-
366347
/**
367348
* Read banner from given options and returns it.
368349
*

‎src/read-file.js

+85
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/**
2+
* The MIT License (MIT)
3+
*
4+
* Copyright (c) 2016-2023 Mickael Jeanroy
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in all
14+
* copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*/
24+
25+
import path from 'path';
26+
import fs from 'fs';
27+
import _ from 'lodash';
28+
import glob from 'glob';
29+
30+
/**
31+
* Find file and returns its content if file exists.
32+
*
33+
* @param {string} dir File directory.
34+
* @param {string} cwd Working directory.
35+
* @param {string|Array<string>} names Potential filenames.
36+
* @returns {string|null} File content, or `null` if file does not exist.
37+
*/
38+
export function readFile(dir, cwd, names) {
39+
const inputs = _.castArray(names);
40+
41+
for (let i = 0; i < inputs.length; ++i) {
42+
const input = generatePattern(inputs[i]);
43+
const absolutePath = path.join(dir, input);
44+
const relativeToCwd = path.relative(cwd, absolutePath);
45+
46+
const findings = glob.sync(relativeToCwd, {cwd});
47+
for (let j = 0; j < findings.length; ++j) {
48+
const file = path.join(cwd, findings[j]);
49+
if (isFile(file)) {
50+
return fs.readFileSync(file, 'utf-8');
51+
}
52+
}
53+
}
54+
55+
return null;
56+
}
57+
58+
/**
59+
* Check that given file exists, and is a real file.
60+
*
61+
* @param {string} file File path.
62+
* @returns {boolean} `true` if `file` is a file, `false` otherwise.
63+
*/
64+
function isFile(file) {
65+
return !!fs.existsSync(file) && !!fs.lstatSync(file).isFile();
66+
}
67+
68+
/**
69+
* Generate glob pattern for given input.
70+
*
71+
* @param {string} input Given input.
72+
* @returns {string} Glob pattern.
73+
*/
74+
function generatePattern(input) {
75+
let pattern = '';
76+
77+
for (let i = 0; i < input.length; ++i) {
78+
const c = input[i];
79+
const up = c.toUpperCase();
80+
const low = c.toLowerCase();
81+
pattern += up !== low ? `[${low}${up}]` : low;
82+
}
83+
84+
return pattern + '*';
85+
}

‎test/read-file.spec.js

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/**
2+
* The MIT License (MIT)
3+
*
4+
* Copyright (c) 2016-2023 Mickael Jeanroy
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in all
14+
* copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*/
24+
25+
import path from 'path';
26+
import {readFile} from '../src/read-file.js';
27+
28+
describe('readFile', () => {
29+
it('should read file using exact name', () => {
30+
const dir = path.join(__dirname, 'fixtures', 'fake-package-2');
31+
const cwd = __dirname;
32+
const name = 'LICENSE.md';
33+
const content = readFile(dir, cwd, name);
34+
expect(content).toEqual('LICENSE.md file');
35+
});
36+
37+
it('should read file using non matching case name', () => {
38+
const dir = path.join(__dirname, 'fixtures', 'fake-package-2');
39+
const cwd = __dirname;
40+
const name = 'license.md';
41+
const content = readFile(dir, cwd, name);
42+
expect(content).toEqual('LICENSE.md file');
43+
});
44+
45+
it('should read file using name without extension', () => {
46+
const dir = path.join(__dirname, 'fixtures', 'fake-package-2');
47+
const cwd = __dirname;
48+
const name = 'license';
49+
const content = readFile(dir, cwd, name);
50+
expect(content).toEqual('LICENSE.md file');
51+
});
52+
});

0 commit comments

Comments
 (0)
Please sign in to comment.