Merge pull request #2480 from github/robertbrignull/app-environment
Add EnvironmentContext so common code can do localisation
This commit is contained in:
@@ -23,6 +23,7 @@ export interface App {
|
|||||||
readonly onDidChangeWorkspaceFolders: Event<WorkspaceFoldersChangeEvent>;
|
readonly onDidChangeWorkspaceFolders: Event<WorkspaceFoldersChangeEvent>;
|
||||||
readonly credentials: Credentials;
|
readonly credentials: Credentials;
|
||||||
readonly commands: AppCommandManager;
|
readonly commands: AppCommandManager;
|
||||||
|
readonly environment: EnvironmentContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum AppMode {
|
export enum AppMode {
|
||||||
@@ -30,3 +31,7 @@ export enum AppMode {
|
|||||||
Development = 2,
|
Development = 2,
|
||||||
Test = 3,
|
Test = 3,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface EnvironmentContext {
|
||||||
|
language: string;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { basename, dirname, join } from "path";
|
import { basename, dirname, join } from "path";
|
||||||
import { env } from "vscode";
|
import { EnvironmentContext } from "./app";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A node in the tree of files. This will be either a `FileTreeDirectory` or a `FileTreeLeaf`.
|
* A node in the tree of files. This will be either a `FileTreeDirectory` or a `FileTreeLeaf`.
|
||||||
@@ -35,6 +35,7 @@ export class FileTreeDirectory<T = undefined> extends FileTreeNode<T> {
|
|||||||
constructor(
|
constructor(
|
||||||
_path: string,
|
_path: string,
|
||||||
_name: string,
|
_name: string,
|
||||||
|
protected readonly env: EnvironmentContext,
|
||||||
private _children: Array<FileTreeNode<T>> = [],
|
private _children: Array<FileTreeNode<T>> = [],
|
||||||
) {
|
) {
|
||||||
super(_path, _name);
|
super(_path, _name);
|
||||||
@@ -66,7 +67,9 @@ export class FileTreeDirectory<T = undefined> extends FileTreeNode<T> {
|
|||||||
this._children.filter(
|
this._children.filter(
|
||||||
(child) => child instanceof FileTreeLeaf || child.children.length > 0,
|
(child) => child instanceof FileTreeLeaf || child.children.length > 0,
|
||||||
);
|
);
|
||||||
this._children.sort((a, b) => a.name.localeCompare(b.name, env.language));
|
this._children.sort((a, b) =>
|
||||||
|
a.name.localeCompare(b.name, this.env.language),
|
||||||
|
);
|
||||||
this._children.forEach((child, i) => {
|
this._children.forEach((child, i) => {
|
||||||
child.finish();
|
child.finish();
|
||||||
if (
|
if (
|
||||||
@@ -77,6 +80,7 @@ export class FileTreeDirectory<T = undefined> extends FileTreeNode<T> {
|
|||||||
const replacement = new FileTreeDirectory<T>(
|
const replacement = new FileTreeDirectory<T>(
|
||||||
child.children[0].path,
|
child.children[0].path,
|
||||||
`${child.name} / ${child.children[0].name}`,
|
`${child.name} / ${child.children[0].name}`,
|
||||||
|
this.env,
|
||||||
Array.from(child.children[0].children),
|
Array.from(child.children[0].children),
|
||||||
);
|
);
|
||||||
this._children[i] = replacement;
|
this._children[i] = replacement;
|
||||||
@@ -89,7 +93,11 @@ export class FileTreeDirectory<T = undefined> extends FileTreeNode<T> {
|
|||||||
if (existingChild !== undefined) {
|
if (existingChild !== undefined) {
|
||||||
return existingChild as FileTreeDirectory<T>;
|
return existingChild as FileTreeDirectory<T>;
|
||||||
} else {
|
} else {
|
||||||
const newChild = new FileTreeDirectory<T>(join(this.path, name), name);
|
const newChild = new FileTreeDirectory<T>(
|
||||||
|
join(this.path, name),
|
||||||
|
name,
|
||||||
|
this.env,
|
||||||
|
);
|
||||||
this.addChild(newChild);
|
this.addChild(newChild);
|
||||||
return newChild;
|
return newChild;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
import { env } from "vscode";
|
||||||
|
import { EnvironmentContext } from "../app";
|
||||||
|
|
||||||
|
export class AppEnvironmentContext implements EnvironmentContext {
|
||||||
|
public get language(): string {
|
||||||
|
return env.language;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,13 +1,14 @@
|
|||||||
import * as vscode from "vscode";
|
import * as vscode from "vscode";
|
||||||
import { VSCodeCredentials } from "./authentication";
|
import { VSCodeCredentials } from "./authentication";
|
||||||
import { Disposable } from "../../pure/disposable-object";
|
import { Disposable } from "../../pure/disposable-object";
|
||||||
import { App, AppMode } from "../app";
|
import { App, AppMode, EnvironmentContext } from "../app";
|
||||||
import { AppEventEmitter } from "../events";
|
import { AppEventEmitter } from "../events";
|
||||||
import { extLogger, Logger, queryServerLogger } from "../logging";
|
import { extLogger, Logger, queryServerLogger } from "../logging";
|
||||||
import { Memento } from "../memento";
|
import { Memento } from "../memento";
|
||||||
import { VSCodeAppEventEmitter } from "./events";
|
import { VSCodeAppEventEmitter } from "./events";
|
||||||
import { AppCommandManager, QueryServerCommandManager } from "../commands";
|
import { AppCommandManager, QueryServerCommandManager } from "../commands";
|
||||||
import { createVSCodeCommandManager } from "./commands";
|
import { createVSCodeCommandManager } from "./commands";
|
||||||
|
import { AppEnvironmentContext } from "./environment-context";
|
||||||
|
|
||||||
export class ExtensionApp implements App {
|
export class ExtensionApp implements App {
|
||||||
public readonly credentials: VSCodeCredentials;
|
public readonly credentials: VSCodeCredentials;
|
||||||
@@ -69,4 +70,8 @@ export class ExtensionApp implements App {
|
|||||||
public createEventEmitter<T>(): AppEventEmitter<T> {
|
public createEventEmitter<T>(): AppEventEmitter<T> {
|
||||||
return new VSCodeAppEventEmitter<T>();
|
return new VSCodeAppEventEmitter<T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public get environment(): EnvironmentContext {
|
||||||
|
return new AppEnvironmentContext();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,10 @@ export class QueryDiscovery
|
|||||||
new MultiFileSystemWatcher(),
|
new MultiFileSystemWatcher(),
|
||||||
);
|
);
|
||||||
|
|
||||||
constructor(app: App, private readonly cliServer: CodeQLCliServer) {
|
constructor(
|
||||||
|
private readonly app: App,
|
||||||
|
private readonly cliServer: CodeQLCliServer,
|
||||||
|
) {
|
||||||
super("Query Discovery", extLogger);
|
super("Query Discovery", extLogger);
|
||||||
|
|
||||||
this.onDidChangeQueriesEmitter = this.push(app.createEventEmitter<void>());
|
this.onDidChangeQueriesEmitter = this.push(app.createEventEmitter<void>());
|
||||||
@@ -124,7 +127,11 @@ export class QueryDiscovery
|
|||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
const rootDirectory = new FileTreeDirectory<string>(fullPath, name);
|
const rootDirectory = new FileTreeDirectory<string>(
|
||||||
|
fullPath,
|
||||||
|
name,
|
||||||
|
this.app.environment,
|
||||||
|
);
|
||||||
for (const queryPath of resolvedQueries) {
|
for (const queryPath of resolvedQueries) {
|
||||||
const relativePath = normalize(relative(fullPath, queryPath));
|
const relativePath = normalize(relative(fullPath, queryPath));
|
||||||
const dirName = dirname(relativePath);
|
const dirName = dirname(relativePath);
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import {
|
|||||||
Uri,
|
Uri,
|
||||||
RelativePattern,
|
RelativePattern,
|
||||||
WorkspaceFolder,
|
WorkspaceFolder,
|
||||||
|
env,
|
||||||
} from "vscode";
|
} from "vscode";
|
||||||
import { MultiFileSystemWatcher } from "../common/vscode/multi-file-system-watcher";
|
import { MultiFileSystemWatcher } from "../common/vscode/multi-file-system-watcher";
|
||||||
import { CodeQLCliServer } from "../codeql-cli/cli";
|
import { CodeQLCliServer } from "../codeql-cli/cli";
|
||||||
@@ -97,7 +98,7 @@ export class QLTestDiscovery extends Discovery<QLTestDiscoveryResults> {
|
|||||||
private async discoverTests(): Promise<FileTreeDirectory> {
|
private async discoverTests(): Promise<FileTreeDirectory> {
|
||||||
const fullPath = this.workspaceFolder.uri.fsPath;
|
const fullPath = this.workspaceFolder.uri.fsPath;
|
||||||
const name = this.workspaceFolder.name;
|
const name = this.workspaceFolder.name;
|
||||||
const rootDirectory = new FileTreeDirectory(fullPath, name);
|
const rootDirectory = new FileTreeDirectory(fullPath, name, env);
|
||||||
|
|
||||||
// Don't try discovery on workspace folders that don't exist on the filesystem
|
// Don't try discovery on workspace folders that don't exist on the filesystem
|
||||||
if (await pathExists(fullPath)) {
|
if (await pathExists(fullPath)) {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { App, AppMode } from "../../src/common/app";
|
import { App, AppMode, EnvironmentContext } from "../../src/common/app";
|
||||||
import { AppEvent, AppEventEmitter } from "../../src/common/events";
|
import { AppEvent, AppEventEmitter } from "../../src/common/events";
|
||||||
import { Memento } from "../../src/common/memento";
|
import { Memento } from "../../src/common/memento";
|
||||||
import { Disposable } from "../../src/pure/disposable-object";
|
import { Disposable } from "../../src/pure/disposable-object";
|
||||||
@@ -24,6 +24,7 @@ export function createMockApp({
|
|||||||
onDidChangeWorkspaceFolders = jest.fn(),
|
onDidChangeWorkspaceFolders = jest.fn(),
|
||||||
credentials = testCredentialsWithStub(),
|
credentials = testCredentialsWithStub(),
|
||||||
commands = createMockCommandManager(),
|
commands = createMockCommandManager(),
|
||||||
|
environment = createMockEnvironmentContext(),
|
||||||
}: {
|
}: {
|
||||||
extensionPath?: string;
|
extensionPath?: string;
|
||||||
workspaceStoragePath?: string;
|
workspaceStoragePath?: string;
|
||||||
@@ -34,6 +35,7 @@ export function createMockApp({
|
|||||||
onDidChangeWorkspaceFolders?: Event<WorkspaceFoldersChangeEvent>;
|
onDidChangeWorkspaceFolders?: Event<WorkspaceFoldersChangeEvent>;
|
||||||
credentials?: Credentials;
|
credentials?: Credentials;
|
||||||
commands?: AppCommandManager;
|
commands?: AppCommandManager;
|
||||||
|
environment?: EnvironmentContext;
|
||||||
}): App {
|
}): App {
|
||||||
return {
|
return {
|
||||||
mode: AppMode.Test,
|
mode: AppMode.Test,
|
||||||
@@ -48,6 +50,7 @@ export function createMockApp({
|
|||||||
createEventEmitter,
|
createEventEmitter,
|
||||||
credentials,
|
credentials,
|
||||||
commands,
|
commands,
|
||||||
|
environment,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,3 +71,9 @@ export class MockAppEventEmitter<T> implements AppEventEmitter<T> {
|
|||||||
// no-op
|
// no-op
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function createMockEnvironmentContext(): EnvironmentContext {
|
||||||
|
return {
|
||||||
|
language: "en-US",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { EventEmitter } from "vscode";
|
import { EventEmitter, env } from "vscode";
|
||||||
import {
|
import {
|
||||||
FileTreeDirectory,
|
FileTreeDirectory,
|
||||||
FileTreeLeaf,
|
FileTreeLeaf,
|
||||||
@@ -31,8 +31,8 @@ describe("QueryTreeDataProvider", () => {
|
|||||||
it("converts FileTreeNode to QueryTreeViewItem", async () => {
|
it("converts FileTreeNode to QueryTreeViewItem", async () => {
|
||||||
const dataProvider = new QueryTreeDataProvider({
|
const dataProvider = new QueryTreeDataProvider({
|
||||||
queries: [
|
queries: [
|
||||||
new FileTreeDirectory<string>("dir1", "dir1", [
|
new FileTreeDirectory<string>("dir1", "dir1", env, [
|
||||||
new FileTreeDirectory<string>("dir1/dir2", "dir2", [
|
new FileTreeDirectory<string>("dir1/dir2", "dir2", env, [
|
||||||
new FileTreeLeaf<string>(
|
new FileTreeLeaf<string>(
|
||||||
"dir1/dir2/file1",
|
"dir1/dir2/file1",
|
||||||
"file1",
|
"file1",
|
||||||
@@ -45,7 +45,7 @@ describe("QueryTreeDataProvider", () => {
|
|||||||
),
|
),
|
||||||
]),
|
]),
|
||||||
]),
|
]),
|
||||||
new FileTreeDirectory<string>("dir3", "dir3", [
|
new FileTreeDirectory<string>("dir3", "dir3", env, [
|
||||||
new FileTreeLeaf<string>("dir3/file3", "file3", "javascript"),
|
new FileTreeLeaf<string>("dir3/file3", "file3", "javascript"),
|
||||||
]),
|
]),
|
||||||
],
|
],
|
||||||
@@ -78,7 +78,7 @@ describe("QueryTreeDataProvider", () => {
|
|||||||
const onDidChangeQueriesEmitter = new EventEmitter<void>();
|
const onDidChangeQueriesEmitter = new EventEmitter<void>();
|
||||||
const queryDiscoverer: QueryDiscoverer = {
|
const queryDiscoverer: QueryDiscoverer = {
|
||||||
queries: [
|
queries: [
|
||||||
new FileTreeDirectory<string>("dir1", "dir1", [
|
new FileTreeDirectory<string>("dir1", "dir1", env, [
|
||||||
new FileTreeLeaf<string>("dir1/file1", "file1", "javascript"),
|
new FileTreeLeaf<string>("dir1/file1", "file1", "javascript"),
|
||||||
]),
|
]),
|
||||||
],
|
],
|
||||||
@@ -89,7 +89,7 @@ describe("QueryTreeDataProvider", () => {
|
|||||||
expect(dataProvider.getChildren().length).toEqual(1);
|
expect(dataProvider.getChildren().length).toEqual(1);
|
||||||
|
|
||||||
queryDiscoverer.queries?.push(
|
queryDiscoverer.queries?.push(
|
||||||
new FileTreeDirectory<string>("dir2", "dir2", [
|
new FileTreeDirectory<string>("dir2", "dir2", env, [
|
||||||
new FileTreeLeaf<string>("dir2/file2", "file2", "javascript"),
|
new FileTreeLeaf<string>("dir2/file2", "file2", "javascript"),
|
||||||
]),
|
]),
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user