Merge pull request #2348 from github/koesie10/non-existing-model-file

Hide link when model file does not exist
This commit is contained in:
Koen Vlaswinkel
2023-04-19 10:21:21 +02:00
committed by GitHub
8 changed files with 93 additions and 59 deletions

View File

@@ -35,7 +35,7 @@ import { readQueryResults, runQuery } from "./external-api-usage-query";
import { createDataExtensionYaml, loadDataExtensionYaml } from "./yaml";
import { ExternalApiUsage } from "./external-api-usage";
import { ModeledMethod } from "./modeled-method";
import { ExtensionPackModelFile } from "./extension-pack-picker";
import { ExtensionPackModelFile } from "./shared/extension-pack";
function getQlSubmoduleFolder(): WorkspaceFolder | undefined {
const workspaceFolder = workspace.workspaceFolders?.find(
@@ -118,7 +118,7 @@ export class DataExtensionsEditorView extends AbstractWebview<
msg.externalApiUsages,
msg.modeledMethods,
);
await this.loadExternalApiUsages();
await Promise.all([this.setViewState(), this.loadExternalApiUsages()]);
break;
case "generateExternalApi":
@@ -134,16 +134,22 @@ export class DataExtensionsEditorView extends AbstractWebview<
super.onWebViewLoaded();
await Promise.all([
this.postMessage({
t: "setDataExtensionEditorInitialData",
extensionPackName: this.modelFile.extensionPack.name,
modelFilename: this.modelFile.filename,
}),
this.setViewState(),
this.loadExternalApiUsages(),
this.loadExistingModeledMethods(),
]);
}
private async setViewState(): Promise<void> {
await this.postMessage({
t: "setDataExtensionEditorViewState",
viewState: {
extensionPackModelFile: this.modelFile,
modelFileExists: await pathExists(this.modelFile.filename),
},
});
}
protected async jumpToUsage(
location: ResolvableLocationValue,
): Promise<void> {

View File

@@ -13,6 +13,7 @@ import { ProgressCallback } from "../progress";
import { DatabaseItem } from "../local-databases";
import { getQlPackPath, QLPACK_FILENAMES } from "../pure/ql";
import { getErrorMessage } from "../pure/helpers-pure";
import { ExtensionPack, ExtensionPackModelFile } from "./shared/extension-pack";
const maxStep = 3;
@@ -22,22 +23,6 @@ const packNameRegex = new RegExp(
);
const packNameLength = 128;
export interface ExtensionPack {
path: string;
yamlPath: string;
name: string;
version: string;
extensionTargets: Record<string, string>;
dataExtensions: string[];
}
export interface ExtensionPackModelFile {
filename: string;
extensionPack: ExtensionPack;
}
export async function pickExtensionPackModelFile(
cliServer: Pick<CodeQLCliServer, "resolveQlpacks" | "resolveExtensions">,
databaseItem: Pick<DatabaseItem, "name" | "language">,

View File

@@ -0,0 +1,15 @@
export interface ExtensionPack {
path: string;
yamlPath: string;
name: string;
version: string;
extensionTargets: Record<string, string>;
dataExtensions: string[];
}
export interface ExtensionPackModelFile {
filename: string;
extensionPack: ExtensionPack;
}

View File

@@ -0,0 +1,6 @@
import { ExtensionPackModelFile } from "./extension-pack";
export interface DataExtensionEditorViewState {
extensionPackModelFile: ExtensionPackModelFile;
modelFileExists: boolean;
}

View File

@@ -16,6 +16,7 @@ import { ErrorLike } from "./errors";
import { DataFlowPaths } from "../variant-analysis/shared/data-flow-paths";
import { ExternalApiUsage } from "../data-extensions-editor/external-api-usage";
import { ModeledMethod } from "../data-extensions-editor/modeled-method";
import { DataExtensionEditorViewState } from "../data-extensions-editor/shared/view-state";
/**
* This module contains types and code that are shared between
@@ -481,10 +482,9 @@ export type ToDataFlowPathsMessage = SetDataFlowPathsMessage;
export type FromDataFlowPathsMessage = CommonFromViewMessages;
export interface SetDataExtensionEditorInitialDataMessage {
t: "setDataExtensionEditorInitialData";
extensionPackName: string;
modelFilename: string;
export interface SetExtensionPackStateMessage {
t: "setDataExtensionEditorViewState";
viewState: DataExtensionEditorViewState;
}
export interface SetExternalApiUsagesMessage {
@@ -536,7 +536,7 @@ export interface GenerateExternalApiMessage {
}
export type ToDataExtensionsEditorMessage =
| SetDataExtensionEditorInitialDataMessage
| SetExtensionPackStateMessage
| SetExternalApiUsagesMessage
| ShowProgressMessage
| AddModeledMethodsMessage;

View File

@@ -15,9 +15,22 @@ const Template: ComponentStory<typeof DataExtensionsEditorComponent> = (
export const DataExtensionsEditor = Template.bind({});
DataExtensionsEditor.args = {
initialExtensionPackName: "codeql/sql2o-models",
initialModelFilename:
"/home/user/vscode-codeql-starter/codeql-custom-queries-java/sql2o/models/sql2o.yml",
initialViewState: {
extensionPackModelFile: {
extensionPack: {
path: "/home/user/vscode-codeql-starter/codeql-custom-queries-java/sql2o",
yamlPath:
"/home/user/vscode-codeql-starter/codeql-custom-queries-java/sql2o/codeql-pack.yml",
name: "codeql/sql2o-models",
version: "0.0.0",
extensionTargets: {},
dataExtensions: [],
},
filename:
"/home/user/vscode-codeql-starter/codeql-custom-queries-java/sql2o/models/sql2o.yml",
},
modelFileExists: true,
},
initialExternalApiUsages: [
{
signature: "org.sql2o.Connection#createQuery(String)",

View File

@@ -20,6 +20,7 @@ import { calculateModeledPercentage } from "./modeled";
import { LinkIconButton } from "../variant-analysis/LinkIconButton";
import { basename } from "../common/path";
import { ViewTitle } from "../common";
import { DataExtensionEditorViewState } from "../../data-extensions-editor/shared/view-state";
const DataExtensionsEditorContainer = styled.div`
margin-top: 1rem;
@@ -31,6 +32,12 @@ const DetailsContainer = styled.div`
align-items: center;
`;
const NonExistingModelFileContainer = styled.div`
display: flex;
gap: 0.2em;
align-items: center;
`;
const EditorContainer = styled.div`
margin-top: 1rem;
`;
@@ -47,24 +54,19 @@ const ProgressBar = styled.div<ProgressBarProps>`
`;
type Props = {
initialExtensionPackName?: string;
initialModelFilename?: string;
initialViewState?: DataExtensionEditorViewState;
initialExternalApiUsages?: ExternalApiUsage[];
initialModeledMethods?: Record<string, ModeledMethod>;
};
export function DataExtensionsEditor({
initialExtensionPackName,
initialModelFilename,
initialViewState,
initialExternalApiUsages = [],
initialModeledMethods = {},
}: Props): JSX.Element {
const [extensionPackName, setExtensionPackName] = useState<
string | undefined
>(initialExtensionPackName);
const [modelFilename, setModelFilename] = useState<string | undefined>(
initialModelFilename,
);
const [viewState, setViewState] = useState<
DataExtensionEditorViewState | undefined
>(initialViewState);
const [externalApiUsages, setExternalApiUsages] = useState<
ExternalApiUsage[]
@@ -83,9 +85,8 @@ export function DataExtensionsEditor({
if (evt.origin === window.origin) {
const msg: ToDataExtensionsEditorMessage = evt.data;
switch (msg.t) {
case "setDataExtensionEditorInitialData":
setExtensionPackName(msg.extensionPackName);
setModelFilename(msg.modelFilename);
case "setDataExtensionEditorViewState":
setViewState(msg.viewState);
break;
case "setExternalApiUsages":
setExternalApiUsages(msg.externalApiUsages);
@@ -181,17 +182,27 @@ export function DataExtensionsEditor({
<>
<ViewTitle>Data extensions editor</ViewTitle>
<DetailsContainer>
{extensionPackName && (
<LinkIconButton onClick={onOpenExtensionPackClick}>
<span slot="start" className="codicon codicon-package"></span>
{extensionPackName}
</LinkIconButton>
)}
{modelFilename && (
<LinkIconButton onClick={onOpenModelFileClick}>
<span slot="start" className="codicon codicon-file-code"></span>
{basename(modelFilename)}
</LinkIconButton>
{viewState?.extensionPackModelFile && (
<>
<LinkIconButton onClick={onOpenExtensionPackClick}>
<span slot="start" className="codicon codicon-package"></span>
{viewState.extensionPackModelFile.extensionPack.name}
</LinkIconButton>
{viewState.modelFileExists ? (
<LinkIconButton onClick={onOpenModelFileClick}>
<span
slot="start"
className="codicon codicon-file-code"
></span>
{basename(viewState.extensionPackModelFile.filename)}
</LinkIconButton>
) : (
<NonExistingModelFileContainer>
<span className="codicon codicon-file-code"></span>
{basename(viewState.extensionPackModelFile.filename)}
</NonExistingModelFileContainer>
)}
</>
)}
<div>{modeledPercentage.toFixed(2)}% modeled</div>
<div>{unModeledPercentage.toFixed(2)}% unmodeled</div>

View File

@@ -6,10 +6,8 @@ import { dir } from "tmp-promise";
import { QlpacksInfo, ResolveExtensionsResult } from "../../../../src/cli";
import * as helpers from "../../../../src/helpers";
import {
ExtensionPack,
pickExtensionPackModelFile,
} from "../../../../src/data-extensions-editor/extension-pack-picker";
import { pickExtensionPackModelFile } from "../../../../src/data-extensions-editor/extension-pack-picker";
import { ExtensionPack } from "../../../../src/data-extensions-editor/shared/extension-pack";
describe("pickExtensionPackModelFile", () => {
let tmpDir: string;