moonrepo / proto

A pluggable multi-language version manager.
https://moonrepo.dev/proto
MIT License
645 stars 31 forks source link

Canary version is always detected as has not been installed even though already installed #618

Open shanipribadi opened 3 hours ago

shanipribadi commented 3 hours ago

What version?

0.41.1

Which command?

proto install

What happened?

I tried installing deno and bun using the following commands

proto install deno canary
proto install bun canary
proto install --canary deno
proto install --canary bun

which successfully download and install the canary version

then running the tool using

PROTO_BUN_VERSION=canary bun
PROTO_DENO_VERSION=canary deno

always give the following error

Error: proto::tool::required

  × This project requires Bun canary, but this version has not been installed. Install it with proto install bun canary, or enable the auto-install setting to automatically install
  │ missing versions!

or

❯ PROTO_DENO_VERSION=canary deno
Error: proto::tool::required

  × This project requires Deno canary, but this version has not been installed. Install it with proto install deno canary, or enable the auto-install setting to automatically install
  │ missing versions!

enabling auto-install does allow the command to run, but only after installing it again, which is slowing things down and waste bandwidth.

Expectation is that once the canary version is installed, proto is able to resolve the installed tool and use it, and only reinstall the canary version when we requested it specifically with proto install --canary deno|bun

Trace logs?

❯ PROTO_LOG=trace PROTO_DEBUG_COMMAND=1 PROTO_DENO_VERSION=canary deno
[DEBUG 2024-09-27 07:48:09.993] proto  Running proto v0.41.1  bin="/home/shanipribadi/.proto/bin/proto" args=["run", "deno"] shim="deno" shim_bin="/home/shanipribadi/.proto/shims/deno" pid=358605
[TRACE 07:48:10.007] starbase::app  Running startup phase
[DEBUG 07:48:10.007] proto_core::proto  Creating proto environment, detecting store  store="/home/shanipribadi/.proto" home="/home/shanipribadi"
[TRACE 07:48:10.007] starbase::app  Running analyze phase
[DEBUG 07:48:10.007] proto::systems  Loading configuration in upwards-global mode  working_dir="/home/shanipribadi/git/proto"
[DEBUG 07:48:10.007] proto_core::proto_config  Loading .prototools  file="/home/shanipribadi/git/proto/.prototools"
[TRACE 07:48:10.007] starbase_utils::fs  Reading file  file="/home/shanipribadi/git/proto/.prototools"
[TRACE 07:48:10.007] schematic::config::loader  Loading partial configuration  config="ProtoConfig"
[TRACE 07:48:10.007] schematic::config::loader  Creating layer from source  config="ProtoConfig" source="<code>"
[TRACE 07:48:10.007] schematic::config::loader  Merging partial layers into a final result  config="ProtoConfig"
[DEBUG 07:48:10.007] proto_core::proto_config  Loading .prototools  file="/home/shanipribadi/.proto/.prototools"
[TRACE 07:48:10.007] starbase_utils::fs  Opening file  file="/home/shanipribadi/.proto/.prototools"
[TRACE 07:48:10.008] starbase_utils::fs_lock  Locking file  file="/home/shanipribadi/.proto/.prototools"
[TRACE 07:48:10.008] starbase_utils::fs_lock  Unlocking file  file="/home/shanipribadi/.proto/.prototools"
[TRACE 07:48:10.008] schematic::config::loader  Loading partial configuration  config="ProtoConfig"
[TRACE 07:48:10.008] schematic::config::loader  Creating layer from source  config="ProtoConfig" source="<code>"
[TRACE 07:48:10.008] schematic::config::loader  Merging partial layers into a final result  config="ProtoConfig"
[DEBUG 07:48:10.008] proto_core::proto_config  Merging loaded configs with global
[DEBUG 07:48:10.008] proto_core::proto_config  Merged 2 configs
[DEBUG 07:48:10.008] proto_core::proto_config  Merging loaded configs without global
[DEBUG 07:48:10.008] proto_core::proto_config  Merged 1 configs
[TRACE 07:48:10.008] starbase::app  Running execute phase
[DEBUG 07:48:10.008] proto_core::tool_loader  Finding a configured plugin  tool="deno"
[DEBUG 07:48:10.008] proto_core::tool_loader  Using a built-in plugin  plugin="https://github.com/moonrepo/tools/releases/download/deno_tool-v0.12.0/deno_tool.wasm"
[TRACE 07:48:10.009] warpgate::loader  Creating plugin loader  cache_dir="/home/shanipribadi/.proto/plugins"
[TRACE 07:48:10.009] warpgate::loader  Loading plugin deno  id="deno" locator="https://github.com/moonrepo/tools/releases/download/deno_tool-v0.12.0/deno_tool.wasm"
[TRACE 07:48:10.009] starbase_utils::fs  Reading file metadata  file="/home/shanipribadi/.proto/plugins/deno-0c576e3fa327e68fc1896e3eb15866c63f35d549fc5fc64ca1f22c271c1c2a9b.wasm"
[TRACE 07:48:10.009] warpgate::loader  Plugin already downloaded and cached  id="deno" path="/home/shanipribadi/.proto/plugins/deno-0c576e3fa327e68fc1896e3eb15866c63f35d549fc5fc64ca1f22c271c1c2a9b.wasm"
[DEBUG 07:48:10.009] proto_core::tool_loader  Loading WASM plugin  source="/home/shanipribadi/.proto/plugins/deno-0c576e3fa327e68fc1896e3eb15866c63f35d549fc5fc64ca1f22c271c1c2a9b.wasm"
[TRACE 07:48:10.012] warpgate::plugin  Storing plugin identifier  id="deno"
[TRACE 07:48:10.012] warpgate::plugin  Storing host environment  id="deno" env={"arch":"x64","libc":"gnu","os":"linux","home_dir":{"path":"/userhome/","virtual_prefix":"/userhome","real_prefix":"/home/shanipribadi"}}
[DEBUG 07:48:10.012] proto_core::tool  Creating tool deno and instantiating plugin
[DEBUG 07:48:10.012] warpgate::client  Creating HTTP client
[DEBUG 07:48:10.018] warpgate::client  Created HTTP client
[TRACE 07:48:10.018] warpgate::plugin  Creating plugin container  id="deno"
[TRACE 07:48:10.031] warpgate::plugin  Created plugin container  id="deno" plugin="5458864e-5738-44ad-84b0-97589df7749b"
[DEBUG 07:48:10.031] proto_core::tool  Created tool deno and its WASM runtime
[TRACE 07:48:10.031] warpgate::plugin  Calling guest function register_tool  id="deno" plugin="5458864e-5738-44ad-84b0-97589df7749b" input={"id":"deno"}
[TRACE 07:48:10.032] warpgate::plugin  Called guest function register_tool  id="deno" plugin="5458864e-5738-44ad-84b0-97589df7749b" output={"config_schema":{"name":"DenoPluginConfig","ty":{"type":"Struct","fields":{"dist-url":{"schema":{"ty":{"type":"String"}},"hidden":false,"nullable":false,"optional":true,"read_only":false,"write_only":false}},"partial":false}},"inventory":{},"name":"Deno","plugin_version":"0.12.0","self_upgrade_commands":["upgrade"],"type":"Language"}
[DEBUG 07:48:10.032] proto_core::tool_manifest  Loading manifest.json  file="/home/shanipribadi/.proto/tools/deno/manifest.json"
[TRACE 07:48:10.032] starbase_utils::fs  Opening file  file="/home/shanipribadi/.proto/tools/deno/manifest.json"
[TRACE 07:48:10.032] starbase_utils::fs_lock  Locking file  file="/home/shanipribadi/.proto/tools/deno/manifest.json"
[TRACE 07:48:10.032] starbase_utils::fs_lock  Unlocking file  file="/home/shanipribadi/.proto/tools/deno/manifest.json"
[DEBUG 07:48:10.032] proto_core::version_detector  Detected version from environment variable  tool="deno" env_var="PROTO_DENO_VERSION" version="canary"
[DEBUG 07:48:10.032] proto_core::flow::resolve  Resolving a semantic version or alias  tool="deno" initial_version="canary"
[DEBUG 07:48:10.032] proto_core::flow::resolve  Resolved to canary (without validation)  tool="deno" version="canary"
[DEBUG 07:48:10.032] proto_core::flow::setup  Checking if tool is installed  tool="deno" install_dir="/home/shanipribadi/.proto/tools/deno/canary"
[DEBUG 07:48:10.032] proto_core::flow::setup  Tool has not been installed  tool="deno"
[TRACE 07:48:10.033] starbase::app  Running shutdown phase (because another phase failed)
Error: proto::tool::required

  × This project requires Deno canary, but this version has not been installed. Install it with proto install deno canary, or enable the auto-install setting to automatically install
  │ missing versions!

Operating system?

Linux

Architecture?

x64

shanipribadi commented 3 hours ago

Looking at the code https://github.com/moonrepo/proto/blob/d7c38b19037dabc6d69d5c009b6cc34e64d5c358/crates/core/src/flow/install.rs#L46

    pub fn is_installed(&self) -> bool {
        let dir = self.get_product_dir();

        self.version
            .as_ref()
            // Canary can be overwritten so treat as not-installed
            .is_some_and(|v| {
                !v.is_latest()
                    && !v.is_canary()
                    && self.inventory.manifest.installed_versions.contains(v)
            })
            && dir.exists()
            && !fs::is_dir_locked(dir)
    }

The comment seem to suggest that this is an intentional behaviour,

and right now proto will not attempt to reinstall/overwrite if we run proto install some_tool some_version once it's been installed.

I think having a

proto install --force some_tool some_version

command line argument to force reinstallation of an installed tool, and removing the !v.is_canary() check on flow::install, will make using canary with proto more convenient.

Or alternatively just have a special case where proto install tool with version as canary still reinstall the tool, but on using the tool from the shim it doesn't reinstall again if it is already there, so that we don't need the --force flag.