Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down Expand Up @@ -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":
Expand All @@ -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> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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">,
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { ExtensionPackModelFile } from "./extension-pack";

export interface DataExtensionEditorViewState {
extensionPackModelFile: ExtensionPackModelFile;
modelFileExists: boolean;
}
10 changes: 5 additions & 5 deletions extensions/ql-vscode/src/pure/interface-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -536,7 +536,7 @@ export interface GenerateExternalApiMessage {
}

export type ToDataExtensionsEditorMessage =
| SetDataExtensionEditorInitialDataMessage
| SetExtensionPackStateMessage
| SetExternalApiUsagesMessage
| ShowProgressMessage
| AddModeledMethodsMessage;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
`;
Expand All @@ -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[]
Expand All @@ -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);
Expand Down Expand Up @@ -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>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down