Documentation
¶
Overview ¶
Package ruby provides parsed, cached views of common Ruby/Rails project files in the build context (Gemfile, Gemfile.lock, .ruby-version, .tool-versions). Rules under the tally/ruby/* namespace consume the typed facts here instead of re-parsing the files themselves.
All entry points return nil when the file is unobservable or fails to parse: rules then degrade gracefully to Dockerfile-only mode.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ParseRubyVersionFile ¶
ParseRubyVersionFile parses a `.ruby-version` file's content. The format accepted by chruby/rbenv/asdf is one of:
3.3.5 ruby-3.3.5
Optional surrounding whitespace and a trailing newline are tolerated. Returns "" when no version is found.
func ParseToolVersionsFile ¶
ParseToolVersionsFile parses a `.tool-versions` (asdf format) file. Each non-blank line lists `<tool> <version> [version2 ...]`. We return the first version listed for the `ruby` tool, or "" if none is found.
Types ¶
type ContextFileReader ¶
type ContextFileReader interface {
// FileExists reports whether path resolves to a regular file in the
// build context.
FileExists(path string) bool
// ReadFile reads a regular file's content from the build context.
ReadFile(path string) ([]byte, error)
// IsIgnored reports whether the path is excluded by .dockerignore.
// Implementations that don't model .dockerignore should return
// (false, nil); a non-nil error reduces to "treat as ignored" so we
// don't reason over inputs the build process cannot see.
IsIgnored(path string) (bool, error)
}
ContextFileReader is the minimal subset of internal/context.BuildContext that the loader needs. Declared locally so the package does not import internal/facts or internal/context, keeping import direction clean.
type GemfileFacts ¶
type GemfileFacts struct {
// RubyConstraint holds the value passed to the top-level ruby "..."
// directive, when present. Quotes are stripped.
RubyConstraint string
// Sources lists every URL passed to a top-level source "..." directive,
// preserving Gemfile order.
Sources []string
// GitGems lists gem entries that pin to a git: or github: source. Order
// matches first appearance.
GitGems []string
// HasDevGroup is true when the Gemfile contains a `group :development do`
// block (multi-group declarations like `group :development, :test do`
// also count).
HasDevGroup bool
// HasTestGroup is true when the Gemfile contains a `group :test do` block
// (multi-group declarations like `group :development, :test do` also count).
HasTestGroup bool
}
GemfileFacts is the typed projection of a Gemfile that complements LockfileFacts. All fields are zero-valued when the Gemfile is unobservable or fails to parse.
func ParseGemfile ¶
func ParseGemfile(content []byte) *GemfileFacts
ParseGemfile parses Gemfile content into typed facts. Returns nil for empty input or input that yields no recognizable directives.
type LockfileFacts ¶
type LockfileFacts struct {
// BundledWith is the value of the BUNDLED WITH block (may be empty for
// legacy Bundler 1.x lockfiles that do not include the block).
BundledWith string
// RubyVersion is the value of the RUBY VERSION block (may be empty).
RubyVersion string
// Platforms lists every entry in the PLATFORMS block.
Platforms []string
// Sources lists every remote: URL declared by GEM/GIT/PATH/PLUGIN SOURCE
// blocks, in the order they appear.
Sources []string
// DirectDeps maps gem name to version constraint, from the DEPENDENCIES
// block. The value preserves the constraint as written in the lockfile
// (for example "~> 8.0", ">= 1.2.3", or empty when no constraint is
// listed).
DirectDeps map[string]string
// Specs maps gem name to exact version, derived from each block's specs:
// section. Platform-suffixed gem names like "nokogiri (1.13.6-x86_64-linux)"
// are normalized to "nokogiri" -> "1.13.6".
Specs map[string]string
// HasGitGems is true when at least one GIT block is present.
HasGitGems bool
// HasPathGems is true when at least one PATH block is present.
HasPathGems bool
// NativeExtGems lists gems detected as native-extension gems via the
// curated list. Order matches first appearance in the lockfile.
NativeExtGems []string
}
LockfileFacts is the typed projection of Gemfile.lock that Ruby rules consume. All fields are zero-valued when Gemfile.lock is not observable or fails to parse.
func ParseLockfile ¶
func ParseLockfile(content []byte) *LockfileFacts
ParseLockfile parses Gemfile.lock content into typed facts. Returns nil when the input is empty or when parsing fails for any reason. Partial input that looks plausibly like a lockfile is accepted; missing sections leave the corresponding fields zero-valued.
type RubyFacts ¶
type RubyFacts struct {
// Lockfile holds parsed Gemfile.lock data, or nil when no observable
// lockfile is present.
Lockfile *LockfileFacts
// Gemfile holds parsed Gemfile data, or nil when no observable Gemfile is
// present.
Gemfile *GemfileFacts
// RubyVersion is the project's resolved Ruby version, in priority order:
//
// 1. .ruby-version
// 2. .tool-versions (the `ruby` line)
// 3. Lockfile.RubyVersion (RUBY VERSION block)
//
// Empty when none of the sources yield a value.
RubyVersion string
// HasEncryptedCredentials reports whether the project ships any of the
// canonical Rails encrypted-credentials files (config/credentials.yml.enc
// or config/credentials/<env>.yml.enc for one of the standard envs).
// Rules that need to know whether RAILS_MASTER_KEY is actually load-bearing
// at build time (e.g. asset-precompile-without-dummy-key) consult this.
HasEncryptedCredentials bool
// EncryptedCredentialsPaths records the observed credentials files in the
// build context. Order matches the probe order. Empty when no credentials
// files are observable.
EncryptedCredentialsPaths []string
}
RubyFacts bundles every observable Ruby project file the rule namespace cares about. Each pointer is nil when the underlying file is missing, unobservable, or malformed.
func Load ¶
func Load(reader ContextFileReader) *RubyFacts
Load reads the four well-known Ruby project files from the build context and returns parsed RubyFacts. A nil reader yields a non-nil RubyFacts with every pointer field nil (rules can then call .Lockfile == nil etc. without special-casing). Read errors and .dockerignore-excluded paths are silently treated as "no signal" — the corresponding pointer is left nil.
Memoization is the caller's responsibility; for the standard rule pipeline it happens inside *facts.FileFacts via sync.Once.