Skip to content

Commit

Permalink
feat: support for project.json files
Browse files Browse the repository at this point in the history
  • Loading branch information
AgentEnder committed Jun 23, 2021
1 parent 46eebfc commit 8567dc2
Show file tree
Hide file tree
Showing 5 changed files with 229 additions and 53 deletions.
6 changes: 5 additions & 1 deletion apps/vscode/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,10 @@ import {
} from '@nx-console/vscode/nx-workspace';
import { environment } from './environments/environment';

import { WorkspaceJsonSchema } from '@nx-console/vscode/json-schema';
import {
WorkspaceJsonSchema,
ProjectJsonSchema,
} from '@nx-console/vscode/json-schema';

let runTargetTreeView: TreeView<RunTargetTreeItem>;
let nxProjectTreeView: TreeView<NxProjectTreeItem>;
Expand Down Expand Up @@ -129,6 +132,7 @@ export function activate(c: ExtensionContext) {
// registers itself as a CodeLensProvider and watches config to dispose/re-register
new WorkspaceCodeLensProvider(context);
new WorkspaceJsonSchema(context);
new ProjectJsonSchema(context);

getTelemetry().extensionActivated((Date.now() - startTime) / 1000);
} catch (e) {
Expand Down
4 changes: 4 additions & 0 deletions apps/vscode/src/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -647,6 +647,10 @@
{
"fileMatch": "angular.json",
"url": "./workspace-schema.json"
},
{
"fileMatch": "project.json",
"url": "./project-schema.json"
}
]
}
Expand Down
1 change: 1 addition & 0 deletions libs/vscode/json-schema/src/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from './lib/workspace-json-schema';
export * from './lib/project-json-schema';
147 changes: 147 additions & 0 deletions libs/vscode/json-schema/src/lib/project-json-schema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
import { watchFile } from '@nx-console/server';
import { WorkspaceConfigurationStore } from '@nx-console/vscode/configuration';
import { dirname, join } from 'path';
import * as vscode from 'vscode';
import { ExecutorInfo, getAllExecutors } from './get-all-executors';

let FILE_WATCHER: vscode.FileSystemWatcher;

export class ProjectJsonSchema {
constructor(context: vscode.ExtensionContext) {
const workspacePath = WorkspaceConfigurationStore.instance.get(
'nxWorkspaceJsonPath',
''
);

if (FILE_WATCHER) {
FILE_WATCHER.dispose();
}

/**
* Whenever a new package is added to the package.json, we recreate the schema.
* This allows newly added plugins to be added
*/
FILE_WATCHER = watchFile(
join(dirname(workspacePath), 'package.json'),
() => {
this.setupSchema(workspacePath, context.extensionUri, true);
}
);
context.subscriptions.push(FILE_WATCHER);

this.setupSchema(workspacePath, context.extensionUri);
}

setupSchema(
workspacePath: string,
extensionUri: vscode.Uri,
clearPackageJsonCache = false
) {
const filePath = vscode.Uri.joinPath(extensionUri, 'project-schema.json');
const collections = getAllExecutors(workspacePath, clearPackageJsonCache);
const contents = getProjectJsonSchema(collections);
vscode.workspace.fs.writeFile(
filePath,
new Uint8Array(Buffer.from(contents, 'utf8'))
);
}
}

function getProjectJsonSchema(collections: ExecutorInfo[]) {
const [builders, executors] = createBuildersAndExecutorsSchema(collections);
const contents = createJsonSchema(builders, executors);
return contents;
}

function createBuildersAndExecutorsSchema(
collections: ExecutorInfo[]
): [string, string] {
const builders = collections
.map(
(collection) => `
{
"if": {
"properties": { "builder": { "const": "${collection.name}" } },
"required": ["builder"]
},
"then": {
"properties": {
"options": {
"$ref": "${collection.path}"
},
"configurations": {
"additionalProperties": {
"$ref": "${collection.path}",
"required": []
}
}
}
}
}
`
)
.join(',');

const executors = collections
.map(
(collection) => `
{
"if": {
"properties": { "executor": { "const": "${collection.name}" } },
"required": ["executor"]
},
"then": {
"properties": {
"options": {
"$ref": "${collection.path}"
},
"configurations": {
"additionalProperties": {
"$ref": "${collection.path}",
"required": []
}
}
}
}
}
`
)
.join(',');

return [builders, executors];
}

function createJsonSchema(builders: string, executors: string) {
return `
{
"title": "JSON schema for Nx projects",
"id": "https://nx.dev/project-schema",
"type": "object",
"properties": {
"targets": {
"description": "Configures all the targets which define what tasks you can run against the project",
"additionalProperties": {
"type": "object",
"properties": {
"executor": {
"description": "The function that Nx will invoke when you run this target",
"type": "string"
},
"options": {
"type": "object"
},
"configurations": {
"description": "provides extra sets of values that will be merged into the options map",
"additionalProperties": {
"type": "object"
}
}
},
"allOf": [
${executors}
]
}
}
}
}`;
}
124 changes: 72 additions & 52 deletions libs/vscode/json-schema/src/lib/workspace-json-schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,36 +133,46 @@ function createJsonSchema(builders: string, executors: string) {
"description": "Read more about this workspace file at https://nx.dev/latest/angular/getting-started/configuration",
"properties": {
"projects": {
"type": "object",
"additionalProperties": {
"type": "object",
"properties": {
"architect": {
"description": "Configures all the targets which define what tasks you can run against the project",
"additionalProperties": {
"type": "object",
"properties": {
"builder": {
"description": "The function that Nx will invoke when you run this architect",
"type": "string"
},
"options": {
"type": "object"
},
"configurations": {
"description": "provides extra sets of values that will be merged into the options map",
"additionalProperties": {
"type": "object"
}
"oneOf": [
{
"type": "object",
"additionalProperties": {
"type": "string"
}
},
{
"type": "object",
"additionalProperties": {
"type": "object",
"properties": {
"architect": {
"description": "Configures all the targets which define what tasks you can run against the project",
"additionalProperties": {
"type": "object",
"properties": {
"builder": {
"description": "The function that Nx will invoke when you run this architect",
"type": "string"
},
"options": {
"type": "object"
},
"configurations": {
"description": "provides extra sets of values that will be merged into the options map",
"additionalProperties": {
"type": "object"
}
}
},
"allOf": [
${builders}
]
}
},
"allOf": [
${builders}
]
}
}
}
}
}
]
}
}
}
Expand All @@ -176,36 +186,46 @@ function createJsonSchema(builders: string, executors: string) {
"description": "Read more about this workspace file at https://nx.dev/latest/react/getting-started/configuration",
"properties": {
"projects": {
"type": "object",
"additionalProperties": {
"type": "object",
"properties": {
"targets": {
"description": "Configures all the targets which define what tasks you can run against the project",
"additionalProperties": {
"type": "object",
"properties": {
"executor": {
"description": "The function that Nx will invoke when you run this target",
"type": "string"
},
"options": {
"type": "object"
},
"configurations": {
"description": "provides extra sets of values that will be merged into the options map",
"additionalProperties": {
"type": "object"
}
"oneOf": [
{
"type": "object",
"additionalProperties": {
"type": "string"
}
},
{
"type": "object",
"additionalProperties": {
"type": "object",
"properties": {
"targets": {
"description": "Configures all the targets which define what tasks you can run against the project",
"additionalProperties": {
"type": "object",
"properties": {
"executor": {
"description": "The function that Nx will invoke when you run this target",
"type": "string"
},
"options": {
"type": "object"
},
"configurations": {
"description": "provides extra sets of values that will be merged into the options map",
"additionalProperties": {
"type": "object"
}
}
},
"allOf": [
${executors}
]
}
},
"allOf": [
${executors}
]
}
}
}
}
}
]
}
}
}
Expand Down

0 comments on commit 8567dc2

Please sign in to comment.