chore(core): remove globForProjectFiles (#18288)
This commit is contained in:
parent
b2763e1cc9
commit
2dda1914b5
@ -4,13 +4,8 @@ import {
|
|||||||
toProjectName,
|
toProjectName,
|
||||||
Workspaces,
|
Workspaces,
|
||||||
} from './workspaces';
|
} from './workspaces';
|
||||||
import { NxJsonConfiguration } from './nx-json';
|
|
||||||
import { vol } from 'memfs';
|
|
||||||
|
|
||||||
import * as fastGlob from 'fast-glob';
|
|
||||||
import { TargetConfiguration } from './workspace-json-project-json';
|
import { TargetConfiguration } from './workspace-json-project-json';
|
||||||
|
import { TempFs } from '../utils/testing/temp-fs';
|
||||||
jest.mock('fs', () => require('memfs').fs);
|
|
||||||
|
|
||||||
const libConfig = (name) => ({
|
const libConfig = (name) => ({
|
||||||
root: `libs/${name}`,
|
root: `libs/${name}`,
|
||||||
@ -24,26 +19,16 @@ const packageLibConfig = (root) => ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('Workspaces', () => {
|
describe('Workspaces', () => {
|
||||||
let globResults: string[];
|
let fs: TempFs;
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
globResults = [
|
fs = new TempFs('Workspaces');
|
||||||
'libs/lib1/package.json',
|
|
||||||
'libs/lib1/project.json',
|
|
||||||
'libs/lib2/package.json',
|
|
||||||
'libs/domain/lib3/package.json',
|
|
||||||
'libs/domain/lib4/project.json',
|
|
||||||
'libs/domain/lib4/package.json',
|
|
||||||
];
|
|
||||||
jest.spyOn(fastGlob, 'sync').mockImplementation(() => globResults);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
jest.resetAllMocks();
|
fs.cleanup();
|
||||||
vol.reset();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('readWorkspaceConfiguration', () => {
|
describe('readWorkspaceConfiguration', () => {
|
||||||
it('should be able to inline project configurations', () => {
|
it('should be able to inline project configurations', async () => {
|
||||||
const standaloneConfig = libConfig('lib1');
|
const standaloneConfig = libConfig('lib1');
|
||||||
|
|
||||||
const config = {
|
const config = {
|
||||||
@ -53,46 +38,41 @@ describe('Workspaces', () => {
|
|||||||
lib2: libConfig('lib2'),
|
lib2: libConfig('lib2'),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
vol.fromJSON(
|
await fs.createFiles({
|
||||||
{
|
'libs/lib1/project.json': JSON.stringify(standaloneConfig),
|
||||||
'libs/lib1/project.json': JSON.stringify(standaloneConfig),
|
'libs/lib2/package.json': JSON.stringify({}),
|
||||||
'libs/lib2/package.json': JSON.stringify({}),
|
'libs/domain/lib3/package.json': JSON.stringify({}),
|
||||||
'libs/domain/lib3/package.json': JSON.stringify({}),
|
'libs/domain/lib4/project.json': JSON.stringify({}),
|
||||||
'libs/domain/lib4/project.json': JSON.stringify({}),
|
'workspace.json': JSON.stringify(config),
|
||||||
'workspace.json': JSON.stringify(config),
|
});
|
||||||
},
|
|
||||||
'/root'
|
|
||||||
);
|
|
||||||
|
|
||||||
const workspaces = new Workspaces('/root');
|
const workspaces = new Workspaces(fs.tempDir);
|
||||||
const resolved = workspaces.readProjectsConfigurations();
|
const resolved = workspaces.readProjectsConfigurations();
|
||||||
expect(resolved.projects.lib1).toEqual(standaloneConfig);
|
expect(resolved.projects.lib1).toEqual(standaloneConfig);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should build project configurations from glob', () => {
|
it('should build project configurations from glob', async () => {
|
||||||
const lib1Config = libConfig('lib1');
|
const lib1Config = libConfig('lib1');
|
||||||
const lib2Config = packageLibConfig('libs/lib2');
|
const lib2Config = packageLibConfig('libs/lib2');
|
||||||
const domainPackageConfig = packageLibConfig('libs/domain/lib3');
|
const domainPackageConfig = packageLibConfig('libs/domain/lib3');
|
||||||
const domainLibConfig = libConfig('domain/lib4');
|
const domainLibConfig = libConfig('domain/lib4');
|
||||||
|
|
||||||
vol.fromJSON(
|
await fs.createFiles({
|
||||||
{
|
'libs/lib1/project.json': JSON.stringify(lib1Config),
|
||||||
'libs/lib1/project.json': JSON.stringify(lib1Config),
|
'libs/lib1/package.json': JSON.stringify({ name: 'some-other-name' }),
|
||||||
'libs/lib1/package.json': JSON.stringify({ name: 'some-other-name' }),
|
'libs/lib2/package.json': JSON.stringify({ name: 'lib2' }),
|
||||||
'libs/lib2/package.json': JSON.stringify({ name: 'lib2' }),
|
'libs/domain/lib3/package.json': JSON.stringify({
|
||||||
'libs/domain/lib3/package.json': JSON.stringify({
|
name: 'domain-lib3',
|
||||||
name: 'domain-lib3',
|
}),
|
||||||
}),
|
'libs/domain/lib4/project.json': JSON.stringify(domainLibConfig),
|
||||||
'libs/domain/lib4/project.json': JSON.stringify(domainLibConfig),
|
'libs/domain/lib4/package.json': JSON.stringify({}),
|
||||||
'libs/domain/lib4/package.json': JSON.stringify({}),
|
'package.json': JSON.stringify({
|
||||||
'package.json': JSON.stringify({
|
name: 'package-name',
|
||||||
workspaces: ['**/package.json'],
|
workspaces: ['**/package.json'],
|
||||||
}),
|
}),
|
||||||
},
|
});
|
||||||
'/root'
|
|
||||||
);
|
|
||||||
|
|
||||||
const workspaces = new Workspaces('/root');
|
const workspaces = new Workspaces(fs.tempDir);
|
||||||
const { projects } = workspaces.readProjectsConfigurations();
|
const { projects } = workspaces.readProjectsConfigurations();
|
||||||
// projects got deduped so the workspace one remained
|
// projects got deduped so the workspace one remained
|
||||||
expect(projects['lib1']).toEqual({
|
expect(projects['lib1']).toEqual({
|
||||||
@ -107,34 +87,24 @@ describe('Workspaces', () => {
|
|||||||
|
|
||||||
describe('to project name', () => {
|
describe('to project name', () => {
|
||||||
it('should lowercase names', () => {
|
it('should lowercase names', () => {
|
||||||
const nxJson: NxJsonConfiguration = {
|
|
||||||
npmScope: '',
|
|
||||||
workspaceLayout: {
|
|
||||||
appsDir: 'my-apps',
|
|
||||||
libsDir: 'packages',
|
|
||||||
},
|
|
||||||
};
|
|
||||||
const appResults = toProjectName('my-apps/directory/my-app/package.json');
|
const appResults = toProjectName('my-apps/directory/my-app/package.json');
|
||||||
const libResults = toProjectName('packages/directory/MyLib/package.json');
|
const libResults = toProjectName('packages/directory/MyLib/package.json');
|
||||||
expect(appResults).toEqual('my-app');
|
expect(appResults).toEqual('my-app');
|
||||||
expect(libResults).toEqual('mylib');
|
expect(libResults).toEqual('mylib');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should use the workspace globs in package.json', () => {
|
it('should use the workspace globs in package.json', async () => {
|
||||||
globResults = ['packages/my-package/package.json'];
|
await fs.createFiles({
|
||||||
vol.fromJSON(
|
'packages/my-package/package.json': JSON.stringify({
|
||||||
{
|
name: 'my-package',
|
||||||
'packages/my-package/package.json': JSON.stringify({
|
}),
|
||||||
name: 'my-package',
|
'package.json': JSON.stringify({
|
||||||
}),
|
name: 'package-name',
|
||||||
'package.json': JSON.stringify({
|
workspaces: ['packages/**'],
|
||||||
workspaces: ['packages/**'],
|
}),
|
||||||
}),
|
});
|
||||||
},
|
|
||||||
'/root2'
|
|
||||||
);
|
|
||||||
|
|
||||||
const workspaces = new Workspaces('/root2');
|
const workspaces = new Workspaces(fs.tempDir);
|
||||||
const resolved = workspaces.readProjectsConfigurations();
|
const resolved = workspaces.readProjectsConfigurations();
|
||||||
expect(resolved.projects['my-package']).toEqual({
|
expect(resolved.projects['my-package']).toEqual({
|
||||||
root: 'packages/my-package',
|
root: 'packages/my-package',
|
||||||
|
|||||||
@ -1,14 +1,13 @@
|
|||||||
import { sync as globSync } from 'fast-glob';
|
|
||||||
import { existsSync } from 'fs';
|
import { existsSync } from 'fs';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import { basename, dirname, join } from 'path';
|
import { basename, dirname, join } from 'path';
|
||||||
import { performance } from 'perf_hooks';
|
|
||||||
import { workspaceRoot } from '../utils/workspace-root';
|
import { workspaceRoot } from '../utils/workspace-root';
|
||||||
import { readJsonFile, readYamlFile } from '../utils/fileutils';
|
import { readJsonFile, readYamlFile } from '../utils/fileutils';
|
||||||
import { logger, NX_PREFIX } from '../utils/logger';
|
import { logger, NX_PREFIX } from '../utils/logger';
|
||||||
import { loadNxPlugins, loadNxPluginsSync } from '../utils/nx-plugin';
|
import { loadNxPlugins, loadNxPluginsSync } from '../utils/nx-plugin';
|
||||||
|
|
||||||
import type { NxJsonConfiguration, TargetDefaults } from './nx-json';
|
import type { NxJsonConfiguration, TargetDefaults } from './nx-json';
|
||||||
|
import { readNxJson } from './nx-json';
|
||||||
import {
|
import {
|
||||||
ProjectConfiguration,
|
ProjectConfiguration,
|
||||||
ProjectsConfigurations,
|
ProjectsConfigurations,
|
||||||
@ -21,9 +20,7 @@ import {
|
|||||||
mergeAngularJsonAndProjects,
|
mergeAngularJsonAndProjects,
|
||||||
shouldMergeAngularProjects,
|
shouldMergeAngularProjects,
|
||||||
} from '../adapter/angular-json';
|
} from '../adapter/angular-json';
|
||||||
import { getNxRequirePaths } from '../utils/installation-directory';
|
import { retrieveProjectConfigurationPaths } from '../project-graph/utils/retrieve-workspace-files';
|
||||||
import { getIgnoredGlobs } from '../utils/ignore';
|
|
||||||
import { readNxJson } from './nx-json';
|
|
||||||
|
|
||||||
export class Workspaces {
|
export class Workspaces {
|
||||||
private cachedProjectsConfig: ProjectsConfigurations;
|
private cachedProjectsConfig: ProjectsConfigurations;
|
||||||
@ -38,7 +35,6 @@ export class Workspaces {
|
|||||||
* @deprecated
|
* @deprecated
|
||||||
*/
|
*/
|
||||||
readProjectsConfigurations(opts?: {
|
readProjectsConfigurations(opts?: {
|
||||||
_ignorePluginInference?: boolean;
|
|
||||||
_includeProjectsFromAngularJson?: boolean;
|
_includeProjectsFromAngularJson?: boolean;
|
||||||
}): ProjectsConfigurations {
|
}): ProjectsConfigurations {
|
||||||
if (
|
if (
|
||||||
@ -48,19 +44,10 @@ export class Workspaces {
|
|||||||
return this.cachedProjectsConfig;
|
return this.cachedProjectsConfig;
|
||||||
}
|
}
|
||||||
const nxJson = readNxJson(this.root);
|
const nxJson = readNxJson(this.root);
|
||||||
|
const projectPaths = retrieveProjectConfigurationPaths(this.root, nxJson);
|
||||||
let projectsConfigurations = buildProjectsConfigurationsFromProjectPaths(
|
let projectsConfigurations = buildProjectsConfigurationsFromProjectPaths(
|
||||||
nxJson,
|
nxJson,
|
||||||
globForProjectFiles(
|
projectPaths,
|
||||||
this.root,
|
|
||||||
opts?._ignorePluginInference
|
|
||||||
? []
|
|
||||||
: getGlobPatternsFromPlugins(
|
|
||||||
nxJson,
|
|
||||||
getNxRequirePaths(this.root),
|
|
||||||
this.root
|
|
||||||
),
|
|
||||||
nxJson
|
|
||||||
),
|
|
||||||
(path) => readJsonFile(join(this.root, path))
|
(path) => readJsonFile(join(this.root, path))
|
||||||
);
|
);
|
||||||
if (
|
if (
|
||||||
@ -132,9 +119,6 @@ export function toProjectName(fileName: string): string {
|
|||||||
return parts[parts.length - 1].toLowerCase();
|
return parts[parts.length - 1].toLowerCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
let projectGlobCache: string[];
|
|
||||||
let projectGlobCacheKey: string;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated Use getGlobPatternsFromPluginsAsync instead.
|
* @deprecated Use getGlobPatternsFromPluginsAsync instead.
|
||||||
*/
|
*/
|
||||||
@ -247,103 +231,6 @@ function removeRelativePath(pattern: string): string {
|
|||||||
return pattern.startsWith('./') ? pattern.substring(2) : pattern;
|
return pattern.startsWith('./') ? pattern.substring(2) : pattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function globForProjectFiles(
|
|
||||||
root: string,
|
|
||||||
pluginsGlobPatterns: string[],
|
|
||||||
nxJson?: NxJsonConfiguration
|
|
||||||
) {
|
|
||||||
// Deal w/ Caching
|
|
||||||
const cacheKey = [root, ...pluginsGlobPatterns].join(',');
|
|
||||||
if (
|
|
||||||
process.env.NX_PROJECT_GLOB_CACHE !== 'false' &&
|
|
||||||
projectGlobCache &&
|
|
||||||
cacheKey === projectGlobCacheKey
|
|
||||||
) {
|
|
||||||
return projectGlobCache;
|
|
||||||
}
|
|
||||||
projectGlobCacheKey = cacheKey;
|
|
||||||
|
|
||||||
const _globPatternsFromPackageManagerWorkspaces =
|
|
||||||
getGlobPatternsFromPackageManagerWorkspaces(root);
|
|
||||||
|
|
||||||
const globPatternsFromPackageManagerWorkspaces =
|
|
||||||
_globPatternsFromPackageManagerWorkspaces ?? [];
|
|
||||||
|
|
||||||
const globsToInclude = globPatternsFromPackageManagerWorkspaces.filter(
|
|
||||||
(glob) => !glob.startsWith('!')
|
|
||||||
);
|
|
||||||
|
|
||||||
const globsToExclude = globPatternsFromPackageManagerWorkspaces
|
|
||||||
.filter((glob) => glob.startsWith('!'))
|
|
||||||
.map((glob) => glob.substring(1))
|
|
||||||
.map((glob) => (glob.startsWith('/') ? glob.substring(1) : glob));
|
|
||||||
|
|
||||||
const projectGlobPatterns: string[] = [
|
|
||||||
'project.json',
|
|
||||||
'**/project.json',
|
|
||||||
...globsToInclude,
|
|
||||||
];
|
|
||||||
|
|
||||||
projectGlobPatterns.push(...pluginsGlobPatterns);
|
|
||||||
|
|
||||||
const combinedProjectGlobPattern = '{' + projectGlobPatterns.join(',') + '}';
|
|
||||||
|
|
||||||
performance.mark('start-glob-for-projects');
|
|
||||||
/**
|
|
||||||
* This configures the files and directories which we always want to ignore as part of file watching
|
|
||||||
* and which we know the location of statically (meaning irrespective of user configuration files).
|
|
||||||
* This has the advantage of being ignored directly within globSync
|
|
||||||
*
|
|
||||||
* Other ignored entries will need to be determined dynamically by reading and evaluating the user's
|
|
||||||
* .gitignore and .nxignore files below.
|
|
||||||
*/
|
|
||||||
|
|
||||||
const staticIgnores = [
|
|
||||||
'node_modules',
|
|
||||||
'**/node_modules',
|
|
||||||
'dist',
|
|
||||||
'.git',
|
|
||||||
...globsToExclude,
|
|
||||||
...getIgnoredGlobs(root, false),
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* TODO: This utility has been implemented multiple times across the Nx codebase,
|
|
||||||
* discuss whether it should be moved to a shared location.
|
|
||||||
*/
|
|
||||||
const opts = {
|
|
||||||
ignore: staticIgnores,
|
|
||||||
absolute: false,
|
|
||||||
cwd: root,
|
|
||||||
dot: true,
|
|
||||||
suppressErrors: true,
|
|
||||||
};
|
|
||||||
|
|
||||||
const globResults = globSync(combinedProjectGlobPattern, opts);
|
|
||||||
|
|
||||||
projectGlobCache = deduplicateProjectFiles(globResults);
|
|
||||||
|
|
||||||
// TODO @vsavkin remove after Nx 16
|
|
||||||
if (
|
|
||||||
projectGlobCache.length === 0 &&
|
|
||||||
_globPatternsFromPackageManagerWorkspaces === undefined &&
|
|
||||||
nxJson?.extends === 'nx/presets/npm.json'
|
|
||||||
) {
|
|
||||||
output.warn({
|
|
||||||
title:
|
|
||||||
'Nx could not find any projects. Check if you need to configure workspaces in package.json or pnpm-workspace.yaml',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
performance.mark('finish-glob-for-projects');
|
|
||||||
performance.measure(
|
|
||||||
'glob-for-project-files',
|
|
||||||
'start-glob-for-projects',
|
|
||||||
'finish-glob-for-projects'
|
|
||||||
);
|
|
||||||
return projectGlobCache;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description Loops through files and reduces them to 1 file per project.
|
* @description Loops through files and reduces them to 1 file per project.
|
||||||
* @param files Array of files that may represent projects
|
* @param files Array of files that may represent projects
|
||||||
|
|||||||
@ -6,8 +6,6 @@ import {
|
|||||||
import {
|
import {
|
||||||
buildProjectsConfigurationsFromProjectPaths,
|
buildProjectsConfigurationsFromProjectPaths,
|
||||||
deduplicateProjectFiles,
|
deduplicateProjectFiles,
|
||||||
getGlobPatternsFromPlugins,
|
|
||||||
globForProjectFiles,
|
|
||||||
renamePropertyWithStableKeys,
|
renamePropertyWithStableKeys,
|
||||||
} from '../../config/workspaces';
|
} from '../../config/workspaces';
|
||||||
import { joinPathFragments, normalizePath } from '../../utils/path';
|
import { joinPathFragments, normalizePath } from '../../utils/path';
|
||||||
@ -18,7 +16,7 @@ import { readJson, writeJson } from './json';
|
|||||||
import { PackageJson } from '../../utils/package-json';
|
import { PackageJson } from '../../utils/package-json';
|
||||||
import { readNxJson } from './nx-json';
|
import { readNxJson } from './nx-json';
|
||||||
import { output } from '../../utils/output';
|
import { output } from '../../utils/output';
|
||||||
import { getNxRequirePaths } from '../../utils/installation-directory';
|
import { retrieveProjectConfigurationPaths } from '../../project-graph/utils/retrieve-workspace-files';
|
||||||
|
|
||||||
export { readNxJson, updateNxJson } from './nx-json';
|
export { readNxJson, updateNxJson } from './nx-json';
|
||||||
export {
|
export {
|
||||||
@ -183,11 +181,7 @@ function readAndCombineAllProjectConfigurations(tree: Tree): {
|
|||||||
} {
|
} {
|
||||||
const nxJson = readNxJson(tree);
|
const nxJson = readNxJson(tree);
|
||||||
|
|
||||||
const globbedFiles = globForProjectFiles(
|
const globbedFiles = retrieveProjectConfigurationPaths(tree.root, nxJson);
|
||||||
tree.root,
|
|
||||||
getGlobPatternsFromPlugins(nxJson, getNxRequirePaths(tree.root), tree.root),
|
|
||||||
nxJson
|
|
||||||
).map(normalizePath);
|
|
||||||
const createdFiles = findCreatedProjectFiles(tree);
|
const createdFiles = findCreatedProjectFiles(tree);
|
||||||
const deletedFiles = findDeletedProjectFiles(tree);
|
const deletedFiles = findDeletedProjectFiles(tree);
|
||||||
const projectFiles = [...globbedFiles, ...createdFiles].filter(
|
const projectFiles = [...globbedFiles, ...createdFiles].filter(
|
||||||
|
|||||||
@ -1,25 +1,13 @@
|
|||||||
import { Tree } from '../../generators/tree';
|
import { Tree } from '../../generators/tree';
|
||||||
import { readNxJson } from '../../generators/utils/nx-json';
|
import { readNxJson } from '../../generators/utils/nx-json';
|
||||||
import {
|
|
||||||
getGlobPatternsFromPluginsAsync,
|
|
||||||
globForProjectFiles,
|
|
||||||
} from '../../config/workspaces';
|
|
||||||
import { dirname } from 'path';
|
import { dirname } from 'path';
|
||||||
import { readJson, writeJson } from '../../generators/utils/json';
|
import { readJson, writeJson } from '../../generators/utils/json';
|
||||||
import { formatChangedFilesWithPrettierIfAvailable } from '../../generators/internal-utils/format-changed-files-with-prettier-if-available';
|
import { formatChangedFilesWithPrettierIfAvailable } from '../../generators/internal-utils/format-changed-files-with-prettier-if-available';
|
||||||
import { getNxRequirePaths } from '../../utils/installation-directory';
|
import { retrieveProjectConfigurationPaths } from '../../project-graph/utils/retrieve-workspace-files';
|
||||||
|
|
||||||
export default async function (tree: Tree) {
|
export default async function (tree: Tree) {
|
||||||
const nxJson = readNxJson(tree);
|
const nxJson = readNxJson(tree);
|
||||||
const projectFiles = globForProjectFiles(
|
const projectFiles = retrieveProjectConfigurationPaths(tree.root, nxJson);
|
||||||
tree.root,
|
|
||||||
await getGlobPatternsFromPluginsAsync(
|
|
||||||
nxJson,
|
|
||||||
getNxRequirePaths(tree.root),
|
|
||||||
tree.root
|
|
||||||
),
|
|
||||||
nxJson
|
|
||||||
);
|
|
||||||
const projectJsons = projectFiles.filter((f) => f.endsWith('project.json'));
|
const projectJsons = projectFiles.filter((f) => f.endsWith('project.json'));
|
||||||
|
|
||||||
for (let f of projectJsons) {
|
for (let f of projectJsons) {
|
||||||
|
|||||||
2
packages/nx/src/native/index.d.ts
vendored
2
packages/nx/src/native/index.d.ts
vendored
@ -38,6 +38,8 @@ export const enum WorkspaceErrors {
|
|||||||
Generic = 'Generic'
|
Generic = 'Generic'
|
||||||
}
|
}
|
||||||
/** Get workspace config files based on provided globs */
|
/** Get workspace config files based on provided globs */
|
||||||
|
export function getProjectConfigurationFiles(workspaceRoot: string, globs: Array<string>): Array<string>
|
||||||
|
/** Get workspace config files based on provided globs */
|
||||||
export function getProjectConfigurations(workspaceRoot: string, globs: Array<string>, parseConfigurations: (arg0: Array<string>) => Record<string, object>): Record<string, object>
|
export function getProjectConfigurations(workspaceRoot: string, globs: Array<string>, parseConfigurations: (arg0: Array<string>) => Record<string, object>): Record<string, object>
|
||||||
export interface NxWorkspaceFiles {
|
export interface NxWorkspaceFiles {
|
||||||
projectFileMap: Record<string, Array<FileData>>
|
projectFileMap: Record<string, Array<FileData>>
|
||||||
|
|||||||
@ -246,7 +246,7 @@ if (!nativeBinding) {
|
|||||||
throw new Error(`Failed to load native binding`)
|
throw new Error(`Failed to load native binding`)
|
||||||
}
|
}
|
||||||
|
|
||||||
const { expandOutputs, remove, copy, hashArray, hashFile, hashFiles, hashFilesMatchingGlobs, ImportResult, findImports, EventType, Watcher, WorkspaceErrors, getProjectConfigurations, getWorkspaceFilesNative } = nativeBinding
|
const { expandOutputs, remove, copy, hashArray, hashFile, hashFiles, hashFilesMatchingGlobs, ImportResult, findImports, EventType, Watcher, WorkspaceErrors, getProjectConfigurationFiles, getProjectConfigurations, getWorkspaceFilesNative } = nativeBinding
|
||||||
|
|
||||||
module.exports.expandOutputs = expandOutputs
|
module.exports.expandOutputs = expandOutputs
|
||||||
module.exports.remove = remove
|
module.exports.remove = remove
|
||||||
@ -260,5 +260,6 @@ module.exports.findImports = findImports
|
|||||||
module.exports.EventType = EventType
|
module.exports.EventType = EventType
|
||||||
module.exports.Watcher = Watcher
|
module.exports.Watcher = Watcher
|
||||||
module.exports.WorkspaceErrors = WorkspaceErrors
|
module.exports.WorkspaceErrors = WorkspaceErrors
|
||||||
|
module.exports.getProjectConfigurationFiles = getProjectConfigurationFiles
|
||||||
module.exports.getProjectConfigurations = getProjectConfigurations
|
module.exports.getProjectConfigurations = getProjectConfigurations
|
||||||
module.exports.getWorkspaceFilesNative = getWorkspaceFilesNative
|
module.exports.getWorkspaceFilesNative = getWorkspaceFilesNative
|
||||||
|
|||||||
@ -7,6 +7,28 @@ use std::collections::hash_map::Entry;
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
|
#[napi]
|
||||||
|
/// Get workspace config files based on provided globs
|
||||||
|
pub fn get_project_configuration_files(
|
||||||
|
workspace_root: String,
|
||||||
|
globs: Vec<String>,
|
||||||
|
) -> napi::Result<Vec<String>> {
|
||||||
|
let globs = build_glob_set(&globs)?;
|
||||||
|
let config_paths: Vec<String> = nx_walker(workspace_root, move |rec| {
|
||||||
|
let mut config_paths: HashMap<PathBuf, PathBuf> = HashMap::new();
|
||||||
|
for (path, _) in rec {
|
||||||
|
insert_config_file_into_map(path, &mut config_paths, &globs);
|
||||||
|
}
|
||||||
|
|
||||||
|
config_paths
|
||||||
|
.into_values()
|
||||||
|
.map(|p| p.to_normalized_string())
|
||||||
|
.collect()
|
||||||
|
});
|
||||||
|
|
||||||
|
Ok(config_paths)
|
||||||
|
}
|
||||||
|
|
||||||
#[napi]
|
#[napi]
|
||||||
/// Get workspace config files based on provided globs
|
/// Get workspace config files based on provided globs
|
||||||
pub fn get_project_configurations<ConfigurationParser>(
|
pub fn get_project_configurations<ConfigurationParser>(
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
import { TempFs } from '../utils/testing/temp-fs';
|
import { TempFs } from '../../utils/testing/temp-fs';
|
||||||
import { globForProjectFiles } from './workspaces';
|
import { retrieveProjectConfigurationPaths } from './retrieve-workspace-files';
|
||||||
|
|
||||||
describe('globForProjectFiles', () => {
|
describe('retrieveProjectConfigurationPaths', () => {
|
||||||
let fs: TempFs;
|
let fs: TempFs;
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
fs = new TempFs('glob-for-project-files');
|
fs = new TempFs('retrieveProjectConfigurationPaths');
|
||||||
});
|
});
|
||||||
afterAll(() => {
|
afterAll(() => {
|
||||||
fs.cleanup();
|
fs.cleanup();
|
||||||
@ -24,10 +24,10 @@ describe('globForProjectFiles', () => {
|
|||||||
name: 'project-1',
|
name: 'project-1',
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
expect(globForProjectFiles(fs.tempDir, [])).not.toContain(
|
expect(retrieveProjectConfigurationPaths(fs.tempDir, {})).not.toContain(
|
||||||
'not-projects/project.json'
|
'not-projects/project.json'
|
||||||
);
|
);
|
||||||
expect(globForProjectFiles(fs.tempDir, [])).toContain(
|
expect(retrieveProjectConfigurationPaths(fs.tempDir, {})).toContain(
|
||||||
'projects/project.json'
|
'projects/project.json'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@ -2,6 +2,7 @@ import { performance } from 'perf_hooks';
|
|||||||
import {
|
import {
|
||||||
buildProjectsConfigurationsFromProjectPaths,
|
buildProjectsConfigurationsFromProjectPaths,
|
||||||
getGlobPatternsFromPackageManagerWorkspaces,
|
getGlobPatternsFromPackageManagerWorkspaces,
|
||||||
|
getGlobPatternsFromPlugins,
|
||||||
getGlobPatternsFromPluginsAsync,
|
getGlobPatternsFromPluginsAsync,
|
||||||
mergeTargetConfigurations,
|
mergeTargetConfigurations,
|
||||||
readTargetDefaultsForTarget,
|
readTargetDefaultsForTarget,
|
||||||
@ -17,7 +18,7 @@ import {
|
|||||||
mergeAngularJsonAndProjects,
|
mergeAngularJsonAndProjects,
|
||||||
shouldMergeAngularProjects,
|
shouldMergeAngularProjects,
|
||||||
} from '../../adapter/angular-json';
|
} from '../../adapter/angular-json';
|
||||||
import { NxJsonConfiguration } from '../../config/nx-json';
|
import { NxJsonConfiguration, readNxJson } from '../../config/nx-json';
|
||||||
import { FileData, ProjectFileMap } from '../../config/project-graph';
|
import { FileData, ProjectFileMap } from '../../config/project-graph';
|
||||||
import type { NxWorkspaceFiles } from '../../native';
|
import type { NxWorkspaceFiles } from '../../native';
|
||||||
|
|
||||||
@ -49,13 +50,7 @@ export async function retrieveWorkspaceFiles(
|
|||||||
workspaceRoot,
|
workspaceRoot,
|
||||||
globs,
|
globs,
|
||||||
(configs: string[]): Record<string, ProjectConfiguration> => {
|
(configs: string[]): Record<string, ProjectConfiguration> => {
|
||||||
const projectConfigurations = createProjectConfigurations(
|
return createProjectConfigurations(workspaceRoot, nxJson, configs);
|
||||||
workspaceRoot,
|
|
||||||
nxJson,
|
|
||||||
configs
|
|
||||||
);
|
|
||||||
|
|
||||||
return projectConfigurations.projects;
|
|
||||||
}
|
}
|
||||||
) as NxWorkspaceFiles;
|
) as NxWorkspaceFiles;
|
||||||
performance.mark('get-workspace-files:end');
|
performance.mark('get-workspace-files:end');
|
||||||
@ -85,21 +80,58 @@ export async function retrieveProjectConfigurations(
|
|||||||
workspaceRoot: string,
|
workspaceRoot: string,
|
||||||
nxJson: NxJsonConfiguration
|
nxJson: NxJsonConfiguration
|
||||||
): Promise<Record<string, ProjectConfiguration>> {
|
): Promise<Record<string, ProjectConfiguration>> {
|
||||||
const { getProjectConfigurations } = require('../../native');
|
const { getProjectConfigurations } =
|
||||||
|
require('../../native') as typeof import('../../native');
|
||||||
const globs = await configurationGlobs(workspaceRoot, nxJson);
|
const globs = await configurationGlobs(workspaceRoot, nxJson);
|
||||||
return getProjectConfigurations(
|
return getProjectConfigurations(
|
||||||
workspaceRoot,
|
workspaceRoot,
|
||||||
globs,
|
globs,
|
||||||
(configs: string[]): Record<string, ProjectConfiguration> => {
|
(configs: string[]): Record<string, ProjectConfiguration> => {
|
||||||
const projectConfigurations = createProjectConfigurations(
|
return createProjectConfigurations(workspaceRoot, nxJson, configs);
|
||||||
workspaceRoot,
|
|
||||||
nxJson,
|
|
||||||
configs
|
|
||||||
);
|
|
||||||
|
|
||||||
return projectConfigurations.projects;
|
|
||||||
}
|
}
|
||||||
);
|
) as Record<string, ProjectConfiguration>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function retrieveProjectConfigurationPaths(
|
||||||
|
root: string,
|
||||||
|
nxJson: NxJsonConfiguration
|
||||||
|
): string[] {
|
||||||
|
const projectGlobPatterns = configurationGlobsSync(root, nxJson);
|
||||||
|
const { getProjectConfigurationFiles } =
|
||||||
|
require('../../native') as typeof import('../../native');
|
||||||
|
return getProjectConfigurationFiles(root, projectGlobPatterns);
|
||||||
|
}
|
||||||
|
|
||||||
|
const projectsWithoutPluginCache = new Map<
|
||||||
|
string,
|
||||||
|
Record<string, ProjectConfiguration>
|
||||||
|
>();
|
||||||
|
|
||||||
|
// TODO: This function is called way too often, it should be optimized without this cache
|
||||||
|
export function retrieveProjectConfigurationsWithoutPluginInference(
|
||||||
|
root: string
|
||||||
|
): Record<string, ProjectConfiguration> {
|
||||||
|
const nxJson = readNxJson(root);
|
||||||
|
const projectGlobPatterns = configurationGlobsWithoutPlugins(root);
|
||||||
|
const cacheKey = root + ',' + projectGlobPatterns.join(',');
|
||||||
|
|
||||||
|
if (projectsWithoutPluginCache.has(cacheKey)) {
|
||||||
|
return projectsWithoutPluginCache.get(cacheKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
const { getProjectConfigurations } =
|
||||||
|
require('../../native') as typeof import('../../native');
|
||||||
|
const projectConfigurations = getProjectConfigurations(
|
||||||
|
root,
|
||||||
|
projectGlobPatterns,
|
||||||
|
(configs: string[]): Record<string, ProjectConfiguration> => {
|
||||||
|
return createProjectConfigurations(root, nxJson, configs);
|
||||||
|
}
|
||||||
|
) as Record<string, ProjectConfiguration>;
|
||||||
|
|
||||||
|
projectsWithoutPluginCache.set(cacheKey, projectConfigurations);
|
||||||
|
|
||||||
|
return projectConfigurations;
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildAllWorkspaceFiles(
|
function buildAllWorkspaceFiles(
|
||||||
@ -124,7 +156,7 @@ function createProjectConfigurations(
|
|||||||
workspaceRoot: string,
|
workspaceRoot: string,
|
||||||
nxJson: NxJsonConfiguration,
|
nxJson: NxJsonConfiguration,
|
||||||
configFiles: string[]
|
configFiles: string[]
|
||||||
): ProjectsConfigurations {
|
): Record<string, ProjectConfiguration> {
|
||||||
performance.mark('build-project-configs:start');
|
performance.mark('build-project-configs:start');
|
||||||
|
|
||||||
let projectConfigurations = mergeTargetDefaultsIntoProjectDescriptions(
|
let projectConfigurations = mergeTargetDefaultsIntoProjectDescriptions(
|
||||||
@ -147,10 +179,7 @@ function createProjectConfigurations(
|
|||||||
'build-project-configs:end'
|
'build-project-configs:end'
|
||||||
);
|
);
|
||||||
|
|
||||||
return {
|
return projectConfigurations;
|
||||||
version: 2,
|
|
||||||
projects: projectConfigurations,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function mergeTargetDefaultsIntoProjectDescriptions(
|
function mergeTargetDefaultsIntoProjectDescriptions(
|
||||||
@ -190,10 +219,29 @@ async function configurationGlobs(
|
|||||||
workspaceRoot
|
workspaceRoot
|
||||||
);
|
);
|
||||||
|
|
||||||
|
return [...configurationGlobsWithoutPlugins(workspaceRoot), ...pluginGlobs];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Use {@link configurationGlobs} instead.
|
||||||
|
*/
|
||||||
|
function configurationGlobsSync(
|
||||||
|
workspaceRoot: string,
|
||||||
|
nxJson: NxJsonConfiguration
|
||||||
|
): string[] {
|
||||||
|
let pluginGlobs = getGlobPatternsFromPlugins(
|
||||||
|
nxJson,
|
||||||
|
getNxRequirePaths(workspaceRoot),
|
||||||
|
workspaceRoot
|
||||||
|
);
|
||||||
|
|
||||||
|
return [...configurationGlobsWithoutPlugins(workspaceRoot), ...pluginGlobs];
|
||||||
|
}
|
||||||
|
|
||||||
|
function configurationGlobsWithoutPlugins(workspaceRoot: string): string[] {
|
||||||
return [
|
return [
|
||||||
'project.json',
|
'project.json',
|
||||||
'**/project.json',
|
'**/project.json',
|
||||||
...pluginGlobs,
|
|
||||||
...getGlobPatternsFromPackageManagerWorkspaces(workspaceRoot),
|
...getGlobPatternsFromPackageManagerWorkspaces(workspaceRoot),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,7 +2,6 @@ import { sync } from 'fast-glob';
|
|||||||
import { existsSync } from 'fs';
|
import { existsSync } from 'fs';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import { ProjectGraphProcessor } from '../config/project-graph';
|
import { ProjectGraphProcessor } from '../config/project-graph';
|
||||||
import { Workspaces } from '../config/workspaces';
|
|
||||||
|
|
||||||
import { workspaceRoot } from './workspace-root';
|
import { workspaceRoot } from './workspace-root';
|
||||||
import { readJsonFile } from '../utils/fileutils';
|
import { readJsonFile } from '../utils/fileutils';
|
||||||
@ -16,7 +15,6 @@ import {
|
|||||||
} from '../plugins/js/utils/register';
|
} from '../plugins/js/utils/register';
|
||||||
import {
|
import {
|
||||||
ProjectConfiguration,
|
ProjectConfiguration,
|
||||||
ProjectsConfigurations,
|
|
||||||
TargetConfiguration,
|
TargetConfiguration,
|
||||||
} from '../config/workspace-json-project-json';
|
} from '../config/workspace-json-project-json';
|
||||||
import { logger } from './logger';
|
import { logger } from './logger';
|
||||||
@ -30,6 +28,7 @@ import { getNxRequirePaths } from './installation-directory';
|
|||||||
import { readTsConfig } from '../plugins/js/utils/typescript';
|
import { readTsConfig } from '../plugins/js/utils/typescript';
|
||||||
|
|
||||||
import type * as ts from 'typescript';
|
import type * as ts from 'typescript';
|
||||||
|
import { retrieveProjectConfigurationsWithoutPluginInference } from '../project-graph/utils/retrieve-workspace-files';
|
||||||
|
|
||||||
export type ProjectTargetConfigurator = (
|
export type ProjectTargetConfigurator = (
|
||||||
file: string
|
file: string
|
||||||
@ -287,10 +286,8 @@ export function registerPluginTSTranspiler() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function lookupLocalPlugin(importPath: string, root = workspaceRoot) {
|
function lookupLocalPlugin(importPath: string, root = workspaceRoot) {
|
||||||
const workspace = new Workspaces(root).readProjectsConfigurations({
|
const projects = retrieveProjectConfigurationsWithoutPluginInference(root);
|
||||||
_ignorePluginInference: true,
|
const plugin = findNxProjectForImportPath(importPath, projects, root);
|
||||||
});
|
|
||||||
const plugin = findNxProjectForImportPath(importPath, workspace, root);
|
|
||||||
if (!plugin) {
|
if (!plugin) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -299,13 +296,13 @@ function lookupLocalPlugin(importPath: string, root = workspaceRoot) {
|
|||||||
registerPluginTSTranspiler();
|
registerPluginTSTranspiler();
|
||||||
}
|
}
|
||||||
|
|
||||||
const projectConfig = workspace.projects[plugin];
|
const projectConfig: ProjectConfiguration = projects[plugin];
|
||||||
return { path: path.join(root, projectConfig.root), projectConfig };
|
return { path: path.join(root, projectConfig.root), projectConfig };
|
||||||
}
|
}
|
||||||
|
|
||||||
function findNxProjectForImportPath(
|
function findNxProjectForImportPath(
|
||||||
importPath: string,
|
importPath: string,
|
||||||
projects: ProjectsConfigurations,
|
projects: Record<string, ProjectConfiguration>,
|
||||||
root = workspaceRoot
|
root = workspaceRoot
|
||||||
): string | null {
|
): string | null {
|
||||||
const tsConfigPaths: Record<string, string[]> = readTsConfigPaths(root);
|
const tsConfigPaths: Record<string, string[]> = readTsConfigPaths(root);
|
||||||
@ -314,7 +311,7 @@ function findNxProjectForImportPath(
|
|||||||
);
|
);
|
||||||
if (possiblePaths?.length) {
|
if (possiblePaths?.length) {
|
||||||
const projectRootMappings =
|
const projectRootMappings =
|
||||||
createProjectRootMappingsFromProjectConfigurations(projects.projects);
|
createProjectRootMappingsFromProjectConfigurations(projects);
|
||||||
for (const tsConfigPath of possiblePaths) {
|
for (const tsConfigPath of possiblePaths) {
|
||||||
const nxProject = findProjectForPath(tsConfigPath, projectRootMappings);
|
const nxProject = findProjectForPath(tsConfigPath, projectRootMappings);
|
||||||
if (nxProject) {
|
if (nxProject) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user