Skip to content

Commit

Permalink
Merge pull request #169 from player-ui/feature/measure-content-comple…
Browse files Browse the repository at this point in the history
…xity

feat: complexity checker plugin
  • Loading branch information
kharrop authored Nov 14, 2024
2 parents f82434d + 01e0096 commit 9af842c
Show file tree
Hide file tree
Showing 31 changed files with 1,152 additions and 524 deletions.
1 change: 1 addition & 0 deletions .bazelignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ language/typescript-expression-plugin/node_modules
language/json-language-service/node_modules
language/json-language-server/node_modules
language/dsl/node_modules
language/complexity-check-plugin/node_modules
helpers/node_modules
devtools/client/node_modules
devtools/messenger/node_modules
Expand Down
6 changes: 4 additions & 2 deletions cli/src/commands/dsl/compile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export default class DSLCompile extends BaseCommand {
}),
severity: Flags.string({
char: "s",
description: "The severity of the validation",
description: "The severity of validation issues",
options: ["error", "warn"],
default: "error",
}),
Expand All @@ -68,14 +68,15 @@ export default class DSLCompile extends BaseCommand {
flags["skip-validation"] ?? config.dsl?.skipValidation ?? false,
exp,
severity: flags.severity,
loglevel: flags.loglevel
};
}

async run(): Promise<{
/** the status code */
exitCode: number;
}> {
const { input, output, skipValidation, exp, severity } =
const { input, output, skipValidation, exp, severity, loglevel } =
await this.getOptions();

const files = await glob(
Expand Down Expand Up @@ -211,6 +212,7 @@ export default class DSLCompile extends BaseCommand {
return result.output?.outputFile ?? "";
}),
...(exp ? ["--exp"] : []),
`-s ${severity} -v ${loglevel}`
]);
} else {
console.log("No output to validate");
Expand Down
33 changes: 22 additions & 11 deletions cli/src/commands/json/validate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { BaseCommand } from "../../utils/base-command";
import { validationRenderer } from "../../utils/diag-renderer";
import { convertToFileGlob } from "../../utils/fs";
import { createTaskRunner } from "../../utils/task-runner";
import { stringToLogLevel } from "../../utils/log-levels"

/** A command to validate JSON content */
export default class Validate extends BaseCommand {
Expand All @@ -23,6 +24,12 @@ export default class Validate extends BaseCommand {
description: "Use experimental language features",
default: false,
}),
severity: Flags.string({
char: "s",
description: "The severity of validation issues",
options: ["error", "warn"],
default: "error",
}),
};

private async getOptions() {
Expand All @@ -41,14 +48,16 @@ export default class Validate extends BaseCommand {
return {
files: Array.isArray(files) ? files : [files],
exp,
severity: flags.severity,
loglevel: flags.loglevel
};
}

async run(): Promise<{
/** the status code */
exitCode: number;
}> {
const { files: inputFiles, exp } = await this.getOptions();
const { files: inputFiles, exp, severity, loglevel } = await this.getOptions();
const expandedFilesList = convertToFileGlob(inputFiles, "**/*.json");
this.debug("Searching for files using: %o", expandedFilesList);
const files = await glob(expandedFilesList, {
Expand All @@ -70,7 +79,6 @@ export default class Validate extends BaseCommand {
},
run: async () => {
const contents = await fs.readFile(f, "utf-8");
const lsp = await this.createLanguageService(exp);

const validations =
(await lsp.validateTextDocument(
Expand All @@ -80,18 +88,21 @@ export default class Validate extends BaseCommand {
return validations;
},
})),
});
loglevel: stringToLogLevel(loglevel)
},);

const taskResults = await taskRunner.run();

taskResults.forEach((t) => {
if (
t.error ||
t.output.some((d) => d.severity === DiagnosticSeverity.Error)
) {
results.exitCode = 100;
}
});
if(severity !== "error"){
taskResults.forEach((t) => {
if (
t.error ||
t.output.some((d) => d.severity === DiagnosticSeverity.Error)
) {
results.exitCode = 100;
}
});
}

this.debug("finished");
this.exit(results.exitCode);
Expand Down
1 change: 1 addition & 0 deletions cli/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ export * from "./config";
export * from "./plugins";
export * from "./utils/base-command";
export * from "./utils/compilation-context";
export * from "./utils/log-levels";
7 changes: 7 additions & 0 deletions cli/src/utils/base-command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import type {
PlayerConfigResolvedShape,
} from "../config";
import { CompilationContext } from "./compilation-context";
import { LogLevels } from "./log-levels";

const configLoader = cosmiconfig("player");

Expand All @@ -21,6 +22,12 @@ export abstract class BaseCommand extends Command {
"Path to a specific config file to load.\nBy default, will automatically search for an rc or config file to load",
char: "c",
}),
loglevel: Flags.string({
char: "v",
description: "How verbose logs should be",
options: LogLevels,
default: "warn",
}),
};

static strict = false;
Expand Down
52 changes: 40 additions & 12 deletions cli/src/utils/diag-renderer.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { Diagnostic, Range } from "vscode-languageserver-types";
import { Diagnostic, Range } from "vscode-languageserver-types";
import { DiagnosticSeverity } from "vscode-languageserver-types";
import chalk from "chalk";
import logSymbols from "log-symbols";
Expand Down Expand Up @@ -92,10 +92,20 @@ function formatDiagnostic(
longestLine: number,
fName: string
): string {
const type =
diag.severity === DiagnosticSeverity.Error
? chalk.red(`${logSymbols.error} `)
: chalk.yellow(`${logSymbols.warning} `);
let type: string;

if (diag.severity === DiagnosticSeverity.Error) {
type = chalk.red(`${logSymbols.error} `);
} else if (diag.severity === DiagnosticSeverity.Warning) {
type = chalk.yellow(`${logSymbols.warning} `);
} else if (diag.severity === DiagnosticSeverity.Information){
type = chalk.blue(`${logSymbols.info} `);
} else if (diag.severity === DiagnosticSeverity.Hint){
type = chalk.gray(`${logSymbols.info} `);
} else {
type = chalk.green(`${logSymbols.info} `);
}

const msg = chalk.bold(diag.message);
const range = getLineRange(diag.range);

Expand All @@ -111,11 +121,13 @@ function formatDiagnostic(
export function formatDiagnosticResults(
filePath: string,
results: Diagnostic[],
verbose = false
loglevel: DiagnosticSeverity
) {
const count = {
errors: 0,
warnings: 0,
info: 0,
trace: 0
};
const linePrefix = " ";
const longestLine = Math.max(
Expand All @@ -128,9 +140,13 @@ export function formatDiagnosticResults(
count.errors += 1;
} else if (diag.severity === DiagnosticSeverity.Warning) {
count.warnings += 1;
} else if (diag.severity === DiagnosticSeverity.Information) {
count.info += 1;
} else if (diag.severity === DiagnosticSeverity.Hint) {
count.trace += 1;
}

if (diag.severity === DiagnosticSeverity.Error || verbose) {
if (diag.severity && loglevel >= diag.severity) {
return linePrefix + formatDiagnostic(diag, longestLine + 1, filePath);
}

Expand All @@ -140,18 +156,30 @@ export function formatDiagnosticResults(

if (count.errors > 0) {
lines = ["", `${chalk.red(logSymbols.error)} ${filePath}`, ...lines, ""];
} else if (verbose) {
if (count.warnings > 0) {
} else if (count.warnings > 0 && loglevel >= DiagnosticSeverity.Warning) {
lines = [
"",
`${chalk.yellow(logSymbols.warning)} ${filePath}`,
...lines,
"",
];
} else if (count.info > 0 && loglevel >= DiagnosticSeverity.Information){
lines = [
"",
`${chalk.blue(logSymbols.info)} ${filePath}`,
...lines,
"",
];
} else if (count.trace > 0 && loglevel >= DiagnosticSeverity.Hint) {
lines = [
"",
`${chalk.gray(logSymbols.info)} ${filePath}`,
...lines,
"",
];
} else {
lines = [`${chalk.green(logSymbols.success)} ${filePath}`, ...lines];
}
}

return {
...count,
Expand Down Expand Up @@ -199,7 +227,7 @@ export const validationRenderer: TaskProgressRenderer<
const formattedDiags = formatDiagnosticResults(
task.data?.file ? normalizePath(task.data.file) : "",
sortDiagnostics(task.output),
true
ctx.loglevel
);

output.push(...formattedDiags.lines);
Expand Down Expand Up @@ -229,7 +257,7 @@ export const validationRenderer: TaskProgressRenderer<
const formattedDiags = formatDiagnosticResults(
t.data?.file ?? "",
t.output,
true
ctx.loglevel
);

count.errors += formattedDiags.errors;
Expand Down
22 changes: 22 additions & 0 deletions cli/src/utils/log-levels.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { DiagnosticSeverity } from "vscode-languageserver-types";

export const LogLevelsMap = {
error: DiagnosticSeverity.Error,
warn: DiagnosticSeverity.Warning,
info: DiagnosticSeverity.Information,
trace: DiagnosticSeverity.Hint,
};

export type LogLevelsType = keyof typeof LogLevelsMap;

export const LogLevels = Object.keys(LogLevelsMap);

function isValidLogLevel(level: string): level is LogLevelsType {
return LogLevels.includes(level);
}

export function stringToLogLevel(level: string): DiagnosticSeverity {
return isValidLogLevel(level)
? LogLevelsMap[level]
: DiagnosticSeverity.Warning;
}
14 changes: 13 additions & 1 deletion cli/src/utils/task-runner.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import logUpdate from "log-update";
import { DiagnosticSeverity } from "vscode-languageserver-types";

/* eslint-disable no-param-reassign */
interface BaseTask<Results, Data> {
Expand Down Expand Up @@ -44,6 +45,9 @@ export interface TaskProgressRenderer<ResultType, Data = unknown> {
onUpdate: (ctx: {
/** The tasks that are running */
tasks: Array<Task<ResultType, Data>>;

/** What level of information to log */
loglevel: DiagnosticSeverity
}) => string;

/** Called for a summary */
Expand All @@ -53,6 +57,9 @@ export interface TaskProgressRenderer<ResultType, Data = unknown> {

/** Number of ms it took to run */
duration: number;

/** What level of information to log */
loglevel: DiagnosticSeverity
}) => string;
}

Expand All @@ -68,12 +75,16 @@ interface TaskRunner<R, Data> {
export const createTaskRunner = <R, D>({
tasks,
renderer,
loglevel,
}: {
/** A list of tasks to run */
tasks: Array<Pick<BaseTask<R, D>, "data" | "run">>;

/** How to report progress */
renderer: TaskProgressRenderer<R, D>;

/** What level of logs to write */
loglevel: DiagnosticSeverity
}): TaskRunner<R, D> => {
const statefulTasks: Array<Task<R, D>> = tasks.map((t) => {
return {
Expand All @@ -93,7 +104,7 @@ export const createTaskRunner = <R, D>({
return;
}

const output = renderer.onUpdate({ tasks: statefulTasks });
const output = renderer.onUpdate({ tasks: statefulTasks, loglevel });
if (process.stdout.isTTY) {
logUpdate(output);
}
Expand Down Expand Up @@ -122,6 +133,7 @@ export const createTaskRunner = <R, D>({
const output = renderer.onEnd({
duration,
tasks: statefulTasks as Array<CompletedTask<R, D>>,
loglevel
});

console.log(output);
Expand Down
26 changes: 26 additions & 0 deletions language/complexity-check-plugin/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
load("@npm//:defs.bzl", "npm_link_all_packages")
load("@rules_player//javascript:defs.bzl", "js_pipeline")
load("//helpers:defs.bzl", "tsup_config", "vitest_config")

npm_link_all_packages(name = "node_modules")

tsup_config(name = "tsup_config")

vitest_config(name = "vitest_config")

js_pipeline(
package_name = "@player-tools/complexity-check-plugin",
test_deps = [
":node_modules/@player-tools/static-xlrs",
],
deps = [
":node_modules/@player-tools/json-language-service",
"//:node_modules/@player-ui/player",
"//:node_modules/jsonc-parser",
"//:node_modules/typescript-template-language-service-decorator",
"//:node_modules/vscode-languageserver-types",
"//:node_modules/vscode-languageserver-textdocument",
"//:node_modules/typescript",

],
)
Loading

0 comments on commit 9af842c

Please sign in to comment.