lalbuild / lal

A strict, language-agnostic build system and dependency manager
MIT License
4 stars 1 forks source link

lal: update error: No such file or directory (os error 2) #39

Closed bencord0 closed 4 years ago

bencord0 commented 4 years ago

lal update panics if the backend does not have an artifact for all supportedEnvironments.

note: using LocalBackend. also, it's fine if you specify the version of component.

Steps to reproduce:

$ mkdir panic1 panic2

$ cd panic1
$ lal init default
$ echo -e '#!/bin/sh\ntouch OUTPUT/panic.txt' > .lal/BUILD
$ chmod +x .lal/BUILD

# build and publish to two environments,
# it doesn't matter what the supportedEnvironments is set
$ lal build --release --with-version=1
$ lal publish panic1

# create a component that depends on panic1, but supports an environment that panic1 is not published to
$ cd ../panic2
$ lal init default
$ cat <<EOF > .lal/manifest.json
{
  "name": "panic2",
  "environment": "default",
  "supportedEnvironments": [
    "default", "alpine"
  ],
  "components": {
    "panic2": {
      "defaultConfig": "release",
      "configurations": [
        "release"
      ]
    }
  },
  "dependencies": {},
  "devDependencies": {}
}
EOF

lal update now panics

$ lal update panic1
lal::update: Fetch default panic1
lal::storage::download: Last versions for panic1 in default env is {1}

lal: update error: No such file or directory (os error 2)

It's fine if you specify the version

$ lal update panic1=1
lal::update: Fetch default panic1=1
lal::storage::local: get_component_info: panic1 Some(1) default

Fetching from the unpublished environment also panics (as expected).

$ lal -e alpine update panic1=1
lal::update: Fetch alpine panic1=1
lal::storage::local: get_component_info: panic1 Some(1) alpine
lal::update: Failed to update panic1 (No such file or directory (os error 2))

lal: update error: No such file or directory (os error 2)

Publishing to both environments (listed in panic2's supportedEnvironments), resolves the issue.


$ cd ../panic1
$ lal -e alpine build --release --with-version=1
$ lal publish panic1

$ cd ../panic2
$ lal update panic1
lal::update: Fetch default panic1
lal::storage::download: Last versions for panic1 in default env is {1}
lal::storage::download: Last versions for panic1 in alpine env is {1}
lal::update: Fetch default panic1=1
lal::storage::local: get_component_info: panic1 Some(1) default
bencord0 commented 4 years ago

Should lal update just fetch from the current environment, which is the behaviour when you do specify the version?

What else explodes if you don't have components for all supported environments?

clux commented 4 years ago

The panic is definitely bad error handling. It should probably bail with an error message if the component does not exist in the environment you are in.

We only loosely assume that you have components built in the same environment. You're not meant to mix and match. It should be perfectly fine to have disjoint dependency trees used in separate projects.

bencord0 commented 4 years ago

What are your thoughts if I just ignore supportedEnvironments when update()ing?

https://github.com/lalbuild/lal/blob/master/src/update.rs#L57

I'm thinking we can just check against the current environment, and not bother checking the other environments.

We should still gracefully error if the current environment doesn't have the dependency published.

I can hack a workaround for now...

@@ -53,11 +55,15 @@ pub fn update<T: CachedBackend + ?Sized>(

             // First, since this potentially goes in the manifest
             // make sure the version is found for all supported environments:
-            let ver = backend
-                .get_latest_supported_versions(comp, manifest.supportedEnvironments.clone())?
+            let supported_versions = backend
+                .get_latest_supported_versions(comp, vec![env.to_string()])?;
+
+            let ver = supported_versions
                 .into_iter()
                 .max()
$ cargo run --manifest-path ../../Cargo.toml update panic1
   Compiling lal v3.9.0 (/home/bencord0/src/lal)
    Finished dev [unoptimized + debuginfo] target(s) in 4.53s
     Running `/home/bencord0/src/lal/target/debug/lal update panic1`
lal::update: Fetch default panic1
lal::storage::download: Last versions for panic1 in default env is {1}
lal::update: Fetch default panic1=1
lal::storage::local: get_component_info: panic1 Some(1) default

Otherwise, I think I can rework this entire section to be a bit simpler if update doesn't have to concern itself with other environments.