Documentation
¶
Overview ¶
Package stackdetect provides filesystem-only, deterministic detection of technology stacks from build files.
Overview ¶
This package detects the programming language, build tool, and release version from a workspace by examining build files. Detection is purely filesystem-based (no execution of build tools) and produces deterministic results for a given workspace state.
Supported Stacks ¶
Currently supported:
- Java with Maven (pom.xml)
- Java with Gradle (build.gradle, build.gradle.kts)
Usage ¶
obs, err := stackdetect.Detect(ctx, "/path/to/workspace")
if err != nil {
var detErr *stackdetect.DetectionError
if errors.As(err, &detErr) {
if detErr.IsAmbiguous() {
// Multiple build tools present
} else if detErr.IsUnknown() {
// No detection possible
}
}
return err
}
fmt.Printf("Detected: %s %s %s\n", obs.Language, obs.Tool, *obs.Release)
Detection Logic ¶
Maven (pom.xml) precedence:
- maven.compiler.release property
- maven.compiler.source + maven.compiler.target (must match)
- java.version property
Gradle (build.gradle/.kts) precedence:
- sourceCompatibility / targetCompatibility (must match if both present)
- kotlinOptions.jvmTarget (best-effort; used only if source/target are absent)
Error Handling ¶
Detection returns a DetectionError with reason codes:
- "ambiguous": Both Maven and Gradle build files present
- "unknown": No build files found, or version cannot be determined
Limitations ¶
This package performs static analysis only:
- Maven property interpolation is limited to local parent POMs
- Gradle detection uses regex patterns (no Groovy/Kotlin parsing)
- Dynamic version logic in Gradle (variables, findProperty, etc.) returns "unknown"
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type DetectionError ¶
type DetectionError struct {
// Reason is a machine-readable error code.
// Values: "ambiguous" (multiple build tools), "unknown" (no detection possible).
Reason string
// Message is a human-readable description of the error.
Message string
// Evidence contains any partial evidence gathered before the error.
Evidence []EvidenceItem
}
DetectionError represents an error during stack detection. It includes a reason code for programmatic handling.
func (*DetectionError) Error ¶
func (e *DetectionError) Error() string
Error implements the error interface.
func (*DetectionError) IsAmbiguous ¶
func (e *DetectionError) IsAmbiguous() bool
IsAmbiguous returns true if the error is due to ambiguous detection (e.g., both Maven and Gradle build files present).
func (*DetectionError) IsUnknown ¶
func (e *DetectionError) IsUnknown() bool
IsUnknown returns true if the error is due to unknown stack (e.g., no build files found, or no version detected).
type EvidenceItem ¶
type EvidenceItem struct {
// Path is the relative path to the file containing the evidence.
Path string `json:"path"`
// Key is the configuration key or property name.
Key string `json:"key"`
// Value is the raw value found in the configuration.
Value string `json:"value"`
}
EvidenceItem represents a single piece of evidence for a detection. It records where in the filesystem a configuration was found.
type Observation ¶
type Observation struct {
// Language is the detected programming language (e.g., "java").
Language string `json:"language"`
// Tool is the detected build tool (e.g., "maven", "gradle").
Tool string `json:"tool"`
// Release is the detected version/release (e.g., "11", "17", "21").
// Nil when no version could be determined.
Release *string `json:"release,omitempty"`
// Evidence contains the file paths and keys that support this detection.
Evidence []EvidenceItem `json:"evidence"`
}
Observation represents a detected stack configuration from the workspace. It captures the language, build tool, and optionally the release version along with evidence supporting the detection.
func Detect ¶
func Detect(ctx context.Context, workspace string) (*Observation, error)
Detect performs filesystem-only, deterministic detection of the project stack from build files in the workspace.
Supported languages (in detection order):
- Java: pom.xml (Maven), build.gradle or build.gradle.kts (Gradle)
- Go: Go module file
- Rust: Cargo.toml, rust-toolchain.toml, rust-toolchain
- Python: .python-version, runtime.txt, or pyproject.toml with Python markers
It returns an Observation on success, or a DetectionError when:
- Multiple languages detected (reason: "ambiguous")
- No build files found (reason: "unknown")
- Version cannot be determined (reason: "unknown")
func DetectTool ¶
func DetectTool(ctx context.Context, workspace string) (*Observation, error)
DetectTool performs deterministic tool/language detection from build files in the workspace, without requiring a release version to be present.
This is used by Build Gate when a default stack is configured: even when strict detection cannot determine a release, Build Gate can still determine the tool (e.g., Maven vs Gradle) to select the correct build command.