Skip to content
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -97,3 +97,6 @@ storybook-static
.cursor/rules/nx-rules.mdc
.github/instructions/nx.instructions.md
.nx/polygraph/

.nx/polygraph
.nx/self-healing
3 changes: 2 additions & 1 deletion .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ apps/intellij/*
!apps/intellij/project.json

/.nx/cache
/.nx/workspace-data
/.nx/workspace-data
.nx/self-healing
2 changes: 1 addition & 1 deletion apps/intellij/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ val nxlsRoot = "${rootDir}/dist/apps/nxls"
layout.buildDirectory = file("${rootDir}/dist/apps/intellij")

plugins {
id("dev.nx.gradle.project-graph") version ("0.1.12")
id("dev.nx.gradle.project-graph") version ("0.1.20")
id("java")
id("org.jetbrains.changelog") version "2.4.0"
id("org.jetbrains.intellij.platform") version "2.11.0"
Expand Down
2 changes: 1 addition & 1 deletion apps/nxls/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ import {
WatcherStatus,
} from '@nx-console/shared-watcher';
import type { ProjectGraph } from 'nx/src/devkit-exports';
import type { ConfigurationSourceMaps } from 'nx/src/project-graph/utils/project-configuration-utils';
import type { ConfigurationSourceMaps } from 'nx/src/project-graph/utils/project-configuration/source-maps';
import { ClientCapabilities, TextDocument } from 'vscode-json-languageservice';
import {
CreateFilesParams,
Expand Down
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ group = "dev.nx.console"
layout.buildDirectory = File("dist")

plugins {
id("dev.nx.gradle.project-graph") version "0.1.12"
id("dev.nx.gradle.project-graph") version "0.1.20"
id("com.ncorti.ktfmt.gradle") version "0.24.0"

id("org.jetbrains.kotlin.jvm") version "2.2.0"
Expand Down
13 changes: 8 additions & 5 deletions libs/language-server/workspace/src/lib/get-pdv-data.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { directoryExists } from '@nx-console/shared-file-system';
import { workspaceDependencyPath } from '@nx-console/shared-npm';
import { findNxPackagePath } from '@nx-console/shared-npm';
import { gte } from '@nx-console/nx-version';
import { PDVData } from '@nx-console/shared-types';
import type {
ProjectConfiguration,
ProjectGraphProjectNode,
} from 'nx/src/devkit-exports';
import { join, relative } from 'path';
import { dirname, join, relative } from 'path';
import { getNxCloudStatus } from './get-nx-cloud-status';
import {
getNxVersion,
Expand Down Expand Up @@ -139,13 +139,16 @@ export async function getPDVData(
async function getGraphBasePath(
workspacePath: string,
): Promise<string | undefined> {
const nxWorkspaceDepPath = await workspaceDependencyPath(workspacePath, 'nx');
const graphIndexPath = await findNxPackagePath(
workspacePath,
join('src', 'core', 'graph', 'index.html'),
);

if (!nxWorkspaceDepPath) {
if (!graphIndexPath) {
return undefined;
}

const graphBasePath = join(nxWorkspaceDepPath, 'src', 'core', 'graph');
const graphBasePath = dirname(graphIndexPath);

if (await directoryExists(graphBasePath)) {
return graphBasePath;
Expand Down
27 changes: 20 additions & 7 deletions libs/shared/npm/src/lib/find-nx-package-path.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,16 @@ export async function findNxPackagePath(
workspacePath: string,
filePath: string,
): Promise<string | undefined> {
const buildPath = (base: string) => join(base, filePath);
const nxPathVariants = getNxPathVariants(filePath);
const buildPaths = (base: string) =>
nxPathVariants.map((path) => join(base, path));

const nxWorkspaceDepPath = await workspaceDependencyPath(workspacePath, 'nx');
if (nxWorkspaceDepPath) {
const path = buildPath(nxWorkspaceDepPath);
if (await fileExists(path)) {
return path;
for (const path of buildPaths(nxWorkspaceDepPath)) {
if (await fileExists(path)) {
return path;
}
}
}

Expand All @@ -31,13 +34,23 @@ export async function findNxPackagePath(
'@nrwl/workspace',
);
if (nrwlWorkspaceDepPath) {
const path = buildPath(nrwlWorkspaceDepPath);
if (await fileExists(path)) {
return path;
for (const path of buildPaths(nrwlWorkspaceDepPath)) {
if (await fileExists(path)) {
return path;
}
}
}
}

function getNxPathVariants(filePath: string): string[] {
const srcPrefix = `src${platform() === 'win32' ? '\\' : '/'}`;
if (filePath === 'src' || filePath.startsWith(srcPrefix)) {
return [filePath, join('dist', filePath)];
}

return [filePath];
}

/**
* Finds the nx executable binary in the workspace.
*
Expand Down
22 changes: 12 additions & 10 deletions libs/shared/npm/src/lib/local-nx-utils/cache-dir.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { join } from 'path';
import {
importWorkspaceDependency,
workspaceDependencyPath,
} from '../workspace-dependencies';
import { findNxPackagePath } from '../find-nx-package-path';
import { importWorkspaceDependency } from '../workspace-dependencies';

export async function getCacheDir(workspacePath: string): Promise<string> {
const nxPath = await workspaceDependencyPath(workspacePath, 'nx');
if (!nxPath) {
const importPath = await findNxPackagePath(
workspacePath,
join('src', 'utils', 'cache-directory.js'),
);
if (!importPath) {
throw 'local nx dependency not found';
}
const importPath = join(nxPath, 'src/utils/cache-directory');
const { cacheDir } =
await importWorkspaceDependency<
typeof import('nx/src/utils/cache-directory')
Expand All @@ -20,11 +20,13 @@ export async function getCacheDir(workspacePath: string): Promise<string> {
export async function getWorkspaceDataDirectory(
workspacePath: string,
): Promise<string> {
const nxPath = await workspaceDependencyPath(workspacePath, 'nx');
if (!nxPath) {
const importPath = await findNxPackagePath(
workspacePath,
join('src', 'utils', 'cache-directory.js'),
);
if (!importPath) {
throw 'local nx dependency not found';
}
const importPath = join(nxPath, 'src/utils/cache-directory');
const { workspaceDataDirectory } =
await importWorkspaceDependency<
typeof import('nx/src/utils/cache-directory')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import type {
ProjectGraph,
} from 'nx/src/devkit-exports';
import type { ProjectGraphError } from 'nx/src/project-graph/error-types';
import type { ConfigurationSourceMaps } from 'nx/src/project-graph/utils/project-configuration-utils';
import type { ConfigurationSourceMaps } from 'nx/src/project-graph/utils/project-configuration/source-maps';
import { performance } from 'perf_hooks';
import {
getNxOutput,
Expand Down
2 changes: 1 addition & 1 deletion libs/shared/nx-workspace-info/src/lib/workspace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { getNxVersion } from './get-nx-version';
import { getNxWorkspaceConfig } from './get-nx-workspace-config';
import { getNxDaemonClient } from './get-nx-workspace-package';
import type { ProjectGraph } from 'nx/src/devkit-exports';
import type { ConfigurationSourceMaps } from 'nx/src/project-graph/utils/project-configuration-utils';
import type { ConfigurationSourceMaps } from 'nx/src/project-graph/utils/project-configuration/source-maps';
import { execSync } from 'child_process';

const enum Status {
Expand Down
39 changes: 37 additions & 2 deletions libs/shared/schema/src/normalize-schema.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@ describe('utils', () => {
};

it('should work with schema without any properties', async () => {
// @ts-expect-error absence of required property "properties" is needed to test failure resistance
const r = await normalizeSchema({});
const r = await normalizeSchema({} as Schema);
expect(r).toEqual([]);
});

Expand Down Expand Up @@ -71,6 +70,42 @@ describe('utils', () => {
expect(r[0].items).toEqual(['test']);
});

it('should set items when items contains an enum object', async () => {
const option = {
...mockOption,
items: {
type: OptionType.String,
enum: ['test'],
},
};
const r = await getSchema({ option });
expect(r[0].items).toEqual(['test']);
});

it('should ignore items objects without an enum', async () => {
const option = {
...mockOption,
items: {
type: OptionType.String,
},
};
const r = await getSchema({ option });
expect(r[0].items).toBeUndefined();
});

it('should ignore tuple-schema items arrays', async () => {
const option = {
...mockOption,
items: [
{
type: OptionType.String,
},
],
};
const r = await getSchema({ option });
expect(r[0].items).toBeUndefined();
});

describe('xPrompt', () => {
const xPromptItems = [
{ value: 'css', label: 'CSS' },
Expand Down
26 changes: 18 additions & 8 deletions libs/shared/schema/src/normalize-schema.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import {
CliOption,
ItemsWithEnum,
ItemTooltips,
LongFormXPrompt,
Option,
Expand Down Expand Up @@ -163,13 +162,24 @@ function isFieldRequired(
}

function getItems(option: CliOption): { items: string[] } | undefined {
return (
option.items && {
items:
(option.items as ItemsWithEnum).enum ||
((option.items as string[]).length && option.items),
}
);
const items = normalizeOptionItems(option.items);
return items ? { items } : undefined;
}

function normalizeOptionItems(items: CliOption['items']): string[] | undefined {
if (!items) {
return undefined;
}

if (Array.isArray(items)) {
return items.every((item) => typeof item === 'string') ? items : undefined;
}

if ('enum' in items && Array.isArray(items.enum)) {
return items.enum.map((item) => String(item));
}

return undefined;
}

function isLongFormXPrompt(xPrompt: XPrompt): xPrompt is LongFormXPrompt {
Expand Down
10 changes: 8 additions & 2 deletions libs/shared/schema/src/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ export enum OptionType {
}

export type OptionPropertyDescription = Schema['properties'][number];
export type CompatibleOptionItems =
| OptionPropertyDescription['items']
| string[]
| ItemsWithEnum;

export type CliOption = {
name: string;
Expand All @@ -18,9 +22,11 @@ export type CliOption = {
alias?: string;
hidden?: boolean;
deprecated?: boolean | string;
} & OptionPropertyDescription;
} & Omit<OptionPropertyDescription, 'items'> & {
items?: CompatibleOptionItems;
};

export interface Option extends CliOption {
export interface Option extends Omit<CliOption, 'items'> {
tooltip?: string;
itemTooltips?: ItemTooltips;
items?: string[] | ItemsWithEnum;
Expand Down
2 changes: 1 addition & 1 deletion libs/shared/types/src/lib/nx-workspace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import type {
ProjectFileMap,
ProjectGraph,
} from 'nx/src/devkit-exports';
import type { ConfigurationSourceMaps } from 'nx/src/project-graph/utils/project-configuration-utils';
import type { ConfigurationSourceMaps } from 'nx/src/project-graph/utils/project-configuration/source-maps';

export type NxProjectConfiguration = ProjectConfiguration & {
files?: { file: string }[];
Expand Down
2 changes: 1 addition & 1 deletion libs/shared/watcher/src/lib/passive-daemon-watcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
import { Logger } from '@nx-console/shared-utils';
import { randomUUID } from 'crypto';
import type { ProjectGraph } from 'nx/src/config/project-graph';
import type { ConfigurationSourceMaps } from 'nx/src/project-graph/utils/project-configuration-utils';
import type { ConfigurationSourceMaps } from 'nx/src/project-graph/utils/project-configuration/source-maps';
import { AnyEventObject, createActor, fromPromise, setup } from 'xstate';

export type WatcherStatus = 'operational' | 'daemonDisabled' | 'notRunning';
Expand Down
17 changes: 10 additions & 7 deletions libs/vscode/graph-base/src/load-graph-base-html.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,27 @@
import { workspaceDependencyPath } from '@nx-console/shared-npm';
import { findNxPackagePath } from '@nx-console/shared-npm';
import { getNxWorkspacePath } from '@nx-console/vscode-configuration';
import { existsSync, readFileSync } from 'fs';
import { join } from 'path';
import { readFileSync } from 'fs';
import { dirname, join } from 'path';
import { Uri, Webview, window } from 'vscode';

export async function loadGraphBaseHtml(webview: Webview): Promise<string> {
const workspacePath = await getNxWorkspacePath();
const nxPath = await workspaceDependencyPath(workspacePath, 'nx');
if (!nxPath || !existsSync(nxPath)) {
const graphIndexPath = await findNxPackagePath(
workspacePath,
join('src', 'core', 'graph', 'index.html'),
);
if (!graphIndexPath) {
window.showErrorMessage(
'Error loading the nx graph. Did you run npm/yarn/pnpm install?',
);
return '';
}
const graphPath = join(nxPath, 'src', 'core', 'graph');
const graphPath = dirname(graphIndexPath);

const asWebviewUri = (path: string) =>
webview.asWebviewUri(Uri.file(join(graphPath, path))).toString();

let html = readFileSync(join(graphPath, 'index.html'), 'utf-8');
let html = readFileSync(graphIndexPath, 'utf-8');
html = html.replace(/environment.js/g, asWebviewUri('environment.js'));
html = html.replace(/polyfills.js/g, asWebviewUri('polyfills.js'));
html = html.replace(/runtime.js/g, asWebviewUri('runtime.js'));
Expand Down
15 changes: 9 additions & 6 deletions libs/vscode/migrate/src/lib/migrate-webview.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import { gte } from '@nx-console/nx-version';
import { directoryExists } from '@nx-console/shared-file-system';
import { workspaceDependencyPath } from '@nx-console/shared-npm';
import {
findNxPackagePath,
workspaceDependencyPath,
} from '@nx-console/shared-npm';
import { getNxWorkspacePath } from '@nx-console/vscode-configuration';
import { getNxVersion } from '@nx-console/vscode-nx-workspace';
import { readFileSync } from 'fs';
import type { MigrationsJsonEntry } from 'nx/src/config/misc-interfaces';
import { join } from 'path';
import { dirname, join } from 'path';
import {
ExtensionContext,
Uri,
Expand Down Expand Up @@ -253,16 +256,16 @@ async function getGraphHtmlLocation(

// TODO: don't simply duplicate this from nxls code?
async function getGraphBasePath(): Promise<string | undefined> {
const nxWorkspaceDepPath = await workspaceDependencyPath(
const graphIndexPath = await findNxPackagePath(
getNxWorkspacePath(),
'nx',
join('src', 'core', 'graph', 'index.html'),
);

if (!nxWorkspaceDepPath) {
if (!graphIndexPath) {
return undefined;
}

const graphBasePath = join(nxWorkspaceDepPath, 'src', 'core', 'graph');
const graphBasePath = dirname(graphIndexPath);

if (await directoryExists(graphBasePath)) {
return graphBasePath;
Expand Down
Loading
Loading