Skip to content

Commit

Permalink
refactor: extract readFile helper
Browse files Browse the repository at this point in the history
  • Loading branch information
mjeanroy committed Mar 9, 2024
1 parent ca6b6d9 commit c6c059f
Show file tree
Hide file tree
Showing 3 changed files with 141 additions and 23 deletions.
27 changes: 4 additions & 23 deletions src/license-plugin.js
Expand Up @@ -28,13 +28,13 @@ import {mkdirp} from 'mkdirp';
import _ from 'lodash';
import moment from 'moment';
import MagicString from 'magic-string';
import glob from 'glob';
import packageNameRegex from 'package-name-regex';

import {Dependency} from './dependency.js';
import {generateBlockComment} from './generate-block-comment.js';
import {licensePluginOptions} from './license-plugin-option.js';
import {licenseValidator} from './license-validator';
import {readFile} from './read-file';
import {PLUGIN_NAME} from './license-plugin-name.js';
import {EOL} from './eol.js';

Expand Down Expand Up @@ -196,14 +196,9 @@ class LicensePlugin {

// Read license file, if it exists.
const cwd = this._cwd || process.cwd();
const absolutePath = path.join(dir, '[lL][iI][cC][eE][nN][cCsS][eE]*');
const relativeToCwd = path.relative(cwd, absolutePath);
const licenseFile = this._findGlob(relativeToCwd, cwd).find((file) => (
fs.existsSync(file) && fs.lstatSync(file).isFile()
));

if (licenseFile) {
pkg.licenseText = fs.readFileSync(licenseFile, 'utf-8');
const licenseText = readFile(dir, cwd, ['license', 'licence']);
if (licenseText) {
pkg.licenseText = licenseText;
}

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

/**
* Find given file, matching given pattern.
*
* @param {string} pattern Pattern to look for.
* @param {string} cwd Working directory.
* @returns {*} All match.
* @private
*/
_findGlob(pattern, cwd) {
return glob.sync(pattern, {
cwd,
});
}

/**
* Read banner from given options and returns it.
*
Expand Down
85 changes: 85 additions & 0 deletions src/read-file.js
@@ -0,0 +1,85 @@
/**
* The MIT License (MIT)
*
* Copyright (c) 2016-2023 Mickael Jeanroy
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

import path from 'path';
import fs from 'fs';
import _ from 'lodash';
import glob from 'glob';

/**
* Find file and returns its content if file exists.
*
* @param {string} dir File directory.
* @param {string} cwd Working directory.
* @param {string|Array<string>} names Potential filenames.
* @returns {string|null} File content, or `null` if file does not exist.
*/
export function readFile(dir, cwd, names) {
const inputs = _.castArray(names);

for (let i = 0; i < inputs.length; ++i) {
const input = generatePattern(inputs[i]);
const absolutePath = path.join(dir, input);
const relativeToCwd = path.relative(cwd, absolutePath);

const findings = glob.sync(relativeToCwd, {cwd});
for (let j = 0; j < findings.length; ++j) {
const file = path.join(cwd, findings[j]);
if (isFile(file)) {
return fs.readFileSync(file, 'utf-8');
}
}
}

return null;
}

/**
* Check that given file exists, and is a real file.
*
* @param {string} file File path.
* @returns {boolean} `true` if `file` is a file, `false` otherwise.
*/
function isFile(file) {
return !!fs.existsSync(file) && !!fs.lstatSync(file).isFile();
}

/**
* Generate glob pattern for given input.
*
* @param {string} input Given input.
* @returns {string} Glob pattern.
*/
function generatePattern(input) {
let pattern = '';

for (let i = 0; i < input.length; ++i) {
const c = input[i];
const up = c.toUpperCase();
const low = c.toLowerCase();
pattern += up !== low ? `[${low}${up}]` : low;
}

return pattern + '*';
}
52 changes: 52 additions & 0 deletions test/read-file.spec.js
@@ -0,0 +1,52 @@
/**
* The MIT License (MIT)
*
* Copyright (c) 2016-2023 Mickael Jeanroy
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

import path from 'path';
import {readFile} from '../src/read-file.js';

describe('readFile', () => {
it('should read file using exact name', () => {
const dir = path.join(__dirname, 'fixtures', 'fake-package-2');
const cwd = __dirname;
const name = 'LICENSE.md';
const content = readFile(dir, cwd, name);
expect(content).toEqual('LICENSE.md file');
});

it('should read file using non matching case name', () => {
const dir = path.join(__dirname, 'fixtures', 'fake-package-2');
const cwd = __dirname;
const name = 'license.md';
const content = readFile(dir, cwd, name);
expect(content).toEqual('LICENSE.md file');
});

it('should read file using name without extension', () => {
const dir = path.join(__dirname, 'fixtures', 'fake-package-2');
const cwd = __dirname;
const name = 'license';
const content = readFile(dir, cwd, name);
expect(content).toEqual('LICENSE.md file');
});
});

0 comments on commit c6c059f

Please sign in to comment.