Skip to content

Commit

Permalink
feat: add support for Gradle
Browse files Browse the repository at this point in the history
  • Loading branch information
stuartwdouglas committed Aug 17, 2024
1 parent 5e788bd commit 0d16fc4
Show file tree
Hide file tree
Showing 11 changed files with 142 additions and 14 deletions.
1 change: 1 addition & 0 deletions bin/.gradle-8.9.pkg
1 change: 1 addition & 0 deletions bin/gradle
11 changes: 7 additions & 4 deletions internal/buildengine/build_java.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,17 @@ import (
"github.com/TBD54566975/ftl"
"github.com/TBD54566975/ftl/internal/exec"
"github.com/TBD54566975/ftl/internal/log"
"github.com/TBD54566975/ftl/internal/moduleconfig"
)

func buildJavaModule(ctx context.Context, module Module) error {
logger := log.FromContext(ctx)
if err := SetPOMProperties(ctx, module.Config.Dir); err != nil {
// This is not a critical error, things will probably work fine
// TBH updating the pom is maybe not the best idea anyway
logger.Warnf("unable to update ftl.version in %s: %s", module.Config.Dir, err.Error())
if module.Config.Java.BuildTool == moduleconfig.JavaBuildToolMaven {
if err := SetPOMProperties(ctx, module.Config.Dir); err != nil {
// This is not a critical error, things will probably work fine
// TBH updating the pom is maybe not the best idea anyway
logger.Warnf("unable to update ftl.version in %s: %s", module.Config.Dir, err.Error())
}
}
logger.Infof("Using build command '%s'", module.Config.Build)
err := exec.Command(ctx, log.Debug, module.Config.Dir, "bash", "-c", module.Config.Build).RunBuffered(ctx)
Expand Down
6 changes: 6 additions & 0 deletions internal/buildengine/discover_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,9 @@ func TestDiscoverModules(t *testing.T) {
"src/**",
"target/generated-sources",
},
Java: moduleconfig.ModuleJavaConfig{
BuildTool: "maven",
},
},
},
{
Expand Down Expand Up @@ -129,6 +132,9 @@ func TestDiscoverModules(t *testing.T) {
"src/**",
"target/generated-sources",
},
Java: moduleconfig.ModuleJavaConfig{
BuildTool: "maven",
},
},
},
{
Expand Down
55 changes: 45 additions & 10 deletions internal/moduleconfig/moduleconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,12 @@ type ModuleGoConfig struct{}
type ModuleKotlinConfig struct{}

// ModuleJavaConfig is language-specific configuration for Java modules.
type ModuleJavaConfig struct{}
type ModuleJavaConfig struct {
BuildTool string `toml:"build-tool"`
}

const JavaBuildToolMaven string = "maven"
const JavaBuildToolGradle string = "gradle"

// ModuleConfig is the configuration for an FTL module.
//
Expand Down Expand Up @@ -130,21 +135,40 @@ func setConfigDefaults(moduleDir string, config *ModuleConfig) error {
}
switch config.Language {
case "kotlin", "java":

if config.Build == "" {
config.Build = "mvn -B package"
}
if config.DeployDir == "" {
config.DeployDir = "target"
pom := filepath.Join(moduleDir, "pom.xml")
buildGradle := filepath.Join(moduleDir, "build.gradle")
buildGradleKts := filepath.Join(moduleDir, "build.gradle.kts")
if config.Java.BuildTool == JavaBuildToolMaven || fileExists(pom) {
config.Java.BuildTool = JavaBuildToolMaven
config.Build = "mvn -B package"
if config.DeployDir == "" {
config.DeployDir = "target"
}
if len(config.Watch) == 0 {
config.Watch = []string{"pom.xml", "src/**", "target/generated-sources"}
}
} else if config.Java.BuildTool == JavaBuildToolGradle || fileExists(buildGradle) || fileExists(buildGradleKts) {
config.Java.BuildTool = JavaBuildToolGradle
config.Build = "gradle build"
if config.DeployDir == "" {
config.DeployDir = "build"
}
if len(config.Watch) == 0 {
config.Watch = []string{"pom.xml", "src/**", "build/generated"}
}
} else {
return fmt.Errorf("could not find JVM build file in %s", moduleDir)
}
}

if config.GeneratedSchemaDir == "" {
config.GeneratedSchemaDir = "src/main/ftl-module-schema"
}
if len(config.Deploy) == 0 {
config.Deploy = []string{"main", "quarkus-app"}
}
if len(config.Watch) == 0 {
config.Watch = []string{"pom.xml", "src/**", "target/generated-sources"}
}
case "go":
if config.DeployDir == "" {
config.DeployDir = ".ftl"
Expand Down Expand Up @@ -178,17 +202,28 @@ func setConfigDefaults(moduleDir string, config *ModuleConfig) error {

// Do some validation.
if !isBeneath(moduleDir, config.DeployDir) {
return fmt.Errorf("deploy-dir must be relative to the module directory")
return fmt.Errorf("deploy-dir %s must be relative to the module directory %s", config.DeployDir, moduleDir)
}
for _, deploy := range config.Deploy {
if !isBeneath(moduleDir, deploy) {
return fmt.Errorf("deploy files must be relative to the module directory")
return fmt.Errorf("deploy %s files must be relative to the module directory %s", deploy, moduleDir)
}
}

return nil
}

func fileExists(filename string) bool {
_, err := os.Stat(filename)
if err == nil {
return true
}
if os.IsNotExist(err) {
return false
}
return false
}

func isBeneath(moduleDir, path string) bool {
resolved := filepath.Clean(filepath.Join(moduleDir, path))
return strings.HasPrefix(resolved, strings.TrimSuffix(moduleDir, "/")+"/")
Expand Down
11 changes: 11 additions & 0 deletions jvm-runtime/jvm_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,17 @@ func TestJVMToGoCall(t *testing.T) {
)
}

func TestGradle(t *testing.T) {
in.Run(t,
in.WithLanguages("java"),
in.CopyModule("gradle"),
in.Deploy("gradle"),
in.Call("gradle", "echo", "Bob", func(t testing.TB, response string) {
assert.Equal(t, "Hello, Bob!", response)
}),
)
}

func PairedTest(name string, testFunc func(module string) in.Action) []in.SubTest {
return []in.SubTest{
{
Expand Down
36 changes: 36 additions & 0 deletions jvm-runtime/testdata/java/gradle/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
plugins {
java
id("io.quarkus")
}

repositories {
mavenCentral()
mavenLocal()
}

val quarkusPlatformGroupId: String by project
val quarkusPlatformArtifactId: String by project
val quarkusPlatformVersion: String by project

dependencies {
implementation(enforcedPlatform("${quarkusPlatformGroupId}:${quarkusPlatformArtifactId}:${quarkusPlatformVersion}"))
implementation("xyz.block.ftl:ftl-java-runtime:1.0-SNAPSHOT")
testImplementation("io.quarkus:quarkus-junit5")
testImplementation("io.rest-assured:rest-assured")
}

group = "org.acme"
version = "1.0.0-SNAPSHOT"

java {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}

tasks.withType<Test> {
systemProperty("java.util.logging.manager", "org.jboss.logmanager.LogManager")
}
tasks.withType<JavaCompile> {
options.encoding = "UTF-8"
options.compilerArgs.add("-parameters")
}
2 changes: 2 additions & 0 deletions jvm-runtime/testdata/java/gradle/ftl.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
module = "gradle"
language = "java"
7 changes: 7 additions & 0 deletions jvm-runtime/testdata/java/gradle/gradle.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Gradle properties

quarkusPluginId=io.quarkus
quarkusPluginVersion=3.13.2
quarkusPlatformGroupId=io.quarkus.platform
quarkusPlatformArtifactId=quarkus-bom
quarkusPlatformVersion=3.13.2
13 changes: 13 additions & 0 deletions jvm-runtime/testdata/java/gradle/settings.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
pluginManagement {
val quarkusPluginVersion: String by settings
val quarkusPluginId: String by settings
repositories {
mavenCentral()
gradlePluginPortal()
mavenLocal()
}
plugins {
id(quarkusPluginId) version quarkusPluginVersion
}
}
rootProject.name="gradle"
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.acme;

import xyz.block.ftl.Export;
import xyz.block.ftl.Verb;

public class EchoVerb {

@Export
@Verb
public String echo(String request) {
return "Hello, " + request + "!";
}
}

0 comments on commit 0d16fc4

Please sign in to comment.