feat(gradle): release v1.6.0 — Gradle build file version bump
Add internal/gradle package with ReadVersion and WriteVersion for build.gradle (Groovy DSL, single-quoted) and build.gradle.kts (Kotlin DSL, double-quoted). Quote style is preserved on write. regexp.QuoteMeta ensures version strings with dots or special characters are safe. Config follows the established multi-value pattern: - gradle.build_file: single path (opt-in, no default) - gradle.build_files: list for multi-module projects (overrides build_file) - --gradle flag overrides build_file and clears build_files 100% per-package statement coverage maintained across all 13 packages; FuzzReadVersion and FuzzWriteVersion added per fuzzing guidelines. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -17,6 +17,7 @@ type Config struct {
|
||||
Git GitConfig `yaml:"git"`
|
||||
Maven MavenConfig `yaml:"maven"`
|
||||
Node NodeConfig `yaml:"node"`
|
||||
Gradle GradleConfig `yaml:"gradle"`
|
||||
GitLab GitLabConfig `yaml:"gitlab"`
|
||||
GitHub GitHubConfig `yaml:"github"`
|
||||
}
|
||||
@@ -73,6 +74,23 @@ func (n NodeConfig) EffectivePaths() []string {
|
||||
return nil
|
||||
}
|
||||
|
||||
type GradleConfig struct {
|
||||
BuildFile string `yaml:"build_file"` // single path (opt-in, no default)
|
||||
BuildFiles []string `yaml:"build_files"` // multiple paths; overrides BuildFile
|
||||
}
|
||||
|
||||
// EffectiveBuildFiles returns the list of Gradle build file paths to process.
|
||||
// Returns nil when no gradle paths are configured (gradle processing is opt-in).
|
||||
func (g GradleConfig) EffectiveBuildFiles() []string {
|
||||
if len(g.BuildFiles) > 0 {
|
||||
return g.BuildFiles
|
||||
}
|
||||
if g.BuildFile != "" {
|
||||
return []string{g.BuildFile}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type GitLabConfig struct {
|
||||
URL string `yaml:"url"`
|
||||
Token string `yaml:"token"`
|
||||
@@ -117,6 +135,8 @@ func defaultSources() Sources {
|
||||
"maven.pom_paths": "default",
|
||||
"node.package_json": "default",
|
||||
"node.package_jsons": "default",
|
||||
"gradle.build_file": "default",
|
||||
"gradle.build_files": "default",
|
||||
"gitlab.url": "default",
|
||||
"gitlab.token": "default",
|
||||
"gitlab.project": "default",
|
||||
@@ -193,6 +213,12 @@ func LoadWithSources(dir string) (Config, Sources, error) {
|
||||
if len(overlay.Node.PackageJSONs) > 0 {
|
||||
src["node.package_jsons"] = "config file"
|
||||
}
|
||||
if overlay.Gradle.BuildFile != "" {
|
||||
src["gradle.build_file"] = "config file"
|
||||
}
|
||||
if len(overlay.Gradle.BuildFiles) > 0 {
|
||||
src["gradle.build_files"] = "config file"
|
||||
}
|
||||
if overlay.GitLab.URL != "" {
|
||||
src["gitlab.url"] = "config file"
|
||||
}
|
||||
|
||||
@@ -292,6 +292,52 @@ func TestApplyEnvWithSourcesCIServerURL(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestGradleEffectiveBuildFiles(t *testing.T) {
|
||||
// Neither set → nil (opt-in)
|
||||
if got := (GradleConfig{}).EffectiveBuildFiles(); got != nil {
|
||||
t.Errorf("empty config: got %v, want nil", got)
|
||||
}
|
||||
// BuildFile only
|
||||
if got := (GradleConfig{BuildFile: "build.gradle"}).EffectiveBuildFiles(); len(got) != 1 || got[0] != "build.gradle" {
|
||||
t.Errorf("BuildFile only: got %v", got)
|
||||
}
|
||||
// BuildFiles wins over BuildFile
|
||||
g := GradleConfig{BuildFile: "build.gradle", BuildFiles: []string{"a/build.gradle", "b/build.gradle"}}
|
||||
if got := g.EffectiveBuildFiles(); len(got) != 2 || got[0] != "a/build.gradle" {
|
||||
t.Errorf("BuildFiles priority: got %v", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadGradleSources(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
content := "gradle:\n build_file: \"build.gradle\"\n"
|
||||
if err := os.WriteFile(filepath.Join(dir, filename), []byte(content), 0644); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
_, src, err := LoadWithSources(dir)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if src["gradle.build_file"] != "config file" {
|
||||
t.Errorf("src[gradle.build_file] = %q, want %q", src["gradle.build_file"], "config file")
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadGradleBuildFilesSources(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
content := "gradle:\n build_files:\n - \"a/build.gradle\"\n - \"b/build.gradle\"\n"
|
||||
if err := os.WriteFile(filepath.Join(dir, filename), []byte(content), 0644); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
_, src, err := LoadWithSources(dir)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if src["gradle.build_files"] != "config file" {
|
||||
t.Errorf("src[gradle.build_files] = %q, want %q", src["gradle.build_files"], "config file")
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadPartialOverride(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
// Only override tag_prefix — commit_message should keep its default
|
||||
|
||||
Reference in New Issue
Block a user