From a7c7816bc59a3a0d429516cf0bf7cb611090d7fd Mon Sep 17 00:00:00 2001 From: Vladimir Vagaytsev Date: Thu, 23 Nov 2023 18:41:41 +0100 Subject: [PATCH] chore: move Garden Cloud utils to own module (#5435) * chore: move Garden Cloud utils to own module * chore: better type-safety * test: add missing tests for `getCloudDistributionName` * refactor: type for Cloud log section name * test: add missing tests for `getCloudLogSectionName` * chore: renamed new files to follow the naming convention --- core/src/cli/cli.ts | 3 +- core/src/cloud/api.ts | 3 +- core/src/commands/base.ts | 9 +-- .../commands/cloud/secrets/secrets-create.ts | 2 +- .../commands/cloud/secrets/secrets-list.ts | 2 +- .../commands/cloud/secrets/secrets-update.ts | 2 +- core/src/commands/cloud/users/users-list.ts | 2 +- core/src/commands/login.ts | 2 +- core/src/commands/logout.ts | 2 +- core/src/commands/serve.ts | 3 +- core/src/garden.ts | 12 +--- core/src/util/cloud.ts | 43 ++++++++++++++ core/src/util/util.ts | 31 +--------- core/test/unit/src/util/cloud.ts | 56 +++++++++++++++++++ 14 files changed, 116 insertions(+), 56 deletions(-) create mode 100644 core/src/util/cloud.ts create mode 100644 core/test/unit/src/util/cloud.ts diff --git a/core/src/cli/cli.ts b/core/src/cli/cli.ts index 79573fa135..c968a57880 100644 --- a/core/src/cli/cli.ts +++ b/core/src/cli/cli.ts @@ -11,7 +11,8 @@ import { resolve, join } from "path" import fsExtra from "fs-extra" const { pathExists } = fsExtra import { getBuiltinCommands } from "../commands/commands.js" -import { shutdown, getPackageVersion, getCloudDistributionName } from "../util/util.js" +import { getCloudDistributionName } from "../util/cloud.js" +import { shutdown, getPackageVersion } from "../util/util.js" import type { Command, CommandResult, BuiltinArgs } from "../commands/base.js" import { CommandGroup } from "../commands/base.js" import type { GardenError } from "../exceptions.js" diff --git a/core/src/cloud/api.ts b/core/src/cloud/api.ts index 686ded70ab..fb0172e842 100644 --- a/core/src/cloud/api.ts +++ b/core/src/cloud/api.ts @@ -26,7 +26,8 @@ import type { GetProjectResponse, ListProjectsResponse, } from "@garden-io/platform-api-types" -import { getCloudDistributionName, getCloudLogSectionName, getPackageVersion } from "../util/util.js" +import { getCloudDistributionName, getCloudLogSectionName } from "../util/cloud.js" +import { getPackageVersion } from "../util/util.js" import type { CommandInfo } from "../plugin-context.js" import type { ClientAuthToken, GlobalConfigStore } from "../config-store/global.js" import { add } from "date-fns" diff --git a/core/src/commands/base.ts b/core/src/commands/base.ts index 8045b30bfa..4dff372b10 100644 --- a/core/src/commands/base.ts +++ b/core/src/commands/base.ts @@ -19,13 +19,8 @@ import type { Log } from "../logger/log-entry.js" import type { LoggerType, LoggerBase, LoggerConfigBase, LogLevel } from "../logger/logger.js" import { eventLogLevel } from "../logger/logger.js" import { printFooter } from "../logger/util.js" -import { - getCloudDistributionName, - getCloudLogSectionName, - getDurationMsec, - getPackageVersion, - userPrompt, -} from "../util/util.js" +import { getCloudDistributionName, getCloudLogSectionName } from "../util/cloud.js" +import { getDurationMsec, getPackageVersion, userPrompt } from "../util/util.js" import { renderOptions, renderCommands, renderArguments, cliStyles, optionsWithAliasValues } from "../cli/helpers.js" import type { GlobalOptions, ParameterValues, ParameterObject } from "../cli/params.js" import { globalOptions } from "../cli/params.js" diff --git a/core/src/commands/cloud/secrets/secrets-create.ts b/core/src/commands/cloud/secrets/secrets-create.ts index f8d3f9f10c..c50d18cef6 100644 --- a/core/src/commands/cloud/secrets/secrets-create.ts +++ b/core/src/commands/cloud/secrets/secrets-create.ts @@ -20,8 +20,8 @@ import { dedent, deline } from "../../../util/string.js" import { IntegerParameter, PathParameter, StringParameter, StringsParameter } from "../../../cli/params.js" import type { StringMap } from "../../../config/common.js" import dotenv from "dotenv" -import { getCloudDistributionName } from "../../../util/util.js" import type { CloudProject } from "../../../cloud/api.js" +import { getCloudDistributionName } from "../../../util/cloud.js" export const secretsCreateArgs = { secrets: new StringsParameter({ diff --git a/core/src/commands/cloud/secrets/secrets-list.ts b/core/src/commands/cloud/secrets/secrets-list.ts index 5cd813fc43..ff865e3da3 100644 --- a/core/src/commands/cloud/secrets/secrets-list.ts +++ b/core/src/commands/cloud/secrets/secrets-list.ts @@ -18,7 +18,7 @@ import type { SecretResult } from "../helpers.js" import { applyFilter, makeSecretFromResponse, noApiMsg } from "../helpers.js" import { sortBy } from "lodash-es" import { StringsParameter } from "../../../cli/params.js" -import { getCloudDistributionName } from "../../../util/util.js" +import { getCloudDistributionName } from "../../../util/cloud.js" import type { CloudApi, CloudProject } from "../../../cloud/api.js" import type { Log } from "../../../logger/log-entry.js" import { styles } from "../../../logger/styles.js" diff --git a/core/src/commands/cloud/secrets/secrets-update.ts b/core/src/commands/cloud/secrets/secrets-update.ts index b3727b5005..f7da805041 100644 --- a/core/src/commands/cloud/secrets/secrets-update.ts +++ b/core/src/commands/cloud/secrets/secrets-update.ts @@ -13,8 +13,8 @@ import type { CloudProject } from "../../../cloud/api.js" import type { StringMap } from "../../../config/common.js" import { CloudApiError, CommandError, ConfigurationError, GardenError } from "../../../exceptions.js" import { printHeader } from "../../../logger/util.js" +import { getCloudDistributionName } from "../../../util/cloud.js" import { dedent, deline } from "../../../util/string.js" -import { getCloudDistributionName } from "../../../util/util.js" import type { CommandParams, CommandResult } from "../../base.js" import { Command } from "../../base.js" import type { ApiCommandError, SecretResult } from "../helpers.js" diff --git a/core/src/commands/cloud/users/users-list.ts b/core/src/commands/cloud/users/users-list.ts index 7951db1399..48d019c20f 100644 --- a/core/src/commands/cloud/users/users-list.ts +++ b/core/src/commands/cloud/users/users-list.ts @@ -17,9 +17,9 @@ import type { UserResult } from "../helpers.js" import { applyFilter, makeUserFromResponse, noApiMsg } from "../helpers.js" import { sortBy } from "lodash-es" import { StringsParameter } from "../../../cli/params.js" -import { getCloudDistributionName } from "../../../util/util.js" import type { CloudProject } from "../../../cloud/api.js" import { styles } from "../../../logger/styles.js" +import { getCloudDistributionName } from "../../../util/cloud.js" export const usersListOpts = { "filter-names": new StringsParameter({ diff --git a/core/src/commands/login.ts b/core/src/commands/login.ts index 29fac6de55..e15acb33bd 100644 --- a/core/src/commands/login.ts +++ b/core/src/commands/login.ts @@ -16,10 +16,10 @@ import type { Log } from "../logger/log-entry.js" import { ConfigurationError, TimeoutError, InternalError, CloudApiError } from "../exceptions.js" import { AuthRedirectServer } from "../cloud/auth.js" import type { EventBus } from "../events/events.js" -import { getCloudDistributionName } from "../util/util.js" import type { ProjectConfig } from "../config/project.js" import { findProjectConfig } from "../config/base.js" import { BooleanParameter } from "../cli/params.js" +import { getCloudDistributionName } from "../util/cloud.js" import { deline } from "../util/string.js" const loginTimeoutSec = 60 diff --git a/core/src/commands/logout.ts b/core/src/commands/logout.ts index fcc4530f3b..30e0a86a1e 100644 --- a/core/src/commands/logout.ts +++ b/core/src/commands/logout.ts @@ -10,8 +10,8 @@ import type { CommandParams, CommandResult } from "./base.js" import { Command } from "./base.js" import { printHeader } from "../logger/util.js" import { CloudApi, getGardenCloudDomain } from "../cloud/api.js" +import { getCloudDistributionName } from "../util/cloud.js" import { dedent, deline } from "../util/string.js" -import { getCloudDistributionName } from "../util/util.js" import { ConfigurationError } from "../exceptions.js" import type { ProjectConfig } from "../config/project.js" import { findProjectConfig } from "../config/base.js" diff --git a/core/src/commands/serve.ts b/core/src/commands/serve.ts index f65f75e38e..09641d63ae 100644 --- a/core/src/commands/serve.ts +++ b/core/src/commands/serve.ts @@ -14,7 +14,8 @@ import { printEmoji, printHeader } from "../logger/util.js" import { dedent } from "../util/string.js" import type { CommandLine } from "../cli/command-line.js" import { GardenInstanceManager } from "../server/instance-manager.js" -import { getCloudDistributionName, sleep } from "../util/util.js" +import { getCloudDistributionName } from "../util/cloud.js" +import { sleep } from "../util/util.js" import type { Log } from "../logger/log-entry.js" import { findProjectConfig } from "../config/base.js" import { CloudApiTokenRefreshError, getGardenCloudDomain } from "../cloud/api.js" diff --git a/core/src/garden.ts b/core/src/garden.ts index e701423b84..2619af01af 100644 --- a/core/src/garden.ts +++ b/core/src/garden.ts @@ -28,16 +28,8 @@ import { defaultNamespace, defaultEnvironment, } from "./config/project.js" -import { - findByName, - pickKeys, - getPackageVersion, - getNames, - findByNames, - duplicatesByKey, - getCloudDistributionName, - getCloudLogSectionName, -} from "./util/util.js" +import { getCloudDistributionName, getCloudLogSectionName } from "./util/cloud.js" +import { findByName, pickKeys, getPackageVersion, getNames, findByNames, duplicatesByKey } from "./util/util.js" import type { GardenError } from "./exceptions.js" import { ConfigurationError, diff --git a/core/src/util/cloud.ts b/core/src/util/cloud.ts new file mode 100644 index 0000000000..2bb41fa1d2 --- /dev/null +++ b/core/src/util/cloud.ts @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2018-2023 Garden Technologies, Inc. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +import { DEFAULT_GARDEN_CLOUD_DOMAIN } from "../constants.js" + +export type CloudDistroName = "Cloud Dashboard" | "Garden Enterprise" | "Garden Cloud" + +/** + * Returns "Garden Cloud" if domain matches https://.app.garden, + * otherwise "Garden Enterprise". + * + * TODO: Return the distribution type from the API and store on the CloudApi class. + */ +export function getCloudDistributionName(domain: string): CloudDistroName { + if (domain === DEFAULT_GARDEN_CLOUD_DOMAIN) { + return "Cloud Dashboard" + } + + // TODO: consider using URL object instead. + if (!domain.match(/^https:\/\/.+\.app\.garden$/i)) { + return "Garden Enterprise" + } + + return "Garden Cloud" +} + +export type CloudLogSectionName = "cloud-dashboard" | "garden-cloud" | "garden-enterprise" + +export function getCloudLogSectionName(distroName: CloudDistroName): CloudLogSectionName { + if (distroName === "Cloud Dashboard") { + return "cloud-dashboard" + } else if (distroName === "Garden Cloud") { + return "garden-cloud" + } else if (distroName === "Garden Enterprise") { + return "garden-enterprise" + } else { + return distroName satisfies never + } +} diff --git a/core/src/util/util.ts b/core/src/util/util.ts index 68438f4769..0a69024fa5 100644 --- a/core/src/util/util.ts +++ b/core/src/util/util.ts @@ -30,7 +30,7 @@ import { isAbsolute, relative } from "node:path" import type { Readable } from "stream" import { Writable } from "stream" import type { PrimitiveMap } from "../config/common.js" -import { DEFAULT_GARDEN_CLOUD_DOMAIN, DOCS_BASE_URL, gardenEnv } from "../constants.js" +import { DOCS_BASE_URL, gardenEnv } from "../constants.js" import { ChildProcessError, InternalError, @@ -119,35 +119,6 @@ export function getPackageVersion(): string { return version } -type CloudDistroName = "Cloud Dashboard" | "Garden Enterprise" | "Garden Cloud" - -/** - * Returns "Garden Cloud" if domain matches https://.app.garden, - * otherwise "Garden Enterprise". - * - * TODO: Return the distribution type from the API and store on the CloudApi class. - */ -export function getCloudDistributionName(domain: string): CloudDistroName { - if (domain === DEFAULT_GARDEN_CLOUD_DOMAIN) { - return "Cloud Dashboard" - } - - if (!domain.match(/^https:\/\/.+\.app\.garden$/i)) { - return "Garden Enterprise" - } - return "Garden Cloud" -} - -export function getCloudLogSectionName(distroName: CloudDistroName): string { - if (distroName === "Cloud Dashboard") { - return "cloud-dashboard" - } else if (distroName === "Garden Cloud") { - return "garden-cloud" - } else { - return "garden-enterprise" - } -} - export async function sleep(msec: number) { return new Promise((resolve) => setTimeout(resolve, msec)) } diff --git a/core/test/unit/src/util/cloud.ts b/core/test/unit/src/util/cloud.ts new file mode 100644 index 0000000000..54a0143ca8 --- /dev/null +++ b/core/test/unit/src/util/cloud.ts @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2018-2023 Garden Technologies, Inc. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +import { describe } from "mocha" +import { getCloudDistributionName, getCloudLogSectionName } from "../../../../src/util/cloud.js" +import { DEFAULT_GARDEN_CLOUD_DOMAIN } from "../../../../src/constants.js" +import { expect } from "chai" + +describe("garden-cloud", () => { + describe("getCloudDistributionName", () => { + context(`when domain name is ${DEFAULT_GARDEN_CLOUD_DOMAIN}`, () => { + it(`returns "Cloud Dashboard" for ${DEFAULT_GARDEN_CLOUD_DOMAIN}`, () => { + expect(getCloudDistributionName(DEFAULT_GARDEN_CLOUD_DOMAIN)).to.eql("Cloud Dashboard") + }) + }) + + context("when top-level domain is .garden", () => { + context("when 2nd level domain is .app", () => { + it(`returns "Garden Cloud" for https urls`, () => { + expect(getCloudDistributionName("https://backend.app.garden")).to.eql("Garden Cloud") + }) + }) + + context("when 2nd level domain is not .app", () => { + it(`returns "Garden Enterprise" for https urls`, () => { + expect(getCloudDistributionName("https://backend.demo.garden")).to.eql("Garden Enterprise") + }) + }) + }) + + context("when domain is something else", () => { + it(`returns "Garden Enterprise" for https urls`, () => { + expect(getCloudDistributionName("https://app.garden-proxy.net")).to.eql("Garden Enterprise") + }) + }) + }) + + describe("getCloudLogSectionName", () => { + it(`returns "cloud-dashboard" for "Cloud Dashboard"`, () => { + expect(getCloudLogSectionName("Cloud Dashboard")).to.eql("cloud-dashboard") + }) + + it(`returns "garden-cloud" for "Garden Cloud"`, () => { + expect(getCloudLogSectionName("Garden Cloud")).to.eql("garden-cloud") + }) + + it(`returns "garden-enterprise" for "Garden Enterprise"`, () => { + expect(getCloudLogSectionName("Garden Enterprise")).to.eql("garden-enterprise") + }) + }) +})