Skip to content

Commit

Permalink
feat: project graph integration (#1305)
Browse files Browse the repository at this point in the history
  • Loading branch information
Cammisuli authored Jul 20, 2022
1 parent 4c4f843 commit ebcd217
Show file tree
Hide file tree
Showing 33 changed files with 944 additions and 79 deletions.
1 change: 1 addition & 0 deletions apps/vscode/src/commands/refresh-workspace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ refresh.pipe(debounceTime(150)).subscribe(async () => {
await nxWorkspace(true);
commands.executeCommand('nxConsole.refreshNxProjectsTree');
commands.executeCommand('nxConsole.refreshRunTargetTree');
commands.executeCommand('nx.graph.refresh');
});

/**
Expand Down
1 change: 0 additions & 1 deletion apps/vscode/src/getting-started/3-common-nx-commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

You can also launch other common Nx commands with the options listed out in the Command Palette.

- `dep-graph`: Graph dependencies within workspace
- `run-many`: Run task for multiple projects
- `affected`: Run task for affected projects

Expand Down
5 changes: 3 additions & 2 deletions apps/vscode/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ import {
NxProjectTreeProvider,
} from '@nx-console/vscode/nx-project-view';
import { environment } from './environments/environment';
import { AsyncReturnType } from 'type-fest';

import {
WorkspaceJsonSchema,
Expand All @@ -58,6 +57,7 @@ import {
refreshWorkspace,
REFRESH_WORKSPACE,
} from './commands/refresh-workspace';
import { projectGraph } from '@nx-console/vscode/project-graph';

let runTargetTreeView: TreeView<RunTargetTreeItem>;
let nxProjectTreeView: TreeView<NxProjectTreeItem>;
Expand Down Expand Up @@ -117,7 +117,8 @@ export async function activate(c: ExtensionContext) {
runTargetTreeView,
revealWebViewPanelCommand,
manuallySelectWorkspaceDefinitionCommand,
refreshWorkspace()
refreshWorkspace(),
projectGraph()
);

// registers itself as a CodeLensProvider and watches config to dispose/re-register
Expand Down
75 changes: 62 additions & 13 deletions apps/vscode/src/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,16 @@
"when": "isNxWorkspace && explorerResourceIsFolder && resourcePath in nxLibsDir && config.nxConsole.enableGenerateFromContextMenu && nx.hasLibraryGenerators",
"command": "nx.generate.ui.lib.fileexplorer",
"group": "2_workspace"
},
{
"when": "isNxWorkspace",
"group": "2_workspace@5",
"command": "nx.graph.focus"
},
{
"when": "isNxWorkspace",
"group": "2_workspace@5",
"command": "nx.graph.select"
}
],
"view/title": [
Expand Down Expand Up @@ -122,6 +132,16 @@
"command": "nxConsole.runTask",
"when": "view == nxProjects && viewItem == task",
"group": "inline"
},
{
"command": "nx.graph.focus.button",
"when": "view == nxProjects && viewItem == project",
"group": "inline@1"
},
{
"command": "nx.graph.select.button",
"when": "view == nxProjects && viewItem == project",
"group": "inline@1"
}
],
"commandPalette": [
Expand Down Expand Up @@ -250,9 +270,25 @@
"when": "isNxWorkspace"
},
{
"command": "nx.dep-graph",
"command": "nx.graph.refresh",
"when": "isNxWorkspace"
},
{
"command": "nx.graph.focus",
"when": "isNxWorkspace"
},
{
"command": "nx.graph.select",
"when": "isNxWorkspace"
},
{
"command": "nx.graph.focus.button",
"when": "false"
},
{
"command": "nx.graph.select.button",
"when": "false"
},
{
"command": "nx.run-many",
"when": "isNxWorkspace"
Expand Down Expand Up @@ -289,10 +325,6 @@
"command": "nx.affected.libs",
"when": "isNxWorkspace"
},
{
"command": "nx.affected.dep-graph",
"when": "isNxWorkspace"
},
{
"command": "nx.list",
"when": "isNxWorkspace"
Expand Down Expand Up @@ -475,8 +507,30 @@
},
{
"category": "Nx",
"title": "dep-graph",
"command": "nx.dep-graph"
"title": "Refresh Nx Graph",
"command": "nx.graph.refresh"
},
{
"category": "Nx",
"title": "Focus in Nx Graph",
"command": "nx.graph.focus"
},
{
"category": "Nx",
"title": "Select in Nx Graph",
"command": "nx.graph.select"
},
{
"category": "Nx",
"title": "Focus in Nx Graph",
"command": "nx.graph.focus.button",
"icon": "$(outline-view-icon)"
},
{
"category": "Nx",
"title": "Select in Nx Graph",
"command": "nx.graph.select.button",
"icon": "$(search)"
},
{
"category": "Nx",
Expand Down Expand Up @@ -523,11 +577,6 @@
"title": "affected libs",
"command": "nx.affected.libs"
},
{
"category": "Nx",
"title": "affected dep-graph",
"command": "nx.affected.dep-graph"
},
{
"category": "Nx",
"title": "list",
Expand Down Expand Up @@ -768,7 +817,7 @@
{
"id": "nxConsole.commonNxCommands",
"title": "Common Nx Commands",
"description": "Open the [dep-graph](command:nx.dep-graph), run a task for [affected](command:nx.affected) projects, or [run-many](command:nx.run-many) on selected projects",
"description": "Open the [graph](command:nx.graph), run a task for [affected](command:nx.affected) projects, or [run-many](command:nx.run-many) on selected projects",
"media": {
"markdown": "getting-started/3-common-nx-commands.md"
}
Expand Down
4 changes: 2 additions & 2 deletions libs/schema/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { WorkspaceJsonConfiguration } from '@nrwl/devkit';
import { ProjectsConfigurations } from '@nrwl/devkit';
import { Schema } from 'nx/src/utils/params';

export enum OptionType {
Expand Down Expand Up @@ -111,6 +111,6 @@ export interface Targets {
export const WORKSPACE_GENERATOR_NAME_REGEX =
/^workspace-(schematic|generator):(.+)/;

export type WorkspaceProjects = WorkspaceJsonConfiguration['projects'];
export type WorkspaceProjects = ProjectsConfigurations['projects'];

export { Store } from './store';
2 changes: 0 additions & 2 deletions libs/vscode/nx-commands-view/src/lib/nx-commands-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,10 @@ export class NxCommandsTreeProvider extends AbstractTreeProvider<NxCommandsTreeI

getChildren() {
return [
'dep-graph',
'run-many',
'affected',
'affected:apps',
'affected:build',
'affected:dep-graph',
'affected:e2e',
'affected:libs',
'affected:lint',
Expand Down
1 change: 1 addition & 0 deletions libs/vscode/nx-workspace/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ export * from './lib/reveal-workspace-json';
export * from './lib/workspace-codelens-provider';
export * from './lib/nx-workspace';
export * from './lib/nx-version';
export * from './lib/find-project-with-path';
37 changes: 37 additions & 0 deletions libs/vscode/nx-workspace/src/lib/find-project-with-path.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { WorkspaceConfigurationStore } from '@nx-console/vscode/configuration';
import { ProjectConfiguration } from '@nrwl/devkit';
import { isAbsolute, join, relative } from 'path';
import { nxWorkspace } from './nx-workspace';

export async function findProjectWithPath(
selectedPath: string | undefined
): Promise<ProjectConfiguration | null> {
if (!selectedPath) {
return null;
}
const workspacePath = WorkspaceConfigurationStore.instance.get(
'nxWorkspacePath',
''
);
const { workspace } = await nxWorkspace();
const projectEntries = Object.entries(workspace.projects);
const entry = projectEntries.find(([, def]) => {
const fullProjectPath = join(
workspacePath,
// If root is empty, that means we're in an angular project with the old ng workspace setup. Otherwise use the sourceRoot
def.root || def.sourceRoot || ''
);
if (fullProjectPath === selectedPath) {
return true;
}

const relativePath = relative(fullProjectPath, selectedPath);
return (
relativePath &&
!relativePath.startsWith('..') &&
!isAbsolute(relativePath)
);
});

return entry ? { name: entry[0], ...entry[1] } : null;
}
1 change: 0 additions & 1 deletion libs/vscode/nx-workspace/src/lib/nx-workspace.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import type { NxJsonConfiguration, ProjectsConfigurations } from '@nrwl/devkit';
import {
checkIsNxWorkspace,
clearJsonCache,
Expand Down
18 changes: 18 additions & 0 deletions libs/vscode/project-graph/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"extends": ["../../../.eslintrc.json"],
"ignorePatterns": ["!**/*", "**/*.html", "**/*.typegen.ts"],
"overrides": [
{
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
"rules": {}
},
{
"files": ["*.ts", "*.tsx"],
"rules": {}
},
{
"files": ["*.js", "*.jsx"],
"rules": {}
}
]
}
11 changes: 11 additions & 0 deletions libs/vscode/project-graph/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# vscode-project-graph

This library was generated with [Nx](https://nx.dev).

## Running unit tests

Run `nx test vscode-project-graph` to execute the unit tests via [Jest](https://jestjs.io).

## Running lint

Run `nx lint vscode-project-graph` to execute the lint via [ESLint](https://eslint.org/).
16 changes: 16 additions & 0 deletions libs/vscode/project-graph/jest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/* eslint-disable */
export default {
displayName: 'vscode-project-graph',
preset: '../../../jest.preset.js',
globals: {
'ts-jest': {
tsconfig: '<rootDir>/tsconfig.spec.json',
},
},
testEnvironment: 'node',
transform: {
'^.+\\.[tj]sx?$': 'ts-jest',
},
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
coverageDirectory: '../../../coverage/libs/vscode/project-graph',
};
23 changes: 23 additions & 0 deletions libs/vscode/project-graph/project.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"$schema": "../../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "libs/vscode/project-graph/src",
"projectType": "library",
"targets": {
"lint": {
"executor": "@nrwl/linter:eslint",
"outputs": ["{options.outputFile}"],
"options": {
"lintFilePatterns": ["libs/vscode/project-graph/**/*.ts"]
}
},
"test": {
"executor": "@nrwl/jest:jest",
"outputs": ["coverage/libs/vscode/project-graph"],
"options": {
"jestConfig": "libs/vscode/project-graph/jest.config.ts",
"passWithNoTests": true
}
}
},
"tags": []
}
1 change: 1 addition & 0 deletions libs/vscode/project-graph/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './lib/project-graph';
61 changes: 61 additions & 0 deletions libs/vscode/project-graph/src/lib/create-project-graph.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { detectPackageManager, getPackageManagerCommand } from '@nrwl/devkit';
import { getOutputChannel } from '@nx-console/server';
import { WorkspaceConfigurationStore } from '@nx-console/vscode/configuration';
import { execSync } from 'child_process';
import * as cacheDir from 'find-cache-dir';

let projectGraphCacheDir: string | undefined;

export async function createProjectGraph() {
return new Promise<void>((res, rej) => {
if (!projectGraphCacheDir) {
projectGraphCacheDir = cacheDir({
name: 'nx-console-project-graph',
cwd: WorkspaceConfigurationStore.instance.get('nxWorkspacePath', ''),
});
}

const workspacePath = WorkspaceConfigurationStore.instance.get(
'nxWorkspacePath',
''
);
const packageManager = detectPackageManager(workspacePath);
const packageCommand = getPackageManagerCommand(packageManager);

// TODO(cammisuli): determine the correct command depending on Nx Version
const command = `${packageCommand.exec} nx dep-graph --file ${
getProjectGraphOutput().relativePath
}`;

getOutputChannel().appendLine(
`Generating graph with command: \`${command}\``
);
try {
execSync(command, {
cwd: workspacePath,
});

res();
} catch (e) {
getOutputChannel().appendLine(
'Unable to create project graph: ' + e.toString()
);
rej();
}
});
}

export function getProjectGraphOutput() {
const directory = projectGraphCacheDir ?? '.';
const fullPath = `${directory}/project-graph.html`;
return {
directory,
relativePath:
'.' +
fullPath.replace(
WorkspaceConfigurationStore.instance.get('nxWorkspacePath', ''),
''
),
fullPath,
};
}
4 changes: 4 additions & 0 deletions libs/vscode/project-graph/src/lib/graph-message-type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export const enum MessageType {
focus = 'FOCUS',
select = 'SELECT',
}
Loading

0 comments on commit ebcd217

Please sign in to comment.