aquaproj / aqua

Declarative CLI Version manager written in Go. Support Lazy Install, Registry, and continuous update with Renovate. CLI version is switched seamlessly
https://aquaproj.github.io
812 stars 34 forks source link

Use local registry from any of the files in the configuration path #3016

Open W1M0R opened 1 month ago

W1M0R commented 1 month ago

Feature Overview

The configuration search order is specified here: https://aquaproj.github.io/docs/reference/config/#configuration-file-path

When I execute aqua i -l, I get a registry isn't found error when the aqua.yaml specifies a package that uses a local registry. The local registry has already been declared in the top-most aqua.yaml file, but it is not being detected by the command. Ideally, since aqua knows about the list of configuration files (via aqua info), instead of registry isn't found, it should try and find the registry in one of the other configuration files (i.e. the root configuration), and then try again with the installation.

Consider the following monorepo setup:

❯ cd src/proj1
❯ aqua info
{
  "version": "2.30.0",
  "commit_hash": "22e2139d9200c1619914bafed680db2cfe39a354",
  "os": "windows",
  "arch": "amd64",
  "pwd": "C:\\Users\\(USER)\\monorepo\\src\\proj1",
  "root_dir": "C:\\Users\\(USER)\\AppData\\Local\\aquaproj-aqua",
  "env": {
    "AQUA_DISABLE_POLICY": "true",
    "AQUA_PROGRESS_BAR": "true",
    "AQUA_ROOT_DIR": "C:\\Users\\(USER)\\AppData\\Local\\aquaproj-aqua"
  },
  "config_files": [
    {
      "path": "C:\\Users\\(USER)\\monorepo\\src\\proj1\\.aqua\\aqua.yaml"
    },
    {
      "path": "C:\\Users\\(USER)\\monorepo\\.aqua\\aqua.yaml"
    }
  ]
}

If I am in proj1 and run the aqua i -l command, it should create shims for all packages found in the list of configuration files.

The monorepo/.aqua/aqua.yaml file looks like this:

---
# aqua - Declarative CLI Version Manager
# https://aquaproj.github.io/
# checksum:
#   enabled: true
#   require_checksum: true
#   supported_envs:
#   - all
registries:
- type: standard
  ref: v4.204.0  # renovate: depName=aquaproj/aqua-registry
- name: local
  type: local
  path: aqua-registry.yaml # Relative path from aqua.yaml
packages:
- name: github.com/stefanlogue/meteor@v0.22.0
  registry: local

The monorepo/.aqua/aqua-registry.yaml file looks like this:

packages:
  - type: go_install
    path: github.com/stefanlogue/meteor
    description: A highly configurable CLI tool for writing conventional commits
    version_source: github_tag
  - type: go_install
    path: github.com/wailsapp/wails/v2/cmd/wails
    description: Create beautiful applications using Go
    version_source: github_tag

The monorepo/src/proj1/.aqua/aqua.yaml looks like this:

---
# aqua - Declarative CLI Version Manager
# https://aquaproj.github.io/
# checksum:
#   enabled: true
#   require_checksum: true
#   supported_envs:
#   - all
registries:
- type: standard
  ref: v4.204.0  # renovate: depName=aquaproj/aqua-registry
packages:
- name: github.com/wailsapp/wails/v2/cmd/wails@v2.9.1
  registry: local

An aqua i -l in proj1 should result in two packages being installed: meteor and wails. However, the following error occurs:

❯ cd src/proj1
❯ aqua i -l
ERRO[0000] install the package                           aqua_version=2.30.0 env=windows/amd64 error="registry isn't found" package_name=github.com/wailsapp/wails/v2/cmd/wails package_version=v2.9.1 program=aqua registry=local

Why is the feature needed?

In a monorepo, it would make sense to have a local registry specified once in the root of the monorepo, that can be used by other projects in the monorepo. The workarounds are good enough, but I think the experience can be improved.

Workaround

A few workarounds exist:

  1. Use a build step to copy the monorepo registry file to $HOME and reference it explicitly
  2. Use a build step to copy the monorepo registry file to the subproject and reference it explicitly
  3. Reference the monorepo registry file explicitly using a relative path

Example aqua.yaml:

---
# aqua - Declarative CLI Version Manager
# https://aquaproj.github.io/
# checksum:
#   enabled: true
#   require_checksum: true
#   supported_envs:
#   - all
registries:
- type: standard
  ref: v4.204.0  # renovate: depName=aquaproj/aqua-registry
- name: local
  type: local
  path: $HOME/aqua-registry-monorepo.yaml # option 1
  path: aqua-registry-copy.yaml # option 2
  path: ../../../aqua-registry.yaml # option 3
packages:
...

Example Code

$ aqua i -l

Configuration

---
# aqua - Declarative CLI Version Manager
# https://aquaproj.github.io/
# checksum:
#   enabled: true
#   require_checksum: true
#   supported_envs:
#   - all
registries:
- type: standard
  ref: v4.204.0  # renovate: depName=aquaproj/aqua-registry
packages:
- name: github.com/wailsapp/wails/v2/cmd/wails@v2.9.1
  registry: local # the local registry is already declared in the root aqua yaml file

Note

No response

suzuki-shunsuke commented 1 month ago

Thank you for your proposal.

it should try and find the registry in one of the other configuration files

I disagree with this idea. aqua.yaml shouldn't depend on other files implicitly.

I recommend the workaround 3. The drawback of the workaround 2 is you need to add copied registry to a policy file and run aqua policy allow.

About policy, please see https://aquaproj.github.io/docs/guides/policy-as-code

But the drawback of the workaround 3 is the relative path depends on the location of aqua.yaml.

  path: ../../../aqua-registry.yaml # option 3

So my idea is to support a template variable like ${{ GitRootDir }} in path.

  path: ${{ GitRootDir }}/aqua-registry.yaml

This is useful when multiple aqua.yaml share a local registry in a Monorepo.

W1M0R commented 1 month ago

Ah, yes, I like your idea, that would be great.

I think I misunderstood the purpose of the configuration file list. I now realize it is only intended for inheriting packages, not so much for inheriting configuration.