From c6e67a8452a8a6f4c90351077670734487d5c10b Mon Sep 17 00:00:00 2001 From: Will Jones Date: Thu, 19 Dec 2024 15:11:08 +0000 Subject: [PATCH] Centralize SDK generation logic Presently, the majority of Java code generation is driven by the `pulumi-java-gen` binary, since Java usage began before we had time to implement the `Generate*` family of language host gRPC methods. Recently, these gRPC methods were implemented, to support (among other things) conformance testing. Unfortunately, while both routes end in `pkg/codegen/java`'s `Generate*` functions, each had accumulated its own special "setup logic" ahead of the call into `pkg/codegen`. This commit attempts to sort this out, pushing all that logic into `pkg/codegen` so that both routes behave identically. As a result of this, we should be able to deprecate `pulumi-java-gen` more safely when the time comes, remove direct build-time dependencies on `pulumi-java` from `pulumi/pulumi` and fix some issues that have arisen as a result of the historic differences, such as #1404 (which looks like it may have already been fixed, but this should cement it). Closes #1404 --- pkg/cmd/pulumi-language-java/main.go | 38 +++++++++++++--------------- pkg/codegen/java/gen.go | 20 +++++++++++++++ pkg/codegen/java/package_info.go | 12 +++++++++ 3 files changed, 50 insertions(+), 20 deletions(-) diff --git a/pkg/cmd/pulumi-language-java/main.go b/pkg/cmd/pulumi-language-java/main.go index ade29127e1e..45dbe6da823 100644 --- a/pkg/cmd/pulumi-language-java/main.go +++ b/pkg/cmd/pulumi-language-java/main.go @@ -714,26 +714,17 @@ func (host *javaLanguageHost) GeneratePackage( }, nil } - if pkg.Description == "" { - pkg.Description = " " - } - if pkg.Repository == "" { - pkg.Repository = "https://example.com" - } - - // Presently, we only support generating Java SDKs which use Gradle as a build system. Specify that here, as well as - // the set of dependencies that all generated SDKs rely on. - pkgInfo := codegen.PackageInfo{ - BuildFiles: "gradle", - Dependencies: map[string]string{ - "com.google.code.gson:gson": "2.8.9", - "com.google.code.findbugs:jsr305": "3.0.2", - }, - } + // While the consumer can specify a PackageInfo object (e.g. from the schema, or a set of manual specifications), we + // need to ensure that local dependencies are reflected in the lists of dependencies and repositories. We'll do this + // here before calling into the codegen package. + pkgOverrides := codegen.PackageInfo{} + dependencies := map[string]string{} repositories := map[string]bool{} - for name, dep := range req.LocalDependencies { + // A local dependency has the form groupId:artifactId:version[:repositoryPath]. We'll parse this and add an + // entry to the dependency map for groupId:artifactId -> version, and add the repositoryPath to the list of + // repositories if it's present. parts := strings.Split(dep, ":") if len(parts) < 3 { return nil, fmt.Errorf( @@ -743,15 +734,22 @@ func (host *javaLanguageHost) GeneratePackage( } k := parts[0] + ":" + parts[1] - pkgInfo.Dependencies[k] = parts[2] + dependencies[k] = parts[2] if len(parts) == 4 { repositories[parts[3]] = true } } - pkgInfo.Repositories = maps.Keys(repositories) - pkg.Language["java"] = pkgInfo + pkgOverrides.Dependencies = dependencies + pkgOverrides.Repositories = maps.Keys(repositories) + + var pkgInfo codegen.PackageInfo + if javaInfo, ok := pkg.Language["java"].(codegen.PackageInfo); ok { + pkgInfo = javaInfo + } + + pkg.Language["java"] = pkgInfo.With(pkgOverrides) files, err := codegen.GeneratePackage("pulumi-language-java", pkg, req.ExtraFiles, req.Local) if err != nil { diff --git a/pkg/codegen/java/gen.go b/pkg/codegen/java/gen.go index b0f8c8255ba..2519b42c15a 100644 --- a/pkg/codegen/java/gen.go +++ b/pkg/codegen/java/gen.go @@ -2043,9 +2043,19 @@ func generateModuleContextMap(tool string, pkg *schema.Package) (map[string]*mod panic(fmt.Sprintf("Failed to cast `pkg.Language[\"java\"]`=%v to `PackageInfo`", raw)) } } + javaInfo = javaInfo. WithDefaultDependencies(). WithJavaSdkDependencyDefault(DefaultSdkVersion) + + // All packages that SupportPack (which in some sense reflects the latest version of the schema) should use + // Gradle if no build system has been explicitly specified. + if p.SupportPack() { + if javaInfo.BuildFiles == "" { + javaInfo.BuildFiles = "gradle" + } + } + info = &javaInfo infos[def] = info } @@ -2225,6 +2235,16 @@ func GeneratePackage( extraFiles map[string][]byte, local bool, ) (map[string][]byte, error) { + // Presently, Gradle is the primary build system we support for generated SDKs. Later on, when we validate the + // package in order to produce build system artifacts, we'll need a description and repository. To this end, we + // ensure there are non-empty values for these fields here. + if pkg.Description == "" { + pkg.Description = " " + } + if pkg.Repository == "" { + pkg.Repository = "https://example.com" + } + modules, info, err := generateModuleContextMap(tool, pkg) if err != nil { return nil, err diff --git a/pkg/codegen/java/package_info.go b/pkg/codegen/java/package_info.go index faf39ed68bb..454e0c18155 100644 --- a/pkg/codegen/java/package_info.go +++ b/pkg/codegen/java/package_info.go @@ -16,6 +16,7 @@ package java import ( "github.com/blang/semver" + "golang.org/x/exp/maps" ) const defaultBasePackage = "com.pulumi." @@ -135,6 +136,17 @@ func (i PackageInfo) With(overrides PackageInfo) PackageInfo { result.Dependencies[k] = v } } + if len(overrides.Repositories) > 0 { + repositories := map[string]bool{} + for _, repo := range result.Repositories { + repositories[repo] = true + } + for _, repo := range overrides.Repositories { + repositories[repo] = true + } + + result.Repositories = maps.Keys(repositories) + } if overrides.GradleNexusPublishPluginVersion != "" { result.GradleNexusPublishPluginVersion = overrides.GradleNexusPublishPluginVersion }