cleanup(repo): remove unused ext from file data and fix ext regex matcher (#6550)
This commit is contained in:
parent
1c19db5ff3
commit
3aca62af68
@ -81,7 +81,7 @@ function run(
|
||||
context: BuilderContext
|
||||
): Observable<BuilderOutput> {
|
||||
const { target, dependencies } = calculateProjectDependencies(
|
||||
readCachedProjectGraph(),
|
||||
readCachedProjectGraph('4.0'),
|
||||
context
|
||||
);
|
||||
|
||||
|
||||
@ -17,7 +17,7 @@ export async function* delegateBuildExecutor(
|
||||
context: ExecutorContext
|
||||
) {
|
||||
const { target, dependencies } = calculateProjectDependencies(
|
||||
readCachedProjectGraph(),
|
||||
readCachedProjectGraph('4.0'),
|
||||
context.root,
|
||||
context.projectName,
|
||||
context.targetName,
|
||||
|
||||
@ -51,7 +51,7 @@ export function createLibraryExecutor(
|
||||
context: ExecutorContext
|
||||
) {
|
||||
const { target, dependencies } = calculateProjectDependencies(
|
||||
readCachedProjectGraph(),
|
||||
readCachedProjectGraph('4.0'),
|
||||
context.root,
|
||||
context.projectName,
|
||||
context.targetName,
|
||||
|
||||
@ -45,7 +45,7 @@ function addHTMLPatternToBuilderConfig(
|
||||
async function updateProjectESLintConfigsAndBuilders(
|
||||
host: Tree
|
||||
): Promise<Rule> {
|
||||
const graph = await createProjectGraphAsync();
|
||||
const graph = await createProjectGraphAsync('4.0');
|
||||
|
||||
/**
|
||||
* Make sure user is already using ESLint and is up to date with
|
||||
|
||||
@ -9,7 +9,8 @@ import type {
|
||||
export interface FileData {
|
||||
file: string;
|
||||
hash: string;
|
||||
ext: string;
|
||||
/** @deprecated this field will be removed in v13. Use {@link path.extname} to parse extension */
|
||||
ext?: string;
|
||||
deps?: string[];
|
||||
}
|
||||
|
||||
@ -29,6 +30,7 @@ export interface ProjectGraph<T = any> {
|
||||
|
||||
// this is optional otherwise it might break folks who use project graph creation
|
||||
allWorkspaceFiles?: FileData[];
|
||||
version?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -106,6 +106,13 @@ export class ProjectGraphBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set version of the project graph
|
||||
*/
|
||||
setVersion(version: string): void {
|
||||
this.graph.version = version;
|
||||
}
|
||||
|
||||
getUpdatedProjectGraph(): ProjectGraph {
|
||||
for (const sourceProject of Object.keys(this.graph.nodes)) {
|
||||
const alreadySetTargetProjects =
|
||||
|
||||
@ -129,7 +129,7 @@ export default createESLintRule<Options, MessageIds>({
|
||||
*/
|
||||
try {
|
||||
(global as any).projectGraph = mapProjectGraphFiles(
|
||||
readCachedProjectGraph()
|
||||
readCachedProjectGraph('4.0')
|
||||
);
|
||||
} catch {}
|
||||
}
|
||||
|
||||
@ -1526,7 +1526,7 @@ linter.defineParser('@typescript-eslint/parser', parser);
|
||||
linter.defineRule(enforceModuleBoundariesRuleName, enforceModuleBoundaries);
|
||||
|
||||
function createFile(f) {
|
||||
return { file: f, ext: extname(f), hash: '' };
|
||||
return { file: f, hash: '' };
|
||||
}
|
||||
|
||||
function runRule(
|
||||
|
||||
@ -27,7 +27,7 @@ export default async function exportExecutor(
|
||||
let dependencies: DependentBuildableProjectNode[] = [];
|
||||
if (!options.buildLibsFromSource) {
|
||||
const result = calculateProjectDependencies(
|
||||
readCachedProjectGraph(),
|
||||
readCachedProjectGraph('4.0'),
|
||||
context.root,
|
||||
context.projectName,
|
||||
'build', // this should be generalized
|
||||
|
||||
@ -54,7 +54,7 @@ export default async function* serveExecutor(
|
||||
const root = resolve(context.root, buildOptions.root);
|
||||
if (!options.buildLibsFromSource) {
|
||||
const result = calculateProjectDependencies(
|
||||
readCachedProjectGraph(),
|
||||
readCachedProjectGraph('4.0'),
|
||||
context.root,
|
||||
context.projectName,
|
||||
'build', // should be generalized
|
||||
|
||||
@ -19,7 +19,7 @@ export async function packageExecutor(
|
||||
const libRoot = context.workspace.projects[context.projectName].root;
|
||||
const normalizedOptions = normalizeOptions(options, context, libRoot);
|
||||
const { target, dependencies } = calculateProjectDependencies(
|
||||
readCachedProjectGraph(),
|
||||
readCachedProjectGraph('4.0'),
|
||||
context.root,
|
||||
context.projectName,
|
||||
context.targetName,
|
||||
|
||||
@ -28,7 +28,7 @@ export default function update(): Rule {
|
||||
return async (host: Tree, context: SchematicContext) => {
|
||||
const updates = [];
|
||||
const conflicts: Array<[string, string]> = [];
|
||||
const projectGraph = await createProjectGraphAsync();
|
||||
const projectGraph = await createProjectGraphAsync('4.0');
|
||||
if (host.exists('/babel.config.json')) {
|
||||
context.logger.info(
|
||||
`
|
||||
|
||||
@ -68,7 +68,7 @@ export default async function* devServerExecutor(
|
||||
|
||||
if (!buildOptions.buildLibsFromSource) {
|
||||
const { target, dependencies } = calculateProjectDependencies(
|
||||
readCachedProjectGraph(),
|
||||
readCachedProjectGraph('4.0'),
|
||||
context.root,
|
||||
context.projectName,
|
||||
'build', // should be generalized
|
||||
|
||||
@ -56,7 +56,7 @@ export default async function* run(
|
||||
context: ExecutorContext
|
||||
) {
|
||||
const project = context.workspace.projects[context.projectName];
|
||||
const projectGraph = readCachedProjectGraph();
|
||||
const projectGraph = readCachedProjectGraph('4.0');
|
||||
const sourceRoot = project.sourceRoot;
|
||||
const { target, dependencies } = calculateProjectDependencies(
|
||||
projectGraph,
|
||||
|
||||
@ -7,7 +7,7 @@ import { hasDependentAppUsingWebBuild } from './utils';
|
||||
|
||||
export async function createBabelrcForWorkspaceLibs(host: Tree) {
|
||||
const projects = getProjects(host);
|
||||
const graph = reverse(await createProjectGraphAsync());
|
||||
const graph = reverse(await createProjectGraphAsync('4.0'));
|
||||
|
||||
for (const [name, p] of projects.entries()) {
|
||||
if (!hasDependentAppUsingWebBuild(name, graph, projects)) {
|
||||
|
||||
@ -37,7 +37,7 @@ export async function affected(
|
||||
|
||||
await connectToNxCloudUsingScan(nxArgs.scan);
|
||||
|
||||
const projectGraph = await createProjectGraphAsync();
|
||||
const projectGraph = await createProjectGraphAsync('4.0');
|
||||
const projects = projectsToRun(nxArgs, projectGraph);
|
||||
const projectsNotExcluded = applyExclude(projects, nxArgs);
|
||||
const env = readEnvironment(nxArgs.target, projectsNotExcluded);
|
||||
|
||||
@ -204,7 +204,7 @@ export async function generateGraph(
|
||||
},
|
||||
affectedProjects: string[]
|
||||
): Promise<void> {
|
||||
let graph = onlyWorkspaceProjects(await createProjectGraphAsync());
|
||||
let graph = onlyWorkspaceProjects(await createProjectGraphAsync('4.0'));
|
||||
const layout = workspaceLayout();
|
||||
|
||||
const projects = Object.values(graph.nodes) as ProjectGraphNode[];
|
||||
|
||||
@ -85,7 +85,7 @@ async function getPatternsFromApps(
|
||||
affectedFiles: string[],
|
||||
matchAllPattern: string
|
||||
): Promise<string[]> {
|
||||
const graph = onlyWorkspaceProjects(await createProjectGraphAsync());
|
||||
const graph = onlyWorkspaceProjects(await createProjectGraphAsync('4.0'));
|
||||
const affectedGraph = filterAffected(
|
||||
graph,
|
||||
calculateFileChanges(affectedFiles)
|
||||
|
||||
@ -8,7 +8,7 @@ import { output } from '../utilities/output';
|
||||
import * as path from 'path';
|
||||
|
||||
export async function workspaceLint(): Promise<void> {
|
||||
const graph = onlyWorkspaceProjects(await createProjectGraphAsync());
|
||||
const graph = onlyWorkspaceProjects(await createProjectGraphAsync('4.0'));
|
||||
|
||||
const cliErrorOutputConfigs = new WorkspaceIntegrityChecks(
|
||||
graph,
|
||||
@ -25,7 +25,7 @@ export async function workspaceLint(): Promise<void> {
|
||||
|
||||
function readAllFilesFromAppsAndLibs() {
|
||||
const wl = workspaceLayout();
|
||||
return readWorkspaceFiles()
|
||||
return readWorkspaceFiles('4.0')
|
||||
.map((f) => f.file)
|
||||
.filter(
|
||||
(f) => f.startsWith(`${wl.appsDir}/`) || f.startsWith(`${wl.libsDir}/`)
|
||||
|
||||
@ -26,7 +26,7 @@ export async function runMany(parsedArgs: yargs.Arguments & RawNxArgs) {
|
||||
|
||||
await connectToNxCloudUsingScan(nxArgs.scan);
|
||||
|
||||
const projectGraph = await createProjectGraphAsync();
|
||||
const projectGraph = await createProjectGraphAsync('4.0');
|
||||
const projects = projectsToRun(nxArgs, projectGraph);
|
||||
const projectsNotExcluded = applyExclude(projects, nxArgs);
|
||||
const env = readEnvironment(nxArgs.target, projectsNotExcluded);
|
||||
|
||||
@ -31,7 +31,7 @@ export async function runOne(opts: {
|
||||
|
||||
await connectToNxCloudUsingScan(nxArgs.scan);
|
||||
|
||||
const projectGraph = await createProjectGraphAsync();
|
||||
const projectGraph = await createProjectGraphAsync('4.0');
|
||||
const { projects, projectsMap } = getProjects(
|
||||
projectGraph,
|
||||
nxArgs.withDeps,
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
import { WorkspaceIntegrityChecks } from './workspace-integrity-checks';
|
||||
import * as chalk from 'chalk';
|
||||
import { ProjectType } from '../core/project-graph';
|
||||
import { extname } from 'path';
|
||||
|
||||
describe('WorkspaceIntegrityChecks', () => {
|
||||
describe('workspace.json is in sync with the filesystem', () => {
|
||||
@ -106,5 +105,5 @@ describe('WorkspaceIntegrityChecks', () => {
|
||||
});
|
||||
|
||||
function createFile(f) {
|
||||
return { file: f, ext: extname(f), hash: '' };
|
||||
return { file: f, hash: '' };
|
||||
}
|
||||
|
||||
@ -122,13 +122,11 @@ describe('project graph', () => {
|
||||
const affected = filterAffected(graph, [
|
||||
{
|
||||
file: 'something-for-api.txt',
|
||||
ext: '.txt',
|
||||
hash: 'some-hash',
|
||||
getChanges: () => [new WholeFileChange()],
|
||||
},
|
||||
{
|
||||
file: 'libs/ui/src/index.ts',
|
||||
ext: '.ts',
|
||||
hash: 'some-hash',
|
||||
getChanges: () => [new WholeFileChange()],
|
||||
},
|
||||
@ -182,7 +180,6 @@ describe('project graph', () => {
|
||||
const affected = filterAffected(graph, [
|
||||
{
|
||||
file: 'package.json',
|
||||
ext: '.json',
|
||||
hash: 'some-hash',
|
||||
getChanges: () => jsonDiff(packageJson, updatedPackageJson),
|
||||
},
|
||||
@ -238,7 +235,6 @@ describe('project graph', () => {
|
||||
const affected = filterAffected(graph, [
|
||||
{
|
||||
file: 'package.json',
|
||||
ext: '.json',
|
||||
hash: 'some-hash',
|
||||
getChanges: () => jsonDiff(packageJson, updatedPackageJson),
|
||||
},
|
||||
@ -259,7 +255,6 @@ describe('project graph', () => {
|
||||
const affected = filterAffected(graph, [
|
||||
{
|
||||
file: 'package.json',
|
||||
ext: '.json',
|
||||
hash: 'some-hash',
|
||||
getChanges: () => jsonDiff(packageJson, updatedPackageJson),
|
||||
},
|
||||
|
||||
@ -41,7 +41,6 @@ describe('getImplicitlyTouchedProjectsByJsonChanges', () => {
|
||||
{
|
||||
file: 'package.json',
|
||||
hash: 'some-hash',
|
||||
ext: '.json',
|
||||
getChanges: () => [getModifiedChange(['some', 'deep-field'])],
|
||||
},
|
||||
],
|
||||
@ -57,7 +56,6 @@ describe('getImplicitlyTouchedProjectsByJsonChanges', () => {
|
||||
{
|
||||
file: 'package.json',
|
||||
hash: 'some-hash',
|
||||
ext: '.json',
|
||||
getChanges: () => [
|
||||
getModifiedChange(['some', 'deep-glob-anything']),
|
||||
getModifiedChange(['match-anything']),
|
||||
@ -77,7 +75,6 @@ describe('getImplicitlyTouchedProjectsByJsonChanges', () => {
|
||||
{
|
||||
file: 'package.json',
|
||||
hash: 'some-hash',
|
||||
ext: '.json',
|
||||
getChanges: () => [new WholeFileChange()],
|
||||
},
|
||||
],
|
||||
|
||||
@ -67,7 +67,6 @@ describe('getTouchedNpmPackages', () => {
|
||||
{
|
||||
file: 'package.json',
|
||||
hash: 'some-hash',
|
||||
ext: '.json',
|
||||
getChanges: () => [
|
||||
{
|
||||
type: DiffType.Modified,
|
||||
@ -98,7 +97,6 @@ describe('getTouchedNpmPackages', () => {
|
||||
{
|
||||
file: 'package.json',
|
||||
hash: 'some-hash',
|
||||
ext: '.json',
|
||||
getChanges: () => [
|
||||
{
|
||||
type: DiffType.Deleted,
|
||||
@ -137,7 +135,6 @@ describe('getTouchedNpmPackages', () => {
|
||||
{
|
||||
file: 'package.json',
|
||||
hash: 'some-hash',
|
||||
ext: '.json',
|
||||
getChanges: () => [
|
||||
{
|
||||
type: DiffType.Added,
|
||||
@ -177,7 +174,6 @@ describe('getTouchedNpmPackages', () => {
|
||||
{
|
||||
file: 'package.json',
|
||||
hash: 'some-hash',
|
||||
ext: '.json',
|
||||
getChanges: () => [new WholeFileChange()],
|
||||
},
|
||||
],
|
||||
|
||||
@ -8,7 +8,6 @@ describe('getTouchedProjectsInNxJson', () => {
|
||||
[
|
||||
{
|
||||
file: 'source.ts',
|
||||
ext: '.ts',
|
||||
hash: 'some-hash',
|
||||
getChanges: () => [new WholeFileChange()],
|
||||
},
|
||||
@ -31,7 +30,6 @@ describe('getTouchedProjectsInNxJson', () => {
|
||||
[
|
||||
{
|
||||
file: 'nx.json',
|
||||
ext: '.json',
|
||||
hash: 'some-hash',
|
||||
getChanges: () => [new WholeFileChange()],
|
||||
},
|
||||
@ -57,7 +55,6 @@ describe('getTouchedProjectsInNxJson', () => {
|
||||
[
|
||||
{
|
||||
file: 'nx.json',
|
||||
ext: '.json',
|
||||
hash: 'some-hash',
|
||||
getChanges: () => [
|
||||
{
|
||||
@ -92,7 +89,6 @@ describe('getTouchedProjectsInNxJson', () => {
|
||||
[
|
||||
{
|
||||
file: 'nx.json',
|
||||
ext: '.json',
|
||||
hash: 'some-hash',
|
||||
getChanges: () => [
|
||||
{
|
||||
@ -137,7 +133,6 @@ describe('getTouchedProjectsInNxJson', () => {
|
||||
[
|
||||
{
|
||||
file: 'nx.json',
|
||||
ext: '.json',
|
||||
hash: 'some-hash',
|
||||
getChanges: () => [
|
||||
{
|
||||
@ -174,7 +169,6 @@ describe('getTouchedProjectsInNxJson', () => {
|
||||
[
|
||||
{
|
||||
file: 'nx.json',
|
||||
ext: '.json',
|
||||
hash: 'some-hash',
|
||||
getChanges: () => [
|
||||
{
|
||||
|
||||
@ -45,7 +45,6 @@ describe('getTouchedProjectsFromTsConfig', () => {
|
||||
[
|
||||
{
|
||||
file: 'source.ts',
|
||||
ext: '.ts',
|
||||
hash: 'some-hash',
|
||||
getChanges: () => [new WholeFileChange()],
|
||||
},
|
||||
@ -69,7 +68,6 @@ describe('getTouchedProjectsFromTsConfig', () => {
|
||||
[
|
||||
{
|
||||
file: tsConfig,
|
||||
ext: '.json',
|
||||
hash: 'some-hash',
|
||||
getChanges: () => [new WholeFileChange()],
|
||||
},
|
||||
@ -89,7 +87,6 @@ describe('getTouchedProjectsFromTsConfig', () => {
|
||||
[
|
||||
{
|
||||
file: tsConfig,
|
||||
ext: '.json',
|
||||
hash: 'some-hash',
|
||||
getChanges: () =>
|
||||
jsonDiff(
|
||||
@ -121,7 +118,6 @@ describe('getTouchedProjectsFromTsConfig', () => {
|
||||
[
|
||||
{
|
||||
file: tsConfig,
|
||||
ext: '.json',
|
||||
hash: 'some-hash',
|
||||
getChanges: () =>
|
||||
jsonDiff(
|
||||
@ -153,7 +149,6 @@ describe('getTouchedProjectsFromTsConfig', () => {
|
||||
[
|
||||
{
|
||||
file: tsConfig,
|
||||
ext: '.json',
|
||||
hash: 'some-hash',
|
||||
getChanges: () =>
|
||||
jsonDiff(
|
||||
@ -187,7 +182,6 @@ describe('getTouchedProjectsFromTsConfig', () => {
|
||||
[
|
||||
{
|
||||
file: tsConfig,
|
||||
ext: '.json',
|
||||
hash: 'some-hash',
|
||||
getChanges: () =>
|
||||
jsonDiff(
|
||||
@ -219,7 +213,6 @@ describe('getTouchedProjectsFromTsConfig', () => {
|
||||
[
|
||||
{
|
||||
file: tsConfig,
|
||||
ext: '.json',
|
||||
hash: 'some-hash',
|
||||
getChanges: () =>
|
||||
jsonDiff(
|
||||
@ -256,7 +249,6 @@ describe('getTouchedProjectsFromTsConfig', () => {
|
||||
[
|
||||
{
|
||||
file: tsConfig,
|
||||
ext: '.json',
|
||||
hash: 'some-hash',
|
||||
getChanges: () =>
|
||||
jsonDiff(
|
||||
@ -291,7 +283,6 @@ describe('getTouchedProjectsFromTsConfig', () => {
|
||||
[
|
||||
{
|
||||
file: tsConfig,
|
||||
ext: '.json',
|
||||
hash: 'some-hash',
|
||||
getChanges: () =>
|
||||
jsonDiff(
|
||||
|
||||
@ -8,7 +8,6 @@ describe('getTouchedProjectsInWorkspaceJson', () => {
|
||||
[
|
||||
{
|
||||
file: 'source.ts',
|
||||
ext: '.ts',
|
||||
hash: 'some-hash',
|
||||
getChanges: () => [new WholeFileChange()],
|
||||
},
|
||||
@ -31,7 +30,6 @@ describe('getTouchedProjectsInWorkspaceJson', () => {
|
||||
[
|
||||
{
|
||||
file: 'workspace.json',
|
||||
ext: '.json',
|
||||
hash: 'some-hash',
|
||||
getChanges: () => [new WholeFileChange()],
|
||||
},
|
||||
@ -56,7 +54,6 @@ describe('getTouchedProjectsInWorkspaceJson', () => {
|
||||
[
|
||||
{
|
||||
file: 'workspace.json',
|
||||
ext: '.json',
|
||||
hash: 'some-hash',
|
||||
getChanges: () => [
|
||||
{
|
||||
@ -90,7 +87,6 @@ describe('getTouchedProjectsInWorkspaceJson', () => {
|
||||
[
|
||||
{
|
||||
file: 'workspace.json',
|
||||
ext: '.json',
|
||||
hash: 'some-hash',
|
||||
getChanges: () => [
|
||||
{
|
||||
@ -131,7 +127,6 @@ describe('getTouchedProjectsInWorkspaceJson', () => {
|
||||
[
|
||||
{
|
||||
file: 'workspace.json',
|
||||
ext: '.json',
|
||||
hash: 'some-hash',
|
||||
getChanges: () => [
|
||||
{
|
||||
@ -166,7 +161,6 @@ describe('getTouchedProjectsInWorkspaceJson', () => {
|
||||
[
|
||||
{
|
||||
file: 'workspace.json',
|
||||
ext: '.json',
|
||||
hash: 'some-hash',
|
||||
getChanges: () => [
|
||||
{
|
||||
|
||||
@ -7,7 +7,6 @@ import {
|
||||
function getFileChanges(files: string[]) {
|
||||
return files.map((f) => ({
|
||||
file: f,
|
||||
ext: `.${f.split('.').pop()}`,
|
||||
hash: 'some-hash',
|
||||
getChanges: () => [new WholeFileChange()],
|
||||
}));
|
||||
|
||||
@ -22,19 +22,17 @@ describe('createFileMap', () => {
|
||||
},
|
||||
};
|
||||
const files = [
|
||||
{ file: 'apps/demo/src/main.ts', hash: 'some-hash', ext: '.ts' },
|
||||
{ file: 'apps/demo-e2e/src/main.ts', hash: 'some-hash', ext: '.ts' },
|
||||
{ file: 'libs/ui/src/index.ts', hash: 'some-hash', ext: '.ts' },
|
||||
{ file: 'apps/demo/src/main.ts', hash: 'some-hash' },
|
||||
{ file: 'apps/demo-e2e/src/main.ts', hash: 'some-hash' },
|
||||
{ file: 'libs/ui/src/index.ts', hash: 'some-hash' },
|
||||
];
|
||||
|
||||
const result = createProjectFileMap(workspaceJson, files);
|
||||
|
||||
expect(result).toEqual({
|
||||
demo: [{ file: 'apps/demo/src/main.ts', hash: 'some-hash', ext: '.ts' }],
|
||||
'demo-e2e': [
|
||||
{ file: 'apps/demo-e2e/src/main.ts', hash: 'some-hash', ext: '.ts' },
|
||||
],
|
||||
ui: [{ file: 'libs/ui/src/index.ts', hash: 'some-hash', ext: '.ts' }],
|
||||
demo: [{ file: 'apps/demo/src/main.ts', hash: 'some-hash' }],
|
||||
'demo-e2e': [{ file: 'apps/demo-e2e/src/main.ts', hash: 'some-hash' }],
|
||||
ui: [{ file: 'libs/ui/src/index.ts', hash: 'some-hash' }],
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -1,4 +1,8 @@
|
||||
import { toOldFormatOrNull, Workspaces } from '@nrwl/tao/src/shared/workspace';
|
||||
import {
|
||||
toOldFormatOrNull,
|
||||
WorkspaceJsonConfiguration,
|
||||
Workspaces,
|
||||
} from '@nrwl/tao/src/shared/workspace';
|
||||
import type {
|
||||
FileData,
|
||||
NxJsonConfiguration,
|
||||
@ -17,6 +21,7 @@ import { fileExists, readJsonFile } from '../utilities/fileutils';
|
||||
import { jsonDiff } from '../utilities/json-diff';
|
||||
import { defaultFileHasher } from './hasher/file-hasher';
|
||||
import type { Environment } from './shared-interfaces';
|
||||
import { projectFileDataCompatAdapter } from './project-graph/project-graph';
|
||||
|
||||
const ignore = require('ignore');
|
||||
|
||||
@ -114,13 +119,13 @@ function getFileData(filePath: string): FileData {
|
||||
return {
|
||||
file,
|
||||
hash: defaultFileHasher.hashFile(filePath),
|
||||
ext: extname(filePath),
|
||||
};
|
||||
}
|
||||
|
||||
export function allFilesInDir(
|
||||
dirName: string,
|
||||
recurse: boolean = true
|
||||
recurse: boolean = true,
|
||||
projectGraphVersion = '3.0'
|
||||
): FileData[] {
|
||||
const ignoredGlobs = getIgnoredGlobs();
|
||||
const relDirName = relative(appRootPath, dirName);
|
||||
@ -139,9 +144,14 @@ export function allFilesInDir(
|
||||
const s = statSync(child);
|
||||
if (!s.isDirectory()) {
|
||||
// add starting with "apps/myapp/..." or "libs/mylib/..."
|
||||
res.push(getFileData(child));
|
||||
res.push(
|
||||
projectFileDataCompatAdapter(
|
||||
getFileData(child),
|
||||
projectGraphVersion
|
||||
)
|
||||
);
|
||||
} else if (s.isDirectory() && recurse) {
|
||||
res = [...res, ...allFilesInDir(child)];
|
||||
res = [...res, ...allFilesInDir(child, true, projectGraphVersion)];
|
||||
}
|
||||
} catch (e) {}
|
||||
});
|
||||
@ -160,7 +170,7 @@ export function readFileIfExisting(path: string) {
|
||||
return existsSync(path) ? readFileSync(path, 'utf-8') : '';
|
||||
}
|
||||
|
||||
export function readWorkspaceJson() {
|
||||
export function readWorkspaceJson(): WorkspaceJsonConfiguration {
|
||||
return readWorkspaceConfig({
|
||||
format: 'nx',
|
||||
path: appRootPath,
|
||||
@ -234,20 +244,28 @@ export function rootWorkspaceFileNames(): string[] {
|
||||
return [`package.json`, workspaceFileName(), `nx.json`, `tsconfig.base.json`];
|
||||
}
|
||||
|
||||
export function rootWorkspaceFileData(): FileData[] {
|
||||
export function rootWorkspaceFileData(projectGraphVersion = '3.0'): FileData[] {
|
||||
return rootWorkspaceFileNames().map((f) =>
|
||||
getFileData(`${appRootPath}/${f}`)
|
||||
projectFileDataCompatAdapter(
|
||||
getFileData(`${appRootPath}/${f}`),
|
||||
projectGraphVersion
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
export function readWorkspaceFiles(): FileData[] {
|
||||
export function readWorkspaceFiles(projectGraphVersion = '3.0'): FileData[] {
|
||||
performance.mark('read workspace files:start');
|
||||
|
||||
if (defaultFileHasher.usesGitForHashing) {
|
||||
const ignoredGlobs = getIgnoredGlobs();
|
||||
const r = defaultFileHasher.workspaceFiles
|
||||
.filter((f) => !ignoredGlobs.ignores(f))
|
||||
.map((f) => getFileData(`${appRootPath}/${f}`));
|
||||
.map((f) =>
|
||||
projectFileDataCompatAdapter(
|
||||
getFileData(`${appRootPath}/${f}`),
|
||||
projectGraphVersion
|
||||
)
|
||||
);
|
||||
performance.mark('read workspace files:end');
|
||||
performance.measure(
|
||||
'read workspace files',
|
||||
@ -258,15 +276,24 @@ export function readWorkspaceFiles(): FileData[] {
|
||||
return r;
|
||||
} else {
|
||||
const r = [];
|
||||
r.push(...rootWorkspaceFileData());
|
||||
r.push(...rootWorkspaceFileData(projectGraphVersion));
|
||||
|
||||
// Add known workspace files and directories
|
||||
appendArray(r, allFilesInDir(appRootPath, false));
|
||||
appendArray(r, allFilesInDir(`${appRootPath}/tools`));
|
||||
appendArray(r, allFilesInDir(appRootPath, false, projectGraphVersion));
|
||||
appendArray(
|
||||
r,
|
||||
allFilesInDir(`${appRootPath}/tools`, true, projectGraphVersion)
|
||||
);
|
||||
const wl = workspaceLayout();
|
||||
appendArray(r, allFilesInDir(`${appRootPath}/${wl.appsDir}`));
|
||||
appendArray(
|
||||
r,
|
||||
allFilesInDir(`${appRootPath}/${wl.appsDir}`, true, projectGraphVersion)
|
||||
);
|
||||
if (wl.appsDir !== wl.libsDir) {
|
||||
appendArray(r, allFilesInDir(`${appRootPath}/${wl.libsDir}`));
|
||||
appendArray(
|
||||
r,
|
||||
allFilesInDir(`${appRootPath}/${wl.libsDir}`, true, projectGraphVersion)
|
||||
);
|
||||
}
|
||||
performance.mark('read workspace files:end');
|
||||
performance.measure(
|
||||
|
||||
@ -44,7 +44,7 @@ describe('Hasher', () => {
|
||||
type: 'lib',
|
||||
data: {
|
||||
root: '',
|
||||
files: [{ file: '/file', ext: '.ts', hash: 'file.hash' }],
|
||||
files: [{ file: '/file.ts', hash: 'file.hash' }],
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -75,7 +75,7 @@ describe('Hasher', () => {
|
||||
|
||||
expect(hash.details.command).toEqual('proj|build||{"prop":"prop-value"}');
|
||||
expect(hash.details.nodes).toEqual({
|
||||
proj: '/file|file.hash|{"root":"proj-from-workspace.json"}|"proj-from-nx.json"',
|
||||
proj: '/file.ts|file.hash|{"root":"proj-from-workspace.json"}|"proj-from-nx.json"',
|
||||
});
|
||||
expect(hash.details.implicitDeps).toEqual({
|
||||
'yarn.lock': 'yarn.lock.hash',
|
||||
@ -99,7 +99,7 @@ describe('Hasher', () => {
|
||||
type: 'lib',
|
||||
data: {
|
||||
root: '',
|
||||
files: [{ file: '/file', ext: '.ts', hash: 'some-hash' }],
|
||||
files: [{ file: '/file.ts', hash: 'some-hash' }],
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -143,7 +143,7 @@ describe('Hasher', () => {
|
||||
type: 'lib',
|
||||
data: {
|
||||
root: '',
|
||||
files: [{ file: '/filea', ext: '.ts', hash: 'a.hash' }],
|
||||
files: [{ file: '/filea.ts', hash: 'a.hash' }],
|
||||
},
|
||||
},
|
||||
child: {
|
||||
@ -151,7 +151,7 @@ describe('Hasher', () => {
|
||||
type: 'lib',
|
||||
data: {
|
||||
root: '',
|
||||
files: [{ file: '/fileb', ext: '.ts', hash: 'b.hash' }],
|
||||
files: [{ file: '/fileb.ts', hash: 'b.hash' }],
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -172,8 +172,8 @@ describe('Hasher', () => {
|
||||
|
||||
// note that the parent hash is based on parent source files only!
|
||||
expect(hash.details.nodes).toEqual({
|
||||
parent: '/filea|a.hash|""|""',
|
||||
child: '/fileb|b.hash|""|""',
|
||||
parent: '/filea.ts|a.hash|""|""',
|
||||
child: '/fileb.ts|b.hash|""|""',
|
||||
});
|
||||
});
|
||||
|
||||
@ -188,7 +188,7 @@ describe('Hasher', () => {
|
||||
type: 'lib',
|
||||
data: {
|
||||
root: '',
|
||||
files: [{ file: '/filea', ext: '.ts', hash: 'a.hash' }],
|
||||
files: [{ file: '/filea.ts', hash: 'a.hash' }],
|
||||
},
|
||||
},
|
||||
projb: {
|
||||
@ -196,7 +196,7 @@ describe('Hasher', () => {
|
||||
type: 'lib',
|
||||
data: {
|
||||
root: '',
|
||||
files: [{ file: '/fileb', ext: '.ts', hash: 'b.hash' }],
|
||||
files: [{ file: '/fileb.ts', hash: 'b.hash' }],
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -223,8 +223,8 @@ describe('Hasher', () => {
|
||||
expect(tasksHash.value).toContain('proj'); //project
|
||||
expect(tasksHash.value).toContain('build'); //target
|
||||
expect(tasksHash.details.nodes).toEqual({
|
||||
proja: '/filea|a.hash|""|""',
|
||||
projb: '/fileb|b.hash|""|""',
|
||||
proja: '/filea.ts|a.hash|""|""',
|
||||
projb: '/fileb.ts|b.hash|""|""',
|
||||
});
|
||||
|
||||
const hashb = await hasher.hashTaskWithDepsAndContext({
|
||||
@ -240,8 +240,8 @@ describe('Hasher', () => {
|
||||
expect(hashb.value).toContain('proj'); //project
|
||||
expect(hashb.value).toContain('build'); //target
|
||||
expect(hashb.details.nodes).toEqual({
|
||||
proja: '/filea|a.hash|""|""',
|
||||
projb: '/fileb|b.hash|""|""',
|
||||
proja: '/filea.ts|a.hash|""|""',
|
||||
projb: '/fileb.ts|b.hash|""|""',
|
||||
});
|
||||
});
|
||||
|
||||
@ -265,12 +265,10 @@ describe('Hasher', () => {
|
||||
{
|
||||
file: 'global1',
|
||||
hash: 'hash1',
|
||||
ext: '',
|
||||
},
|
||||
{
|
||||
file: 'global2',
|
||||
hash: 'hash2',
|
||||
ext: '',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
@ -102,7 +102,6 @@ describe('nx deps utils', () => {
|
||||
files: [
|
||||
{
|
||||
file: 'index.ts',
|
||||
ext: 'ts',
|
||||
hash: 'hash1',
|
||||
},
|
||||
],
|
||||
@ -116,7 +115,6 @@ describe('nx deps utils', () => {
|
||||
mylib: [
|
||||
{
|
||||
file: 'index.ts',
|
||||
ext: 'ts',
|
||||
hash: 'hash1',
|
||||
},
|
||||
],
|
||||
@ -131,7 +129,6 @@ describe('nx deps utils', () => {
|
||||
mylib: {
|
||||
'index.ts': {
|
||||
file: 'index.ts',
|
||||
ext: 'ts',
|
||||
hash: 'hash1',
|
||||
},
|
||||
},
|
||||
@ -148,7 +145,6 @@ describe('nx deps utils', () => {
|
||||
files: [
|
||||
{
|
||||
file: 'index.ts',
|
||||
ext: 'ts',
|
||||
hash: 'hash1',
|
||||
},
|
||||
],
|
||||
@ -162,14 +158,12 @@ describe('nx deps utils', () => {
|
||||
mylib: [
|
||||
{
|
||||
file: 'index.ts',
|
||||
ext: 'ts',
|
||||
hash: 'hash1',
|
||||
},
|
||||
],
|
||||
secondlib: [
|
||||
{
|
||||
file: 'index.ts',
|
||||
ext: 'ts',
|
||||
hash: 'hash2',
|
||||
},
|
||||
],
|
||||
@ -183,7 +177,6 @@ describe('nx deps utils', () => {
|
||||
secondlib: [
|
||||
{
|
||||
file: 'index.ts',
|
||||
ext: 'ts',
|
||||
hash: 'hash2',
|
||||
},
|
||||
],
|
||||
@ -192,13 +185,12 @@ describe('nx deps utils', () => {
|
||||
mylib: {
|
||||
'index.ts': {
|
||||
file: 'index.ts',
|
||||
ext: 'ts',
|
||||
hash: 'hash1',
|
||||
},
|
||||
},
|
||||
});
|
||||
expect(r.filesToProcess).toEqual({
|
||||
secondlib: [{ ext: 'ts', file: 'index.ts', hash: 'hash2' }],
|
||||
secondlib: [{ file: 'index.ts', hash: 'hash2' }],
|
||||
});
|
||||
});
|
||||
|
||||
@ -212,17 +204,14 @@ describe('nx deps utils', () => {
|
||||
files: [
|
||||
{
|
||||
file: 'index1.ts',
|
||||
ext: 'ts',
|
||||
hash: 'hash1',
|
||||
},
|
||||
{
|
||||
file: 'index2.ts',
|
||||
ext: 'ts',
|
||||
hash: 'hash2',
|
||||
},
|
||||
{
|
||||
file: 'index3.ts',
|
||||
ext: 'ts',
|
||||
hash: 'hash3',
|
||||
},
|
||||
],
|
||||
@ -236,17 +225,14 @@ describe('nx deps utils', () => {
|
||||
mylib: [
|
||||
{
|
||||
file: 'index1.ts',
|
||||
ext: 'ts',
|
||||
hash: 'hash1',
|
||||
},
|
||||
{
|
||||
file: 'index2.ts',
|
||||
ext: 'ts',
|
||||
hash: 'hash2b',
|
||||
},
|
||||
{
|
||||
file: 'index4.ts',
|
||||
ext: 'ts',
|
||||
hash: 'hash4',
|
||||
},
|
||||
],
|
||||
@ -260,12 +246,10 @@ describe('nx deps utils', () => {
|
||||
mylib: [
|
||||
{
|
||||
file: 'index2.ts',
|
||||
ext: 'ts',
|
||||
hash: 'hash2b',
|
||||
},
|
||||
{
|
||||
file: 'index4.ts',
|
||||
ext: 'ts',
|
||||
hash: 'hash4',
|
||||
},
|
||||
],
|
||||
@ -274,7 +258,6 @@ describe('nx deps utils', () => {
|
||||
mylib: {
|
||||
'index1.ts': {
|
||||
file: 'index1.ts',
|
||||
ext: 'ts',
|
||||
hash: 'hash1',
|
||||
},
|
||||
},
|
||||
|
||||
@ -92,7 +92,7 @@ export function writeCache(
|
||||
version: packageJsonDeps[p],
|
||||
}));
|
||||
const newValue: ProjectGraphCache = {
|
||||
version: '3.0',
|
||||
version: projectGraph.version || '4.0',
|
||||
deps: packageJsonDeps,
|
||||
pathMappings: tsConfig.compilerOptions.paths || {},
|
||||
nxJsonPlugins,
|
||||
@ -119,7 +119,9 @@ export function shouldRecomputeWholeGraph(
|
||||
if (
|
||||
Object.keys(cache.nodes).some(
|
||||
(p) =>
|
||||
(cache.nodes[p].type === 'app' || cache.nodes[p].type === 'lib') &&
|
||||
(cache.nodes[p].type === 'app' ||
|
||||
cache.nodes[p].type === 'lib' ||
|
||||
cache.nodes[p].type === 'e2e') &&
|
||||
!workspaceJson.projects[p]
|
||||
)
|
||||
) {
|
||||
|
||||
@ -4,7 +4,12 @@ jest.mock('fs', () => require('memfs').fs);
|
||||
jest.mock('@nrwl/tao/src/utils/app-root', () => ({
|
||||
appRootPath: '/root',
|
||||
}));
|
||||
import { createProjectGraphAsync } from './project-graph';
|
||||
import {
|
||||
createProjectGraphAsync,
|
||||
projectFileDataCompatAdapter,
|
||||
projectGraphMigrate3to4,
|
||||
projectGraphCompat4to3,
|
||||
} from './project-graph';
|
||||
import {
|
||||
NxJsonConfiguration,
|
||||
stripIndents,
|
||||
@ -239,4 +244,170 @@ describe('project graph', () => {
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
describe('project graph adapters', () => {
|
||||
it('should map FileData to deprecated graph version', () => {
|
||||
expect(
|
||||
projectFileDataCompatAdapter({ file: 'a.ts', hash: 'some hash' }, '3.0')
|
||||
).toEqual({ file: 'a.ts', hash: 'some hash', ext: '.ts' });
|
||||
expect(
|
||||
projectFileDataCompatAdapter(
|
||||
{
|
||||
file: 'a.ts',
|
||||
hash: 'some hash',
|
||||
deps: [],
|
||||
},
|
||||
'3.0'
|
||||
)
|
||||
).toEqual({ file: 'a.ts', hash: 'some hash', ext: '.ts', deps: [] });
|
||||
expect(
|
||||
projectFileDataCompatAdapter(
|
||||
{
|
||||
file: 'a.ts',
|
||||
hash: 'some hash',
|
||||
ext: '.keepthis',
|
||||
},
|
||||
'3.0'
|
||||
)
|
||||
).toEqual({ file: 'a.ts', hash: 'some hash', ext: '.keepthis' });
|
||||
});
|
||||
it('should map FileData to latest graph version', () => {
|
||||
expect(
|
||||
projectFileDataCompatAdapter(
|
||||
{ file: 'a.ts', hash: 'some hash', ext: '.ts' },
|
||||
'4.0'
|
||||
)
|
||||
).toEqual({ file: 'a.ts', hash: 'some hash' });
|
||||
expect(
|
||||
projectFileDataCompatAdapter(
|
||||
{ file: 'a.ts', hash: 'some hash', ext: '.ts', deps: [] },
|
||||
'4.0'
|
||||
)
|
||||
).toEqual({ file: 'a.ts', hash: 'some hash', deps: [] });
|
||||
});
|
||||
it('should map nodes to deprecated graph version', () => {
|
||||
const source = {
|
||||
nodes: {
|
||||
node1: {
|
||||
name: 'node1',
|
||||
type: 'app',
|
||||
data: {
|
||||
files: [
|
||||
{ file: 'index.ts', hash: 'some hash' },
|
||||
{
|
||||
file: 'node1.jpeg',
|
||||
hash: 'some hash',
|
||||
ext: '.keepextension',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
node2: {
|
||||
name: 'node2',
|
||||
type: 'lib',
|
||||
data: {
|
||||
files: [{ file: 'node2.html', hash: 'some hash', deps: [] }],
|
||||
},
|
||||
},
|
||||
},
|
||||
dependencies: {},
|
||||
version: '4.0',
|
||||
};
|
||||
const result = {
|
||||
nodes: {
|
||||
node1: {
|
||||
name: 'node1',
|
||||
type: 'app',
|
||||
data: {
|
||||
files: [
|
||||
{ file: 'index.ts', hash: 'some hash', ext: '.ts' },
|
||||
{
|
||||
file: 'node1.jpeg',
|
||||
hash: 'some hash',
|
||||
ext: '.keepextension',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
node2: {
|
||||
name: 'node2',
|
||||
type: 'lib',
|
||||
data: {
|
||||
files: [
|
||||
{
|
||||
file: 'node2.html',
|
||||
hash: 'some hash',
|
||||
deps: [],
|
||||
ext: '.html',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
dependencies: {},
|
||||
version: '3.0',
|
||||
};
|
||||
expect(projectGraphCompat4to3(source)).toEqual(result);
|
||||
});
|
||||
it('should map nodes to latest graph version', () => {
|
||||
const source = {
|
||||
nodes: {
|
||||
node1: {
|
||||
name: 'node1',
|
||||
type: 'app',
|
||||
data: {
|
||||
files: [
|
||||
{ file: 'index.ts', hash: 'some hash', ext: '.ts' },
|
||||
{
|
||||
file: 'node1.jpeg',
|
||||
hash: 'some hash',
|
||||
ext: '.keepextension',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
node2: {
|
||||
name: 'node2',
|
||||
type: 'lib',
|
||||
data: {
|
||||
files: [
|
||||
{
|
||||
file: 'node2.html',
|
||||
hash: 'some hash',
|
||||
deps: [],
|
||||
ext: '.html',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
dependencies: {},
|
||||
version: '3.0',
|
||||
};
|
||||
const result = {
|
||||
nodes: {
|
||||
node1: {
|
||||
name: 'node1',
|
||||
type: 'app',
|
||||
data: {
|
||||
files: [
|
||||
{ file: 'index.ts', hash: 'some hash' },
|
||||
{ file: 'node1.jpeg', hash: 'some hash' },
|
||||
],
|
||||
},
|
||||
},
|
||||
node2: {
|
||||
name: 'node2',
|
||||
type: 'lib',
|
||||
data: {
|
||||
files: [{ file: 'node2.html', hash: 'some hash', deps: [] }],
|
||||
},
|
||||
},
|
||||
},
|
||||
dependencies: {},
|
||||
version: '4.0',
|
||||
};
|
||||
expect(projectGraphMigrate3to4(source)).toEqual(result);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -6,12 +6,13 @@ import type {
|
||||
ProjectConfiguration,
|
||||
ProjectFileMap,
|
||||
ProjectGraph,
|
||||
ProjectGraphNode,
|
||||
ProjectGraphProcessorContext,
|
||||
WorkspaceJsonConfiguration,
|
||||
} from '@nrwl/devkit';
|
||||
import { ProjectGraphBuilder, readJsonFile, logger } from '@nrwl/devkit';
|
||||
import { appRootPath } from '@nrwl/tao/src/utils/app-root';
|
||||
import { join } from 'path';
|
||||
import { join, extname } from 'path';
|
||||
import { performance } from 'perf_hooks';
|
||||
import { assertWorkspaceValidity } from '../assert-workspace-validity';
|
||||
import { createProjectFileMap } from '../file-graph';
|
||||
@ -41,27 +42,127 @@ import {
|
||||
/**
|
||||
* Synchronously reads the latest cached copy of the workspace's ProjectGraph.
|
||||
* @throws {Error} if there is no cached ProjectGraph to read from
|
||||
|
||||
* @param {string} projectGraphVersion Version to map ProjectGraph to
|
||||
* @returns {ProjectGraph}
|
||||
*/
|
||||
export function readCachedProjectGraph(): ProjectGraph {
|
||||
export function readCachedProjectGraph(
|
||||
projectGraphVersion = '3.0'
|
||||
): ProjectGraph {
|
||||
const projectGraphCache: ProjectGraphCache | false = readCache();
|
||||
if (!projectGraphCache) {
|
||||
throw new Error(`
|
||||
[readCachedProjectGraph] ERROR: No cached ProjectGraph is available.
|
||||
|
||||
|
||||
If you are leveraging \`readCachedProjectGraph()\` directly then you will need to refactor your usage to first ensure that
|
||||
the ProjectGraph is created by calling \`await createProjectGraphAsync()\` somewhere before attempting to read the data.
|
||||
|
||||
If you encounter this error as part of running standard \`nx\` commands then please open an issue on https://github.com/nrwl/nx
|
||||
`);
|
||||
}
|
||||
return {
|
||||
let projectGraph: ProjectGraph = {
|
||||
version: projectGraphCache.version,
|
||||
nodes: projectGraphCache.nodes,
|
||||
dependencies: projectGraphCache.dependencies,
|
||||
};
|
||||
if (projectGraphVersion !== projectGraph.version) {
|
||||
projectGraph =
|
||||
projectGraphVersion === '3.0'
|
||||
? projectGraphCompat4to3(projectGraph)
|
||||
: projectGraphMigrate3to4(projectGraph);
|
||||
}
|
||||
return projectGraph;
|
||||
}
|
||||
|
||||
export async function createProjectGraphAsync(): Promise<ProjectGraph> {
|
||||
return createProjectGraph();
|
||||
/**
|
||||
* Migrate project graph from v3 to v4
|
||||
* @param {ProjectGraph} projectGraph
|
||||
*/
|
||||
export function projectGraphMigrate3to4(
|
||||
projectGraph: ProjectGraph
|
||||
): ProjectGraph {
|
||||
const nodes: Record<string, ProjectGraphNode> = {};
|
||||
Object.entries(projectGraph.nodes).forEach(([name, node]) => {
|
||||
const files = node.data.files.map(({ file, hash, deps }) => ({
|
||||
file,
|
||||
hash,
|
||||
...(deps && { deps }),
|
||||
}));
|
||||
nodes[name] = {
|
||||
...node,
|
||||
data: {
|
||||
...node.data,
|
||||
files,
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
return {
|
||||
...projectGraph,
|
||||
nodes,
|
||||
version: '4.0',
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Backwards compatibility adapter for project Nodes
|
||||
* @param {ProjectGraph} projectGraph
|
||||
* @returns {ProjectGraph}
|
||||
*/
|
||||
export function projectGraphCompat4to3(
|
||||
projectGraph: ProjectGraph
|
||||
): ProjectGraph {
|
||||
const nodes: Record<string, ProjectGraphNode> = {};
|
||||
Object.entries(projectGraph.nodes).forEach(([name, node]) => {
|
||||
const files = node.data.files.map(({ file, hash, ext, deps }) => ({
|
||||
file,
|
||||
hash,
|
||||
ext: ext || extname(file),
|
||||
...(deps && { deps }),
|
||||
}));
|
||||
nodes[name] = {
|
||||
...node,
|
||||
data: {
|
||||
...node.data,
|
||||
files,
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
return {
|
||||
...projectGraph,
|
||||
nodes,
|
||||
version: '3.0',
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Backwards compatibility adapter for FileData
|
||||
* @param {FileData} fileData
|
||||
* @param {string?} projectGraphVersion
|
||||
* @returns
|
||||
*/
|
||||
export function projectFileDataCompatAdapter(
|
||||
fileData: FileData,
|
||||
projectGraphVersion: string
|
||||
): FileData {
|
||||
const { file, hash, ext, deps } = fileData;
|
||||
if (projectGraphVersion !== '3.0') {
|
||||
return { file, hash, ...{ deps } };
|
||||
} else {
|
||||
return { file, hash, ext: ext || extname(file), ...{ deps } };
|
||||
}
|
||||
}
|
||||
|
||||
export async function createProjectGraphAsync(
|
||||
projectGraphVersion = '3.0'
|
||||
): Promise<ProjectGraph> {
|
||||
return createProjectGraph(
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
projectGraphVersion
|
||||
);
|
||||
}
|
||||
|
||||
function readCombinedDeps() {
|
||||
@ -74,10 +175,16 @@ function readCombinedDeps() {
|
||||
* @deprecated This function is deprecated in favor of the new asynchronous version {@link createProjectGraphAsync}
|
||||
*/
|
||||
export function createProjectGraph(
|
||||
workspaceJson = readWorkspaceJson(),
|
||||
nxJson = readNxJson(),
|
||||
workspaceFiles = readWorkspaceFiles()
|
||||
workspaceJson?: WorkspaceJsonConfiguration,
|
||||
nxJson?: NxJsonConfiguration,
|
||||
workspaceFiles?: FileData[],
|
||||
projectGraphVersion?: string
|
||||
): ProjectGraph {
|
||||
projectGraphVersion = projectGraphVersion || '3.0';
|
||||
workspaceJson = workspaceJson || readWorkspaceJson();
|
||||
nxJson = nxJson || readNxJson();
|
||||
workspaceFiles = workspaceFiles || readWorkspaceFiles(projectGraphVersion);
|
||||
|
||||
const cacheEnabled = process.env.NX_CACHE_PROJECT_GRAPH !== 'false';
|
||||
let cache = cacheEnabled ? readCache() : false;
|
||||
assertWorkspaceValidity(workspaceJson, nxJson);
|
||||
@ -90,15 +197,14 @@ export function createProjectGraph(
|
||||
let cachedFileData = {};
|
||||
if (
|
||||
cache &&
|
||||
cache.version === '3.0' &&
|
||||
(cache.version === '3.0' || cache.version === '4.0') &&
|
||||
!shouldRecomputeWholeGraph(
|
||||
cache,
|
||||
packageJsonDeps,
|
||||
workspaceJson,
|
||||
normalizedNxJson,
|
||||
rootTsConfig
|
||||
) &&
|
||||
cacheEnabled
|
||||
)
|
||||
) {
|
||||
const fromCache = extractCachedFileData(projectFileMap, cache);
|
||||
filesToProcess = fromCache.filesToProcess;
|
||||
@ -110,7 +216,17 @@ export function createProjectGraph(
|
||||
projectFileMap,
|
||||
filesToProcess
|
||||
);
|
||||
const projectGraph = buildProjectGraph(context, cachedFileData);
|
||||
let projectGraph = buildProjectGraph(
|
||||
context,
|
||||
cachedFileData,
|
||||
projectGraphVersion
|
||||
);
|
||||
if (cache && cache.version && projectGraphVersion !== cache.version) {
|
||||
projectGraph =
|
||||
projectGraphVersion === '3.0'
|
||||
? projectGraphCompat4to3(projectGraph)
|
||||
: projectGraphMigrate3to4(projectGraph);
|
||||
}
|
||||
if (cacheEnabled) {
|
||||
writeCache(packageJsonDeps, nxJson, rootTsConfig, projectGraph);
|
||||
}
|
||||
@ -135,7 +251,8 @@ function addWorkspaceFiles(
|
||||
|
||||
function buildProjectGraph(
|
||||
ctx: ProjectGraphProcessorContext,
|
||||
cachedFileData: { [project: string]: { [file: string]: FileData } }
|
||||
cachedFileData: { [project: string]: { [file: string]: FileData } },
|
||||
projectGraphVersion: string
|
||||
) {
|
||||
performance.mark('build project graph:start');
|
||||
|
||||
@ -155,6 +272,7 @@ function buildProjectGraph(
|
||||
buildExplicitTypeScriptDependencies(ctx, builder);
|
||||
buildExplicitPackageJsonDependencies(ctx, builder);
|
||||
buildImplicitProjectDependencies(ctx, builder);
|
||||
builder.setVersion(projectGraphVersion);
|
||||
const initProjectGraph = builder.getUpdatedProjectGraph();
|
||||
|
||||
const r = updateProjectGraphWithPlugins(ctx, initProjectGraph);
|
||||
@ -175,16 +293,16 @@ function createContext(
|
||||
fileMap: ProjectFileMap,
|
||||
filesToProcess: ProjectFileMap
|
||||
): ProjectGraphProcessorContext {
|
||||
const projects = Object.keys(workspaceJson.projects).reduce(
|
||||
(map, projectName) => {
|
||||
map[projectName] = {
|
||||
...workspaceJson.projects[projectName],
|
||||
...nxJson.projects[projectName],
|
||||
};
|
||||
return map;
|
||||
},
|
||||
{} as Record<string, ProjectConfiguration & NxJsonProjectConfiguration>
|
||||
);
|
||||
const projects: Record<
|
||||
string,
|
||||
ProjectConfiguration & NxJsonProjectConfiguration
|
||||
> = Object.keys(workspaceJson.projects).reduce((map, projectName) => {
|
||||
map[projectName] = {
|
||||
...workspaceJson.projects[projectName],
|
||||
...nxJson.projects[projectName],
|
||||
};
|
||||
return map;
|
||||
}, {});
|
||||
return {
|
||||
workspace: {
|
||||
...workspaceJson,
|
||||
|
||||
@ -77,14 +77,12 @@ describe('findTargetProjectWithImport', () => {
|
||||
{
|
||||
file: 'libs/proj/index.ts',
|
||||
hash: 'some-hash',
|
||||
ext: '.ts',
|
||||
},
|
||||
],
|
||||
proj2: [
|
||||
{
|
||||
file: 'libs/proj2/index.ts',
|
||||
hash: 'some-hash',
|
||||
ext: '.ts',
|
||||
},
|
||||
{
|
||||
file: 'libs/proj2/deep/index.ts',
|
||||
@ -96,14 +94,12 @@ describe('findTargetProjectWithImport', () => {
|
||||
{
|
||||
file: 'libs/proj3a/index.ts',
|
||||
hash: 'some-hash',
|
||||
ext: '.ts',
|
||||
},
|
||||
],
|
||||
proj4ab: [
|
||||
{
|
||||
file: 'libs/proj4ab/index.ts',
|
||||
hash: 'some-hash',
|
||||
ext: '.ts',
|
||||
},
|
||||
],
|
||||
proj5: [
|
||||
@ -131,21 +127,18 @@ describe('findTargetProjectWithImport', () => {
|
||||
{
|
||||
file: 'libs/proj123/index.ts',
|
||||
hash: 'some-hash',
|
||||
ext: '.ts',
|
||||
},
|
||||
],
|
||||
proj1234: [
|
||||
{
|
||||
file: 'libs/proj1234/index.ts',
|
||||
hash: 'some-hash',
|
||||
ext: '.ts',
|
||||
},
|
||||
],
|
||||
'proj1234-child': [
|
||||
{
|
||||
file: 'libs/proj1234-child/index.ts',
|
||||
hash: 'some-hash',
|
||||
ext: '.ts',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
@ -18,7 +18,7 @@ export async function tscExecutor(
|
||||
const normalizedOptions = normalizeOptions(options, context);
|
||||
// const projectRoot = context.workspace.projects[context.projectName].root;
|
||||
|
||||
const projectGraph = readCachedProjectGraph();
|
||||
const projectGraph = readCachedProjectGraph('4.0');
|
||||
const { target, dependencies } = calculateProjectDependencies(
|
||||
projectGraph,
|
||||
context.root,
|
||||
|
||||
@ -16,7 +16,7 @@ export async function checkDependencies(_, schema: Schema): Promise<void> {
|
||||
return;
|
||||
}
|
||||
|
||||
const graph: ProjectGraph = await createProjectGraphAsync();
|
||||
const graph: ProjectGraph = await createProjectGraphAsync('4.0');
|
||||
|
||||
const reverseGraph = onlyWorkspaceProjects(reverse(graph));
|
||||
|
||||
|
||||
@ -10,6 +10,7 @@ import {
|
||||
import { Rule } from './nxEnforceModuleBoundariesRule';
|
||||
import { TargetProjectLocator } from '../core/target-project-locator';
|
||||
import { mapProjectGraphFiles } from '../utils/runtime-lint-utils';
|
||||
import { FileData } from 'packages/devkit/src/project-graph/interfaces';
|
||||
|
||||
jest.mock('fs', () => require('memfs').fs);
|
||||
jest.mock('@nrwl/tao/src/utils/app-root', () => ({ appRootPath: '/root' }));
|
||||
@ -1155,8 +1156,8 @@ describe('Enforce Module Boundaries (tslint)', () => {
|
||||
});
|
||||
});
|
||||
|
||||
function createFile(f) {
|
||||
return { file: f, ext: extname(f), hash: '' };
|
||||
function createFile(f): FileData {
|
||||
return { file: f, hash: '' };
|
||||
}
|
||||
|
||||
function runRule(
|
||||
|
||||
@ -51,7 +51,7 @@ export class Rule extends Lint.Rules.AbstractRule {
|
||||
*/
|
||||
try {
|
||||
(global as any).projectGraph = mapProjectGraphFiles(
|
||||
readCachedProjectGraph()
|
||||
readCachedProjectGraph('4.0')
|
||||
);
|
||||
} catch {}
|
||||
}
|
||||
|
||||
@ -6,5 +6,5 @@ import { createProjectGraph } from '../core/project-graph/project-graph';
|
||||
* @deprecated This method is deprecated and `await {@link createProjectGraphAsync}()` should be used instead
|
||||
*/
|
||||
export function createProjectGraphFromTree(tree: Tree) {
|
||||
return createProjectGraph(undefined, undefined, undefined);
|
||||
return createProjectGraph(undefined, undefined, undefined, '3.0');
|
||||
}
|
||||
|
||||
@ -17,7 +17,7 @@ export function createGlobPatternsForDependencies(
|
||||
fileGlobPattern: string
|
||||
): string[] {
|
||||
const filenameRelativeToWorkspaceRoot = relative(appRootPath, dirPath);
|
||||
const projectGraph = readCachedProjectGraph();
|
||||
const projectGraph = readCachedProjectGraph('4.0');
|
||||
|
||||
// find the project
|
||||
let projectName;
|
||||
|
||||
@ -20,7 +20,7 @@ export function projectHasTargetAndConfiguration(
|
||||
|
||||
export function getSourceDirOfDependentProjects(
|
||||
projectName: string,
|
||||
projectGraph = readCachedProjectGraph()
|
||||
projectGraph = readCachedProjectGraph('4.0')
|
||||
): string[] {
|
||||
if (!projectGraph.nodes[projectName]) {
|
||||
throw new Error(
|
||||
@ -41,7 +41,7 @@ export function getSourceDirOfDependentProjects(
|
||||
*/
|
||||
export function getProjectNameFromDirPath(
|
||||
projRelativeDirPath: string,
|
||||
projectGraph = readCachedProjectGraph()
|
||||
projectGraph = readCachedProjectGraph('4.0')
|
||||
) {
|
||||
let parentNodeName = null;
|
||||
for (const [nodeName, node] of Object.entries(projectGraph.nodes)) {
|
||||
@ -75,7 +75,7 @@ export function getProjectNameFromDirPath(
|
||||
*/
|
||||
function findAllProjectNodeDependencies(
|
||||
parentNodeName: string,
|
||||
projectGraph = readCachedProjectGraph()
|
||||
projectGraph = readCachedProjectGraph('4.0')
|
||||
): string[] {
|
||||
const dependencyNodeNames = new Set<string>();
|
||||
|
||||
|
||||
@ -367,7 +367,9 @@ export function readJsonInTree<T extends object = any>(
|
||||
* Method for utilizing the project graph in schematics
|
||||
*/
|
||||
export function getProjectGraphFromHost(host: Tree): ProjectGraph {
|
||||
return onlyWorkspaceProjects(createProjectGraph());
|
||||
return onlyWorkspaceProjects(
|
||||
createProjectGraph(undefined, undefined, undefined, '3.0')
|
||||
);
|
||||
}
|
||||
|
||||
// TODO(v13): remove this deprecated method
|
||||
@ -375,7 +377,7 @@ export function getProjectGraphFromHost(host: Tree): ProjectGraph {
|
||||
* @deprecated This method is deprecated and `await {@link createProjectGraphAsync}()` should be used instead
|
||||
*/
|
||||
export function getFullProjectGraphFromHost(host: Tree): ProjectGraph {
|
||||
return createProjectGraph(undefined, undefined, undefined);
|
||||
return createProjectGraph(undefined, undefined, undefined, '3.0');
|
||||
}
|
||||
|
||||
// TODO(v13): remove this deprecated method
|
||||
|
||||
@ -42,7 +42,7 @@ function hasTag(proj: ProjectGraphNode, tag: string) {
|
||||
}
|
||||
|
||||
function removeExt(file: string): string {
|
||||
return file.replace(/\.[^/.]+$/, '');
|
||||
return file.replace(/(?<!(^|\/))\.[^/.]+$/, '');
|
||||
}
|
||||
|
||||
export function matchImportWithWildcard(
|
||||
@ -200,8 +200,8 @@ export function mapProjectGraphFiles<T>(
|
||||
const nodes: Record<string, MappedProjectGraphNode> = {};
|
||||
Object.entries(projectGraph.nodes).forEach(([name, node]) => {
|
||||
const files: Record<string, FileData> = {};
|
||||
node.data.files.forEach(({ file, hash, ext }) => {
|
||||
files[file.slice(0, -ext.length)] = { file, hash, ext };
|
||||
node.data.files.forEach(({ file, hash }) => {
|
||||
files[removeExt(file)] = { file, hash };
|
||||
});
|
||||
const data = { ...node.data, files };
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user