diff --git a/src/cli/install-tool/index.spec.ts b/src/cli/install-tool/index.spec.ts index 53719a14ae..d496922f84 100644 --- a/src/cli/install-tool/index.spec.ts +++ b/src/cli/install-tool/index.spec.ts @@ -9,7 +9,7 @@ import { RubyBaseInstallService, RubyGemVersionResolver, } from '../tools/ruby/utils'; -import { logger } from '../utils'; +import { isDockerBuild, logger } from '../utils'; import { MissingParent } from '../utils/codes'; import { installTool, linkTool, resolveVersion } from '.'; import { ensurePaths, rootPath } from '~test/path'; @@ -18,6 +18,10 @@ vi.mock('del'); vi.mock('nano-spawn'); vi.mock('../tools/bun'); vi.mock('../tools/php/composer'); +vi.mock('../utils', async (importActual) => ({ + ...(await importActual()), + isDockerBuild: vi.fn(), +})); describe('cli/install-tool/index', () => { beforeAll(async () => { @@ -53,6 +57,7 @@ describe('cli/install-tool/index', () => { describe('installTool', () => { test('fails if parent is missing', async () => { + vi.mocked(isDockerBuild).mockResolvedValueOnce(true); expect(await installTool('gradle', '1.0.0')).toBe(MissingParent); expect(logger.fatal).toHaveBeenCalledExactlyOnceWith( { tool: 'gradle', parent: 'java' }, diff --git a/src/cli/install-tool/index.ts b/src/cli/install-tool/index.ts index 54916bed6a..8390eca7b9 100644 --- a/src/cli/install-tool/index.ts +++ b/src/cli/install-tool/index.ts @@ -8,9 +8,13 @@ import { DenoInstallService } from '../tools/deno'; import { DevboxInstallService } from '../tools/devbox'; import { DockerInstallService } from '../tools/docker'; import { DotnetInstallService } from '../tools/dotnet'; +import { ErlangInstallService } from '../tools/erlang'; +import { ElixirInstallService } from '../tools/erlang/elixir'; import { FlutterInstallService } from '../tools/flutter'; import { FluxInstallService } from '../tools/flux'; +import { GitLfsInstallService } from '../tools/git/lfs'; import { GleamInstallService } from '../tools/gleam'; +import { GolangInstallService } from '../tools/golang'; import { HelmInstallService } from '../tools/helm'; import { HelmfileInstallService } from '../tools/helmfile'; import { @@ -28,8 +32,12 @@ import { JavaJreVersionResolver, JavaVersionResolver, } from '../tools/java/resolver'; +import { SbtInstallService } from '../tools/java/sbt'; +import { ScalaInstallService } from '../tools/java/scala'; +import { JsonnetBundlerInstallService } from '../tools/jb'; import { KubectlInstallService } from '../tools/kubectl'; import { KustomizeInstallService } from '../tools/kustomize'; +import { NixInstallService } from '../tools/nix'; import { NodeInstallService } from '../tools/node'; import { RenovateInstallService, @@ -48,7 +56,9 @@ import { ComposerVersionResolver, } from '../tools/php/composer'; import { PixiInstallService } from '../tools/pixi'; +import { PowershellInstallService } from '../tools/powershell'; import { ProtocInstallService } from '../tools/protoc'; +import { PythonInstallService } from '../tools/python'; import { ConanInstallService, ConanVersionResolver, @@ -56,6 +66,7 @@ import { import { PipVersionResolver } from '../tools/python/pip'; import { PoetryVersionResolver } from '../tools/python/poetry'; import { PipBaseInstallService } from '../tools/python/utils'; +import { RubyInstallService } from '../tools/ruby'; import { CocoapodsInstallService, CocoapodsVersionResolver, @@ -64,10 +75,15 @@ import { RubyBaseInstallService, RubyGemVersionResolver, } from '../tools/ruby/utils'; +import { RustInstallService } from '../tools/rust'; import { SkopeoInstallService } from '../tools/skopeo'; import { SopsInstallService } from '../tools/sops'; +import { SwiftInstallService } from '../tools/swift'; +import { TerraformInstallService } from '../tools/terraform'; +import { VendirInstallService } from '../tools/vendir'; import { WallyInstallService } from '../tools/wally'; import { logger } from '../utils'; +import { isNotKnownV2Tool } from '../utils/v2-tool'; import { V1ToolInstallService, V2ToolInstallService, @@ -99,32 +115,48 @@ async function prepareInstallContainer(): Promise { container.bind(INSTALL_TOOL_TOKEN).to(DevboxInstallService); container.bind(INSTALL_TOOL_TOKEN).to(DockerInstallService); container.bind(INSTALL_TOOL_TOKEN).to(DotnetInstallService); + container.bind(INSTALL_TOOL_TOKEN).to(ElixirInstallService); + container.bind(INSTALL_TOOL_TOKEN).to(ErlangInstallService); container.bind(INSTALL_TOOL_TOKEN).to(FlutterInstallService); container.bind(INSTALL_TOOL_TOKEN).to(FluxInstallService); + container.bind(INSTALL_TOOL_TOKEN).to(GitLfsInstallService); container.bind(INSTALL_TOOL_TOKEN).to(GleamInstallService); + container.bind(INSTALL_TOOL_TOKEN).to(GolangInstallService); container.bind(INSTALL_TOOL_TOKEN).to(GradleInstallService); container.bind(INSTALL_TOOL_TOKEN).to(HelmInstallService); container.bind(INSTALL_TOOL_TOKEN).to(HelmfileInstallService); container.bind(INSTALL_TOOL_TOKEN).to(JavaInstallService); container.bind(INSTALL_TOOL_TOKEN).to(JavaJreInstallService); container.bind(INSTALL_TOOL_TOKEN).to(JavaJdkInstallService); + container.bind(INSTALL_TOOL_TOKEN).to(JsonnetBundlerInstallService); container.bind(INSTALL_TOOL_TOKEN).to(KubectlInstallService); container.bind(INSTALL_TOOL_TOKEN).to(KustomizeInstallService); container.bind(INSTALL_TOOL_TOKEN).to(MavenInstallService); + container.bind(INSTALL_TOOL_TOKEN).to(NixInstallService); container.bind(INSTALL_TOOL_TOKEN).to(NodeInstallService); container.bind(INSTALL_TOOL_TOKEN).to(PhpInstallService); container.bind(INSTALL_TOOL_TOKEN).to(PixiInstallService); + container.bind(INSTALL_TOOL_TOKEN).to(PowershellInstallService); container.bind(INSTALL_TOOL_TOKEN).to(ProtocInstallService); + container.bind(INSTALL_TOOL_TOKEN).to(PythonInstallService); container.bind(INSTALL_TOOL_TOKEN).to(RenovateInstallService); + container.bind(INSTALL_TOOL_TOKEN).to(RubyInstallService); + container.bind(INSTALL_TOOL_TOKEN).to(RustInstallService); + container.bind(INSTALL_TOOL_TOKEN).to(SbtInstallService); + container.bind(INSTALL_TOOL_TOKEN).to(ScalaInstallService); container.bind(INSTALL_TOOL_TOKEN).to(SkopeoInstallService); container.bind(INSTALL_TOOL_TOKEN).to(SopsInstallService); + container.bind(INSTALL_TOOL_TOKEN).to(SwiftInstallService); + container.bind(INSTALL_TOOL_TOKEN).to(TerraformInstallService); + container.bind(INSTALL_TOOL_TOKEN).to(VendirInstallService); container.bind(INSTALL_TOOL_TOKEN).to(WallyInstallService); container.bind(INSTALL_TOOL_TOKEN).to(YarnInstallService); container.bind(INSTALL_TOOL_TOKEN).to(YarnSlimInstallService); // v2 tool services const pathSvc = await container.getAsync(PathService); - for (const tool of await pathSvc.findLegacyTools()) { + const legacyTools = await pathSvc.findLegacyTools(); + for (const tool of legacyTools.filter(isNotKnownV2Tool)) { @injectable() @injectFromHierarchy() class GenericInstallService extends V2ToolInstallService { diff --git a/src/cli/prepare-tool/index.ts b/src/cli/prepare-tool/index.ts index 2afcb1fa0d..264e8a9293 100644 --- a/src/cli/prepare-tool/index.ts +++ b/src/cli/prepare-tool/index.ts @@ -3,16 +3,26 @@ import { PathService, createContainer } from '../services'; import { DartPrepareService } from '../tools/dart'; import { DockerPrepareService } from '../tools/docker'; import { DotnetPrepareService } from '../tools/dotnet'; +import { ErlangPrepareService } from '../tools/erlang'; +import { ElixirPrepareService } from '../tools/erlang/elixir'; import { FlutterPrepareService } from '../tools/flutter'; +import { GolangPrepareService } from '../tools/golang'; import { JavaJdkPrepareService, JavaJrePrepareService, JavaPrepareService, } from '../tools/java'; +import { SbtPrepareService } from '../tools/java/sbt'; import { NodePrepareService } from '../tools/node'; import { PhpPrepareService } from '../tools/php'; +import { PowershellPrepareService } from '../tools/powershell'; +import { PythonPrepareService } from '../tools/python'; import { ConanPrepareService } from '../tools/python/conan'; +import { RubyPrepareService } from '../tools/ruby'; +import { RustPrepareService } from '../tools/rust'; +import { SwiftPrepareService } from '../tools/swift'; import { logger } from '../utils'; +import { isNotKnownV2Tool } from '../utils/v2-tool'; import { V2ToolPrepareService } from './prepare-legacy-tools.service'; import { PREPARE_TOOL_TOKEN, PrepareToolService } from './prepare-tool.service'; @@ -25,7 +35,8 @@ async function prepareContainer(): Promise { // v2 tool services const pathSvc = await container.getAsync(PathService); - for (const tool of await pathSvc.findLegacyTools()) { + const v2Tools = await pathSvc.findLegacyTools(); + for (const tool of v2Tools.filter(isNotKnownV2Tool)) { @injectable() @injectFromHierarchy() class GenericV2ToolPrepareService extends V2ToolPrepareService { @@ -39,12 +50,21 @@ async function prepareContainer(): Promise { container.bind(PREPARE_TOOL_TOKEN).to(DartPrepareService); container.bind(PREPARE_TOOL_TOKEN).to(DotnetPrepareService); container.bind(PREPARE_TOOL_TOKEN).to(DockerPrepareService); + container.bind(PREPARE_TOOL_TOKEN).to(ElixirPrepareService); + container.bind(PREPARE_TOOL_TOKEN).to(ErlangPrepareService); container.bind(PREPARE_TOOL_TOKEN).to(FlutterPrepareService); + container.bind(PREPARE_TOOL_TOKEN).to(GolangPrepareService); container.bind(PREPARE_TOOL_TOKEN).to(JavaPrepareService); container.bind(PREPARE_TOOL_TOKEN).to(JavaJrePrepareService); container.bind(PREPARE_TOOL_TOKEN).to(JavaJdkPrepareService); container.bind(PREPARE_TOOL_TOKEN).to(NodePrepareService); container.bind(PREPARE_TOOL_TOKEN).to(PhpPrepareService); + container.bind(PREPARE_TOOL_TOKEN).to(PowershellPrepareService); + container.bind(PREPARE_TOOL_TOKEN).to(PythonPrepareService); + container.bind(PREPARE_TOOL_TOKEN).to(RubyPrepareService); + container.bind(PREPARE_TOOL_TOKEN).to(RustPrepareService); + container.bind(PREPARE_TOOL_TOKEN).to(SbtPrepareService); + container.bind(PREPARE_TOOL_TOKEN).to(SwiftPrepareService); logger.trace('preparing container done'); return container; diff --git a/src/cli/services/v2-tool.service.ts b/src/cli/services/v2-tool.service.ts index f0ac1c24fa..5221ab15ed 100644 --- a/src/cli/services/v2-tool.service.ts +++ b/src/cli/services/v2-tool.service.ts @@ -7,6 +7,7 @@ import { postConstruct, } from 'inversify'; import { logger } from '../utils'; +import { isNotKnownV2Tool } from '../utils/v2-tool'; import { PathService } from './path.service'; @injectable(bindingScopeValues.Singleton) @@ -19,7 +20,8 @@ export class V2ToolService { @postConstruct() protected async [Symbol('_construct')](): Promise { - for (const tool of await this.pathSvc.findLegacyTools()) { + const tools = await this.pathSvc.findLegacyTools(); + for (const tool of tools.filter(isNotKnownV2Tool)) { const content = await readFile( join(this.pathSvc.usrPath, 'tools/v2', `${tool}.sh`), { encoding: 'utf8' }, diff --git a/src/cli/tools/erlang/elixir.ts b/src/cli/tools/erlang/elixir.ts new file mode 100644 index 0000000000..600202b1db --- /dev/null +++ b/src/cli/tools/erlang/elixir.ts @@ -0,0 +1,33 @@ +import { injectFromHierarchy, injectable } from 'inversify'; +import { V2ToolInstallService } from '../../install-tool/install-legacy-tool.service'; +import { V2ToolPrepareService } from '../../prepare-tool/prepare-legacy-tools.service'; +import { v2Tool } from '../../utils/v2-tool'; + +@injectable() +@injectFromHierarchy() +@v2Tool('elixir') +export class ElixirPrepareService extends V2ToolPrepareService { + override readonly name = 'elixir'; + + override needsPrepare(): boolean { + return true; + } + override needsInitialize(): boolean { + return true; + } +} + +@injectable() +@injectFromHierarchy() +@v2Tool('elixir') +export class ElixirInstallService extends V2ToolInstallService { + override readonly name = 'elixir'; + override readonly parent = 'erlang'; + + override needsPrepare(): boolean { + return true; + } + override needsInitialize(): boolean { + return true; + } +} diff --git a/src/cli/tools/erlang/index.ts b/src/cli/tools/erlang/index.ts new file mode 100644 index 0000000000..caac217018 --- /dev/null +++ b/src/cli/tools/erlang/index.ts @@ -0,0 +1,32 @@ +import { injectFromHierarchy, injectable } from 'inversify'; +import { V2ToolInstallService } from '../../install-tool/install-legacy-tool.service'; +import { V2ToolPrepareService } from '../../prepare-tool/prepare-legacy-tools.service'; +import { v2Tool } from '../../utils/v2-tool'; + +@injectable() +@injectFromHierarchy() +@v2Tool('elixir') +export class ErlangPrepareService extends V2ToolPrepareService { + override readonly name = 'erlang'; + + override needsPrepare(): boolean { + return true; + } + override needsInitialize(): boolean { + return false; + } +} + +@injectable() +@injectFromHierarchy() +@v2Tool('erlang') +export class ErlangInstallService extends V2ToolInstallService { + override readonly name = 'erlang'; + + override needsPrepare(): boolean { + return true; + } + override needsInitialize(): boolean { + return false; + } +} diff --git a/src/cli/tools/git/lfs.ts b/src/cli/tools/git/lfs.ts new file mode 100644 index 0000000000..48c4037c36 --- /dev/null +++ b/src/cli/tools/git/lfs.ts @@ -0,0 +1,18 @@ +import { injectFromHierarchy, injectable } from 'inversify'; +import { V2ToolInstallService } from '../../install-tool/install-legacy-tool.service'; +import { v2Tool } from '../../utils/v2-tool'; + +@injectable() +@injectFromHierarchy() +@v2Tool('git-lfs') +export class GitLfsInstallService extends V2ToolInstallService { + override readonly name = 'git-lfs'; + override readonly parent = 'git'; + + override needsPrepare(): boolean { + return false; + } + override needsInitialize(): boolean { + return false; + } +} diff --git a/src/cli/tools/golang.ts b/src/cli/tools/golang.ts new file mode 100644 index 0000000000..13af1e76aa --- /dev/null +++ b/src/cli/tools/golang.ts @@ -0,0 +1,32 @@ +import { injectFromHierarchy, injectable } from 'inversify'; +import { V2ToolInstallService } from '../install-tool/install-legacy-tool.service'; +import { V2ToolPrepareService } from '../prepare-tool/prepare-legacy-tools.service'; +import { v2Tool } from '../utils/v2-tool'; + +@injectable() +@injectFromHierarchy() +@v2Tool('golang') +export class GolangPrepareService extends V2ToolPrepareService { + override readonly name = 'golang'; + + override needsPrepare(): boolean { + return true; + } + override needsInitialize(): boolean { + return true; + } +} + +@injectable() +@injectFromHierarchy() +@v2Tool('golang') +export class GolangInstallService extends V2ToolInstallService { + override readonly name = 'golang'; + + override needsPrepare(): boolean { + return true; + } + override needsInitialize(): boolean { + return true; + } +} diff --git a/src/cli/tools/index.ts b/src/cli/tools/index.ts index 4898f89ab9..2ff3a61aba 100644 --- a/src/cli/tools/index.ts +++ b/src/cli/tools/index.ts @@ -13,15 +13,18 @@ export const NoPrepareTools = [ 'deno', 'devbox', 'flux', + 'git-lfs', 'gleam', 'gradle', 'hashin', 'helm', 'helmfile', + 'jb', 'kubectl', 'kustomize', 'lerna', 'maven', + 'nix', 'npm', 'pdm', 'pip-tools', @@ -31,15 +34,23 @@ export const NoPrepareTools = [ 'poetry', 'protoc', 'renovate', + 'scala', 'skopeo', 'sops', + 'terraform', 'uv', + 'vendir', 'wally', 'yarn', 'yarn-slim', ]; -export const NoInitTools = [...NoPrepareTools]; +export const NoInitTools = [ + ...NoPrepareTools, + 'erlang', + 'powershell', + 'python', +]; /** * Tools in this map are implicit mapped from `install-tool` to `install-`. diff --git a/src/cli/tools/java/sbt.ts b/src/cli/tools/java/sbt.ts new file mode 100644 index 0000000000..ec370c5bc3 --- /dev/null +++ b/src/cli/tools/java/sbt.ts @@ -0,0 +1,33 @@ +import { injectFromHierarchy, injectable } from 'inversify'; +import { V2ToolInstallService } from '../../install-tool/install-legacy-tool.service'; +import { V2ToolPrepareService } from '../../prepare-tool/prepare-legacy-tools.service'; +import { v2Tool } from '../../utils/v2-tool'; + +@injectable() +@injectFromHierarchy() +@v2Tool('sbt') +export class SbtPrepareService extends V2ToolPrepareService { + override readonly name = 'sbt'; + + override needsPrepare(): boolean { + return true; + } + override needsInitialize(): boolean { + return true; + } +} + +@injectable() +@injectFromHierarchy() +@v2Tool('sbt') +export class SbtInstallService extends V2ToolInstallService { + override readonly name = 'sbt'; + override readonly parent = 'java'; + + override needsPrepare(): boolean { + return true; + } + override needsInitialize(): boolean { + return true; + } +} diff --git a/src/cli/tools/java/scala.ts b/src/cli/tools/java/scala.ts new file mode 100644 index 0000000000..b7aecdc5d2 --- /dev/null +++ b/src/cli/tools/java/scala.ts @@ -0,0 +1,18 @@ +import { injectFromHierarchy, injectable } from 'inversify'; +import { V2ToolInstallService } from '../../install-tool/install-legacy-tool.service'; +import { v2Tool } from '../../utils/v2-tool'; + +@injectable() +@injectFromHierarchy() +@v2Tool('scala') +export class ScalaInstallService extends V2ToolInstallService { + override readonly name = 'scala'; + override readonly parent = 'java'; + + override needsPrepare(): boolean { + return false; + } + override needsInitialize(): boolean { + return false; + } +} diff --git a/src/cli/tools/jb.ts b/src/cli/tools/jb.ts new file mode 100644 index 0000000000..5f3ffad5cf --- /dev/null +++ b/src/cli/tools/jb.ts @@ -0,0 +1,17 @@ +import { injectFromHierarchy, injectable } from 'inversify'; +import { V2ToolInstallService } from '../install-tool/install-legacy-tool.service'; +import { v2Tool } from '../utils/v2-tool'; + +@injectable() +@injectFromHierarchy() +@v2Tool('jb') +export class JsonnetBundlerInstallService extends V2ToolInstallService { + override readonly name = 'jb'; + + override needsPrepare(): boolean { + return false; + } + override needsInitialize(): boolean { + return false; + } +} diff --git a/src/cli/tools/nix.ts b/src/cli/tools/nix.ts new file mode 100644 index 0000000000..9fae7f6a3a --- /dev/null +++ b/src/cli/tools/nix.ts @@ -0,0 +1,17 @@ +import { injectFromHierarchy, injectable } from 'inversify'; +import { V2ToolInstallService } from '../install-tool/install-legacy-tool.service'; +import { v2Tool } from '../utils/v2-tool'; + +@injectable() +@injectFromHierarchy() +@v2Tool('nix') +export class NixInstallService extends V2ToolInstallService { + override readonly name = 'nix'; + + override needsPrepare(): boolean { + return false; + } + override needsInitialize(): boolean { + return false; + } +} diff --git a/src/cli/tools/powershell.ts b/src/cli/tools/powershell.ts new file mode 100644 index 0000000000..4bfb6f9eca --- /dev/null +++ b/src/cli/tools/powershell.ts @@ -0,0 +1,32 @@ +import { injectFromHierarchy, injectable } from 'inversify'; +import { V2ToolInstallService } from '../install-tool/install-legacy-tool.service'; +import { V2ToolPrepareService } from '../prepare-tool/prepare-legacy-tools.service'; +import { v2Tool } from '../utils/v2-tool'; + +@injectable() +@injectFromHierarchy() +@v2Tool('powershell') +export class PowershellPrepareService extends V2ToolPrepareService { + override readonly name = 'powershell'; + + override needsPrepare(): boolean { + return true; + } + override needsInitialize(): boolean { + return false; + } +} + +@injectable() +@injectFromHierarchy() +@v2Tool('powershell') +export class PowershellInstallService extends V2ToolInstallService { + override readonly name = 'powershell'; + + override needsPrepare(): boolean { + return true; + } + override needsInitialize(): boolean { + return false; + } +} diff --git a/src/cli/tools/python/index.ts b/src/cli/tools/python/index.ts new file mode 100644 index 0000000000..96dcd31d6a --- /dev/null +++ b/src/cli/tools/python/index.ts @@ -0,0 +1,32 @@ +import { injectFromHierarchy, injectable } from 'inversify'; +import { V2ToolInstallService } from '../../install-tool/install-legacy-tool.service'; +import { V2ToolPrepareService } from '../../prepare-tool/prepare-legacy-tools.service'; +import { v2Tool } from '../../utils/v2-tool'; + +@injectable() +@injectFromHierarchy() +@v2Tool('python') +export class PythonPrepareService extends V2ToolPrepareService { + override readonly name = 'python'; + + override needsPrepare(): boolean { + return true; + } + override needsInitialize(): boolean { + return false; + } +} + +@injectable() +@injectFromHierarchy() +@v2Tool('python') +export class PythonInstallService extends V2ToolInstallService { + override readonly name = 'python'; + + override needsPrepare(): boolean { + return true; + } + override needsInitialize(): boolean { + return false; + } +} diff --git a/src/cli/tools/ruby/index.ts b/src/cli/tools/ruby/index.ts new file mode 100644 index 0000000000..e3769a2a78 --- /dev/null +++ b/src/cli/tools/ruby/index.ts @@ -0,0 +1,32 @@ +import { injectFromHierarchy, injectable } from 'inversify'; +import { V2ToolInstallService } from '../../install-tool/install-legacy-tool.service'; +import { V2ToolPrepareService } from '../../prepare-tool/prepare-legacy-tools.service'; +import { v2Tool } from '../../utils/v2-tool'; + +@injectable() +@injectFromHierarchy() +@v2Tool('ruby') +export class RubyPrepareService extends V2ToolPrepareService { + override readonly name = 'ruby'; + + override needsPrepare(): boolean { + return true; + } + override needsInitialize(): boolean { + return true; + } +} + +@injectable() +@injectFromHierarchy() +@v2Tool('ruby') +export class RubyInstallService extends V2ToolInstallService { + override readonly name = 'ruby'; + + override needsPrepare(): boolean { + return true; + } + override needsInitialize(): boolean { + return true; + } +} diff --git a/src/cli/tools/rust.ts b/src/cli/tools/rust.ts new file mode 100644 index 0000000000..d4401748d2 --- /dev/null +++ b/src/cli/tools/rust.ts @@ -0,0 +1,32 @@ +import { injectFromHierarchy, injectable } from 'inversify'; +import { V2ToolInstallService } from '../install-tool/install-legacy-tool.service'; +import { V2ToolPrepareService } from '../prepare-tool/prepare-legacy-tools.service'; +import { v2Tool } from '../utils/v2-tool'; + +@injectable() +@injectFromHierarchy() +@v2Tool('rust') +export class RustPrepareService extends V2ToolPrepareService { + override readonly name = 'rust'; + + override needsPrepare(): boolean { + return true; + } + override needsInitialize(): boolean { + return false; + } +} + +@injectable() +@injectFromHierarchy() +@v2Tool('rust') +export class RustInstallService extends V2ToolInstallService { + override readonly name = 'rust'; + + override needsPrepare(): boolean { + return true; + } + override needsInitialize(): boolean { + return false; + } +} diff --git a/src/cli/tools/swift.ts b/src/cli/tools/swift.ts new file mode 100644 index 0000000000..49f3e3f4eb --- /dev/null +++ b/src/cli/tools/swift.ts @@ -0,0 +1,32 @@ +import { injectFromHierarchy, injectable } from 'inversify'; +import { V2ToolInstallService } from '../install-tool/install-legacy-tool.service'; +import { V2ToolPrepareService } from '../prepare-tool/prepare-legacy-tools.service'; +import { v2Tool } from '../utils/v2-tool'; + +@injectable() +@injectFromHierarchy() +@v2Tool('swift') +export class SwiftPrepareService extends V2ToolPrepareService { + override readonly name = 'swift'; + + override needsPrepare(): boolean { + return true; + } + override needsInitialize(): boolean { + return true; + } +} + +@injectable() +@injectFromHierarchy() +@v2Tool('swift') +export class SwiftInstallService extends V2ToolInstallService { + override readonly name = 'swift'; + + override needsPrepare(): boolean { + return true; + } + override needsInitialize(): boolean { + return true; + } +} diff --git a/src/cli/tools/terraform.ts b/src/cli/tools/terraform.ts new file mode 100644 index 0000000000..7a434e4c38 --- /dev/null +++ b/src/cli/tools/terraform.ts @@ -0,0 +1,17 @@ +import { injectFromHierarchy, injectable } from 'inversify'; +import { V2ToolInstallService } from '../install-tool/install-legacy-tool.service'; +import { v2Tool } from '../utils/v2-tool'; + +@injectable() +@injectFromHierarchy() +@v2Tool('terraform') +export class TerraformInstallService extends V2ToolInstallService { + override readonly name = 'terraform'; + + override needsPrepare(): boolean { + return false; + } + override needsInitialize(): boolean { + return false; + } +} diff --git a/src/cli/tools/vendir.ts b/src/cli/tools/vendir.ts new file mode 100644 index 0000000000..b134ee7db0 --- /dev/null +++ b/src/cli/tools/vendir.ts @@ -0,0 +1,17 @@ +import { injectFromHierarchy, injectable } from 'inversify'; +import { V2ToolInstallService } from '../install-tool/install-legacy-tool.service'; +import { v2Tool } from '../utils/v2-tool'; + +@injectable() +@injectFromHierarchy() +@v2Tool('vendir') +export class VendirInstallService extends V2ToolInstallService { + override readonly name = 'vendir'; + + override needsPrepare(): boolean { + return false; + } + override needsInitialize(): boolean { + return false; + } +} diff --git a/src/cli/utils/types.ts b/src/cli/utils/types.ts index 3dce393824..0ba30a3db4 100644 --- a/src/cli/utils/types.ts +++ b/src/cli/utils/types.ts @@ -16,3 +16,5 @@ export const cliModes = [ export type CliMode = (typeof cliModes)[number]; export type Arch = 'arm64' | 'amd64'; + +export type ClazzDecorator = (target: V) => V | void; diff --git a/src/cli/utils/v2-tool.spec.ts b/src/cli/utils/v2-tool.spec.ts new file mode 100644 index 0000000000..6eecb91298 --- /dev/null +++ b/src/cli/utils/v2-tool.spec.ts @@ -0,0 +1,19 @@ +import { describe, expect, test } from 'vitest'; +import { isKnownV2Tool, isNotKnownV2Tool, v2Tool } from './v2-tool'; + +describe('cli/utils/v2-tool', () => { + @v2Tool('test-tool') + class TestTool { + readonly name = 'test-tool'; + } + + const tool = new TestTool().name; + + test('isKnownV2Tool', () => { + expect(isKnownV2Tool(tool)).toBe(true); + }); + + test('isNotKnownV2Tool', () => { + expect(isNotKnownV2Tool(tool)).toBe(false); + }); +}); diff --git a/src/cli/utils/v2-tool.ts b/src/cli/utils/v2-tool.ts new file mode 100644 index 0000000000..aa5d39425c --- /dev/null +++ b/src/cli/utils/v2-tool.ts @@ -0,0 +1,22 @@ +import type { ClazzDecorator } from './types'; + +const knownV2Tools = new Set(); + +export function isKnownV2Tool(tool: string): boolean { + return knownV2Tools.has(tool); +} +export function isNotKnownV2Tool(tool: string): boolean { + return !knownV2Tools.has(tool); +} + +interface V2ToolInstallerService { + prototype: { name: string }; +} + +export function v2Tool(tool: string): ClazzDecorator { + return (target: T): T | void => { + knownV2Tools.add(tool); + + return target; + }; +}