Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stops Conflicting Vendordeps and Installs Required Ones #715

Merged
merged 9 commits into from
Nov 1, 2024
5 changes: 5 additions & 0 deletions vscode-wpilib/media/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,11 @@
document.getElementById('refresh-action')?.addEventListener('click', () => {
vscode.postMessage({ type: 'refresh' })
});

// Listen for focus events
window.addEventListener('blur', () => {
vscode.postMessage({ type: 'blur' });
});
}

function addDropdownListeners() {
Expand Down
97 changes: 84 additions & 13 deletions vscode-wpilib/src/dependencyView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ export class DependencyViewProvider implements vscode.WebviewViewProvider {
private externalApi: IExternalAPI;
private ghURL = `https://raw.githubusercontent.com/wpilibsuite/vendor-json-repo/master/`;
private wp: vscode.WorkspaceFolder | undefined;
private changed = 0;

private _view?: vscode.WebviewView;

Expand Down Expand Up @@ -80,7 +81,15 @@ export class DependencyViewProvider implements vscode.WebviewViewProvider {
void this.refresh(this.wp);
webviewView.onDidChangeVisibility(() => {
if (this.wp) {
void this.refresh(this.wp);
// If the webview becomes visible refresh it, invisible then check for changes
if (webviewView.visible) {
void this.refresh(this.wp);
} else {
if (this.changed > this.vendorLibraries.getLastBuild()) {
this.externalApi.getBuildTestAPI().buildCode(this.wp, undefined);
this.changed = 0;
}
}
}
});

Expand Down Expand Up @@ -118,6 +127,16 @@ export class DependencyViewProvider implements vscode.WebviewViewProvider {
}
break;
}
case 'blur':
{
if (this.wp) {
if (this.changed > this.vendorLibraries.getLastBuild()) {
this.externalApi.getBuildTestAPI().buildCode(this.wp, undefined);
this.changed = 0;
}
}
break;
}
default:
{
break;
Expand Down Expand Up @@ -175,35 +194,74 @@ export class DependencyViewProvider implements vscode.WebviewViewProvider {
}

private async uninstall(index: string) {
this.sortInstalledDeps();
const uninstall = [this.installedDeps[parseInt(index, 10)]];
if (this.wp) {
await this.vendorLibraries.uninstallVendorLibraries(uninstall, this.wp);
const success = await this.vendorLibraries.uninstallVendorLibraries(uninstall, this.wp);
if (success) {
this.changed = Date.now();
}
await this.refresh(this.wp);
}
}

private async getURLInstallDep(avail: IJsonList | undefined) {
if (avail && this.wp) {
const dep = await this.listToDependency(avail);

if (dep) {
let conflictdep = undefined;
if (dep.conflictsWith) {
// Check to see if it conflicts with currently installed deps
for (const conflict of dep.conflictsWith) {
if (this.installedDeps.find(installedDep => installedDep.uuid === conflict.uuid)) {
conflictdep = conflict;
break;
}
}
}

// If no conflict is found install otherwise show dialog
if (!conflictdep) {
const success = await this.vendorLibraries.installDependency(dep, this.vendorLibraries.getWpVendorFolder(this.wp), true);

if (success) {
this.changed = Date.now();

if (dep.requires) {
let reqDep = undefined;
// Check to see if there are required deps and install those too
for (const required of dep.requires) {
reqDep = this.availableDeps.find(requiredDep => requiredDep.uuid === required.uuid);
const newDep = await this.listToDependency(reqDep);
if (reqDep && newDep) {
await this.vendorLibraries.installDependency(newDep, this.vendorLibraries.getWpVendorFolder(this.wp), true);
}
}
}
}
} else {
vscode.window.showErrorMessage(i18n('message', '{0}', conflictdep.errorMessage), {modal: true});
}
}
}
}

private async listToDependency(avail: IJsonList | undefined) {
let dependency = undefined;
if (avail && this.wp) {
// Check to see if it is already a URL
let url = avail.path;
if (url.substring(0, 4) !== 'http') {
url = this.ghURL + url;
}
let dep;
try {
dep = await this.vendorLibraries.getJsonDepURL(url);
dependency = await this.vendorLibraries.getJsonDepURL(url);
} catch {
dep = this.homeDeps.find(homdep => homdep.uuid === avail.uuid && homdep.version === avail.version);
}

if (dep) {
const success = await this.vendorLibraries.installDependency(dep, this.vendorLibraries.getWpVendorFolder(this.wp), true);

if (success) {
this.vendorLibraries.offerBuild(this.wp);
}
dependency = this.homeDeps.find(homdep => homdep.uuid === avail.uuid && homdep.version === avail.version);
}
}
return dependency;
}

public addDependency() {
Expand Down Expand Up @@ -305,6 +363,19 @@ export class DependencyViewProvider implements vscode.WebviewViewProvider {
});
}

private sortInstalledDeps() {
this.installedDeps.sort((a, b) => {
if (a.name.toLowerCase() > b.name.toLowerCase()) {
return 1;
}
else if (a.name.toLowerCase() === b.name.toLowerCase()) {
return 0;
} else {
return -1;
}
});
}

private sortAvailable() {
this.availableDepsList.sort((a, b) => {
if (a.name.toLowerCase() > b.name.toLowerCase()) {
Expand Down
15 changes: 15 additions & 0 deletions vscode-wpilib/src/shared/vendorlibrariesbase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,21 @@ export interface IJsonDependency {
uuid: string;
jsonUrl: string;
fileName: string;
conflictsWith: IJsonConflicts[] | undefined;
requires: IJsonRequires[] | undefined;
}

export interface IJsonRequires {
uuid: string;
errorMessage: string;
offlineFileName: string;
onlineUrl: string;
}

export interface IJsonConflicts {
uuid: string;
errorMessage: string;
offlineFileName: string;
}

export function isJsonDependency(arg: unknown): arg is IJsonDependency {
Expand Down
29 changes: 17 additions & 12 deletions vscode-wpilib/src/vendorlibraries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class LibraryQuickPick implements vscode.QuickPickItem {
export class VendorLibraries extends VendorLibrariesBase {
private disposables: vscode.Disposable[] = [];
private externalApi: IExternalAPI;
private lastBuildTime = 1;

constructor(externalApi: IExternalAPI) {
super(externalApi.getUtilitiesAPI());
Expand Down Expand Up @@ -127,9 +128,9 @@ export class VendorLibraries extends VendorLibrariesBase {
}
}

public async uninstallVendorLibraries(toRemove: IJsonDependency[] | undefined, workspace: vscode.WorkspaceFolder) {
public async uninstallVendorLibraries(toRemove: IJsonDependency[] | undefined, workspace: vscode.WorkspaceFolder): Promise<boolean> {
let anySucceeded = false;
if (toRemove !== undefined) {
let anySucceeded = false;
const url = this.getWpVendorFolder(workspace);
const files = await readdirAsync(url);
for (const file of files) {
Expand All @@ -144,11 +145,8 @@ export class VendorLibraries extends VendorLibrariesBase {
}
}
}

if (anySucceeded) {
this.offerBuild(workspace);
}
}
return anySucceeded;
}

private async offlineUpdates(workspace: vscode.WorkspaceFolder): Promise<void> {
Expand Down Expand Up @@ -185,7 +183,7 @@ export class VendorLibraries extends VendorLibrariesBase {
}
}
if (anySucceeded) {
this.offerBuild(workspace);
this.offerBuild(workspace, true);
}
}
} else {
Expand Down Expand Up @@ -241,7 +239,7 @@ export class VendorLibraries extends VendorLibrariesBase {
}
}
if (anySucceeded) {
this.offerBuild(workspace);
this.offerBuild(workspace, true);
}
}
} else {
Expand Down Expand Up @@ -287,7 +285,7 @@ export class VendorLibraries extends VendorLibrariesBase {
}
}
if (anySucceeded) {
this.offerBuild(workspace);
this.offerBuild(workspace, true);
}
}
} else {
Expand Down Expand Up @@ -316,7 +314,7 @@ export class VendorLibraries extends VendorLibrariesBase {

const success = await this.installDependency(file, this.getWpVendorFolder(workspace), true);
if (success) {
this.offerBuild(workspace);
this.offerBuild(workspace, true);
} else {
vscode.window.showErrorMessage(i18n('message', 'Failed to install {0}', file.name));
}
Expand All @@ -331,15 +329,22 @@ export class VendorLibraries extends VendorLibrariesBase {
return this.getDependencies(this.getWpVendorFolder(workspace));
}

public async offerBuild(workspace: vscode.WorkspaceFolder) {
public async offerBuild(workspace: vscode.WorkspaceFolder, modal = false): Promise<boolean> {
const buildRes = await vscode.window.showInformationMessage(i18n('message',
'It is recommended to run a "Build" after a vendor update. ' +
'Would you like to do this now?'), {
modal: false,
modal: modal
}, {title: i18n('ui', 'Yes')}, {title: i18n('ui', 'No'), isCloseAffordance: true});
if (buildRes?.title === i18n('ui', 'Yes')) {
await this.externalApi.getBuildTestAPI().buildCode(workspace, undefined);
this.lastBuildTime = Date.now();
return true;
}
return false;
}

public getLastBuild(): number {
return this.lastBuildTime;
}
}

Expand Down