Skip to content

Commit

Permalink
Add language plugin executors form gradle and maven
Browse files Browse the repository at this point in the history
fixes #303
  • Loading branch information
pawelprazak committed Jan 26, 2024
1 parent dae9cfb commit 3e7bf5e
Show file tree
Hide file tree
Showing 6 changed files with 423 additions and 2 deletions.
4 changes: 3 additions & 1 deletion language-plugin/pulumi-language-scala/executors/executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,15 @@ func NewScalaExecutor(opts ScalaExecutorOptions) (*ScalaExecutor, error) {
e, err := combineScalaExecutorFactories(
&jarexec{},
&sbt{},
&gradle{},
&maven{},
&scalacli{},
).NewScalaExecutor(opts)
if err != nil {
return nil, err
}
if e == nil {
return nil, fmt.Errorf("failed to configure executor, tried: jar, sbt, scala-cli")
return nil, fmt.Errorf("failed to configure executor, tried: jar, sbt, scala-cli, gradle")
}
return e, nil
}
Expand Down
130 changes: 130 additions & 0 deletions language-plugin/pulumi-language-scala/executors/executor_gradle.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
// Copyright 2024, Pulumi Corporation. All rights reserved.

package executors

import (
"fmt"
"io/fs"
"strings"

"github.com/pulumi/pulumi/sdk/v3/go/common/util/logging"
"github.com/virtuslab/besom/language-host/fsys"
)

type gradle struct{}

var _ scalaExecutorFactory = &gradle{}

func (g gradle) NewScalaExecutor(opts ScalaExecutorOptions) (*ScalaExecutor, error) {
ok, err := g.isGradleProject(opts.WD, opts)
if err != nil {
return nil, err
}
if !ok {
return nil, nil
}
probePaths := []string{opts.UseExecutor}
if opts.UseExecutor == "" {
probePaths = []string{"./gradlew", "gradle"}
}
gradleRoot, subproject, err := g.findGradleRoot(opts.WD)
if err != nil {
return nil, err
}
cmd, err := fsys.LookPath(gradleRoot, probePaths...)
if err != nil {
return nil, err
}
executor, err := g.newGradleExecutor(gradleRoot, cmd, subproject)
if err != nil {
return nil, err
}

logging.V(3).Infof(`Detected Gradle Java executor:
Cmd: %s
Dir: %s
RunArgs: %s
PluginArgs: %s
BuildArgs: %s`,
executor.Cmd,
executor.Dir,
strings.Join(executor.RunArgs, " "),
strings.Join(executor.PluginArgs, " "),
strings.Join(executor.BuildArgs, " "))
return executor, err
}

func (gradle) findGradleRoot(workdir fsys.ParentFS) (fsys.ParentFS, string, error) {
gradleRootMarkers := []string{
"settings.gradle",
"settings.gradle.kts",
}
d := workdir
subproject := ""
for {
for _, p := range gradleRootMarkers {
isGradleRoot, err := fsys.FileExists(d, p)
if err != nil {
return nil, subproject, err
}
if isGradleRoot {
return d, subproject, nil
}
}
if !d.HasParent() {
// Abort search and assume workdir is the root
return workdir, subproject, nil
}
subproject = fmt.Sprintf(":%s%s", d.Base(), subproject)
d = d.Parent()
}
}

func (gradle) isGradleProject(dir fs.FS, opts ScalaExecutorOptions) (bool, error) {
if strings.Contains(opts.UseExecutor, "gradle") {
return true, nil
}
gradleMarkers := []string{
"settings.gradle",
"settings.gradle.kts",
"build.gradle",
}
for _, p := range gradleMarkers {
isGradle, err := fsys.FileExists(dir, p)
if err != nil {
return false, err
}
if isGradle {
return true, nil
}
}
return false, nil
}

func (g gradle) newGradleExecutor(gradleRoot fsys.ParentFS, cmd, subproject string) (*ScalaExecutor, error) {
se := &ScalaExecutor{
Name: "gradle",
Cmd: cmd,
Dir: gradleRoot.Path(),
BuildArgs: []string{g.prefix(subproject, "build"), "--console=plain"},
RunArgs: []string{g.prefix(subproject, "run"), "--console=plain"},
PluginArgs: []string{
/* STDOUT needs to be clean of gradle output,
because we expect a JSON with plugin
results */
"-q", // must go first due to a bug https://github.com/gradle/gradle/issues/5098
g.prefix(subproject, "run"), "--console=plain",
"-PmainClass=besom.bootstrap.PulumiPluginsDiscoverer",
},
VersionArgs: []string{"--version"},
}

return se, nil
}

func (gradle) prefix(subproject, task string) string {
if subproject == "" {
return task
}
return fmt.Sprintf("%s:%s", subproject, task)
}
64 changes: 64 additions & 0 deletions language-plugin/pulumi-language-scala/executors/executor_maven.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// Copyright 2024, Pulumi Corporation. All rights reserved.

package executors

import (
"strings"

"github.com/virtuslab/besom/language-host/fsys"
)

type maven struct{}

var _ scalaExecutorFactory = &maven{}

func (m maven) NewScalaExecutor(opts ScalaExecutorOptions) (*ScalaExecutor, error) {
ok, err := m.isMavenProject(opts)
if err != nil {
return nil, err
}
if !ok {
return nil, nil
}
probePaths := []string{opts.UseExecutor}
if opts.UseExecutor == "" {
probePaths = []string{"./mvnw", "mvn"}
}
cmd, err := fsys.LookPath(opts.WD, probePaths...)
if err != nil {
return nil, err
}
return m.newMavenExecutor(cmd)
}

func (maven) isMavenProject(opts ScalaExecutorOptions) (bool, error) {
if strings.Contains(opts.UseExecutor, "mvn") {
return true, nil
}
return fsys.FileExists(opts.WD, "pom.xml")
}

func (maven) newMavenExecutor(cmd string) (*ScalaExecutor, error) {
return &ScalaExecutor{
Cmd: cmd,
BuildArgs: []string{
/* only output warning or higher to reduce noise */
"-Dorg.slf4j.simpleLogger.defaultLogLevel=warn",
"--no-transfer-progress",
"compile",
},
RunArgs: []string{
/* only output warning or higher to reduce noise */
"-Dorg.slf4j.simpleLogger.defaultLogLevel=warn",
"--no-transfer-progress",
"scala:run",
},
PluginArgs: []string{
/* move normal output to STDERR, because we need STDOUT for JSON with plugin results */
"-Dorg.slf4j.simpleLogger.logFile=System.err",
"--no-transfer-progress", "scala:run",
"-DmainClass=besom.bootstrap.PulumiPluginsDiscoverer",
},
VersionArgs: []string{"--version"},
}, nil
}
Loading

0 comments on commit 3e7bf5e

Please sign in to comment.