Skip to content

Commit

Permalink
feat(core): use package manager workspace globs to find projects (#9131)
Browse files Browse the repository at this point in the history
  • Loading branch information
FrozenPandaz committed Mar 2, 2022
1 parent ea33428 commit 5964379
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 27 deletions.
2 changes: 2 additions & 0 deletions packages/devkit/src/generators/project-configuration.ts
Expand Up @@ -135,6 +135,7 @@ export function updateWorkspaceConfiguration(
generators,
implicitDependencies,
plugins,
pluginsConfig,
npmScope,
targetDependencies,
workspaceLayout,
Expand All @@ -146,6 +147,7 @@ export function updateWorkspaceConfiguration(
const nxJson: Required<NxJsonConfiguration> = {
implicitDependencies,
plugins,
pluginsConfig,
npmScope,
targetDependencies,
workspaceLayout,
Expand Down
6 changes: 6 additions & 0 deletions packages/tao/src/shared/nx.ts
Expand Up @@ -92,6 +92,12 @@ export interface NxJsonConfiguration<T = '*' | string[]> {
* Plugins for extending the project graph
*/
plugins?: string[];

/**
* Configuration for Nx Plugins
*/
pluginsConfig?: Record<string, unknown>;

/**
* Default project. When project isn't provided, the default project
* will be used. Convenient for small workspaces with one main application.
Expand Down
49 changes: 38 additions & 11 deletions packages/tao/src/shared/workspace.spec.ts
Expand Up @@ -2,18 +2,9 @@ import { toProjectName, Workspaces } from './workspace';
import { NxJsonConfiguration } from './nx';
import { vol } from 'memfs';

jest.mock('fs', () => require('memfs').fs);
import * as fastGlob from 'fast-glob';

jest.mock('fast-glob', () => ({
sync: () => [
'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.mock('fs', () => require('memfs').fs);

const libConfig = (name) => ({
root: `libs/${name}`,
Expand All @@ -26,7 +17,21 @@ const packageLibConfig = (root) => ({
});

describe('Workspaces', () => {
let globResults: string[];
beforeEach(() => {
globResults = [
'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(() => {
jest.resetAllMocks();
vol.reset();
});

Expand Down Expand Up @@ -136,5 +141,27 @@ describe('Workspaces', () => {
expect(appResults).toEqual('directory-my-app');
expect(libResults).toEqual('directory-mylib');
});

it('should use the workspace globs in package.json', () => {
globResults = ['packages/my-package/package.json'];
vol.fromJSON(
{
'packages/my-package/package.json': JSON.stringify({
name: 'my-package',
}),
'package.json': JSON.stringify({
workspaces: ['packages/**'],
}),
},
'/root2'
);

const workspaces = new Workspaces('/root2');
const resolved = workspaces.readWorkspaceConfiguration();
expect(resolved.projects['my-package']).toEqual({
root: 'packages/my-package',
sourceRoot: 'packages/my-package',
});
});
});
});
56 changes: 46 additions & 10 deletions packages/tao/src/shared/workspace.ts
Expand Up @@ -666,22 +666,58 @@ export function toProjectName(

let projectGlobCache: string[];
let projectGlobCacheKey: string;
export function globForProjectFiles(root, nxJson?: NxJsonConfiguration) {

function getGlobPatternsFromPlugins(nxJson: NxJsonConfiguration): string[] {
const plugins = loadNxPlugins(nxJson?.plugins);

const patterns = [];
for (const plugin of plugins) {
if (!plugin.projectFilePatterns) {
continue;
}
for (const filePattern of plugin.projectFilePatterns) {
patterns.push('**/' + filePattern);
}
}

return patterns;
}

/**
* Get the package.json globs from package manager workspaces
*/
function getGlobPatternsFromPackageManagerWorkspaces(root: string): string[] {
// TODO: add support for pnpm
try {
const { workspaces } = readJsonFile(join(root, 'package.json'));

return (
workspaces?.map((pattern) => pattern + '/package.json') ?? [
'**/package.json',
]
);
} catch {
return ['**/package.json'];
}
}

export function globForProjectFiles(
root: string,
nxJson?: NxJsonConfiguration
) {
// Deal w/ Caching
const cacheKey = [root, ...(nxJson?.plugins || [])].join(',');
if (projectGlobCache && cacheKey === projectGlobCacheKey)
return projectGlobCache;
projectGlobCacheKey = cacheKey;

// Load plugins
const plugins = loadNxPlugins(nxJson?.plugins).filter(
(x) => !!x.projectFilePatterns
);
let combinedProjectGlobPattern = `**/+(project.json|package.json${
plugins.length
? '|' + plugins.map((x) => x.projectFilePatterns.join('|')).join('|')
: ''
})`;
const projectGlobPatterns: string[] = [
'**/project.json',
...getGlobPatternsFromPackageManagerWorkspaces(root),
...getGlobPatternsFromPlugins(nxJson),
];

const combinedProjectGlobPattern = '{' + projectGlobPatterns.join(',') + '}';

performance.mark('start-glob-for-projects');
/**
Expand Down
13 changes: 7 additions & 6 deletions packages/workspace/src/core/project-graph/build-project-graph.ts
Expand Up @@ -169,12 +169,13 @@ async function buildProjectGraphUsingContext(
return r;
}

function jsPluginConfig(nxJson: any) {
if (nxJson?.pluginsConfig?.['@nrwl/js']) {
return nxJson?.pluginsConfig['@nrwl/js'];
} else {
return {};
}
interface NrwlJsPluginConfig {
analyzeSourceFiles?: boolean;
analyzePackageJson?: boolean;
}

function jsPluginConfig(nxJson: NxJsonConfiguration): NrwlJsPluginConfig {
return nxJson?.pluginsConfig?.['@nrwl/js'] ?? {};
}

function buildExplicitDependencies(
Expand Down

0 comments on commit 5964379

Please sign in to comment.