apple / pkl

A configuration as code language with rich validation and tooling.
https://pkl-lang.org
Apache License 2.0
9.85k stars 258 forks source link

Package aliases #353

Open ericzbeard opened 3 months ago

ericzbeard commented 3 months ago

It would be nice if we could alias package imports.

What I do now:

amends "package://github.com/aws-cloudformation/rain/releases/download/v1.8.2-alpha1/cloudformation@1.8.2-alpha1#/template.pkl"
import "package://github.com/aws-cloudformation/rain/releases/download/v1.8.2-alpha1/cloudformation@1.8.2-alpha1#/aws/s3/bucket.pkl"

Description = "testing imports"
Resources {
    ["Foo"] = new {
        Type = "AWS::S3::Bucket"
    }
    ["Bar"] = new bucket.Bucket {
        BucketName = "my-bucket-name"
    }
}

What I would like to do:

use "package://github.com/aws-cloudformation/rain/releases/download/v1.8.2-alpha1/cloudformation@1.8.2-alpha1" as cfn

amends "cfn/template.pkl"
import "cfn/aws/s3/bucket.pkl"

or

amends cfn.template
import cfn.aws.s3.bucket

...
bioball commented 3 months ago

You can do this by declaring them as project dependencies. See docs here: https://pkl-lang.org/main/current/language-reference/index.html#project-dependencies

By the way: package URIs should only have the version once in their path, after the last @. This is because Pkl uses the base path to determine what the name of the package is. It then uses the package name to resolve dependencies.

If you are publishing packages as GitHub releases, a path you can take is:

  1. Create a tag and release called <name>@<version> to hold the package assets
  2. Use package://pkg.pkl-lang.org/github.com/<org>/<repo>/<name>@<version> as the package URI. This is a redirect server that redirects back to github.com.

For example, here's how we manage the releases for pkl-go: https://github.com/apple/pkl-go/releases. We create two GitHub releases for every release; one as the Go release, and one as the Pkl package release.

ericzbeard commented 3 months ago

I struggled with figuring out the right format for the PklProject file. I think I'm complicating the issue by releasing this package as a part of a larger repo, so it's not the only thing being released. See the assets in this release. Maybe it would be better to put this in a repo by itself, but it makes development a bit easier having it all together.

ericzbeard commented 3 months ago

And thank you, the code is much cleaner now!

amends "@cfn/template.pkl"
import "@cfn/aws/s3/bucket.pkl"

Description = "testing imports"
Resources {
    ["Foo"] = new {
        Type = "AWS::S3::Bucket"
    }
    ["Bar"] = new bucket.Bucket {
        BucketName = "my-bucket-name"
    }
}
bioball commented 3 months ago

Something else you can do here is to deploy these assets elsewhere, e.g. to an S3 bucket (and then maybe CNAME'd so the url is shorter). Pkl doesn't actually care where these packages come from, only that they are accessible via HTTPS.

Some notes about the PklProject:

amends "pkl:Project"

package {
  name = "cloudformation"
  baseUri = "package://example.com/\(name)"
  version = read("path/to/some/version.txt").text.trim()
  packageZipUrl = "https://github.com/aws-cloudformation/rain/releases/download/v\(version)/cloudformation@\(version).zip"
  sourceCode = "https://github.com/aws-cloudformation/rain"
  sourceCodeUrlScheme = "\(sourceCode)/blob/v\(version)/pkl%{path}#L%{line}-%{endLine}"
}