Skip to content

Commit

Permalink
Wrapped globSync and extracted blueprintRoot (#24)
Browse files Browse the repository at this point in the history
* refactor: Created a function that wraps globSync

* refactor: Removed unused argument

* refactor: Renamed variable

* refactor: Extracted function (unionize)

* refactor: Extracted constant (blueprintRoot)

* chore: Added tests

* refactor: Extracted function (validatePackageJson)

* chore: Added warning

---------

Co-authored-by: ijlee2 <ijlee2@users.noreply.github.com>
ijlee2 and ijlee2 authored Mar 10, 2023

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
1 parent e2e0135 commit 610d178
Showing 16 changed files with 196 additions and 122 deletions.
12 changes: 4 additions & 8 deletions src/migration/ember-addon/steps/analyze-addon.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
import { globSync } from 'glob';

import { decideVersion } from '../../../utils/blueprints.js';
import { renameDirectory } from '../../../utils/files.js';
import { findFiles, renameDirectory } from '../../../utils/files.js';

function getAppReexports(options) {
const { projectRoot } = options;

const filePaths = globSync('app/**/*.js', {
const filePaths = findFiles('app/**/*.js', {
cwd: projectRoot,
});

@@ -30,10 +28,8 @@ function getProjectRootDevDependencies(options) {
function getPublicAssets(options) {
const { projectRoot } = options;

const filePaths = globSync('public/**/*', {
const filePaths = findFiles('public/**/*', {
cwd: projectRoot,
dot: true,
nodir: true,
});

return filePaths
@@ -49,7 +45,7 @@ function getPublicAssets(options) {
function getPublicEntrypoints(options) {
const { projectRoot } = options;

const filePaths = globSync('{addon,addon-test-support}/**/*.{js,ts}', {
const filePaths = findFiles('{addon,addon-test-support}/**/*.{js,ts}', {
cwd: projectRoot,
});

26 changes: 5 additions & 21 deletions src/migration/ember-addon/steps/create-files-from-blueprint.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,8 @@
import { readFileSync } from 'node:fs';
import { dirname, join } from 'node:path';
import { fileURLToPath } from 'node:url';
import { join } from 'node:path';

import { globSync } from 'glob';

import { processTemplate } from '../../../utils/blueprints.js';
import { createFiles } from '../../../utils/files.js';

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);

function getBlueprintRoot() {
const codemodRoot = join(__dirname, '../../../..');

return join(codemodRoot, 'src/blueprints/ember-addon');
}
import { blueprintRoot, processTemplate } from '../../../utils/blueprints.js';
import { createFiles, findFiles } from '../../../utils/files.js';

function getFilePath(blueprintFilePath, options) {
const { locations } = options;
@@ -43,15 +31,11 @@ function getFilesToSkip(options) {
}

export function createFilesFromBlueprint(context, options) {
const blueprintRoot = getBlueprintRoot();

const filesToSkip = getFilesToSkip(options);

const blueprintFilePaths = globSync('**/*', {
const blueprintFilePaths = findFiles('**/*', {
cwd: blueprintRoot,
dot: true,
ignore: filesToSkip,
nodir: true,
ignoreList: filesToSkip,
});

const fileMapping = new Map(
57 changes: 36 additions & 21 deletions src/migration/ember-addon/steps/create-options.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,26 @@
import { readFileSync } from 'node:fs';
import { join } from 'node:path';

import { globSync } from 'glob';
import { findFiles, unionize } from '../../../utils/files.js';

function validatePackageJson({ name, version }) {
if (!name) {
throw new SyntaxError('Package name is missing.');
}

if (name.includes('/')) {
// eslint-disable-next-line no-unused-vars
const [_scope, packageName] = name.split('/');

if (!packageName) {
throw new SyntaxError('Package name is missing.');
}
}

if (!version) {
throw new SyntaxError('Package version is missing.');
}
}

function analyzePackageJson(codemodOptions) {
const { projectRoot } = codemodOptions;
@@ -20,13 +39,7 @@ function analyzePackageJson(codemodOptions) {
version,
} = JSON.parse(packageJsonFile);

if (!name) {
throw new SyntaxError('Package name is missing.');
}

if (!version) {
throw new SyntaxError('Package version is missing.');
}
validatePackageJson({ name, version });

const projectDependencies = new Map([
...Object.entries(dependencies ?? {}),
@@ -51,11 +64,19 @@ function analyzePackageJson(codemodOptions) {
function analyzePackageManager(codemodOptions) {
const { projectRoot } = codemodOptions;

const lockFiles = globSync('{package-lock.json,pnpm-lock.yaml,yarn.lock}', {
const mapping = new Map([
['package-lock.json', 'npm'],
['pnpm-lock.yaml', 'pnpm'],
['yarn.lock', 'yarn'],
]);

const lockFiles = [...mapping.keys()];

const filePaths = findFiles(unionize(lockFiles), {
cwd: projectRoot,
});

if (lockFiles.length !== 1) {
if (filePaths.length !== 1) {
console.warn('WARNING: Package manager is unknown. Yarn will be assumed.');

return {
@@ -65,12 +86,12 @@ function analyzePackageManager(codemodOptions) {
};
}

const [lockFile] = lockFiles;
const packageManager = mapping.get(filePaths[0]);

return {
isNpm: lockFile === 'package-lock.json',
isPnpm: lockFile === 'pnpm-lock.yaml',
isYarn: lockFile === 'yarn.lock',
isNpm: packageManager === 'npm',
isPnpm: packageManager === 'pnpm',
isYarn: packageManager === 'yarn',
};
}

@@ -81,13 +102,7 @@ function deriveAddonLocation(addonPackage) {
}

// eslint-disable-next-line no-unused-vars
const [scope, packageName] = addonPackage.name.split('/');

if (!packageName) {
throw new SyntaxError(
`ERROR: In package.json, the package name \`${addonPackage.name}\` is not valid.`
);
}
const [_scope, packageName] = addonPackage.name.split('/');

return packageName;
}
29 changes: 11 additions & 18 deletions src/migration/ember-addon/steps/move-addon-files.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import { globSync } from 'glob';

import { mapFilePaths, moveFiles, removeFiles } from '../../../utils/files.js';
import {
findFiles,
mapFilePaths,
moveFiles,
removeFiles,
} from '../../../utils/files.js';

function moveAddonFolder(options) {
const { locations, projectRoot } = options;

const filePaths = globSync('addon/**/*', {
const filePaths = findFiles('addon/**/*', {
cwd: projectRoot,
dot: true,
nodir: true,
});

const pathMapping = mapFilePaths(filePaths, {
@@ -22,10 +23,8 @@ function moveAddonFolder(options) {
function moveAddonTestSupportFolder(options) {
const { locations, projectRoot } = options;

const filePaths = globSync('addon-test-support/**/*', {
const filePaths = findFiles('addon-test-support/**/*', {
cwd: projectRoot,
dot: true,
nodir: true,
});

const pathMapping = mapFilePaths(filePaths, {
@@ -39,10 +38,8 @@ function moveAddonTestSupportFolder(options) {
function moveBlueprintsFolder(options) {
const { locations, projectRoot } = options;

const filePaths = globSync('blueprints/**/*', {
const filePaths = findFiles('blueprints/**/*', {
cwd: projectRoot,
dot: true,
nodir: true,
});

const pathMapping = mapFilePaths(filePaths, {
@@ -56,10 +53,8 @@ function moveBlueprintsFolder(options) {
function movePublicFolder(options) {
const { locations, projectRoot } = options;

const filePaths = globSync('public/**/*', {
const filePaths = findFiles('public/**/*', {
cwd: projectRoot,
dot: true,
nodir: true,
});

const pathMapping = mapFilePaths(filePaths, {
@@ -73,10 +68,8 @@ function movePublicFolder(options) {
function removeAppFolder(options) {
const { projectRoot } = options;

const filePaths = globSync('app/**/*', {
const filePaths = findFiles('app/**/*', {
cwd: projectRoot,
dot: true,
nodir: true,
});

removeFiles(filePaths, options);
20 changes: 6 additions & 14 deletions src/migration/ember-addon/steps/move-project-root-files.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,18 @@
import { globSync } from 'glob';

import {
copyFiles,
findFiles,
mapFilePaths,
moveFiles,
removeFiles,
unionize,
} from '../../../utils/files.js';

function globPattern(files) {
if (files.length <= 1) {
return files.join(',');
}

return `{${files.join(',')}}`;
}

function copyToAddon(options) {
const { locations, projectRoot } = options;

const files = ['LICENSE.md', 'README.md'];

const filePaths = globSync(globPattern(files), {
const filePaths = findFiles(unionize(files), {
cwd: projectRoot,
});

@@ -55,7 +47,7 @@ function moveToAddonAndTestApp(options) {
files.add('tsconfig.json');
}

const filePaths = globSync(globPattern([...files]), {
const filePaths = findFiles(unionize([...files]), {
cwd: projectRoot,
});

@@ -86,7 +78,7 @@ function moveToTestApp(options) {
'testem.js',
];

const filePaths = globSync(globPattern(files), {
const filePaths = findFiles(unionize(files), {
cwd: projectRoot,
});

@@ -103,7 +95,7 @@ function removeFromProjectRoot(options) {

const files = ['.npmignore', 'index.js'];

const filePaths = globSync(globPattern(files), {
const filePaths = findFiles(unionize(files), {
cwd: projectRoot,
});

28 changes: 8 additions & 20 deletions src/migration/ember-addon/steps/move-test-app-files.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
import { readFileSync, writeFileSync } from 'node:fs';
import { join } from 'node:path';

import { globSync } from 'glob';

import { mapFilePaths, moveFiles } from '../../../utils/files.js';
import { findFiles, mapFilePaths, moveFiles } from '../../../utils/files.js';

function moveTestsFolder(options) {
const { locations, projectRoot } = options;

let filePaths = globSync('tests/dummy/**/*', {
let filePaths = findFiles('tests/dummy/**/*', {
cwd: projectRoot,
dot: true,
nodir: true,
});

let pathMapping = mapFilePaths(filePaths, {
@@ -21,11 +17,9 @@ function moveTestsFolder(options) {

moveFiles(pathMapping, options);

filePaths = globSync('tests/**/*', {
filePaths = findFiles('tests/**/*', {
cwd: projectRoot,
dot: true,
ignore: 'tests/dummy/**/*',
nodir: true,
ignoreList: ['tests/dummy/**/*'],
});

pathMapping = mapFilePaths(filePaths, {
@@ -43,10 +37,8 @@ function moveTypesFolder(options) {
return;
}

let filePaths = globSync('types/dummy/**/*', {
let filePaths = findFiles('types/dummy/**/*', {
cwd: projectRoot,
dot: true,
nodir: true,
});

let pathMapping = mapFilePaths(filePaths, {
@@ -56,11 +48,9 @@ function moveTypesFolder(options) {

moveFiles(pathMapping, options);

filePaths = globSync('types/**/*', {
filePaths = findFiles('types/**/*', {
cwd: projectRoot,
dot: true,
ignore: 'types/dummy/**/*',
nodir: true,
ignoreList: ['types/dummy/**/*'],
});

pathMapping = mapFilePaths(filePaths, {
@@ -76,10 +66,8 @@ function renameDummy(options) {

// File extensions had been specified, partly to encode assumptions
// about Ember, and partly to avoid corrupting non-text files
const filePaths = globSync(`${locations.testApp}/**/*.{d.ts,html,js,ts}`, {
const filePaths = findFiles(`${locations.testApp}/**/*.{d.ts,html,js,ts}`, {
cwd: projectRoot,
dot: true,
nodir: true,
});

filePaths.forEach((filePath) => {
3 changes: 3 additions & 0 deletions src/migration/ember-addon/steps/update-addon-package-json.js
Original file line number Diff line number Diff line change
@@ -108,6 +108,9 @@ function updateOtherFields(packageJson, context, options) {
packageJson['exports'] = {
'.': './dist/index.js',
'./*': {
/*
This object has an order dependency. The `default` key must appear last.
*/
types: './dist/*.d.ts',
default: './dist/*.js',
},
10 changes: 3 additions & 7 deletions src/migration/ember-addon/steps/use-relative-paths.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { readFileSync, writeFileSync } from 'node:fs';
import { dirname, join, relative } from 'node:path';

import { globSync } from 'glob';
import { findFiles } from '../../../utils/files.js';

function normalizeRelativePath(relativePath) {
if (!relativePath.startsWith('..')) {
@@ -38,10 +38,8 @@ function useRelativePathInAddonFolder(options) {

// File extensions had been specified, partly to encode assumptions
// about Ember, and partly to avoid corrupting non-text files
const filePaths = globSync('addon/**/*.{d.ts,js,ts}', {
const filePaths = findFiles('addon/**/*.{d.ts,js,ts}', {
cwd: projectRoot,
dot: true,
nodir: true,
});

filePaths.forEach((filePath) => {
@@ -63,10 +61,8 @@ function useRelativePathInTestsDummyFolder(options) {

// File extensions had been specified, partly to encode assumptions
// about Ember, and partly to avoid corrupting non-text files
const filePaths = globSync('tests/dummy/**/*.{d.ts,js,ts}', {
const filePaths = findFiles('tests/dummy/**/*.{d.ts,js,ts}', {
cwd: projectRoot,
dot: true,
nodir: true,
});

filePaths.forEach((filePath) => {
1 change: 1 addition & 0 deletions src/utils/blueprints.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from './blueprints/blueprint-root.js';
export * from './blueprints/decide-version.js';
export * from './blueprints/process-template.js';
13 changes: 13 additions & 0 deletions src/utils/blueprints/blueprint-root.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { dirname, join } from 'node:path';
import { fileURLToPath } from 'node:url';

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);

function getBlueprintRoot() {
const srcDirectory = join(__dirname, '../..');

return join(srcDirectory, 'blueprints/ember-addon');
}

export const blueprintRoot = getBlueprintRoot();
1 change: 1 addition & 0 deletions src/utils/files.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export * from './files/copy-files.js';
export * from './files/create-files.js';
export * from './files/find-files.js';
export * from './files/map-file-paths.js';
export * from './files/move-files.js';
export * from './files/remove-directory-if-empty.js';
28 changes: 28 additions & 0 deletions src/utils/files/find-files.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { globSync } from 'glob';

export function findFiles(pattern, { cwd, ignoreList = [] }) {
if (!pattern) {
throw new RangeError('ERROR: The glob pattern is unknown.\n');
}

if (!cwd) {
throw new RangeError('ERROR: The current working directory is unknown.\n');
}

const filePaths = globSync(pattern, {
cwd,
dot: true,
ignore: ignoreList,
nodir: true,
});

return filePaths;
}

export function unionize(files) {
if (files.length <= 1) {
return files.join(',');
}

return `{${files.join(',')}}`;
}
22 changes: 10 additions & 12 deletions tests/helpers/testing/convert-fixture-to-json.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { readFileSync } from 'node:fs';
import { join } from 'node:path';

import { globSync } from 'glob';
import { findFiles } from '../../../src/utils/files.js';

function updateJson(json, { keys, projectRoot }) {
function updateJson(json, { currentDirectory, keys }) {
const key = keys.shift();
const isFile = keys.length === 0;

if (isFile) {
json[key] = readFileSync(join(projectRoot, key), 'utf8');
json[key] = readFileSync(join(currentDirectory, key), 'utf8');

return;
}
@@ -18,31 +18,29 @@ function updateJson(json, { keys, projectRoot }) {
}

updateJson(json[key], {
currentDirectory: join(currentDirectory, key),
keys,
projectRoot: join(projectRoot, key),
});
}

function createJson(filePaths = [], projectRoot) {
function createJson(filePaths = [], currentDirectory) {
const json = {};

filePaths.forEach((filePath) => {
const keys = filePath.split('/');

updateJson(json, { keys, projectRoot });
updateJson(json, { currentDirectory, keys });
});

return json;
}

export function convertFixtureToJson(projectRoot) {
const absolutePath = `${process.cwd()}/tests/fixtures/${projectRoot}`;
const currentDirectory = `${process.cwd()}/tests/fixtures/${projectRoot}`;

const filePaths = globSync('**/*', {
cwd: absolutePath,
dot: true,
nodir: true,
const filePaths = findFiles('**/*', {
cwd: currentDirectory,
});

return createJson(filePaths, absolutePath);
return createJson(filePaths, currentDirectory);
}
Original file line number Diff line number Diff line change
@@ -24,7 +24,7 @@ test('migration | ember-addon | steps | create-options > error handling (package
(error) => {
assert.strictEqual(
error.message,
'ERROR: In package.json, the package name `@ijlee2/` is not valid.'
'ERROR: package.json is missing or is not valid. (Package name is missing.)\n'
);

return true;
9 changes: 9 additions & 0 deletions tests/utils/blueprints/blueprint-root.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { blueprintRoot } from '../../../src/utils/blueprints.js';
import { assert, test } from '../../helpers/testing.js';

test('utils | blueprints | blueprint-root', function () {
assert.strictEqual(
blueprintRoot.endsWith('src/blueprints/ember-addon'),
true
);
});
57 changes: 57 additions & 0 deletions tests/utils/files/find-files.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { findFiles } from '../../../src/utils/files.js';
import { codemodOptions } from '../../helpers/shared-test-setups/typescript.js';
import { assert, loadFixture, test } from '../../helpers/testing.js';

test('utils | files | find-files', function () {
const inputProject = {
tests: {
dummy: {
app: {
'.eslintrc.js': '',
'app.ts': '',
'index.html': '',
'router.ts': '',
},
config: {
'environment.js': '',
'optional-features.json': '',
'targets.js': '',
},
},
integration: {
components: {
'container-query-test.ts': '',
},
},
'index.html': '',
'test-helper.ts': '',
},
'ember-cli-build.js': '',
'index.js': '',
'package.json': '',
};

loadFixture(inputProject, codemodOptions);

let filePaths = findFiles('tests/dummy/**/*.{js,ts}', {
cwd: codemodOptions.projectRoot,
});

assert.deepStrictEqual(filePaths.sort(), [
'tests/dummy/app/.eslintrc.js',
'tests/dummy/app/app.ts',
'tests/dummy/app/router.ts',
'tests/dummy/config/environment.js',
'tests/dummy/config/targets.js',
]);

filePaths = findFiles('tests/**/*.{js,ts}', {
cwd: codemodOptions.projectRoot,
ignoreList: ['tests/dummy/**/*'],
});

assert.deepStrictEqual(filePaths.sort(), [
'tests/integration/components/container-query-test.ts',
'tests/test-helper.ts',
]);
});

0 comments on commit 610d178

Please sign in to comment.