feat(core): include community plugins when running nx report

This commit is contained in:
AgentEnder 2021-10-29 09:47:06 -05:00 committed by Victor Savkin
parent 3cc17d7566
commit 91967a37a7
4 changed files with 210 additions and 12 deletions

View File

@ -0,0 +1,122 @@
import { findInstalledCommunityPlugins } from './report';
import * as devkit from '@nrwl/devkit';
import * as fileUtils from '../utilities/fileutils';
import { join } from 'path';
jest.mock('@nrwl/tao/src/utils/app-root', () => ({
appRootPath: '',
}));
jest.mock('../utilities/fileutils', () => ({
...(jest.requireActual('../utilities/fileutils') as typeof fileUtils),
resolve: (file) => `node_modules/${file}`,
}));
describe('report', () => {
describe('findInstalledCommunityPlugins', () => {
afterEach(() => jest.resetAllMocks());
it('should read angular-devkit plugins', () => {
jest.spyOn(devkit, 'readJsonFile').mockImplementation((path) => {
console.log(path);
if (path === 'package.json') {
return {
dependencies: {
'plugin-one': '1.0.0',
},
devDependencies: {
'plugin-two': '2.0.0',
},
};
} else if (
path.includes(join('node_modules', 'plugin-one', 'package.json'))
) {
return {
'ng-update': {},
version: '1.0.0',
};
} else if (
path.includes(join('node_modules', 'plugin-two', 'package.json'))
) {
return {
schematics: {},
version: '2.0.0',
};
}
});
const plugins = findInstalledCommunityPlugins();
expect(plugins).toEqual([
{ package: 'plugin-one', version: '1.0.0' },
{ package: 'plugin-two', version: '2.0.0' },
]);
});
it('should read nx devkit plugins', () => {
jest.spyOn(devkit, 'readJsonFile').mockImplementation((path) => {
if (path === 'package.json') {
return {
dependencies: {
'plugin-one': '1.0.0',
},
devDependencies: {
'plugin-two': '2.0.0',
},
};
} else if (
path.includes(join('node_modules', 'plugin-one', 'package.json'))
) {
return {
'nx-migrations': {},
version: '1.0.0',
};
} else if (
path.includes(join('node_modules', 'plugin-two', 'package.json'))
) {
return {
generators: {},
version: '2.0.0',
};
}
});
const plugins = findInstalledCommunityPlugins();
expect(plugins).toEqual([
{ package: 'plugin-one', version: '1.0.0' },
{ package: 'plugin-two', version: '2.0.0' },
]);
});
it('should not include non-plugins', () => {
jest.spyOn(devkit, 'readJsonFile').mockImplementation((path) => {
if (path === 'package.json') {
return {
dependencies: {
'plugin-one': '1.0.0',
},
devDependencies: {
'plugin-two': '2.0.0',
'other-package': '1.44.0',
},
};
} else if (
path.includes(join('node_modules', 'plugin-one', 'package.json'))
) {
return {
'nx-migrations': {},
};
} else if (
path.includes(join('node_modules', 'plugin-two', 'package.json'))
) {
return {
generators: {},
};
} else {
return {
version: '',
};
}
});
const plugins = findInstalledCommunityPlugins().map((x) => x.package);
expect(plugins).not.toContain('other-package');
});
});
});

View File

@ -6,6 +6,8 @@ import {
readJsonFile,
} from '@nrwl/devkit';
import { output } from '../utilities/output';
import { join } from 'path';
import { resolve } from '../utilities/fileutils';
export const packagesWeCareAbout = [
'nx',
@ -22,6 +24,7 @@ export const packagesWeCareAbout = [
'@nrwl/node',
'@nrwl/nx-cloud',
'@nrwl/react',
'@nrwl/react-native',
'@nrwl/schematics',
'@nrwl/tao',
'@nrwl/web',
@ -29,8 +32,15 @@ export const packagesWeCareAbout = [
'@nrwl/storybook',
'@nrwl/gatsby',
'typescript',
'rxjs',
];
export const packagesWeIgnoreInCommunityReport = new Set([
...packagesWeCareAbout,
'@schematics/angular',
'@nestjs/schematics',
]);
export const report = {
command: 'report',
describe: 'Reports useful version numbers to copy into the Nx issue template',
@ -58,14 +68,15 @@ function reportHandler() {
];
packagesWeCareAbout.forEach((p) => {
let status = 'Not Found';
try {
const packageJsonPath = require.resolve(`${p}/package.json`, {
paths: [appRootPath],
bodyLines.push(`${chalk.green(p)} : ${chalk.bold(readPackageVersion(p))}`);
});
status = readJsonFile(packageJsonPath).version;
} catch {}
bodyLines.push(`${chalk.green(p)} : ${chalk.bold(status)}`);
bodyLines.push('---------------------------------------');
const communityPlugins = findInstalledCommunityPlugins();
bodyLines.push('Community plugins:');
communityPlugins.forEach((p) => {
bodyLines.push(`\t ${chalk.green(p.package)}: ${chalk.bold(p.version)}`);
});
output.log({
@ -73,3 +84,65 @@ function reportHandler() {
bodyLines,
});
}
export function readPackageJson(p: string) {
try {
const packageJsonPath = resolve(`${p}/package.json`, {
paths: [appRootPath],
});
return readJsonFile(packageJsonPath);
} catch {
return {};
}
}
export function readPackageVersion(p: string) {
let status = 'Not Found';
try {
status = readPackageJson(p).version;
} catch {}
return status;
}
export function findInstalledCommunityPlugins(): {
package: string;
version: string;
}[] {
const { dependencies, devDependencies } = readJsonFile(
join(appRootPath, 'package.json')
);
const deps = [
Object.keys(dependencies || {}),
Object.keys(devDependencies || {}),
].flat();
return deps.reduce(
(arr: any[], nextDep: string): { project: string; version: string }[] => {
if (packagesWeIgnoreInCommunityReport.has(nextDep)) {
return arr;
}
try {
const depPackageJson = readPackageJson(nextDep);
if (
[
'ng-update',
'nx-migrations',
'schematics',
'generators',
'builders',
'executors',
].some((field) => field in depPackageJson)
) {
arr.push({ package: nextDep, version: depPackageJson.version });
return arr;
} else {
return arr;
}
} catch {
console.warn(`Error parsing packageJson for ${nextDep}`);
return arr;
}
},
[]
);
}

View File

@ -8,7 +8,7 @@ import {
renameSync as fsRenameSync,
} from 'fs';
import { ensureDirSync } from 'fs-extra';
import { basename, dirname, resolve } from 'path';
import { basename, dirname, resolve as pathResolve } from 'path';
import {
parseJson,
serializeJson,
@ -40,7 +40,7 @@ export function updateJsonFile(path: string, callback: (a: any) => any) {
export function copyFile(file: string, target: string) {
const f = basename(file);
const source = createReadStream(file);
const dest = createWriteStream(resolve(target, f));
const dest = createWriteStream(pathResolve(target, f));
source.pipe(dest);
source.on('error', (e) => console.error(e));
}
@ -62,7 +62,7 @@ export function fileExists(filePath: string): boolean {
}
export function createDirectory(directoryPath: string) {
const parentPath = resolve(directoryPath, '..');
const parentPath = pathResolve(directoryPath, '..');
if (!directoryExists(parentPath)) {
createDirectory(parentPath);
}
@ -84,7 +84,7 @@ export function renameSync(
}
// Make sure parent path exists
const parentPath = resolve(to, '..');
const parentPath = pathResolve(to, '..');
createDirectory(parentPath);
fsRenameSync(from, to);
@ -102,3 +102,5 @@ export function isRelativePath(path: string): boolean {
path.startsWith('../')
);
}
export const resolve = require.resolve;

View File

@ -29,6 +29,7 @@ function check() {
'packages/create-nx-workspace/bin/create-nx-workspace.ts',
'packages/create-nx-plugin/bin/create-nx-plugin.ts',
'packages/workspace/src/command-line/affected.ts',
'packages/workspace/src/command-line/report.ts',
'packages/workspace/src/core/file-utils.ts',
'packages/workspace/src/generators/preset/preset.ts',
'packages/workspace/src/generators/init/init.ts',