Skip to content

Commit

Permalink
feat: provide json schema for workspace.json (#1077)
Browse files Browse the repository at this point in the history
* feat: create json schema for workspace file
  • Loading branch information
Cammisuli authored Jun 4, 2021
1 parent 969b115 commit ae35ec5
Show file tree
Hide file tree
Showing 18 changed files with 424 additions and 4 deletions.
32 changes: 32 additions & 0 deletions angular.json
Original file line number Diff line number Diff line change
Expand Up @@ -619,6 +619,38 @@
}
}
}
},
"vscode-json-schema": {
"root": "libs/vscode/json-schema",
"sourceRoot": "libs/vscode/json-schema/src",
"projectType": "library",
"architect": {
"lint": {
"builder": "@nrwl/linter:eslint",
"options": {
"lintFilePatterns": ["libs/vscode/json-schema/**/*.ts"]
}
},
"test": {
"builder": "@nrwl/jest:jest",
"outputs": ["coverage/libs/vscode/json-schema"],
"options": {
"jestConfig": "libs/vscode/json-schema/jest.config.js",
"passWithNoTests": true
}
},
"build": {
"builder": "@nrwl/node:package",
"outputs": ["{options.outputPath}"],
"options": {
"outputPath": "dist/libs/vscode/json-schema",
"tsConfig": "libs/vscode/json-schema/tsconfig.lib.json",
"packageJson": "libs/vscode/json-schema/package.json",
"main": "libs/vscode/json-schema/src/index.ts",
"assets": ["libs/vscode/json-schema/*.md"]
}
}
}
}
}
}
3 changes: 3 additions & 0 deletions apps/vscode/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ import {
} from '@nx-console/vscode/nx-workspace';
import { environment } from './environments/environment';

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

let runTargetTreeView: TreeView<RunTargetTreeItem>;
let nxProjectTreeView: TreeView<NxProjectTreeItem>;
let nxCommandsTreeView: TreeView<NxCommandsTreeItem>;
Expand Down Expand Up @@ -126,6 +128,7 @@ export function activate(c: ExtensionContext) {

// registers itself as a CodeLensProvider and watches config to dispose/re-register
new WorkspaceCodeLensProvider(context);
new WorkspaceJsonSchema(context);

getTelemetry().extensionActivated((Date.now() - startTime) / 1000);
} catch (e) {
Expand Down
12 changes: 11 additions & 1 deletion apps/vscode/src/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -639,6 +639,16 @@
"when": "isNxWorkspace || isAngularWorkspace"
}
]
}
},
"jsonValidation": [
{
"fileMatch": "workspace.json",
"url": "./workspace-schema.json"
},
{
"fileMatch": "angular.json",
"url": "./workspace-schema.json"
}
]
}
}
1 change: 1 addition & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@ module.exports = {
'<rootDir>/libs/vscode/nx-run-target-view',
'<rootDir>/libs/vscode/nx-commands-view',
'<rootDir>/libs/vscode/webview',
'<rootDir>/libs/vscode/json-schema',
],
};
1 change: 1 addition & 0 deletions libs/server/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@ export {
readAndCacheJsonFile,
clearJsonCache,
toLegacyWorkspaceFormat,
listOfUnnestedNpmPackages,
} from './lib/utils/utils';
export { watchFile } from './lib/utils/watch-file';
3 changes: 2 additions & 1 deletion libs/server/src/lib/utils/read-schematic-collections.ts
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,8 @@ export async function readSchematicOptions(
nodeModulesDir
);
const collectionJson = readAndCacheJsonFile(
collectionPackageJson.json.schematics || collectionPackageJson.json.generators,
collectionPackageJson.json.schematics ||
collectionPackageJson.json.generators,
dirname(collectionPackageJson.path)
);
const schematicSchema = readAndCacheJsonFile(
Expand Down
21 changes: 21 additions & 0 deletions libs/vscode/json-schema/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"extends": ["../../../.eslintrc.json"],
"ignorePatterns": ["!**/*"],
"overrides": [
{
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
"parserOptions": {
"project": ["libs/vscode/json-schema/tsconfig.*?.json"]
},
"rules": {}
},
{
"files": ["*.ts", "*.tsx"],
"rules": {}
},
{
"files": ["*.js", "*.jsx"],
"rules": {}
}
]
}
7 changes: 7 additions & 0 deletions libs/vscode/json-schema/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# vscode-json-schema

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

## Running unit tests

Run `nx test vscode-json-schema` to execute the unit tests via [Jest](https://jestjs.io).
14 changes: 14 additions & 0 deletions libs/vscode/json-schema/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
module.exports = {
displayName: 'vscode-json-schema',
preset: '../../../jest.preset.js',
globals: {
'ts-jest': {
tsConfig: '<rootDir>/tsconfig.spec.json',
},
},
transform: {
'^.+\\.[tj]sx?$': 'ts-jest',
},
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
coverageDirectory: '../../../coverage/libs/vscode/json-schema',
};
4 changes: 4 additions & 0 deletions libs/vscode/json-schema/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"name": "@nx-console/vscode/json-schema",
"version": "0.0.1"
}
1 change: 1 addition & 0 deletions libs/vscode/json-schema/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './lib/workspace-json-schema';
99 changes: 99 additions & 0 deletions libs/vscode/json-schema/src/lib/get-all-executors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { clearJsonCache, readAndCacheJsonFile } from '@nx-console/server';
import { dirname, join } from 'path';

export interface ExecutorInfo {
name: string;
path: string;
}

export function getAllExecutors(
workspaceJsonPath: string,
clearPackageJsonCache: boolean
): ExecutorInfo[] {
return readExecutorCollectionsFromNodeModules(
workspaceJsonPath,
clearPackageJsonCache
);
}

function readExecutorCollectionsFromNodeModules(
workspaceJsonPath: string,
clearPackageJsonCache: boolean
): ExecutorInfo[] {
const basedir = join(workspaceJsonPath, '..');
const nodeModulesDir = join(basedir, 'node_modules');

if (clearPackageJsonCache) {
clearJsonCache('package.json', basedir);
}

const packages: { [packageName: string]: string } =
readAndCacheJsonFile('package.json', basedir).json.devDependencies || {};
const executorCollections = Object.keys(packages).filter((p) => {
try {
const packageJson = readAndCacheJsonFile(
join(p, 'package.json'),
nodeModulesDir
).json;
// TODO: to add support for schematics, we can change this to include schematics/generators
return !!(packageJson.builders || packageJson.executors);
} catch (e) {
if (
e.message &&
(e.message.indexOf('no such file') > -1 ||
e.message.indexOf('not a directory') > -1)
) {
return false;
} else {
throw e;
}
}
});

return executorCollections
.map((c) => readCollections(nodeModulesDir, c))
.flat()
.filter((c): c is ExecutorInfo => Boolean(c));
}

function readCollections(
basedir: string,
collectionName: string
): ExecutorInfo[] | null {
try {
const packageJson = readAndCacheJsonFile(
join(collectionName, 'package.json'),
basedir
);

const collection = readAndCacheJsonFile(
packageJson.json.builders || packageJson.json.executors,
dirname(packageJson.path)
);

return getBuilderPaths(collectionName, collection.path, collection.json);
} catch (e) {
return null;
}
}

function getBuilderPaths(
collectionName: string,
path: string,
json: any
): ExecutorInfo[] {
const baseDir = dirname(path);

const builders: ExecutorInfo[] = [];
for (const [key, value] of Object.entries<any>(
json.builders || json.executors
)) {
builders.push({
name: `${collectionName}:${key}`,
path: join(baseDir, value.schema),
});
}

return builders;
}
Loading

0 comments on commit ae35ec5

Please sign in to comment.