feat(core): nx report should support encapsulated installs (#15032)
This commit is contained in:
parent
b0f68aa0d7
commit
56289555fc
@ -1,19 +1,13 @@
|
|||||||
import { NxJsonConfiguration } from '@nrwl/devkit';
|
|
||||||
import {
|
import {
|
||||||
checkFilesDoNotExist,
|
|
||||||
checkFilesExist,
|
|
||||||
cleanupProject,
|
cleanupProject,
|
||||||
createNonNxProjectDirectory,
|
createNonNxProjectDirectory,
|
||||||
getPackageManagerCommand,
|
getPackageManagerCommand,
|
||||||
getPublishedVersion,
|
getPublishedVersion,
|
||||||
getSelectedPackageManager,
|
getSelectedPackageManager,
|
||||||
newEncapsulatedNxWorkspace,
|
|
||||||
removeFile,
|
|
||||||
renameFile,
|
renameFile,
|
||||||
runCLI,
|
runCLI,
|
||||||
runCommand,
|
runCommand,
|
||||||
updateFile,
|
updateFile,
|
||||||
updateJson,
|
|
||||||
} from '@nrwl/e2e/utils';
|
} from '@nrwl/e2e/utils';
|
||||||
|
|
||||||
describe('nx init', () => {
|
describe('nx init', () => {
|
||||||
@ -102,60 +96,4 @@ describe('nx init', () => {
|
|||||||
expect(output).not.toContain('HELLO COMPOUND');
|
expect(output).not.toContain('HELLO COMPOUND');
|
||||||
cleanupProject();
|
cleanupProject();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('encapsulated', () => {
|
|
||||||
it('should support running targets in a encapsulated repo', () => {
|
|
||||||
const runEncapsulatedNx = newEncapsulatedNxWorkspace();
|
|
||||||
updateFile(
|
|
||||||
'projects/a/project.json',
|
|
||||||
JSON.stringify({
|
|
||||||
name: 'a',
|
|
||||||
targets: {
|
|
||||||
echo: {
|
|
||||||
command: `echo 'Hello from A'`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
updateJson<NxJsonConfiguration>('nx.json', (json) => ({
|
|
||||||
...json,
|
|
||||||
tasksRunnerOptions: {
|
|
||||||
default: {
|
|
||||||
...json.tasksRunnerOptions['default'],
|
|
||||||
options: {
|
|
||||||
...json.tasksRunnerOptions['default'].options,
|
|
||||||
cacheableOperations: ['echo'],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
|
|
||||||
expect(runEncapsulatedNx('echo a')).toContain('Hello from A');
|
|
||||||
|
|
||||||
expect(runEncapsulatedNx('echo a')).toContain(
|
|
||||||
'Nx read the output from the cache instead of running the command for 1 out of 1 tasks'
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(() =>
|
|
||||||
checkFilesDoNotExist(
|
|
||||||
'node_modules',
|
|
||||||
'package.json',
|
|
||||||
'package-lock.json',
|
|
||||||
'yarn-lock.json',
|
|
||||||
'pnpm-lock.yaml'
|
|
||||||
)
|
|
||||||
).not.toThrow();
|
|
||||||
expect(() =>
|
|
||||||
checkFilesExist(
|
|
||||||
'.nx/installation/package.json',
|
|
||||||
'.nx/installation/package-lock.json',
|
|
||||||
'.nx/cache/terminalOutputs'
|
|
||||||
)
|
|
||||||
).not.toThrow();
|
|
||||||
});
|
|
||||||
cleanupProject({
|
|
||||||
skipReset: true,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|||||||
84
e2e/nx-misc/src/encapsulated.test.ts
Normal file
84
e2e/nx-misc/src/encapsulated.test.ts
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
import type { NxJsonConfiguration } from '@nrwl/devkit';
|
||||||
|
import {
|
||||||
|
newEncapsulatedNxWorkspace,
|
||||||
|
updateFile,
|
||||||
|
updateJson,
|
||||||
|
checkFilesDoNotExist,
|
||||||
|
checkFilesExist,
|
||||||
|
cleanupProject,
|
||||||
|
getPublishedVersion,
|
||||||
|
} from '@nrwl/e2e/utils';
|
||||||
|
|
||||||
|
describe('encapsulated nx', () => {
|
||||||
|
let runEncapsulatedNx: ReturnType<typeof newEncapsulatedNxWorkspace>;
|
||||||
|
|
||||||
|
beforeAll(() => {
|
||||||
|
runEncapsulatedNx = newEncapsulatedNxWorkspace();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
cleanupProject({
|
||||||
|
skipReset: true,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should support running targets in a encapsulated repo', () => {
|
||||||
|
updateFile(
|
||||||
|
'projects/a/project.json',
|
||||||
|
JSON.stringify({
|
||||||
|
name: 'a',
|
||||||
|
targets: {
|
||||||
|
echo: {
|
||||||
|
command: `echo 'Hello from A'`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
updateJson<NxJsonConfiguration>('nx.json', (json) => ({
|
||||||
|
...json,
|
||||||
|
tasksRunnerOptions: {
|
||||||
|
default: {
|
||||||
|
...json.tasksRunnerOptions['default'],
|
||||||
|
options: {
|
||||||
|
...json.tasksRunnerOptions['default'].options,
|
||||||
|
cacheableOperations: ['echo'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
expect(runEncapsulatedNx('echo a')).toContain('Hello from A');
|
||||||
|
|
||||||
|
expect(runEncapsulatedNx('echo a')).toContain(
|
||||||
|
'Nx read the output from the cache instead of running the command for 1 out of 1 tasks'
|
||||||
|
);
|
||||||
|
|
||||||
|
assertNoRootPackages();
|
||||||
|
expect(() =>
|
||||||
|
checkFilesExist(
|
||||||
|
'.nx/installation/package.json',
|
||||||
|
'.nx/installation/package-lock.json',
|
||||||
|
'.nx/cache/terminalOutputs'
|
||||||
|
)
|
||||||
|
).not.toThrow();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should work with nx report', () => {
|
||||||
|
expect(runEncapsulatedNx('report')).toMatch(
|
||||||
|
new RegExp(`nx.*:.*${getPublishedVersion()}`)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function assertNoRootPackages() {
|
||||||
|
expect(() =>
|
||||||
|
checkFilesDoNotExist(
|
||||||
|
'node_modules',
|
||||||
|
'package.json',
|
||||||
|
'package-lock.json',
|
||||||
|
'yarn-lock.json',
|
||||||
|
'pnpm-lock.yaml'
|
||||||
|
)
|
||||||
|
).not.toThrow();
|
||||||
|
}
|
||||||
@ -22,7 +22,6 @@ describe('report', () => {
|
|||||||
|
|
||||||
it('should read angular-devkit plugins', () => {
|
it('should read angular-devkit plugins', () => {
|
||||||
jest.spyOn(fileUtils, 'readJsonFile').mockImplementation((path) => {
|
jest.spyOn(fileUtils, 'readJsonFile').mockImplementation((path) => {
|
||||||
console.log(path);
|
|
||||||
if (path === 'package.json') {
|
if (path === 'package.json') {
|
||||||
return {
|
return {
|
||||||
dependencies: {
|
dependencies: {
|
||||||
@ -32,6 +31,8 @@ describe('report', () => {
|
|||||||
'plugin-two': '2.0.0',
|
'plugin-two': '2.0.0',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
} else if (path === 'nx.json') {
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
jest.spyOn(packageJsonUtils, 'readModulePackageJson').mockImplementation(
|
jest.spyOn(packageJsonUtils, 'readModulePackageJson').mockImplementation(
|
||||||
@ -64,6 +65,8 @@ describe('report', () => {
|
|||||||
'plugin-two': '2.0.0',
|
'plugin-two': '2.0.0',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
} else if (path === 'nx.json') {
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
jest.spyOn(packageJsonUtils, 'readModulePackageJson').mockImplementation(
|
jest.spyOn(packageJsonUtils, 'readModulePackageJson').mockImplementation(
|
||||||
@ -91,6 +94,8 @@ describe('report', () => {
|
|||||||
'plugin-two': '2.0.0',
|
'plugin-two': '2.0.0',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
} else if (path === 'nx.json') {
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
jest.spyOn(packageJsonUtils, 'readModulePackageJson').mockImplementation(
|
jest.spyOn(packageJsonUtils, 'readModulePackageJson').mockImplementation(
|
||||||
@ -112,6 +117,47 @@ describe('report', () => {
|
|||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should read nx plugins from installations', () => {
|
||||||
|
jest.spyOn(fileUtils, 'readJsonFile').mockImplementation((path) => {
|
||||||
|
if (path === 'package.json') {
|
||||||
|
return {
|
||||||
|
dependencies: {},
|
||||||
|
devDependencies: {
|
||||||
|
'plugin-two': '2.0.0',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
} else if (path === 'nx.json') {
|
||||||
|
return {
|
||||||
|
installation: {
|
||||||
|
version: '1.12.0',
|
||||||
|
plugins: {
|
||||||
|
'plugin-one': '1.0.0',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
jest.spyOn(packageJsonUtils, 'readModulePackageJson').mockImplementation(
|
||||||
|
provideMockPackages({
|
||||||
|
'plugin-one': {
|
||||||
|
'nx-migrations': {},
|
||||||
|
version: '1.0.0',
|
||||||
|
},
|
||||||
|
'plugin-two': {
|
||||||
|
generators: '',
|
||||||
|
version: '2.0.0',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
const plugins = findInstalledCommunityPlugins();
|
||||||
|
expect(plugins).toEqual(
|
||||||
|
expect.arrayContaining([
|
||||||
|
expect.objectContaining({ package: 'plugin-one', version: '1.0.0' }),
|
||||||
|
expect.objectContaining({ package: 'plugin-two', version: '2.0.0' }),
|
||||||
|
])
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
it('should not include non-plugins', () => {
|
it('should not include non-plugins', () => {
|
||||||
jest.spyOn(fileUtils, 'readJsonFile').mockImplementation((path) => {
|
jest.spyOn(fileUtils, 'readJsonFile').mockImplementation((path) => {
|
||||||
if (path === 'package.json') {
|
if (path === 'package.json') {
|
||||||
@ -124,6 +170,8 @@ describe('report', () => {
|
|||||||
'other-package': '1.44.0',
|
'other-package': '1.44.0',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
} else if (path === 'nx.json') {
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
jest.spyOn(packageJsonUtils, 'readModulePackageJson').mockImplementation(
|
jest.spyOn(packageJsonUtils, 'readModulePackageJson').mockImplementation(
|
||||||
|
|||||||
@ -19,6 +19,7 @@ import {
|
|||||||
readProjectsConfigurationFromProjectGraph,
|
readProjectsConfigurationFromProjectGraph,
|
||||||
} from '../project-graph/project-graph';
|
} from '../project-graph/project-graph';
|
||||||
import { gt, valid } from 'semver';
|
import { gt, valid } from 'semver';
|
||||||
|
import { NxJsonConfiguration } from '../config/nx-json';
|
||||||
|
|
||||||
const nxPackageJson = readJsonFile<typeof import('../../package.json')>(
|
const nxPackageJson = readJsonFile<typeof import('../../package.json')>(
|
||||||
join(__dirname, '../../package.json')
|
join(__dirname, '../../package.json')
|
||||||
@ -190,7 +191,10 @@ async function findLocalPlugins() {
|
|||||||
|
|
||||||
function readPackageJson(p: string): PackageJson | null {
|
function readPackageJson(p: string): PackageJson | null {
|
||||||
try {
|
try {
|
||||||
return readModulePackageJson(p).packageJson;
|
return readModulePackageJson(p, [
|
||||||
|
workspaceRoot,
|
||||||
|
join(workspaceRoot, '.nx', 'installation'),
|
||||||
|
]).packageJson;
|
||||||
} catch {
|
} catch {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -248,14 +252,9 @@ export function findMisalignedPackagesForPackage(
|
|||||||
export function findInstalledCommunityPlugins(): (PackageJson & {
|
export function findInstalledCommunityPlugins(): (PackageJson & {
|
||||||
package: string;
|
package: string;
|
||||||
})[] {
|
})[] {
|
||||||
const { dependencies, devDependencies } = readJsonFile(
|
const packageJsonDeps = getDependenciesFromPackageJson();
|
||||||
join(workspaceRoot, 'package.json')
|
const nxJsonDeps = getDependenciesFromNxJson();
|
||||||
);
|
const deps = packageJsonDeps.concat(nxJsonDeps);
|
||||||
const deps = [
|
|
||||||
Object.keys(dependencies || {}),
|
|
||||||
Object.keys(devDependencies || {}),
|
|
||||||
].flat();
|
|
||||||
|
|
||||||
return deps.reduce(
|
return deps.reduce(
|
||||||
(arr: any[], nextDep: string): { project: string; version: string }[] => {
|
(arr: any[], nextDep: string): { project: string; version: string }[] => {
|
||||||
if (
|
if (
|
||||||
@ -302,3 +301,25 @@ export function findInstalledPackagesWeCareAbout() {
|
|||||||
return acc;
|
return acc;
|
||||||
}, [] as { package: string; version: string }[]);
|
}, [] as { package: string; version: string }[]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getDependenciesFromPackageJson(
|
||||||
|
packageJsonPath = 'package.json'
|
||||||
|
): string[] {
|
||||||
|
try {
|
||||||
|
const { dependencies, devDependencies } = readJsonFile(
|
||||||
|
join(workspaceRoot, packageJsonPath)
|
||||||
|
);
|
||||||
|
return Object.keys({ ...dependencies, ...devDependencies });
|
||||||
|
} catch {}
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
function getDependenciesFromNxJson(): string[] {
|
||||||
|
const { installation } = readJsonFile<NxJsonConfiguration>(
|
||||||
|
join(workspaceRoot, 'nx.json')
|
||||||
|
);
|
||||||
|
if (!installation) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
return ['nx', ...Object.keys(installation.plugins || {})];
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user