openllb / hlb

A developer-first language to build and test any software efficiently
https://openllb.github.io/hlb/
Apache License 2.0
112 stars 12 forks source link

Resolve import rel paths correctly in both local and remote imports #309

Closed hinshun closed 2 years ago

hinshun commented 2 years ago

Broken somewhat by #290

Even before that PR, relative paths in remote imports was still broken.

Regression

What was broken is best illustrated by an example:

# ./build.hlb
import other from "./sub/other.hlb"
fs default() {
    other.build
}
# ./sub/other.hlb
import common from "../common.hlb"
export build
fs build() {
    common.build
}

The content of ./common.hlb doesn't matter.

When evaluating the line import common from "../common.hlb" we need to resolve ../common.hlb relative to the ./sub directory, this was fixed in this PR.

However, for remote imports this wasn't fixed yet.

Context for remote imports

Remote imports need their filenames represented by some kind of unique path that is also understandable by humans. For this, the input digest is combined with the module path that imported it like so:

# ./build.hlb
import other from image("other.hlb")
# image("other.hlb")/module.hlb
export build
fs build() { ... }

Then the path will be computed as build.hlb#other/module.hlb. This is used for source mapping, and other things.

If image("other.hlb") imported image("another.hlb") then its path would be build.hlb#other/module.hlb#another/module.hlb.

However, when resolving relative directories for the purposes of opening files in this buildkit ref, it's true module directory is / the rootfs of the image. The PR introduces codegen.WithImportPath to capture this special prefix and trim it when computing codegen.ModuleDir(ctx).