Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pkl + plz: multi-directory genrule outs #3123

Open
sean- opened this issue Apr 9, 2024 · 2 comments
Open

pkl + plz: multi-directory genrule outs #3123

sean- opened this issue Apr 9, 2024 · 2 comments

Comments

@sean-
Copy link
Contributor

sean- commented Apr 9, 2024

Howdy. I've started tinkering with pkl and am pretty pleased with it (no pun intended), but am running into a few quirks integrating it into plz. Using the following example.pkl file:

@go.Package { name = "github.com/example/mycmd/pkl" }
module example.mycmd.Config
import "package://pkg.pkl-lang.org/pkl-go/[email protected]#/go.pkl"

typealias LogLevel = "trace"|"debug"|"info"|"warn"|"error"
log_level: LogLevel = "trace"

foo_param: String

To generate the .go files by hand, you run:

pkl-gen-go --base-path=github.com/example/mycmd/pkl example.pkl

which emits the following files:

Config.pkl.go
init.pkl.go
loglevel/LogLevel.pkl.go

The problem is loglevel/LogLevel.pkl.go and my genrule() command. The BUILD.plz that I'm using now is:

# mycmd/pkl/BUILD.plz
go_library(
    name = "pkl",
    srcs = [
        ":gen-go",
    ],
    visibility = ["//mycmd/..."],
    deps = [
        ":gen-go",
        "//mycmd/pkl/loglevel",
    ],
)

PKL_FILENAME = "example.pkl"

genrule(
    name = "gen-go",
    srcs = [
        PKL_FILENAME,
    ],
    outs = [
        "Config.pkl.go",
        "init.pkl.go",
    ],
    # FIXME(seanc@): Replace env HOME garbage with
    # `--cache-dir=$(plz_out)/pkl-gen-go/v0.6.0` once it becomes available.
    cmd = "env HOME=$(echo $HOME | perl -p -e 's#plz-out(.*)#plz-out/.pkl-gen-go/v0.6.0#') pkl-gen-go --base-path=github.com/example/mycmd/resources/pkl/mycmd resources/pkl/mycmd/{}".format(PKL_FILENAME),
    exit_on_error = True,
    labels = ["codegen"],
    optional_outs = [
        PKL_FILENAME,
    ],
    tools = ["pkl-gen-go"],
)

and:

# mycmd/pkl/loglevel/BUILD.plz
go_library(
    name = "loglevel",
    srcs = [
        "LogLevel.pkl.go",
    ],
    visibility = ["//mycmd/pkl/..."],
    deps = [
        "//third_party/go:pkl",
    ],
)

If I add loglevel/LogLevel.pkl.go to outs, I get the following error:

$ plz build
Build stopped after 340ms. 1 target failed:
    //resources/pkl/optimizer:gen-go
trying to output file resources/pkl/optimizer/loglevel/LogLevel.pkl.go, but that directory belongs to another package (resources/pkl/optimizer/loglevel)

Two One question:

  1. How do I copy loglevel/LogLevel.pkl.go so I don't need a random build file for every subdirectory? Ideally, outs would include loglevel/LogLevel.pkl.go and it would be copied to loglevel/LogLevel.pkl.go, but that doesn't appear to be the case.
    2. My editor's language server doesn't like the missing *.pkl..go files, so I have to manually generate the .pkl.go files in mycmd/pkl/. Is there a way to copy or have symlinks created for the generated files? Something like mycmd/pkl/Config.pkl.go -> ./plz-out/go/src/mycmd/pkl/Config.pkl.go? Protobuf has a similar problem, iirc.
@sean-
Copy link
Contributor Author

sean- commented Apr 18, 2024

Regarding the second question, I'm going to answer my own question and post this here for future eyeballs. I just discovered the:

; .plzconfig
[Build]
LinkGeneratedSources = soft
UpdateGitignore = true

options and the codegen label, which generate the right symlinks automatically!

# BUILD.plz:
genrule(
    name = "gen-go",
    srcs = [
        PKL_FILENAME,
    ],
    outs = [
        "Config.pkl.go",
        "init.pkl.go",
    ],
    # FIXME(seanc@): Replace env HOME garbage with
    # `--cache-dir=$(plz_out)/pkl-gen-go/v0.6.0` once it becomes available.
    cmd = "env HOME=$(echo $HOME | perl -p -e 's#plz-out(.*)#plz-out/.pkl-gen-go/v0.6.0#') pkl-gen-go --base-path=github.com/example/mycmd/resources/pkl/mycmd resources/pkl/mycmd/{}".format(PKL_FILENAME),
    exit_on_error = True,
    labels = ["codegen"],
    optional_outs = [
        PKL_FILENAME,
    ],
    tools = ["pkl-gen-go"],
)
➜ ll resources/pkl/optimizer
total 40
-rw-r--r--  1 seanc  staff    10 Apr 17 22:29 .gitignore
-rw-r--r--  1 seanc  staff  1617 Apr 18 08:48 BUILD.plz
lrwxr-xr-x  1 seanc  staff    80 Apr 18 08:49 Config.pkl.go -> /Users/seanc/src/example/mycmd/plz-out/gen/resources/pkl/mycmd/Config.pkl.go
lrwxr-xr-x  1 seanc  staff    78 Apr 18 08:49 init.pkl.go -> /Users/seanc/src/example/mycmd/plz-out/gen/resources/pkl/mycmd/init.pkl.go
drwxr-xr-x  5 seanc  staff   160 Apr 17 22:29 loglevel
-rw-r--r--  1 seanc  staff  1972 Apr 17 22:29 mycmd.pkl

@sean- sean- changed the title pkl + plz pkl + plz: multi-directory genrule outs Apr 18, 2024
@Tatskaari
Copy link
Member

I might suggest wrapping go_library() for your project:

_orig_go_lib = go_library

def go_library(name, src, pki_src, etc...):
    if not pki_srcs:
        return _orig_go_lib(...)
    else srcs += [genrule(...)] # the genrule from above
    return _orig_go_lib(...)

alternatively you can call this pki_go_library or something.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants