gradlefile

package
v0.19.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 6, 2026 License: Apache-2.0 Imports: 10 Imported by: 0

Documentation

Overview

Package gradlefile is a small parsing and editing library for the Gradle files omnibump needs to patch: build scripts (build.gradle, build.gradle.kts and other *.gradle(.kts) scripts such as gradle/dependencies.gradle), settings scripts with inline version catalogs, gradle.properties-style files, and gradle/libs.versions.toml version catalogs.

It is intentionally not a general Gradle DSL parser. Files are scanned for the version-bearing constructs omnibump understands, each construct is recorded with its source span, and edits are format-preserving splices at those spans: everything outside the edited value is preserved byte for byte. Both the Groovy and Kotlin DSL syntaxes are supported, selected by file extension.

The package performs no file I/O: callers pass content in and read content back via Content(). Path policy (size limits, symlink and root-boundary checks) belongs to the caller.

Index

Examples

Constants

View Source
const (
	// ForceBlockBegin opens the managed block.
	ForceBlockBegin = "// omnibump:resolutionStrategy:begin"
	// ForceBlockEnd closes the managed block.
	ForceBlockEnd = "// omnibump:resolutionStrategy:end"
)

Marker comments delimiting the omnibump-managed block. The block is hosted in the root settings script and pins transitive dependency versions (via dependency constraints) and coordinate swaps (via dependencySubstitution); re-running omnibump merges into the existing block instead of appending duplicates. See managed.go for the writer.

Variables

View Source
var (
	// ErrInvalidVersion is returned when a version string contains characters
	// outside the safe allowlist. The allowlist prevents code injection into
	// Gradle scripts through crafted version strings.
	ErrInvalidVersion = errors.New("invalid version string")

	// ErrInvalidCoordinate is returned when a group or artifact identifier
	// contains characters outside the safe allowlist.
	ErrInvalidCoordinate = errors.New("invalid coordinate")

	// ErrConflictingEdit is returned when two edits target the same or
	// overlapping source spans with different replacement values.
	ErrConflictingEdit = errors.New("conflicting edit")

	// ErrNotEditable is returned when an edit is requested on a construct the
	// library cannot rewrite in place (for example setting the version of a
	// declaration whose version is a variable reference).
	ErrNotEditable = errors.New("construct is not editable")
)

Functions

func IsManagedClasspathName added in v0.18.6

func IsManagedClasspathName(name string) bool

IsManagedClasspathName reports whether name is a compile/runtime classpath configuration already covered by the default managed match, so it need not be added to the extra ship-configuration list.

Example
package main

import (
	"fmt"

	"github.com/chainguard-dev/omnibump/pkg/gradlefile"
)

func main() {
	fmt.Println(gradlefile.IsManagedClasspathName("testRuntimeClasspath"))
	fmt.Println(gradlefile.IsManagedClasspathName("lineageImplementation"))
}
Output:
true
false

func IsNonShippingConfigName added in v0.18.6

func IsNonShippingConfigName(name string) bool

IsNonShippingConfigName reports whether name denotes a documentation, lint, static-analysis or annotation-processing configuration whose dependencies do not ship at runtime, so it should be excluded from auto-detected ship configurations.

Example
package main

import (
	"fmt"

	"github.com/chainguard-dev/omnibump/pkg/gradlefile"
)

func main() {
	fmt.Println(gradlefile.IsNonShippingConfigName("groovyDoc"))
	fmt.Println(gradlefile.IsNonShippingConfigName("lineageImplementation"))
}
Output:
true
false

func NewSettingsFileContent added in v0.18.0

func NewSettingsFileContent(dsl DSL, constraints map[string]string, subs []Substitution) (string, error)

NewSettingsFileContent returns the content for a brand-new root settings script that exists only to host the managed block.

Example
package main

import (
	"fmt"

	"github.com/chainguard-dev/omnibump/pkg/gradlefile"
)

func main() {
	content, err := gradlefile.NewSettingsFileContent(gradlefile.Kotlin, map[string]string{"a.b:c": "1.0"}, nil)
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println(content[:len(gradlefile.ForceBlockBegin)])
}
Output:
// omnibump:resolutionStrategy:begin

func NewSettingsFileContentWithConfigs added in v0.18.6

func NewSettingsFileContentWithConfigs(dsl DSL, constraints map[string]string, subs []Substitution, extraConfigs []string) (string, error)

NewSettingsFileContentWithConfigs is NewSettingsFileContent plus extraConfigs: the names of configurations beyond the compile/runtime classpaths whose contents ship inside a packaged artifact and on which the pins must also be forced.

Example
package main

import (
	"fmt"
	"strings"

	"github.com/chainguard-dev/omnibump/pkg/gradlefile"
)

func main() {
	content, err := gradlefile.NewSettingsFileContentWithConfigs(
		gradlefile.Groovy,
		map[string]string{"a.b:c": "1.0"},
		nil,
		[]string{"lineageImplementation"},
	)
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println(strings.Contains(content, "configuration.name in ['lineageImplementation']"))
}
Output:
true

func NormalizeAlias

func NormalizeAlias(alias string) string

NormalizeAlias normalizes a catalog accessor path (netty.codec.http) to the catalog entry key form (netty-codec-http). Gradle generates accessors by splitting alias keys on '-', '_' and '.'; normalizing to dashes matches how keys are conventionally written in catalog files.

Example
package main

import (
	"fmt"

	"github.com/chainguard-dev/omnibump/pkg/gradlefile"
)

func main() {
	fmt.Println(gradlefile.NormalizeAlias("netty.codec.http"))
}
Output:
netty-codec-http

func ValidateCoordinate

func ValidateCoordinate(coordinate string) error

ValidateCoordinate reports whether a group or artifact identifier is safe to embed in a Gradle file.

Example
package main

import (
	"fmt"

	"github.com/chainguard-dev/omnibump/pkg/gradlefile"
)

func main() {
	fmt.Println(gradlefile.ValidateCoordinate("io.netty"))
	fmt.Println(gradlefile.ValidateCoordinate("io.netty'") != nil)
}
Output:
<nil>
true

func ValidateModule added in v0.18.0

func ValidateModule(module string) error

ValidateModule reports whether module is a well-formed "group:artifact" coordinate safe to embed in a managed-block rule. Callers use it to decide whether a dependency can be force-pinned: aliases that are not real coordinates (e.g. Spring Boot's library("Commons Lang3") display names) fail this check and must not be added to the managed block.

func ValidateVersion

func ValidateVersion(version string) error

ValidateVersion reports whether version is safe to embed in a Gradle file.

Example
package main

import (
	"fmt"

	"github.com/chainguard-dev/omnibump/pkg/gradlefile"
)

func main() {
	fmt.Println(gradlefile.ValidateVersion("4.1.133.Final"))
	fmt.Println(gradlefile.ValidateVersion(`1.0"; exec("rm")`) != nil)
}
Output:
<nil>
true

Types

type BuildFile

type BuildFile struct {
	// contains filtered or unexported fields
}

BuildFile is a parsed Gradle build script.

func ParseBuild

func ParseBuild(path string, content []byte) (*BuildFile, error)

ParseBuild parses a Gradle build script (build.gradle, build.gradle.kts or any other *.gradle(.kts) script). The DSL dialect is derived from the path.

Example
package main

import (
	"fmt"

	"github.com/chainguard-dev/omnibump/pkg/gradlefile"
)

func main() {
	content := []byte(`dependencies {
    implementation "io.netty:netty-codec:4.1.100.Final"
    implementation "ch.qos.logback:logback-classic:${logbackVersion}"
}`)

	build, err := gradlefile.ParseBuild("build.gradle", content)
	if err != nil {
		fmt.Println(err)
		return
	}
	for _, dep := range build.Dependencies() {
		fmt.Printf("%s:%s version=%q varRef=%q\n", dep.Group, dep.Artifact, dep.Version, dep.VarRef)
	}
}
Output:
io.netty:netty-codec version="4.1.100.Final" varRef=""
ch.qos.logback:logback-classic version="" varRef="logbackVersion"

func (*BuildFile) ChangeCount

func (f *BuildFile) ChangeCount() int

ChangeCount returns the number of queued edits that modify the content.

func (*BuildFile) Changed

func (f *BuildFile) Changed() bool

Changed reports whether any queued edit modifies the original content.

func (*BuildFile) Content

func (f *BuildFile) Content() []byte

Content renders the script with all queued edits applied.

func (*BuildFile) DSL

func (f *BuildFile) DSL() DSL

DSL returns the script's DSL dialect.

func (*BuildFile) Dependencies

func (f *BuildFile) Dependencies() []DependencyDecl

Dependencies returns all dependency declarations found in the script.

func (*BuildFile) ForcedCoordinates

func (f *BuildFile) ForcedCoordinates() map[string]string

ForcedCoordinates returns the "group:artifact" -> version entries of a legacy force block in this build file, or an empty map when none exists. Current omnibump writes the managed block to the settings script (see SettingsFile.EnsureManagedBlock); this reader keeps older build-script force blocks visible to the project model.

func (*BuildFile) Path

func (f *BuildFile) Path() string

Path returns the file path the script was parsed from.

func (*BuildFile) ResolutionRules

func (f *BuildFile) ResolutionRules() []ResolutionRule

ResolutionRules returns all dependency resolve rules found in the script.

Example
package main

import (
	"fmt"

	"github.com/chainguard-dev/omnibump/pkg/gradlefile"
)

func main() {
	content := []byte(`eachDependency { DependencyResolveDetails details ->
    if (details.requested.group == "io.netty" && !details.requested.name.startsWith("netty-tcnative-")) {
        details.useVersion(libs.versions.netty.get())
    }
    if (details.requested.group == 'com.signalfx.public') {
        if (details.requested.name == 'signalfx-java') {
            details.useVersion '1.0.49'
        }
    }
}`)
	build, _ := gradlefile.ParseBuild("build.gradle", content)

	for _, rule := range build.ResolutionRules() {
		fmt.Printf("group=%s artifact=%q catalogKey=%q version=%q\n", rule.Group, rule.Artifact, rule.CatalogKey, rule.Version)
	}

	// Literal rules are editable in place; catalog-backed rules are bumped
	// through their [versions] key instead.
	for _, rule := range build.ResolutionRules() {
		if rule.Version != "" {
			if err := build.SetResolutionRuleVersion(rule, "1.0.50"); err != nil {
				fmt.Println(err)
			}
		}
	}
	fmt.Println("changed:", build.Changed())
}
Output:
group=io.netty artifact="" catalogKey="netty" version=""
group=com.signalfx.public artifact="signalfx-java" catalogKey="" version="1.0.49"
changed: true

func (*BuildFile) SetDependencyVersion

func (f *BuildFile) SetDependencyVersion(d DependencyDecl, version string) error

SetDependencyVersion queues an in-place rewrite of d's version literal. Declarations whose version is a variable reference cannot be edited here; update the variable definition instead.

Example
package main

import (
	"fmt"

	"github.com/chainguard-dev/omnibump/pkg/gradlefile"
)

func main() {
	build, _ := gradlefile.ParseBuild("build.gradle", []byte(`implementation "io.netty:netty-codec:4.1.100.Final"`))

	for _, dep := range build.Dependencies() {
		if err := build.SetDependencyVersion(dep, "4.1.133.Final"); err != nil {
			fmt.Println(err)
			return
		}
	}
	fmt.Println(string(build.Content()))
	fmt.Println("changed:", build.Changed(), "edits:", build.ChangeCount())
}
Output:
implementation "io.netty:netty-codec:4.1.133.Final"
changed: true edits: 1

func (*BuildFile) SetResolutionRuleVersion

func (f *BuildFile) SetResolutionRuleVersion(r ResolutionRule, version string) error

SetResolutionRuleVersion queues an in-place rewrite of r's version literal. Rules whose version comes from a catalog key or variable cannot be edited here; update the referenced source instead.

func (*BuildFile) SetVariable

func (f *BuildFile) SetVariable(v VarDef, value string) error

SetVariable queues an in-place rewrite of v's value.

Example
package main

import (
	"fmt"

	"github.com/chainguard-dev/omnibump/pkg/gradlefile"
)

func main() {
	build, _ := gradlefile.ParseBuild("dependencies.gradle", []byte(`versions += [
  log4j2: "2.25.1",
]`))

	for _, variable := range build.Variables() {
		if variable.Path() == "versions.log4j2" {
			if err := build.SetVariable(variable, "2.25.4"); err != nil {
				fmt.Println(err)
				return
			}
		}
	}
	fmt.Println(string(build.Content()))
}
Output:
versions += [
  log4j2: "2.25.4",
]

func (*BuildFile) ShipConfigs added in v0.18.6

func (f *BuildFile) ShipConfigs() []ShipConfigRef

ShipConfigs returns the configuration references bundled into shipped artifacts by packaging tasks in this build script.

Example
package main

import (
	"fmt"

	"github.com/chainguard-dev/omnibump/pkg/gradlefile"
)

func main() {
	// A shadowJar bundling a custom configuration alongside runtimeClasspath:
	// both end up inside the fat jar, so both must be force-pinned.
	content := []byte("shadowJar {\n    configurations = [project.configurations.runtimeClasspath, project.configurations.lineageImplementation]\n}\n")
	build, _ := gradlefile.ParseBuild("build.gradle", content)

	for _, ref := range build.ShipConfigs() {
		fmt.Println(ref.Name)
	}
}
Output:
runtimeClasspath
lineageImplementation

func (*BuildFile) Variables

func (f *BuildFile) Variables() []VarDef

Variables returns all version-variable definitions found in the script.

type CatalogFile

type CatalogFile struct {
	// contains filtered or unexported fields
}

CatalogFile is a parsed gradle/libs.versions.toml version catalog. The TOML structure is read with a real TOML parser; edits are line-targeted splices on the raw text so formatting, comments and key alignment survive.

func ParseCatalog

func ParseCatalog(path string, content []byte) (*CatalogFile, error)

ParseCatalog parses a libs.versions.toml version catalog.

Example
package main

import (
	"fmt"

	"github.com/chainguard-dev/omnibump/pkg/gradlefile"
)

func main() {
	content := []byte(`[versions]
netty = "4.2.12.Final"

[libraries]
netty-codec = { module = "io.netty:netty-codec", version.ref = "netty" }
okio = { module = "com.squareup.okio:okio", version = "3.4.0" }
`)
	catalog, err := gradlefile.ParseCatalog("gradle/libs.versions.toml", content)
	if err != nil {
		fmt.Println(err)
		return
	}

	for _, library := range catalog.Libraries() {
		fmt.Printf("%s -> ref=%q inline=%q\n", library.Module(), library.VersionRef, library.Version)
	}
	if err := catalog.SetVersion("netty", "4.2.13.Final"); err != nil {
		fmt.Println(err)
		return
	}
	for _, version := range catalog.Versions() {
		fmt.Println(version.Key)
	}
	fmt.Println("changed:", catalog.Changed(), "edits:", catalog.ChangeCount(), catalog.Path())
}
Output:
io.netty:netty-codec -> ref="netty" inline=""
com.squareup.okio:okio -> ref="" inline="3.4.0"
netty
changed: true edits: 1 gradle/libs.versions.toml

func (*CatalogFile) ChangeCount

func (f *CatalogFile) ChangeCount() int

ChangeCount returns the number of queued edits that modify the content.

func (*CatalogFile) Changed

func (f *CatalogFile) Changed() bool

Changed reports whether any queued edit modifies the original content.

func (*CatalogFile) Content

func (f *CatalogFile) Content() []byte

Content renders the catalog with all queued edits applied.

func (*CatalogFile) Libraries

func (f *CatalogFile) Libraries() []CatalogLibrary

Libraries returns the [libraries] entries with resolvable coordinates.

func (*CatalogFile) Path

func (f *CatalogFile) Path() string

Path returns the file path the catalog was parsed from.

func (*CatalogFile) SetLibraryVersion

func (f *CatalogFile) SetLibraryVersion(lib CatalogLibrary, value string) error

SetLibraryVersion queues a rewrite of lib's inline version literal. Libraries that use version.ref are updated through SetVersion on the referenced key instead.

Example
package main

import (
	"fmt"

	"github.com/chainguard-dev/omnibump/pkg/gradlefile"
)

func main() {
	catalog, _ := gradlefile.ParseCatalog("libs.versions.toml", []byte(`[libraries]
okio = { module = "com.squareup.okio:okio", version = "3.4.0" }
`))

	for _, library := range catalog.Libraries() {
		if err := catalog.SetLibraryVersion(library, "3.6.0"); err != nil {
			fmt.Println(err)
			return
		}
	}
	fmt.Print(string(catalog.Content()))
}
Output:
[libraries]
okio = { module = "com.squareup.okio:okio", version = "3.6.0" }

func (*CatalogFile) SetVersion

func (f *CatalogFile) SetVersion(key, value string) error

SetVersion queues a rewrite of the [versions] entry named key.

func (*CatalogFile) Versions

func (f *CatalogFile) Versions() []CatalogVersion

Versions returns the [versions] entries with string values.

type CatalogLibrary

type CatalogLibrary struct {
	// Alias is the catalog entry key, e.g. "netty-codec".
	Alias string

	// Group and Artifact are the Maven coordinates.
	Group    string
	Artifact string

	// VersionRef is the referenced [versions] key, or empty.
	VersionRef string

	// Version is the inline version literal, or empty.
	Version string
	// contains filtered or unexported fields
}

CatalogLibrary is one library entry of a version catalog, mapping an alias to Maven coordinates and a version (either by reference or inline).

func (CatalogLibrary) Module

func (l CatalogLibrary) Module() string

Module returns the library's "group:artifact" module coordinates.

type CatalogVersion

type CatalogVersion struct {
	// Key is the version key, e.g. "netty".
	Key string

	// Value is the current version string.
	Value string
	// contains filtered or unexported fields
}

CatalogVersion is one version entry of a version catalog: a [versions] key in a TOML catalog or a version("key", "value") declaration in a settings script's inline catalog.

type DSL

type DSL int

DSL identifies the Gradle script dialect of a file.

const (
	// Groovy is the classic Gradle DSL (*.gradle).
	Groovy DSL = iota
	// Kotlin is the Kotlin Gradle DSL (*.gradle.kts).
	Kotlin
)

func DSLFromPath

func DSLFromPath(path string) DSL

DSLFromPath returns the DSL dialect implied by a file path.

Example
package main

import (
	"fmt"

	"github.com/chainguard-dev/omnibump/pkg/gradlefile"
)

func main() {
	fmt.Println(gradlefile.DSLFromPath("build.gradle") == gradlefile.Groovy)
	fmt.Println(gradlefile.DSLFromPath("build.gradle.kts") == gradlefile.Kotlin)
}
Output:
true
true

type DeclKind

type DeclKind int

DeclKind identifies the syntactic form of a dependency declaration.

const (
	// StringNotation is implementation("group:artifact:version") or the
	// paren-less Groovy form, including coordinate values in ext maps.
	StringNotation DeclKind = iota
	// MapNotationKotlin is group = "g", name = "a", version = "v".
	MapNotationKotlin
	// MapNotationGroovy is group: 'g', name: 'a', version: 'v'.
	MapNotationGroovy
	// LibraryFn is the Spring Boot bom-plugin form library("name", "version").
	LibraryFn
	// StrictlyBlock is a rich-version constraint version { strictly("v") }.
	StrictlyBlock
	// CatalogRef is a version-catalog accessor such as api(libs.netty.codec);
	// it carries no version of its own.
	CatalogRef
	// DependencySet is one entry of a Spring dependency-management plugin
	// dependencySet(group: 'g', version: 'v') { entry 'a' } block. All
	// entries of a set share one version literal.
	DependencySet
)

type DependencyDecl

type DependencyDecl struct {
	// Group and Artifact are the Maven coordinates. Group is empty for
	// LibraryFn declarations (the library name is matched against artifact
	// ids) and for CatalogRef/StrictlyBlock declarations identified only by a
	// catalog alias.
	Group    string
	Artifact string

	// Version is the literal version, or empty when the version is a
	// variable reference or the declaration carries no version.
	Version string

	// VarRef is the referenced variable path when the version is
	// interpolated, e.g. "nettyVersion" or "versions.log4j2".
	VarRef string

	// CatalogAlias is the version-catalog accessor path (dots preserved,
	// without the "libs." prefix) for CatalogRef and alias-based
	// StrictlyBlock declarations.
	CatalogAlias string

	// Kind is the syntactic form of the declaration.
	Kind DeclKind
	// contains filtered or unexported fields
}

DependencyDecl is one dependency declaration found in a build script.

type PropertiesFile

type PropertiesFile struct {
	// contains filtered or unexported fields
}

PropertiesFile is a parsed gradle.properties or version.properties-style file. Order, comments and unrelated lines are preserved on edit.

func ParseProperties

func ParseProperties(path string, content []byte) (*PropertiesFile, error)

ParseProperties parses a properties file.

Example
package main

import (
	"fmt"

	"github.com/chainguard-dev/omnibump/pkg/gradlefile"
)

func main() {
	properties, err := gradlefile.ParseProperties("gradle.properties", []byte("nettyVersion=4.1.125.Final\njackson = 2.15.0\n"))
	if err != nil {
		fmt.Println(err)
		return
	}

	fmt.Println(properties.Keys())
	if err := properties.Set("nettyVersion", "4.1.133.Final"); err != nil {
		fmt.Println(err)
		return
	}
	value, ok := properties.Get("nettyVersion")
	fmt.Println(value, ok, len(properties.Entries()))
	fmt.Print(string(properties.Content()))
}
Output:
[nettyVersion jackson]
4.1.125.Final true 2
nettyVersion=4.1.133.Final
jackson = 2.15.0

func (*PropertiesFile) ChangeCount

func (f *PropertiesFile) ChangeCount() int

ChangeCount returns the number of queued edits that modify the content.

func (*PropertiesFile) Changed

func (f *PropertiesFile) Changed() bool

Changed reports whether any queued edit modifies the original content.

func (*PropertiesFile) Content

func (f *PropertiesFile) Content() []byte

Content renders the file with all queued edits applied.

func (*PropertiesFile) Entries

func (f *PropertiesFile) Entries() []PropertyEntry

Entries returns all key/value pairs in file order.

func (*PropertiesFile) Get

func (f *PropertiesFile) Get(key string) (string, bool)

Get returns the value of key and whether it is defined.

func (*PropertiesFile) Keys

func (f *PropertiesFile) Keys() []string

Keys returns all defined property names in file order.

func (*PropertiesFile) Path

func (f *PropertiesFile) Path() string

Path returns the file path the properties were parsed from.

func (*PropertiesFile) Set

func (f *PropertiesFile) Set(key, value string) error

Set queues an in-place rewrite of key's value. Only the value segment of the line is replaced; separator style and surrounding content are preserved. All occurrences of the key are updated.

type PropertyEntry

type PropertyEntry struct {
	// Key is the property name.
	Key string

	// Value is the current value.
	Value string
	// contains filtered or unexported fields
}

PropertyEntry is one key/value pair of a properties file.

type ResolutionRule

type ResolutionRule struct {
	// Group is the dependency group the rule matches.
	Group string

	// Artifact narrows the rule to one module; empty matches the whole group.
	Artifact string

	// CatalogKey is the referenced [versions] key (normalized) when the rule
	// reads a catalog version accessor such as libs.versions.netty.get().
	CatalogKey string

	// VarRef is the referenced variable path when the rule interpolates one.
	VarRef string

	// Version is the literal version, or empty.
	Version string
	// contains filtered or unexported fields
}

ResolutionRule is a dependency resolve rule found in a build script: a conditional inside resolutionStrategy.eachDependency that redirects a group (or one module) to a version source, e.g.

if (details.requested.group == "io.netty" && !details.requested.name.startsWith("netty-tcnative-")) {
    details.useVersion(libs.versions.netty.get())
}

Rules link modules to the catalog key, variable or literal that governs their version even when no [libraries] entry or interpolation does.

type SettingsFile

type SettingsFile struct {
	// contains filtered or unexported fields
}

SettingsFile is a parsed settings.gradle(.kts) script. Only the inline version-catalog declarations are modeled.

func ParseSettings

func ParseSettings(path string, content []byte) (*SettingsFile, error)

ParseSettings parses a settings.gradle(.kts) script.

Example
package main

import (
	"fmt"

	"github.com/chainguard-dev/omnibump/pkg/gradlefile"
)

func main() {
	content := []byte(`dependencyResolutionManagement {
    versionCatalogs {
        create("libs") {
            version("netty", "4.1.100.Final")
            library("netty-codec", "io.netty", "netty-codec").versionRef("netty")
        }
    }
}`)
	settings, err := gradlefile.ParseSettings("settings.gradle.kts", content)
	if err != nil {
		fmt.Println(err)
		return
	}

	for _, version := range settings.CatalogVersions() {
		if err := settings.SetCatalogVersion(version, "4.1.133.Final"); err != nil {
			fmt.Println(err)
			return
		}
	}
	fmt.Println(len(settings.CatalogLibraries()), settings.Changed(), settings.ChangeCount(), settings.Path())
}
Output:
1 true 1 settings.gradle.kts

func (*SettingsFile) CatalogLibraries

func (f *SettingsFile) CatalogLibraries() []CatalogLibrary

CatalogLibraries returns the inline catalog library declarations that reference a version key.

func (*SettingsFile) CatalogVersions

func (f *SettingsFile) CatalogVersions() []CatalogVersion

CatalogVersions returns the inline catalog version declarations.

func (*SettingsFile) ChangeCount

func (f *SettingsFile) ChangeCount() int

ChangeCount returns the number of queued edits that modify the content.

func (*SettingsFile) Changed

func (f *SettingsFile) Changed() bool

Changed reports whether any queued edit modifies the original content.

func (*SettingsFile) Content

func (f *SettingsFile) Content() []byte

Content renders the script with all queued edits applied.

func (*SettingsFile) DSL

func (f *SettingsFile) DSL() DSL

DSL returns the script's DSL dialect.

func (*SettingsFile) EnsureManagedBlock added in v0.18.0

func (f *SettingsFile) EnsureManagedBlock(constraints map[string]string, subs []Substitution) error

EnsureManagedBlock queues an edit that guarantees the settings file's managed block pins every constraint and applies every substitution. An existing block is merged (new versions/targets win, entries deduplicated and sorted); otherwise the block is appended. The operation is idempotent.

Example
package main

import (
	"fmt"

	"github.com/chainguard-dev/omnibump/pkg/gradlefile"
)

func main() {
	settings, _ := gradlefile.ParseSettings("settings.gradle", []byte("rootProject.name = 'demo'\n"))

	err := settings.EnsureManagedBlock(
		map[string]string{"io.netty:netty-handler": "4.1.135.Final"},
		[]gradlefile.Substitution{{OldModule: "org.lz4:lz4-java", NewModule: "at.yawk.lz4:lz4-java", Version: "1.10.1"}},
	)
	if err != nil {
		fmt.Println(err)
		return
	}

	// Re-parsing the result exposes the managed block's effective pins: each
	// constraint, and each substitution's new module at its target version.
	pinned, _ := gradlefile.ParseSettings("settings.gradle", settings.Content())
	fmt.Println(pinned.ManagedCoordinates()["io.netty:netty-handler"])
	fmt.Println(pinned.ManagedCoordinates()["at.yawk.lz4:lz4-java"])
}
Output:
4.1.135.Final
1.10.1

func (*SettingsFile) EnsureManagedBlockWithConfigs added in v0.18.6

func (f *SettingsFile) EnsureManagedBlockWithConfigs(constraints map[string]string, subs []Substitution, extraConfigs []string) error

EnsureManagedBlockWithConfigs is EnsureManagedBlock plus extraConfigs: the names of configurations beyond the compile/runtime classpaths whose resolved contents ship inside a packaged artifact (fat jar, capsule, war, ...), on which the pins must also be forced.

Example
package main

import (
	"fmt"
	"strings"

	"github.com/chainguard-dev/omnibump/pkg/gradlefile"
)

func main() {
	settings, _ := gradlefile.ParseSettings("settings.gradle", []byte("rootProject.name = 'demo'\n"))

	// lineageImplementation is bundled into the artifact but is not a classpath,
	// so it is added to the managed block's guard alongside the default match.
	err := settings.EnsureManagedBlockWithConfigs(
		map[string]string{"a.b:c": "1.0"},
		nil,
		[]string{"lineageImplementation"},
	)
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println(strings.Contains(string(settings.Content()), "configuration.name in ['lineageImplementation']"))
}
Output:
true

func (*SettingsFile) ManagedCoordinates added in v0.18.0

func (f *SettingsFile) ManagedCoordinates() map[string]string

ManagedCoordinates returns the effective "group:artifact" -> version pins of the file's managed block: each constraint, plus each substitution's new module at its target version. This lets the project model surface the settings-managed pins to dependency validation.

func (*SettingsFile) Path

func (f *SettingsFile) Path() string

Path returns the file path the script was parsed from.

func (*SettingsFile) SetCatalogVersion

func (f *SettingsFile) SetCatalogVersion(c CatalogVersion, value string) error

SetCatalogVersion queues an in-place rewrite of c's value.

type ShipConfigRef added in v0.18.6

type ShipConfigRef struct {
	// Name is the resolved configuration name (e.g. "lineageImplementation"),
	// or empty when the bundling site references a configuration in a form
	// omnibump cannot resolve to a literal name.
	Name string

	// Source labels how the reference was found (e.g. "configurations =",
	// "from", "classpath", "embedConfiguration"), for diagnostics.
	Source string

	// Raw is a trimmed source snippet, surfaced in warnings for unresolved
	// references.
	Raw string

	// Resolved reports whether Name was extracted. False marks a bundling site
	// whose configuration could not be statically determined, so the operator
	// must pin it explicitly.
	Resolved bool
}

ShipConfigRef is a reference to a Gradle configuration whose resolved contents are bundled into a shipped artifact: a fat/uber jar (shadow plugin or a hand-rolled Jar task), a capsule, a distribution, or a war. omnibump must force its managed version pins on these configurations too, because a configuration whose name is not a compile or runtime classpath escapes managedConfigurations yet still ends up inside the published artifact (e.g. nextflow's shadowJar bundles a custom 'lineageImplementation' configuration).

type Substitution added in v0.18.0

type Substitution struct {
	OldModule string
	NewModule string
	Version   string
}

Substitution is a coordinate swap: every request for OldModule ("group:artifact") is redirected to NewModule ("group:artifact") at Version. It is the resolution-rule analog of a version bump for the case where the dependency's coordinate itself changes (e.g. a fork), and it applies to both declared and transitive requests.

type VarDef

type VarDef struct {
	// Name is the variable or map-entry name, e.g. "nettyVersion" or
	// "log4j2".
	Name string

	// MapName is the enclosing Groovy map variable name (e.g. "versions")
	// or empty for flat definitions.
	MapName string

	// Value is the current value.
	Value string
	// contains filtered or unexported fields
}

VarDef is one version-variable definition found in a build script: a flat ext property, a Kotlin extra property, or an entry in a Groovy version map.

func (VarDef) Path

func (v VarDef) Path() string

Path returns the variable's reference path as used in interpolations: "versions.log4j2" for map entries, "nettyVersion" for flat definitions.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL