Skip to content

Commit

Permalink
fix(init): Update pom.xml when running ftl init kotlin on an existi…
Browse files Browse the repository at this point in the history
…ng directory (#591)

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
  • Loading branch information
alecthomas and github-actions[bot] authored Nov 14, 2023
1 parent 8bf4c9a commit ae6fa53
Show file tree
Hide file tree
Showing 7 changed files with 91 additions and 27 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/cc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
- uses: cashapp/activate-hermit@v1
- name: Update PR title
run: |
orig="${{ github.event.pull_request.title }}"
orig='${{ github.event.pull_request.title }}'
modified="$(gptcc "$orig")"
diff -u <(echo "$orig") <(echo "$modified") | tail +4 || true
gh pr edit --title "$modified"
Expand Down
76 changes: 67 additions & 9 deletions cmd/ftl/cmd_init.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ import (

"github.com/TBD54566975/scaffolder"
"github.com/alecthomas/errors"
"github.com/beevik/etree"
"github.com/iancoleman/strcase"

goruntime "github.com/TBD54566975/ftl/go-runtime"
"github.com/TBD54566975/ftl/internal"
kotlinruntime "github.com/TBD54566975/ftl/kotlin-runtime"
)
Expand All @@ -32,7 +32,13 @@ func (i initGoCmd) Run(parent *initCmd) error {
if i.Name == "" {
i.Name = filepath.Base(i.Dir)
}
return errors.WithStack(scaffold(goruntime.Files, parent.Hermit, i.Dir, i))
tmpDir, err := unzipToTmpDir(kotlinruntime.Files)
if err != nil {
return errors.Wrap(err, "failed to unzip kotlin runtime")
}
defer os.RemoveAll(tmpDir)

return errors.WithStack(scaffold(parent.Hermit, tmpDir, i.Dir, i))
}

type initKotlinCmd struct {
Expand All @@ -42,28 +48,80 @@ type initKotlinCmd struct {
Name string `arg:"" help:"Name of the FTL module to create underneath the base directory."`
}

func (i *initKotlinCmd) Run(parent *initCmd) error {
func (i initKotlinCmd) Run(parent *initCmd) error {
if i.Name == "" {
i.Name = filepath.Base(i.Dir)
}
return errors.WithStack(scaffold(kotlinruntime.Files, parent.Hermit, i.Dir, i))

if _, err := os.Stat(filepath.Join(i.Dir, i.Name)); err == nil {
return errors.Errorf("module directory %s already exists", filepath.Join(i.Dir, i.Name))
}

options := []scaffolder.Option{}

// Update root POM if it already exists.
pomFile := filepath.Join(i.Dir, "pom.xml")
if _, err := os.Stat(pomFile); err == nil {
options = append(options, scaffolder.Exclude("pom.xml"))
if err := updatePom(pomFile, i.Name); err != nil {
return errors.WithStack(err)
}
}

tmpDir, err := unzipToTmpDir(kotlinruntime.Files)
if err != nil {
return errors.Wrap(err, "failed to unzip kotlin runtime")
}
defer os.RemoveAll(tmpDir)

return errors.WithStack(scaffold(parent.Hermit, tmpDir, i.Dir, i, options...))
}

func scaffold(reader *zip.Reader, hermit bool, dir string, ctx any) error {
tmpDir, err := os.MkdirTemp("", "ftl-init-*")
func updatePom(pomFile, name string) error {
tree := etree.NewDocument()
err := tree.ReadFromFile(pomFile)
if err != nil {
return errors.WithStack(err)
}
defer os.RemoveAll(tmpDir)
err = internal.UnzipDir(reader, tmpDir)

// Add new module entry to root of XML file
root := tree.Root()
modules := root.SelectElement("modules")
if modules == nil {
modules = root.CreateElement("modules")
}
modules.CreateText(" ")
module := modules.CreateElement("module")
module.SetText("ftl-module-" + name)
modules.CreateText("\n ")

// Write updated XML file back to disk
err = tree.WriteToFile(pomFile)
if err != nil {
return errors.WithStack(err)
}
return nil
}

func unzipToTmpDir(reader *zip.Reader) (string, error) {
tmpDir, err := os.MkdirTemp("", "ftl-init-*")
if err != nil {
return "", errors.WithStack(err)
}
err = internal.UnzipDir(reader, tmpDir)
if err != nil {
return "", errors.WithStack(err)
}
return tmpDir, nil
}

func scaffold(hermit bool, source string, destination string, ctx any, options ...scaffolder.Option) error {
opts := []scaffolder.Option{scaffolder.Functions(scaffoldFuncs), scaffolder.Exclude("go.mod")}
if !hermit {
opts = append(opts, scaffolder.Exclude("bin"))
}
if err := scaffolder.Scaffold(tmpDir, dir, ctx, opts...); err != nil {
opts = append(opts, options...)
if err := scaffolder.Scaffold(source, destination, ctx, opts...); err != nil {
return errors.Wrap(err, "failed to scaffold")
}
return nil
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ require (
github.com/alecthomas/errors v0.4.0
github.com/alecthomas/participle/v2 v2.0.0
github.com/alecthomas/types v0.7.1
github.com/beevik/etree v1.2.0
github.com/deckarep/golang-set/v2 v2.3.0
github.com/gofrs/flock v0.8.1
github.com/iancoleman/strcase v0.2.0
Expand Down
2 changes: 2 additions & 0 deletions go.sum

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
<version>1.0-SNAPSHOT</version>
</parent>

<properties>
<ftlModuleName>{{ .Name | lower }}</ftlModuleName>
</properties>

<build>
<plugins>
<plugin>
Expand Down
2 changes: 1 addition & 1 deletion kotlin-runtime/scaffolding/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@
<argument>target/dependency/ftl-generator.jar</argument>
<argument>--endpoint=http://127.0.0.1:8892</argument>
<argument>--dest=${project.build.directory}</argument>
<argument>--module={{ .Name | camel | lower }}</argument>
<argument>--module=${ftlModuleName}</argument>
<argument>--module-client-suffix=ModuleClient</argument>
</arguments>
</configuration>
Expand Down
31 changes: 15 additions & 16 deletions scripts/integration-tests
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,12 @@ error() {

build_release() {
info "Building release"
bit build/release/ftl-controller \
build/release/ftl-runner \
build/release/ftl \
bit build/release/ftl \
kotlin-runtime/ftl-runtime/target/ftl-runtime-1.0-SNAPSHOT.jar \
kotlin-runtime/ftl-generator/target/ftl-generator-1.0-SNAPSHOT-jar-with-dependencies.jar \
build/template/ftl/jars/ftl-runtime.jar
}

wipe_database() {
info "Initialising database"
ftl-initdb --recreate
}

wait_for() {
info "Waiting for $1"
for _ in {1..240}; do
Expand All @@ -45,7 +38,7 @@ stop_cluster() {

start_cluster() {
info "Starting cluster"
goreman -logtime=false -f Procfile.integration start &
ftl serve --recreate &
wait_for "cluster to become ready" "ftl status"
trap stop_cluster EXIT INT TERM
}
Expand All @@ -59,27 +52,29 @@ deploy_echo_kotlin() (

deploy_fresh_kotlin() (
info "Deploying newly initialised Kotlin module"
rm -rf build/echo2
ftl init kotlin build/modules echo2
cd build/modules/ftl-module-echo2
IT_MODULES=build/modules
rm -rf "${IT_MODULES}"
ftl init kotlin "${IT_MODULES}" echo2
ftl init kotlin "${IT_MODULES}" echo3
cd "${IT_MODULES}"
mvn compile
ftl deploy target
ftl deploy ftl-module-echo2/target
ftl deploy ftl-module-echo3/target
)

deploy_time_go() (
info "Deploying time"
cd examples
# Pull a supported platforms from the cluster.
platform="$(ftl status | jq -r '.runners[].labels | "\(.os)-\(.arch)"' | sort | uniq | head -1)"
platform="$(ftl status | jq -r '(.runners // [])[].labels | "\(.os)-\(.arch)"' | sort | uniq | head -1)"
ftl-go --os "${platform%-*}" --arch "${platform#*-}" deploy time
)

wait_for_deploys() {
wait_for "deployments to come up" 'ftl status | jq -r ".routes[].module" | sort | paste -sd " " - | grep -q "echo echo2 time"'
wait_for "deployments to come up" 'ftl status | jq -r "(.routes // [])[].module" | sort | paste -sd " " - | grep -q "echo echo2 echo3 time"'
}

build_release
wipe_database
start_cluster

# Cluster is up, start interacting with it.
Expand All @@ -95,4 +90,8 @@ message="$(ftl call echo.echo '{"name": "Alice"}' | jq -r .message)"

message="$(ftl call echo2.echo '{"name": "Alice"}' | jq -r .message)"
[[ "$message" =~ "Hello, Alice!" ]] || error "Unexpected response from echo2: $message"

message="$(ftl call echo3.echo '{"name": "Alice"}' | jq -r .message)"
[[ "$message" =~ "Hello, Alice!" ]] || error "Unexpected response from echo2: $message"

info "Success!"

0 comments on commit ae6fa53

Please sign in to comment.