Files
pack/core/providers/java/java.go
T
Michael BiancoandGitHub 392d3fef96 feat: respect dockerignore on initial source load (#373)
* docs: add claude ref to agents

* refactor: simplify DockerignoreContext passing and make it required

* refactor: another take at fixing the initial docker ignore load stuff

* style: whitespace formatting tweaks

I'm not sure how it got into this state :/

* fix: apply dockerignore rules when copying local app context, not later in the build process

* fix: merge dockerignore excludes with top-level railpack.json excludes/includes

* test: top-level railpack.json exclude/include

* docs: update excluding files docs

* test: add negation to an existing dockerignore to expand test coverage

* fix: hack to determine if I'm understanding the llb exclude functionality right

* refactor: remove Includes and instead use negation operators and Excludes

* test: respect dockerignore on initial source load

- Apply exclude and include filters during the initial buildkit context load to improve local build performance
- Support top-level exclude and include configurations in railpack.json

Generated-by: aiautocommit

* feat: respect dockerignore on initial source load

- Load local source layers using the plan package directly to ensure .dockerignore patterns are respected at the buildkit level.
- Prevent unnecessary loading of ignored files like node_modules and virtual environments during local builds.

Generated-by: aiautocommit

* style: formatting updates

* docs(config): update documentation for dockerignore and exclude pattern handling

Generated-by: aiautocommit

* feat(plan): respect dockerignore on initial source load

Generated-by: aiautocommit

* refactor(core): access include rules directly from layer struct

Generated-by: aiautocommit

* feat(buildkit): respect exclude patterns on initial source load

- Apply exclude patterns at the buildkit level during local context loading to prevent transferring unnecessary large directories like node_modules or virtual environments.

Generated-by: aiautocommit

* feat: respect dockerignore on initial source load

Generated-by: aiautocommit

* feat(core): respect dockerignore on initial source load

- Expose the parsed dockerignore context via the build generate context
- Ensure build results preserve the correct dockerignore metadata and excludes on initial load

Generated-by: aiautocommit

* style(docs): fix trailing whitespace in CLAUDE.md

Generated-by: aiautocommit

* feat(core): respect dockerignore on initial source load

- Apply exclude and include filters during buildkit context setup to avoid loading large ignored directories locally.
- Support top-level exclude and include configuration in railpack.json.

Generated-by: aiautocommit

* test(plan): assert all expected empty dockerignore examples are found

Generated-by: aiautocommit

* docs(config): fix typo in excluding-files guide

Generated-by: aiautocommit

* feat(dockerignore): respect dockerignore on initial source load

- Apply exclude and include filters during Buildkit context establishment to drastically improve local build performance.
- Support top-level `exclude` and `include` rules directly in `railpack.json`.

Generated-by: aiautocommit

* docs(config): clarify directory matching behavior in excluding-files guide

Generated-by: aiautocommit

* refactor(core): remove dead dockerignore context fields

- Remove unused dockerignore context properties from build plans and options
- Clean up obsolete metadata checks in core tests

Generated-by: aiautocommit

* feat: add top-level exclude option to railpack config

Generated-by: aiautocommit
2026-07-31 07:41:35 -06:00

117 lines
3.2 KiB
Go

package java
import (
"fmt"
"github.com/railwayapp/railpack/core/generate"
"github.com/railwayapp/railpack/core/plan"
)
type JavaProvider struct{}
func (p *JavaProvider) Name() string {
return "java"
}
func (p *JavaProvider) Detect(ctx *generate.GenerateContext) (bool, error) {
return ctx.App.HasMatch("pom.{xml,atom,clj,groovy,rb,scala,yaml,yml}") || ctx.App.HasMatch("gradlew"), nil
}
func (p *JavaProvider) Initialize(ctx *generate.GenerateContext) error {
return nil
}
func (p *JavaProvider) CleansePlan(buildPlan *plan.BuildPlan) {}
func (p *JavaProvider) StartCommandHelp() string {
return ""
}
func (p *JavaProvider) Plan(ctx *generate.GenerateContext) error {
build := ctx.NewCommandStep("build")
build.AddInput(plan.NewStepLayer(ctx.GetMiseStepBuilder().Name()))
build.AddInput(plan.NewLocalLayer())
if p.usesGradle(ctx) {
ctx.Logger.LogInfo("Using Gradle")
p.setGradleVersion(ctx)
p.setJDKVersion(ctx, ctx.GetMiseStepBuilder())
if ctx.App.HasMatch("gradlew") && !ctx.App.IsFileExecutable("gradlew") {
build.AddCommand(plan.NewExecCommand("chmod +x gradlew"))
}
build.AddCommand(plan.NewExecCommand("./gradlew clean build -x check -x test -Pproduction"))
build.AddCache(p.gradleCache(ctx))
} else {
ctx.Logger.LogInfo("Using Maven")
ctx.GetMiseStepBuilder().Default("maven", "latest")
p.setJDKVersion(ctx, ctx.GetMiseStepBuilder())
if ctx.App.HasMatch("mvnw") && !ctx.App.IsFileExecutable("mvnw") {
build.AddCommand(plan.NewExecCommand("chmod +x mvnw"))
}
build.AddCommand(plan.NewExecCommand(fmt.Sprintf("%s -DoutputFile=target/mvn-dependency-list.log -B -DskipTests clean dependency:list install -Pproduction", p.getMavenExe(ctx))))
build.AddCache(p.mavenCache(ctx))
}
runtimeMiseStep := ctx.NewMiseStepBuilder("packages:mise:runtime")
p.setJDKVersion(ctx, runtimeMiseStep)
outPath := "target/."
if ctx.App.HasMatch("**/build/libs/*.jar") || p.usesGradle(ctx) {
outPath = "."
}
ctx.Deploy.AddInputs([]plan.Layer{
runtimeMiseStep.GetLayer(),
plan.NewStepLayer(build.Name(), plan.Filter{
Include: []string{outPath},
}),
})
ctx.Deploy.StartCmd = p.getStartCmd(ctx)
p.addMetadata(ctx)
return nil
}
func (p *JavaProvider) getStartCmd(ctx *generate.GenerateContext) string {
if p.usesGradle(ctx) {
buildGradle := p.readBuildGradle(ctx)
return fmt.Sprintf("java $JAVA_OPTS -jar %s $(ls -1 */build/libs/*jar | grep -v plain)", getGradlePortConfig(buildGradle))
} else if ctx.App.HasMatch("pom.xml") {
return fmt.Sprintf("java %s $JAVA_OPTS -jar target/*jar", getMavenPortConfig(ctx))
} else {
return "java $JAVA_OPTS -jar target/*jar"
}
}
func (p *JavaProvider) addMetadata(ctx *generate.GenerateContext) {
hasGradle := p.usesGradle(ctx)
if hasGradle {
ctx.Metadata.Set("javaPackageManager", "gradle")
} else {
ctx.Metadata.Set("javaPackageManager", "maven")
}
var framework string
if p.usesSpringBoot(ctx) {
framework = "spring-boot"
}
ctx.Metadata.Set("javaFramework", framework)
}
func (p *JavaProvider) usesSpringBoot(ctx *generate.GenerateContext) bool {
return ctx.App.HasMatch("**/spring-boot*.jar") ||
ctx.App.HasMatch("**/spring-boot*.class") ||
ctx.App.HasMatch("**/org/springframework/boot/**")
}