Better handle local project tree item when not initialized (#1955)

This commit is contained in:
Eric Jizba 2020-03-18 10:30:27 -07:00 коммит произвёл GitHub
Родитель d306c246b6
Коммит ac991b93ce
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
8 изменённых файлов: 123 добавлений и 67 удалений

Просмотреть файл

@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M8.44 1H7.56L1 13.26L1.44 14H14.54L14.98 13.26L8.44 1ZM2.28 13L8 2.28L13.7 13H2.28ZM7.5 6H8.5V10H7.5V6ZM7.5 11H8.5V12H7.5V11Z" fill="#FFCC00"/>
</svg>

После

Ширина:  |  Высота:  |  Размер: 256 B

Просмотреть файл

@ -0,0 +1,4 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M8.44 1H7.56L1 13.26L1.44 14H14.54L14.98 13.26L8.44 1ZM2.28 13L8 2.28L13.7 13H2.28ZM7.5 6H8.5V10H7.5V6ZM7.5 11H8.5V12H7.5V11Z" fill="#FFCC00"/>
<path d="M8.44 1H7.56L1 13.26L1.44 14H14.54L14.98 13.26L8.44 1ZM2.28 13L8 2.28L13.7 13H2.28ZM7.5 6H8.5V10H7.5V6ZM7.5 11H8.5V12H7.5V11Z" fill="#DDB100"/>
</svg>

После

Ширина:  |  Высота:  |  Размер: 409 B

Просмотреть файл

@ -10,6 +10,7 @@ import { ext } from "../../extensionVariables";
import { FuncVersion } from "../../FuncVersion";
import { localize } from "../../localize";
import { LocalFunctionTreeItem } from "../../tree/localProject/LocalFunctionTreeItem";
import { LocalProjectTreeItem } from "../../tree/localProject/LocalProjectTreeItem";
import { nonNullValue } from "../../utils/nonNull";
import { getContainingWorkspace } from "../../utils/workspace";
import { verifyInitForVSCode } from "../../vsCodeConfig/verifyInitForVSCode";
@ -22,12 +23,15 @@ export async function addBinding(context: IActionContext, data: Uri | LocalFunct
let workspaceFolder: WorkspaceFolder;
let workspacePath: string;
let projectPath: string | undefined;
let language: ProjectLanguage;
let version: FuncVersion;
if (data instanceof Uri) {
functionJsonPath = data.fsPath;
workspaceFolder = nonNullValue(getContainingWorkspace(functionJsonPath), 'workspaceFolder');
workspacePath = workspaceFolder.uri.fsPath;
projectPath = await tryGetFunctionProjectRoot(workspacePath) || workspacePath;
[language, version] = await verifyInitForVSCode(context, projectPath);
} else {
if (!data) {
const noItemFoundErrorMessage: string = localize('noLocalProject', 'No matching functions found. C# and Java projects do not support this operation.');
@ -35,12 +39,15 @@ export async function addBinding(context: IActionContext, data: Uri | LocalFunct
}
functionJsonPath = data.functionJsonPath;
workspaceFolder = data.parent.parent.workspaceFolder;
workspacePath = data.parent.parent.workspacePath;
projectPath = data.parent.parent.effectiveProjectPath;
const projectTi: LocalProjectTreeItem = data.parent.parent;
workspaceFolder = projectTi.workspaceFolder;
workspacePath = projectTi.workspacePath;
projectPath = projectTi.effectiveProjectPath;
language = projectTi.langauge;
version = projectTi.version;
}
const [language, version]: [ProjectLanguage, FuncVersion] = await verifyInitForVSCode(context, projectPath);
const wizardContext: IBindingWizardContext = Object.assign(context, { functionJsonPath, workspacePath, projectPath, workspaceFolder, language, version });
const wizard: AzureWizard<IBindingWizardContext> = createBindingWizard(wizardContext);
await wizard.prompt();

Просмотреть файл

@ -10,14 +10,17 @@ import { tryGetFunctionProjectRoot } from '../commands/createNewProject/verifyIs
import { getJavaDebugSubpath } from '../commands/initProjectForVSCode/InitVSCodeStep/JavaInitVSCodeStep';
import { funcVersionSetting, hostFileName, ProjectLanguage, projectLanguageSetting } from '../constants';
import { ext } from '../extensionVariables';
import { FuncVersion, tryParseFuncVersion } from '../FuncVersion';
import { localize } from '../localize';
import { dotnetUtils } from '../utils/dotnetUtils';
import { mavenUtils } from '../utils/mavenUtils';
import { treeUtils } from '../utils/treeUtils';
import { getWorkspaceSetting } from '../vsCodeConfig/settings';
import { createRefreshFileWatcher } from './localProject/createRefreshFileWatcher';
import { InitLocalProjectTreeItem } from './localProject/InitLocalProjectTreeItem';
import { InvalidLocalProjectTreeItem } from './localProject/InvalidLocalProjectTreeItem';
import { LocalProjectTreeItem } from './localProject/LocalProjectTreeItem';
import { LocalProjectTreeItemBase } from './localProject/LocalProjectTreeItemBase';
import { isLocalProjectCV, isProjectCV, isRemoteProjectCV } from './projectContextValues';
import { SubscriptionTreeItem } from './SubscriptionTreeItem';
@ -59,19 +62,25 @@ export class AzureAccountTreeItemWithProjects extends AzureAccountTreeItemBase {
try {
hasLocalProject = true;
let preCompiledProjectPath: string | undefined;
let effectiveProjectPath: string;
const compiledProjectPath: string | undefined = await getCompiledProjectPath(projectPath);
if (compiledProjectPath) {
preCompiledProjectPath = projectPath;
effectiveProjectPath = compiledProjectPath;
const language: ProjectLanguage | undefined = getWorkspaceSetting(projectLanguageSetting, projectPath);
const version: FuncVersion | undefined = tryParseFuncVersion(getWorkspaceSetting(funcVersionSetting, projectPath));
if (language === undefined || version === undefined) {
children.push(new InitLocalProjectTreeItem(this, projectPath));
} else {
effectiveProjectPath = projectPath;
}
let preCompiledProjectPath: string | undefined;
let effectiveProjectPath: string;
const compiledProjectPath: string | undefined = await getCompiledProjectPath(projectPath, language);
if (compiledProjectPath) {
preCompiledProjectPath = projectPath;
effectiveProjectPath = compiledProjectPath;
} else {
effectiveProjectPath = projectPath;
}
const treeItem: LocalProjectTreeItem = new LocalProjectTreeItem(this, { effectiveProjectPath, folder, preCompiledProjectPath });
this._projectDisposables.push(treeItem);
children.push(treeItem);
const treeItem: LocalProjectTreeItem = new LocalProjectTreeItem(this, { effectiveProjectPath, folder, language, version, preCompiledProjectPath });
this._projectDisposables.push(treeItem);
children.push(treeItem);
}
} catch (error) {
children.push(new InvalidLocalProjectTreeItem(this, projectPath, error));
}
@ -96,9 +105,9 @@ export class AzureAccountTreeItemWithProjects extends AzureAccountTreeItemBase {
}
public compareChildrenImpl(item1: AzExtTreeItem, item2: AzExtTreeItem): number {
if (item1 instanceof LocalProjectTreeItem && !(item2 instanceof LocalProjectTreeItem)) {
if (item1 instanceof LocalProjectTreeItemBase && !(item2 instanceof LocalProjectTreeItemBase)) {
return 1;
} else if (!(item1 instanceof LocalProjectTreeItem) && item2 instanceof LocalProjectTreeItem) {
} else if (!(item1 instanceof LocalProjectTreeItemBase) && item2 instanceof LocalProjectTreeItemBase) {
return -1;
} else {
return super.compareChildrenImpl(item1, item2);
@ -124,8 +133,7 @@ export class AzureAccountTreeItemWithProjects extends AzureAccountTreeItemBase {
}
}
async function getCompiledProjectPath(projectPath: string): Promise<string | undefined> {
const projectLanguage: string | undefined = getWorkspaceSetting(projectLanguageSetting, projectPath);
async function getCompiledProjectPath(projectPath: string, projectLanguage: ProjectLanguage): Promise<string | undefined> {
if (projectLanguage === ProjectLanguage.CSharp || projectLanguage === ProjectLanguage.FSharp) {
const projFiles: string[] = await dotnetUtils.getProjFiles(projectLanguage, projectPath);
if (projFiles.length === 1) {

Просмотреть файл

@ -0,0 +1,35 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { AzExtParentTreeItem, AzExtTreeItem, GenericTreeItem } from 'vscode-azureextensionui';
import { localize } from '../../localize';
import { treeUtils } from '../../utils/treeUtils';
import { LocalProjectTreeItemBase } from './LocalProjectTreeItemBase';
export class InitLocalProjectTreeItem extends LocalProjectTreeItemBase {
public contextValue: string = 'initAzFuncLocalProject';
private readonly _projectPath: string;
public constructor(parent: AzExtParentTreeItem, projectPath: string) {
super(parent, projectPath);
this._projectPath = projectPath;
}
public hasMoreChildrenImpl(): boolean {
return false;
}
public async loadMoreChildrenImpl(_clearCache: boolean): Promise<AzExtTreeItem[]> {
const ti: GenericTreeItem = new GenericTreeItem(this, {
contextValue: 'initProject',
label: localize('initProject', 'Initialize Project for Use with VS Code...'),
commandId: 'azureFunctions.initProjectForVSCode',
iconPath: treeUtils.getThemedIconPath('warning')
});
ti.commandArgs = [this._projectPath];
return [ti];
}
}

Просмотреть файл

@ -3,36 +3,19 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as path from 'path';
import { AzExtParentTreeItem, AzExtTreeItem, TreeItemIconPath } from 'vscode-azureextensionui';
import { localize } from '../../localize';
import { treeUtils } from '../../utils/treeUtils';
import { AzExtParentTreeItem, AzExtTreeItem } from 'vscode-azureextensionui';
import { LocalProjectTreeItemBase } from './LocalProjectTreeItemBase';
export class InvalidLocalProjectTreeItem extends AzExtParentTreeItem {
export class InvalidLocalProjectTreeItem extends LocalProjectTreeItemBase {
public contextValue: string = 'invalidAzFuncLocalProject';
public readonly label: string = localize('localProject', 'Local Project');
private readonly _projectName: string;
private readonly _projectError: unknown | undefined;
public constructor(parent: AzExtParentTreeItem, projectPath: string, projectError: unknown) {
super(parent);
this._projectName = path.basename(projectPath);
super(parent, projectPath);
this._projectError = projectError;
}
public get iconPath(): TreeItemIconPath {
return treeUtils.getThemedIconPath('CreateNewProject');
}
public get id(): string {
return 'localProject' + this._projectName;
}
public get description(): string {
return this._projectName;
}
public hasMoreChildrenImpl(): boolean {
return false;
}

Просмотреть файл

@ -6,41 +6,39 @@
import * as fse from 'fs-extra';
import * as path from 'path';
import { Disposable, WorkspaceFolder } from 'vscode';
import { AzExtParentTreeItem, AzExtTreeItem, TreeItemIconPath } from 'vscode-azureextensionui';
import { functionJsonFileName, funcVersionSetting, hostFileName, localSettingsFileName } from '../../constants';
import { AzExtParentTreeItem, AzExtTreeItem } from 'vscode-azureextensionui';
import { functionJsonFileName, hostFileName, localSettingsFileName, ProjectLanguage } from '../../constants';
import { IParsedHostJson, parseHostJson } from '../../funcConfig/host';
import { getLocalSettingsJson, ILocalSettingsJson } from '../../funcConfig/local.settings';
import { FuncVersion, tryParseFuncVersion } from '../../FuncVersion';
import { localize } from '../../localize';
import { nonNullValue } from '../../utils/nonNull';
import { treeUtils } from '../../utils/treeUtils';
import { getWorkspaceSetting } from '../../vsCodeConfig/settings';
import { FuncVersion } from '../../FuncVersion';
import { ApplicationSettings, IProjectTreeItem } from '../IProjectTreeItem';
import { isLocalProjectCV, matchesAnyPart, ProjectResource, ProjectSource } from '../projectContextValues';
import { createRefreshFileWatcher } from './createRefreshFileWatcher';
import { LocalFunctionsTreeItem } from './LocalFunctionsTreeItem';
import { LocalProjectTreeItemBase } from './LocalProjectTreeItemBase';
export class LocalProjectTreeItem extends AzExtParentTreeItem implements Disposable, IProjectTreeItem {
export class LocalProjectTreeItem extends LocalProjectTreeItemBase implements Disposable, IProjectTreeItem {
public static contextValue: string = 'azFuncLocalProject';
public contextValue: string = LocalProjectTreeItem.contextValue;
public readonly label: string = localize('localProject', 'Local Project');
public readonly source: ProjectSource = ProjectSource.Local;
public readonly projectName: string;
public readonly effectiveProjectPath: string;
public readonly preCompiledProjectPath: string | undefined;
public readonly workspacePath: string;
public readonly workspaceFolder: WorkspaceFolder;
public readonly version: FuncVersion;
public readonly langauge: ProjectLanguage;
private readonly _disposables: Disposable[] = [];
private readonly _localFunctionsTreeItem: LocalFunctionsTreeItem;
public constructor(parent: AzExtParentTreeItem, options: { effectiveProjectPath: string; folder: WorkspaceFolder; preCompiledProjectPath?: string }) {
super(parent);
this.projectName = path.basename(options.preCompiledProjectPath || options.effectiveProjectPath);
public constructor(parent: AzExtParentTreeItem, options: { effectiveProjectPath: string; folder: WorkspaceFolder; version: FuncVersion; language: ProjectLanguage; preCompiledProjectPath?: string }) {
super(parent, options.preCompiledProjectPath || options.effectiveProjectPath);
this.effectiveProjectPath = options.effectiveProjectPath;
this.workspacePath = options.folder.uri.fsPath;
this.workspaceFolder = options.folder;
this.preCompiledProjectPath = options.preCompiledProjectPath;
this.version = options.version;
this.langauge = options.language;
this._disposables.push(createRefreshFileWatcher(this, path.join(this.effectiveProjectPath, '*', functionJsonFileName)));
this._disposables.push(createRefreshFileWatcher(this, path.join(this.effectiveProjectPath, localSettingsFileName)));
@ -48,18 +46,6 @@ export class LocalProjectTreeItem extends AzExtParentTreeItem implements Disposa
this._localFunctionsTreeItem = new LocalFunctionsTreeItem(this);
}
public get iconPath(): TreeItemIconPath {
return treeUtils.getThemedIconPath('CreateNewProject');
}
public get id(): string {
return 'localProject' + this.projectName;
}
public get description(): string {
return this.projectName;
}
public get hostUrl(): string {
return 'http://localhost:7071';
}
@ -98,8 +84,7 @@ export class LocalProjectTreeItem extends AzExtParentTreeItem implements Disposa
}
public async getVersion(): Promise<FuncVersion> {
const rawSetting: string | undefined = getWorkspaceSetting(funcVersionSetting, this.workspacePath);
return nonNullValue(tryParseFuncVersion(rawSetting), 'version');
return this.version;
}
public async getApplicationSettings(): Promise<ApplicationSettings> {

Просмотреть файл

@ -0,0 +1,31 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as path from 'path';
import { AzExtParentTreeItem, TreeItemIconPath } from 'vscode-azureextensionui';
import { localize } from '../../localize';
import { treeUtils } from '../../utils/treeUtils';
export abstract class LocalProjectTreeItemBase extends AzExtParentTreeItem {
public readonly label: string = localize('localProject', 'Local Project');
private readonly _projectName: string;
public constructor(parent: AzExtParentTreeItem, projectPath: string) {
super(parent);
this._projectName = path.basename(projectPath);
}
public get iconPath(): TreeItemIconPath {
return treeUtils.getThemedIconPath('CreateNewProject');
}
public get id(): string {
return 'localProject' + this._projectName;
}
public get description(): string {
return this._projectName;
}
}