From fdd132f968bd21f0b4bd90e609fc3219ccb6f704 Mon Sep 17 00:00:00 2001 From: Victor Rubezhny Date: Sun, 15 Sep 2024 19:38:36 +0200 Subject: [PATCH] "Components" sidebar section take a while to load #3850 Fixes: #3850 Signed-off-by: Victor Rubezhny --- .../devfileRegistryWrapper.ts | 4 +- src/odo/odoPreference.ts | 92 +++++++++++++++++++ src/odo/odoWrapper.ts | 56 +++++------ src/registriesView.ts | 7 +- test/integration/odoWrapper.test.ts | 18 ++-- 5 files changed, 136 insertions(+), 41 deletions(-) create mode 100644 src/odo/odoPreference.ts diff --git a/src/devfile-registry/devfileRegistryWrapper.ts b/src/devfile-registry/devfileRegistryWrapper.ts index a74af5ec3..00fda9c25 100644 --- a/src/devfile-registry/devfileRegistryWrapper.ts +++ b/src/devfile-registry/devfileRegistryWrapper.ts @@ -6,7 +6,7 @@ import * as https from 'https'; import * as YAML from 'js-yaml'; import { ExecutionContext } from '../cli'; import { Registry } from '../odo/componentType'; -import { Odo } from '../odo/odoWrapper'; +import { OdoPreference } from '../odo/odoPreference'; import { DevfileData, DevfileInfo } from './devfileInfo'; export const DEVFILE_VERSION_LATEST: string = 'latest'; @@ -86,7 +86,7 @@ export class DevfileRegistry { let registries: Registry[] = []; const key = ExecutionContext.key('getRegistries'); if (this.executionContext && !this.executionContext.has(key)) { - registries = await Odo.Instance.getRegistries(); + registries = await OdoPreference.Instance.getRegistries(); this.executionContext.set(key, registries); } else { registries = this.executionContext.get(key); diff --git a/src/odo/odoPreference.ts b/src/odo/odoPreference.ts new file mode 100644 index 000000000..0c3caa651 --- /dev/null +++ b/src/odo/odoPreference.ts @@ -0,0 +1,92 @@ +/*----------------------------------------------------------------------------------------------- + * Copyright (c) Red Hat, Inc. All rights reserved. + * Licensed under the MIT License. See LICENSE file in the project root for license information. + *-----------------------------------------------------------------------------------------------*/ + +import * as fs from 'fs/promises'; +import * as YAML from 'js-yaml'; +import * as path from 'path'; +import { Platform } from '../util/platform'; +import { Registry } from './componentType'; + + +type OdoSettings = { + OdoSettings: { + RegistryList: [{ + Name: string; + URL: string; + secure: boolean; + }]; + } +}; + +export class OdoPreference { + private static instance: OdoPreference; + + public static get Instance(): OdoPreference { + if (!OdoPreference.instance) { + OdoPreference.instance = new OdoPreference(); + } + return OdoPreference.instance; + } + + private getOdoPreferenceFile(): string { + // This value can be provided to set a seperate directory for users 'homedir' resolution + // note for mocking purpose ONLY + const customHomeDir = Platform.ENV.CUSTOM_HOMEDIR; + const configFileName = 'preference.yaml'; + + if (customHomeDir && customHomeDir.length > 0) { + return path.join(customHomeDir, '.odo', configFileName); + } + + const userHomeDir = Platform.getUserHomePath(); + return path.join(userHomeDir, '.odo', configFileName); + } + + public async getRegistries(): Promise { + const odoPreference = await this.readOdoPreference(); + const odoRegistryList = (odoPreference as OdoSettings)?.OdoSettings?.RegistryList; + return odoRegistryList?.map((r) => { + return { + name: r.Name, + url: r.URL, + secure: r.secure } as Registry; + }); + } + + public async addRegistry(name: string, url: string, token: string): Promise { + const odoPreference = await this.readOdoPreference(); + odoPreference.OdoSettings.RegistryList.push({ + Name: name, + URL: url, + secure: !!token + } as never); + await this.writeOdoPreference(odoPreference); + return { + name, + secure: !!token, + url, + }; + } + + public async removeRegistry(name: string): Promise { + const odoPreference = await this.readOdoPreference(); + + odoPreference.OdoSettings.RegistryList.splice( + odoPreference.OdoSettings.RegistryList.findIndex((registry) => registry.name === name), 1 + ); + + await this.writeOdoPreference(odoPreference); + } + + public async readOdoPreference(): Promise { + const odoPreferenceFile = await fs.readFile(this.getOdoPreferenceFile(), 'utf8'); + return YAML.load(odoPreferenceFile); + } + + public async writeOdoPreference(preference: any): Promise { + const preferenceYaml = YAML.dump(preference); + await fs.writeFile(this.getOdoPreferenceFile(), preferenceYaml, 'utf8'); + } +} \ No newline at end of file diff --git a/src/odo/odoWrapper.ts b/src/odo/odoWrapper.ts index 7912d6020..7e9849117 100644 --- a/src/odo/odoWrapper.ts +++ b/src/odo/odoWrapper.ts @@ -11,7 +11,6 @@ import { ToolsConfig } from '../tools'; import { ChildProcessUtil, CliExitData } from '../util/childProcessUtil'; import { VsCommandError } from '../vscommand'; import { Command } from './command'; -import { Registry } from './componentType'; import { ComponentDescription } from './componentTypeDescription'; import { BindableService } from './odoTypes'; @@ -259,36 +258,37 @@ export class Odo { // return data; // } - private async loadRegistryFromPreferences() { - const cliData = await this.execute(new CommandText('odo', 'preference view -o json')); - const prefs = JSON.parse(cliData.stdout) as { registries: Registry[] }; - return prefs.registries; - } + // private async loadRegistryFromPreferences() { + // const cliData = await this.execute(new CommandText('odo', 'preference view -o json')); + // const prefs = JSON.parse(cliData.stdout) as { registries: Registry[] }; + // return prefs.registries; + // } - public getRegistries(): Promise { - return this.loadRegistryFromPreferences(); - } + // public getRegistries(): Promise { + // // return this.loadRegistryFromPreferences(); + // return OdoPreference.Instance.getOdoRegistries(); + // } - public async addRegistry(name: string, url: string, token: string): Promise { - const command = new CommandText('odo', `preference add registry ${name} ${url}`); - if (token) { - command.addOption(new CommandOption('--token', token)); - } - await this.execute(command); - return { - name, - secure: !!token, - url, - }; - } + // public async addRegistry(name: string, url: string, token: string): Promise { + // const command = new CommandText('odo', `preference add registry ${name} ${url}`); + // if (token) { + // command.addOption(new CommandOption('--token', token)); + // } + // await this.execute(command); + // return { + // name, + // secure: !!token, + // url, + // }; + // } - public async removeRegistry(name: string): Promise { - await this.execute( - new CommandText('odo', `preference remove registry ${name}`, [ - new CommandOption('--force'), - ]), - ); - } + // public async removeRegistry(name: string): Promise { + // await this.execute( + // new CommandText('odo', `preference remove registry ${name}`, [ + // new CommandOption('--force'), + // ]), + // ); + // } /** * Deletes all the odo configuration files associated with the component (`.odo`, `devfile.yaml`) located at the given path. diff --git a/src/registriesView.ts b/src/registriesView.ts index e274ed52f..b60d30a0c 100644 --- a/src/registriesView.ts +++ b/src/registriesView.ts @@ -15,6 +15,7 @@ import { Registry } from './odo/componentType'; import { StarterProject } from './odo/componentTypeDescription'; +import { OdoPreference } from './odo/odoPreference'; import { Odo } from './odo/odoWrapper'; import { inputValue, quickBtn } from './util/inputValue'; import { Progress } from './util/progress'; @@ -364,9 +365,9 @@ export class ComponentTypesView implements TreeDataProvider { const devfileInfos = await DevfileRegistry.Instance.getDevfileInfoList(regURL); if (devfileInfos.length > 0) { - const newRegistry = await Odo.Instance.addRegistry(regName, regURL, token); + const newRegistry = await OdoPreference.Instance.addRegistry(regName, regURL, token); if (registryContext) { - await Odo.Instance.removeRegistry(registryContext.name); + await OdoPreference.Instance.removeRegistry(registryContext.name); ComponentTypesView.instance.replaceRegistry(registryContext, newRegistry); } else { ComponentTypesView.instance.addRegistry(newRegistry); @@ -393,7 +394,7 @@ export class ComponentTypesView implements TreeDataProvider { 'No', ); if (yesNo === 'Yes') { - await Odo.Instance.removeRegistry(registry.name); + await OdoPreference.Instance.removeRegistry(registry.name); ComponentTypesView.instance.removeRegistry(registry); // ComponentTypesView.instance.refresh(); // if (!isEdit) { diff --git a/test/integration/odoWrapper.test.ts b/test/integration/odoWrapper.test.ts index f8d695de2..d3acd875e 100644 --- a/test/integration/odoWrapper.test.ts +++ b/test/integration/odoWrapper.test.ts @@ -12,6 +12,7 @@ import * as tmp from 'tmp'; import { promisify } from 'util'; import { Uri, workspace } from 'vscode'; import { Oc } from '../../src/oc/ocWrapper'; +import { OdoPreference } from '../../src/odo/odoPreference'; import { Odo } from '../../src/odo/odoWrapper'; import { LoginUtil } from '../../src/util/loginUtil'; @@ -102,42 +103,43 @@ suite('./odo/odoWrapper.ts', function () { }); }); + // TODO: Move this out of odoWrapper suite('registries', function () { const TEST_REGISTRY = 'TestRegistry'; suiteSetup(async function () { - const registries = await Odo.Instance.getRegistries(); + const registries = await OdoPreference.Instance.getRegistries(); if (registries.find((registry) => registry.name === TEST_REGISTRY)) { - await Odo.Instance.removeRegistry(TEST_REGISTRY); + await OdoPreference.Instance.removeRegistry(TEST_REGISTRY); } }); suiteTeardown(async function () { try { - await Odo.Instance.removeRegistry(TEST_REGISTRY); + await OdoPreference.Instance.removeRegistry(TEST_REGISTRY); } catch { // do nothing, it's probably already deleted } }); test('getRegistries()', async function () { - const registries = await Odo.Instance.getRegistries(); + const registries = await OdoPreference.Instance.getRegistries(); expect(registries).to.be.of.length(1); const registryNames = registries.map((registry) => registry.name); expect(registryNames).to.contain('DefaultDevfileRegistry'); }); test('addRegistry()', async function () { - await Odo.Instance.addRegistry(TEST_REGISTRY, 'https://example.org', undefined); - const registries = await Odo.Instance.getRegistries(); + await OdoPreference.Instance.addRegistry(TEST_REGISTRY, 'https://example.org', undefined); + const registries = await OdoPreference.Instance.getRegistries(); expect(registries).to.be.of.length(2); const registryNames = registries.map((registry) => registry.name); expect(registryNames).to.contain(TEST_REGISTRY); }); test('removeRegistry()', async function () { - await Odo.Instance.removeRegistry(TEST_REGISTRY); - const registries = await Odo.Instance.getRegistries(); + await OdoPreference.Instance.removeRegistry(TEST_REGISTRY); + const registries = await OdoPreference.Instance.getRegistries(); expect(registries).to.be.of.length(1); const registryNames = registries.map((registry) => registry.name); expect(registryNames).to.not.contain(TEST_REGISTRY);