diff --git a/cmd/resolve.go b/cmd/resolve.go index 24b651f..2a52cde 100644 --- a/cmd/resolve.go +++ b/cmd/resolve.go @@ -2,10 +2,14 @@ package cmd import ( "fmt" + "maps" "net/url" + "path/filepath" + "regexp" "strings" "github.com/Masterminds/semver/v3" + "github.com/apple/pkl-go/pkl" "github.com/spf13/cobra" "hpkl.io/hpkl/pkg/app" "hpkl.io/hpkl/pkg/pklutils" @@ -42,22 +46,37 @@ func NewResolveCmd(appConfig *app.AppConfig) *cobra.Command { return cmd } -func Resolve(appConfig *app.AppConfig) error { - resolver, err := app.NewResolver(appConfig) - sugar := appConfig.Logger.Sugar() - project := appConfig.Project() +func CollectDependencies(dependecies *pkl.ProjectDependencies, include bool) map[string]app.Dependency { + result := make(map[string]app.Dependency) - deps := project.Dependencies() + for _, dep := range dependecies.LocalDependencies { + remote := dep.Dependencies.RemoteDependencies - sugar.Infow("got", "config", appConfig.Project()) + for n, remoteDep := range remote { + result[remoteDep.PackageUri] = app.Dependency{Uri: remoteDep.PackageUri, Name: n, Include: false} + } - dependencies := make(map[string]app.Dependency, len(deps.RemoteDependencies)) + for _, localDep := range dep.Dependencies.LocalDependencies { + inner := CollectDependencies(localDep.Dependencies, false) + maps.Copy(result, inner) + } + } - for n, d := range appConfig.Project().Dependencies().RemoteDependencies { - dependencies[n] = app.Dependency{Uri: d.PackageUri} + for n, dep := range dependecies.RemoteDependencies { + result[dep.PackageUri] = app.Dependency{Uri: dep.PackageUri, Name: n, Include: include} } - resolvedDependencies, err := resolver.Resolve(dependencies) + return result +} + +func Resolve(appConfig *app.AppConfig) error { + resolver, err := app.NewResolver(appConfig) + // sugar := appConfig.Logger.Sugar() + project := appConfig.Project() + + remoteDependencies := CollectDependencies(project.Dependencies(), true) + + resolvedDependencies, err := resolver.Resolve(remoteDependencies) if err != nil { return err @@ -69,34 +88,71 @@ func Resolve(appConfig *app.AppConfig) error { return err } + dependencies := make(map[string]*pklutils.ResolvedDependency, len(resolvedDependencies)+len(project.Dependencies().LocalDependencies)) + projectDeps := pklutils.ProjectDeps{ SchemaVersion: 1, - ResolvedDependencies: make(map[string]*pklutils.ResolvedDependency, len(resolvedDependencies)), + ResolvedDependencies: dependencies, } for depUri, dep := range resolvedDependencies { + if dep.Include { + baseUri, err := url.Parse(depUri) + + if err != nil { + return err + } + + mapUri := *baseUri + mapUri.Path = strings.Replace(mapUri.Path, fmt.Sprintf("@%s", dep.Version), "", 1) - baseUri, err := url.Parse(depUri) + baseUri.Scheme = "projectpackage" + versionParsed := semver.MustParse(dep.Version) + majorVersion := fmt.Sprintf("@%x", versionParsed.Major()) + mapUri.Path += majorVersion + resolvedDependency := pklutils.ResolvedDependency{ + DependencyType: "remote", + Uri: baseUri.String(), + Checksums: map[string]string{"sha256": dep.PackageZipChecksums.Sha256}, + } + + projectDeps.ResolvedDependencies[mapUri.String()] = &resolvedDependency + } + } + + projectFileUri, err := url.Parse(project.ProjectFileUri) + projectFilePath := strings.Replace(projectFileUri.Path, "/PklProject", "", 1) + + versionRegex := regexp.MustCompile("^(.*)\\@(\\d+)\\.\\d.\\d$") + + for _, dep := range project.Dependencies().LocalDependencies { + + projectUri, err := url.Parse(dep.PackageUri) if err != nil { return err } + projectUri.Scheme = "projectpackage" - mapUri := *baseUri - mapUri.Path = strings.Replace(mapUri.Path, fmt.Sprintf("@%s", dep.Version), "", 1) + mapUri := versionRegex.ReplaceAllString(dep.PackageUri, "$1@$2") - baseUri.Scheme = "projectpackage" - versionParsed := semver.MustParse(dep.Version) - majorVersion := fmt.Sprintf("@%x", versionParsed.Major()) - mapUri.Path += majorVersion + depProjectFileUri, err := url.Parse(dep.ProjectFileUri) + if err != nil { + return err + } - resolvedDependency := pklutils.ResolvedDependency{ - DependencyType: "remote", - Uri: baseUri.String(), - Checksums: map[string]string{"sha256": dep.PackageZipChecksums.Sha256}, + rel, err := filepath.Rel(projectFilePath, strings.Replace(depProjectFileUri.Path, "/PklProject", "", 1)) + + if err != nil { + return err } - projectDeps.ResolvedDependencies[mapUri.String()] = &resolvedDependency + resolvedDependency := pklutils.ResolvedDependency{ + DependencyType: "local", + Path: rel, + Uri: projectUri.String(), + } + projectDeps.ResolvedDependencies[mapUri] = &resolvedDependency } err = pklutils.PklWriteDeps(appConfig.WorkingDir, &projectDeps) diff --git a/go.mod b/go.mod index 25b17c4..07c12f8 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.22.3 require ( github.com/Masterminds/semver/v3 v3.2.1 - github.com/apple/pkl-go v0.7.0 + github.com/apple/pkl-go v0.8.0 github.com/containerd/containerd v1.7.17 github.com/helmfile/vals v0.37.1 github.com/opencontainers/image-spec v1.1.0 diff --git a/go.sum b/go.sum index 0cdf20d..7838b50 100644 --- a/go.sum +++ b/go.sum @@ -139,6 +139,8 @@ github.com/apple/pkl-go v0.6.0 h1:v7y9GqGanyUoa5NaYA/gjrlNblWY3g0F+5/5iheHR0o= github.com/apple/pkl-go v0.6.0/go.mod h1:xr5s9RAJdlEHU2efRenGiWkE0gssttQs0LE1HyBY2LQ= github.com/apple/pkl-go v0.7.0 h1:tn21SeH8QN/hdWsUg+ys/ItQem5WM9WuvjAwql3Gm14= github.com/apple/pkl-go v0.7.0/go.mod h1:5Hwil5tyZGrOekh7JXLZJvIAcGHb4gT19lnv4WEiKeI= +github.com/apple/pkl-go v0.8.0 h1:GRcBvFWeXjT9rc7A5gHK89qrel2wGZ3/a7ge4rPlT5M= +github.com/apple/pkl-go v0.8.0/go.mod h1:5Hwil5tyZGrOekh7JXLZJvIAcGHb4gT19lnv4WEiKeI= github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de h1:FxWPpzIjnTlhPwqqXc4/vE0f7GvRjuAsbW+HOIe8KnA= github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de/go.mod h1:DCaWoUhZrYW9p1lxo/cm8EmUOOzAPSEZNGF2DK1dJgw= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= diff --git a/pkg/app/resolver.go b/pkg/app/resolver.go index 07b3bb9..87dcdf3 100644 --- a/pkg/app/resolver.go +++ b/pkg/app/resolver.go @@ -26,6 +26,8 @@ type ( Dependency struct { Uri string `json:"uri"` Checksums *Checksums `json:"checksums"` + Include bool `json:"include"` + Name string `json:"name"` } Metadata struct { @@ -38,6 +40,7 @@ type ( Dependencies map[string]Dependency `json:"dependencies"` ResolverType ResolverType `json:"-"` PlainHttp bool `json:"-"` + Include bool `json:"-"` } Resolver struct { @@ -109,8 +112,9 @@ func (r *Resolver) Resolve(dependencies map[string]Dependency) (map[string]*Meta logger := r.appConfig.Logger.Sugar() - for dependencyName, dependency := range dependencies { + for _, dependency := range dependencies { metadata, ok := r.cache[dependency.Uri] + dependencyName := dependency.Name if !ok { var resolver DependencyResolver @@ -125,6 +129,7 @@ func (r *Resolver) Resolve(dependencies map[string]Dependency) (map[string]*Meta plain := strings.Contains(dependencyName, ".plain") metadata, err := resolver.ResolveMetadata(dependency.Uri, plain) + metadata.Include = dependency.Include if err != nil { logger.Errorw("Metadata resolving error", "name", dependencyName, "value", dependency) diff --git a/pkg/pklutils/deps.go b/pkg/pklutils/deps.go index cd97de8..b81eef1 100644 --- a/pkg/pklutils/deps.go +++ b/pkg/pklutils/deps.go @@ -11,8 +11,9 @@ import ( type ResolvedDependency struct { DependencyType string `json:"type"` - Uri string `json:"uri"` - Checksums map[string]string `json:"checksums"` + Uri string `json:"uri,omitempty"` + Path string `json:"path,omitempty"` + Checksums map[string]string `json:"checksums,omitempty"` } type ProjectDeps struct {