Documentation
¶
Index ¶
- Constants
- Variables
- func CanWriteToDir(dir string) bool
- func CanWriteToExistingAncestor(dir string) bool
- func CanWriteToFile(path string) bool
- func CompareVersions(a, b string) int
- func CreateFileWritable(path string) (*os.File, error)
- func CurrentCondaPlatform() string
- func DepSatisfiedByVersion(installedVersion, op, minVersion, preferredVersion string) bool
- func DirExists(path string) bool
- func DownloadExecutable(ctx context.Context, url, destPath string) error
- func DownloadFile(ctx context.Context, url, destPath string) error
- func EnsureTmpSubdir(dir string) error
- func EnsureWritableDir(dir string) bool
- func ExpandPlaceholders(defs []PlaceholderDef) []map[string]string
- func ExtractImgPackageTokens(imgPackages string) []string
- func FetchCondaSummary(packageName string, channels []string) string
- func FileExists(path string) bool
- func FindEnvOverlay(envImg, wd string) string
- func FormatBytes(bytes int64) string
- func FormatChoicesInline(vlist []string) string
- func FormatDuration(d time.Duration) string
- func FormatMemoryMB(mb int64) string
- func GetDependenciesFromScript(scriptPath string, parseModuleLoad bool) ([]string, error)
- func GetExternalBuildTypeFromScript(scriptPath string) (string, error)
- func GetInteractivePromptsFromScript(scriptPath string) ([]string, error)
- func GetTargetFromScript(scriptPath string) (string, error)
- func GetTmpDir() string
- func GetWhatIsFromScript(scriptPath string) string
- func HighlightTemplatePlaceholders(pattern string) string
- func InterpolateVars(s string, vars map[string]string) string
- func IsCondaFile(path string) bool
- func IsImg(path string) bool
- func IsInteractiveShell() bool
- func IsOverlay(path string) bool
- func IsSif(path string) bool
- func IsSqf(path string) bool
- func IsStdinPiped() bool
- func LatestVersion(versions []string) string
- func MakeExecutable(path string) error
- func MatchTemplateTarget(pattern, concrete string) (map[string]string, bool)
- func MatchVersion(input string, versions []string) string
- func MkdirAllShared(dir string) error
- func NormalizeNameVersion(nameVersion string) string
- func ParseDHMSTime(timeStr string) (time.Duration, error)
- func ParseHMSTime(timeStr string) (time.Duration, error)
- func ParseMemoryMB(memStr string) (int64, error)
- func ParseMemoryMBWithDefault(memStr, defaultUnit string) (int64, error)
- func ParseSizeToMB(sizeStr string) (int, error)
- func ParseValueList(raw string) ([]string, bool, error)
- func ParseWalltime(timeStr string) (time.Duration, error)
- func PrintDebug(format string, a ...any)
- func PrintError(format string, a ...any)
- func PrintHint(format string, a ...any)
- func PrintMessage(format string, a ...any)
- func PrintNote(format string, a ...any)
- func PrintSuccess(format string, a ...any)
- func PrintWarning(format string, a ...any)
- func ReadGzipJSONFile(path string, out any) error
- func ReadLineContext(ctx context.Context) (string, error)
- func RemoveDirIfEmpty(dir string)
- func ShareWithParentGroup(path string)
- func ShouldAnswerYes() bool
- func SortVersionsDescending(values []string) []string
- func SplitDepConstraint(raw string) (nameVersion, op, minVersion string)
- func StripInlineComment(s string) string
- func StyleAction(act string) string
- func StyleDebug(msg string) string
- func StyleError(msg string) string
- func StyleHighlight(text string) string
- func StyleHint(msg string) string
- func StyleInfo(msg string) string
- func StyleName(name string) string
- func StyleNote(msg string) string
- func StyleNumber(num any) string
- func StylePath(path string) string
- func StyleSuccess(msg string) string
- func StyleTitle(title string) string
- func StyleWarning(msg string) string
- func TruncateWords(s string, n int) string
- func URLExists(ctx context.Context, url string) bool
- func ValidateTemplatePlaceholders(target string, plNames []string) []string
- func VersionChoicesDisplay(versions []string) []string
- func WriteGzipJSONFileAtomic(path string, value any) error
- type ApptainerFilter
- type CondaSearchResult
- type PlaceholderDef
Constants ¶
const ( ApptainerWarning = "WARNING:" ApptainerInfo = "INFO:" ApptainerDebug = "DEBUG:" ApptainerVerbose = "VERBOSE:" ApptainerError = "ERROR:" ApptainerFatal = "FATAL:" )
Apptainer log-line prefixes, for selecting which lines to drop.
const BuildScriptDefName = ".cnt-build-script.def"
BuildScriptDefName is the file a def or scheme:// (docker://) build embeds at the overlay root to record the definition that produced the overlay.
const BuildScriptName = ".cnt-build-script"
BuildScriptName is the file a script/ref build embeds under its payload dir (/cnt/<name>/<version>/) to record the recipe that produced the overlay.
const PermDir os.FileMode = 0775
Dir: u=rwx, g=rwx, o=rx (Requires +x to traverse)
const PermExec os.FileMode = 0775
Exec: u=rwx, g=rwx, o=rx (Executable files with group write access)
const PermFile os.FileMode = 0664
Standard default permissions File: u=rw, g=rw, o=r
Variables ¶
var ApptainerNonError = []string{ApptainerWarning, ApptainerInfo, ApptainerDebug, ApptainerVerbose}
ApptainerNonError lists the non-error log prefixes; dropping these keeps only ERROR:/FATAL: and non-Apptainer output.
var DebugMode = false
DebugMode controls whether PrintDebug output is visible.
var QuietMode = false
QuietMode controls whether verbose messages are suppressed (errors/warnings still shown)
var YesMode = false
YesMode controls whether to automatically answer yes to all prompts
Functions ¶
func CanWriteToDir ¶ added in v1.4.0
CanWriteToDir checks whether an existing directory is writable using a permission check syscall, without creating the directory or writing any files. Returns false if the directory does not exist. Use this for probe operations (display, bind decisions, search-path scanning). Use EnsureWritableDir when you intend to actually create the directory on first use.
func CanWriteToExistingAncestor ¶ added in v1.5.0
CanWriteToExistingAncestor walks up the path until it finds an existing directory and checks whether it is writable. Use this when dir may not exist yet but will be created by MkdirAll — a non-existent dir is not read-only, it just needs a writable parent.
func CanWriteToFile ¶ added in v1.5.1
CanWriteToFile reports whether path can be written to. An existing file must itself be writable — a writable parent directory is not enough, since a read-only file (e.g. a frozen shared config) cannot be opened for writing. A file that does not exist yet only needs a writable ancestor directory.
func CompareVersions ¶ added in v1.4.0
CompareVersions compares two partial version strings component by component. Missing trailing components are treated as 0 (so "1.16" == "1.16.0"). Returns -1 if a < b, 0 if equal, 1 if a > b.
func CreateFileWritable ¶ added in v1.3.0
CreateFileWritable creates or truncates a file using standard writable file permissions.
func CurrentCondaPlatform ¶ added in v1.4.0
func CurrentCondaPlatform() string
CurrentCondaPlatform returns the conda platform string for the current OS and architecture, e.g. "linux-64", "linux-aarch64", "osx-arm64". Note: Linux ARM64 is "linux-aarch64" while macOS ARM64 is "osx-arm64".
func DepSatisfiedByVersion ¶ added in v1.4.0
DepSatisfiedByVersion returns true if installedVersion satisfies the constraint (op + minVersion) and does not exceed preferredVersion (upper bound). op must be ">=" or ">". preferredVersion may be empty to skip the upper bound check.
func DownloadExecutable ¶
DownloadExecutable downloads a file and sets it as executable (PermExec). The download is cancelled if ctx is cancelled.
func DownloadFile ¶
DownloadFile downloads a file from url to destPath. The download is cancelled if ctx is cancelled.
func EnsureTmpSubdir ¶ added in v1.3.0
EnsureTmpSubdir creates the leaf directory dir with permissions based on the parent:
- Parent world-writable (o+w, e.g. /tmp with mode 1777): use 0700 so other users on the same node cannot read or list the contents; not group-shared.
- Otherwise (private path, or a group-shared scratch): use PermDir and ShareWithParentGroup, so a group-writable (2775) parent propagates group-write down into the workspace built underneath.
Only the leaf is created; the parent must already exist. An already-existing directory is accepted silently (safe for concurrent builds).
func EnsureWritableDir ¶ added in v1.4.0
EnsureWritableDir creates dir if it does not exist, then checks it is writable. Permissions are set only when the directory is newly created. Returns true if the directory exists (or was created) and is writable.
func ExpandPlaceholders ¶ added in v1.4.0
func ExpandPlaceholders(defs []PlaceholderDef) []map[string]string
ExpandPlaceholders returns the Cartesian product of all placeholder value combinations. "*" is never used as a concrete iteration value. Returns [{}] (a slice with one empty map) when defs is empty.
func ExtractImgPackageTokens ¶ added in v1.5.0
ExtractImgPackageTokens returns the unique {KEY} token names from an #IMG_PACKAGES: template.
func FetchCondaSummary ¶ added in v1.4.0
FetchCondaSummary queries the anaconda.org API for a package summary. Channels are tried in the order provided; returns "" if not found or on error. The summary is truncated to at most 100 words.
func FileExists ¶
FileExists checks if a file exists and is not a directory.
func FindEnvOverlay ¶ added in v1.5.0
FindEnvOverlay returns the first env.img found under wd using the standard search order. At each location the user-specific variant (env-$USER.img) is checked before the generic one:
{wd}/env-$USER.img → {wd}/env.img
{wd}/overlay/env-$USER.img → {wd}/overlay/env.img
{wd}/src/overlay/env-$USER.img → {wd}/src/overlay/env.img
envImg may be an explicit path (returned as-is) or "" / "env.img" (triggers search). Returns "" if nothing is found.
func FormatBytes ¶
FormatBytes formats bytes into human-readable format (e.g., "1.50 GB").
func FormatChoicesInline ¶ added in v1.5.0
FormatChoicesInline formats a value list for single-line display. Version lists (entries containing a dot) are grouped by minor version with the patch shown in dim parentheses: "3.13(.2), 3.12(.10), 3.11(.12)". Option lists are joined with " | ": "github | microsoft".
func FormatDuration ¶ added in v1.3.0
FormatDuration formats a duration dropping zero trailing components. Examples: 2h0m0s → "2h", 48h → "2d", 25h30m → "1d1h30m", 1h30m15s → "1h30m15s".
func FormatMemoryMB ¶ added in v1.3.0
FormatMemoryMB formats a MB value into a human-readable string. Uses "GB" when divisible by 1024, otherwise "MB". Examples: 8192 → "8GB", 1536 → "1536MB".
func GetDependenciesFromScript ¶
GetDependenciesFromScript parses a build script and extracts dependencies from #DEP: comments and, optionally, module load / ml commands. Set parseModuleLoad=true to also parse "module load" and "ml" lines. Returns a list of normalized dependency names with duplicates removed.
func GetExternalBuildTypeFromScript ¶ added in v1.3.0
GetExternalBuildTypeFromScript parses external build script TYPE metadata. Supported tag forms:
- #TYPE:<value>
- TYPE:<value>
If TYPE is not present, it defaults to "app". Supported values (case-insensitive):
- app aliases: app, env, tool, conda, small
- data aliases: data, ref, large
func GetInteractivePromptsFromScript ¶
GetInteractivePromptsFromScript parses a build script and extracts interactive prompt lines beginning with "#INTERACTIVE:". Returns a list of prompt strings (without the prefix) or an error if the file cannot be read.
func GetTargetFromScript ¶ added in v1.4.0
GetTargetFromScript reads a build script and returns the value of the first #TARGET: line (trimmed). Returns "" if no #TARGET: line is present.
func GetTmpDir ¶ added in v1.3.0
func GetTmpDir() string
GetTmpDir returns the best available tmp directory for condatainer builds. Priority:
- CNT_TMPDIR (explicit override)
- Scheduler-specific local node storage: SLURM_TMPDIR, PBS_TMPDIR, LSF_TMPDIR, _CONDOR_SCRATCH_DIR
- TMPDIR (POSIX standard)
- /tmp (always available)
Always appends cnt-$USER to avoid collisions between users.
func GetWhatIsFromScript ¶ added in v1.2.0
GetWhatIsFromScript reads a script and extracts the first #WHATIS: line. Returns the trimmed description string, or empty string if not found.
func HighlightTemplatePlaceholders ¶ added in v1.4.0
HighlightTemplatePlaceholders renders a #TARGET: pattern with {var} tokens in yellow-bold and the surrounding literal path segments in default color.
func InterpolateVars ¶ added in v1.4.0
InterpolateVars replaces {varname} occurrences in s with the corresponding value from vars. Unknown keys are left unchanged.
func IsCondaFile ¶ added in v1.5.1
IsCondaFile reports whether path is a Conda environment input file: a YAML environment file (.yaml/.yml) or an explicit/spec text file (.txt, e.g. the @EXPLICIT output of `export -e`). All are accepted by `micromamba create -f`.
func IsImg ¶
IsImg checks if the path has an ext3 overlay extension (.img, .ext3). Note: In Apptainer context, these imply a writable ext3 overlay.
func IsInteractiveShell ¶
func IsInteractiveShell() bool
IsInteractiveShell checks if stdout is connected to a TTY (interactive terminal). Returns true if the program is running in an interactive shell, false otherwise.
func IsOverlay ¶
IsOverlay checks if the path is an overlay file (.img, .sqf, .sqsh, .squashfs). This is used for CondaTainer overlay detection.
func IsSif ¶
IsSif checks if the path has a Singularity Image Format extension (.sif). This is the native format for Apptainer/Singularity.
func IsSqf ¶
IsSqf checks if the path has a SquashFS extension (.sqf, .sqsh, .squashfs). These are read-only compressed images.
func IsStdinPiped ¶ added in v1.4.0
func IsStdinPiped() bool
IsStdinPiped returns true if stdin is a pipe or redirected (not a TTY).
func LatestVersion ¶ added in v1.5.0
LatestVersion returns the first (newest) entry in a versions list, or "" if empty.
func MakeExecutable ¶ added in v1.5.1
MakeExecutable adds an execute bit wherever the matching read bit is set (x where r), then shares with the parent group. Mirroring the read bits keeps it umask-respecting, unlike os.Chmod(path, PermExec) which forces 0775 and leaks group/other-write into personal installs — so prefer this whenever a created file must be made executable.
func MatchTemplateTarget ¶ added in v1.4.0
MatchTemplateTarget extracts placeholder values from a concrete name by matching it against a template pattern (e.g. a #TARGET: or #DEP: line containing {var} tokens). Returns the vars map and true on a full match, or nil and false otherwise.
func MatchVersion ¶ added in v1.5.0
MatchVersion does a partial version match against a list sorted newest-first. Input "3.12" matches the first entry beginning with "3.12." (latest patch). Exact match always takes priority. Returns input unchanged if nothing matches.
func MkdirAllShared ¶ added in v1.5.1
MkdirAllShared is os.MkdirAll plus ShareWithParentGroup on every level it creates, so nested dirs under a shared "2775" tree all become group-writable. Pre-existing dirs are left untouched. Prefer this over os.MkdirAll for data/state directories.
func NormalizeNameVersion ¶
NormalizeNameVersion normalizes package spec formats so that "name/version", "name=version", "name@version" are treated the same. Converts = and @ to /, and -- to /, then strips whitespace. Any version constraint suffix (e.g. ">=1.10") is preserved as-is.
func ParseDHMSTime ¶ added in v1.2.0
ParseDHMSTime handles colon-separated and D-HH:MM:SS walltime formats.
func ParseHMSTime ¶ added in v1.2.0
ParseHMSTime parses colon-separated walltime "HH:MM:SS", "HH:MM", or "MM" (bare minutes).
func ParseMemoryMB ¶ added in v1.2.0
ParseMemoryMB parses memory strings like "8G", "1024M", "512K", "1T" into MB (int64). Default unit is MB when no suffix is given.
func ParseMemoryMBWithDefault ¶ added in v1.3.0
ParseMemoryMBWithDefault parses a memory string into MB. When the string has an explicit unit suffix (G/GB/M/MB/K/KB/T/TB) it is used directly. For bare numbers the provided defaultUnit is applied (e.g. "KB", "MB", "GB").
func ParseSizeToMB ¶
ParseSizeToMB converts strings like "10G", "500M", "1024" into Megabytes (int). Default unit is MB if no suffix is provided. Delegates to ParseMemoryMB.
func ParseValueList ¶ added in v1.5.1
ParseValueList parses a value specification. It backs both build script #PL: headers and helper #VALUE: headers so the two share one dialect.
The separator selects the ordering:
"3.10,3.9,3.8" comma → sorted descending (version lists) "kasm | turbo" pipe → author's order preserved (labels)
In either form:
- "a-b" expands to every integer in [a, b].
- "*" marks the list open-ended (any value accepted). It is reported via the returned bool and appended as the final element, so index 0 stays the default.
- Duplicates are dropped and surrounding whitespace trimmed.
An "EXPR:..." spec is returned verbatim as a single element. Returns an error when the list ends up with no values and is not open-ended.
func ParseWalltime ¶ added in v1.2.0
ParseWalltime parses a walltime string into a duration. Supported formats:
Compound (Go-style, with int day): 4d12h, 2h30m, 3h, 90m, 1d2h30m45s, 1.5h
Colon-separated: D-HH:MM:SS, HH:MM:SS, HH:MM, MM
func PrintDebug ¶
PrintDebug prints a debug message with a Gray prefix (only if DebugMode is true). → stderr Output: [CNT…] Executing: rm -rf /tmp/foo
func PrintError ¶
PrintError prints an error message with a Red prefix. → stderr Output: [CNT✗] Something failed.
func PrintHint ¶
PrintHint prints a helpful hint with a Cyan prefix. → stderr Output: [CNT▶] Try running with --force.
func PrintMessage ¶
PrintMessage prints a standard info message. → stderr Output: [CNT] Message...
func PrintNote ¶
PrintNote prints a note with a Magenta prefix. → stderr Output: [CNT◇] This might take a while.
func PrintSuccess ¶
PrintSuccess prints a success message with a Green prefix. → stderr Output: [CNT✓] Operation complete.
func PrintWarning ¶
PrintWarning prints a warning with a Yellow prefix. → stderr Output: [CNT!] Disk is almost full.
func ReadGzipJSONFile ¶ added in v1.3.0
ReadGzipJSONFile opens a .json.gz file and decodes JSON into out.
func ReadLineContext ¶ added in v1.2.0
ReadLineContext reads a trimmed line from stdin, preserving case. Returns context.Canceled if ctx is done before input arrives.
func RemoveDirIfEmpty ¶ added in v1.3.0
func RemoveDirIfEmpty(dir string)
RemoveDirIfEmpty removes dir if it exists and contains no files or subdirectories. Silently does nothing if dir is not empty or does not exist.
func ShareWithParentGroup ¶ added in v1.5.1
func ShareWithParentGroup(path string)
ShareWithParentGroup grants the group g+rw (plus g+x on dirs and executables) when path's parent is group-writable, and does nothing otherwise — so files land group-writable in a shared "2775" install and untouched in a personal one. Best-effort: errors are ignored (path may be on another owner's dir).
func ShouldAnswerYes ¶
func ShouldAnswerYes() bool
ShouldAnswerYes checks if we should automatically answer yes to prompts Returns true if --yes flag is set, false otherwise
func SortVersionsDescending ¶ added in v1.4.0
SortVersionsDescending sorts version strings in descending natural order. Segments are split on ".", "-", or "_" and compared numerically when both segments are integers, otherwise lexicographically. The highest version comes first.
func SplitDepConstraint ¶ added in v1.4.0
SplitDepConstraint splits a raw dep string into its nameVersion and optional version constraint. Supports ">=" and ">" operators. Example: "samtools/1.21>=1.16" → ("samtools/1.21", ">=", "1.16") Example: "samtools/1.21" → ("samtools/1.21", "", "")
func StripInlineComment ¶ added in v1.2.0
StripInlineComment removes everything after the first '#' character (inline comment). Returns the trimmed string without the comment.
func StyleAction ¶
StyleAction formats verbs or active operations (Yellow).
func StyleDebug ¶
StyleDebug formats low-level technical info (Gray).
func StyleError ¶
StyleError formats critical failure messages (Red).
func StyleHighlight ¶
StyleHighlight formats search matches or highlighted text (Yellow Bold).
func StyleNumber ¶
StyleNumber formats counts, sizes, or IDs (Magenta).
func StyleSuccess ¶
StyleSuccess formats success messages (Green).
func StyleWarning ¶
StyleWarning formats non-critical warnings (Yellow).
func TruncateWords ¶ added in v1.4.0
TruncateWords returns s truncated to at most n words, appending "..." if truncated.
func URLExists ¶
URLExists checks if a URL exists (returns HTTP 200) using a HEAD request. Returns false if ctx is cancelled.
func ValidateTemplatePlaceholders ¶ added in v1.5.1
ValidateTemplatePlaceholders checks that a #TARGET: pattern and the #PL: declarations of a build script agree with each other. Every declared placeholder must appear as a {name} token in target, and every {name} token in target must have a matching declaration.
A declared placeholder missing from target would make every one of its values interpolate to the same name, silently collapsing the expansion to one entry; a token with no declaration would be left uninterpolated in the entry name. Returns one human-readable message per problem, or nil when the template is valid.
func VersionChoicesDisplay ¶ added in v1.5.0
VersionChoicesDisplay formats a newest-first full-patch list into grouped minor version summary strings: ["3.13.2","3.12.10","3.11.12"] → ["3.13(.2)", "3.12(.10)", "3.11(.12)"].
func WriteGzipJSONFileAtomic ¶ added in v1.3.0
WriteGzipJSONFileAtomic encodes value as JSON, writes it as .json.gz to a temp file, then atomically renames it to path.
Types ¶
type ApptainerFilter ¶ added in v1.5.1
type ApptainerFilter struct {
// contains filtered or unexported fields
}
ApptainerFilter is an io.Writer that drops Apptainer log lines whose prefix is in drop (e.g. noisy bind-mount warnings) and forwards the rest. Partial lines are buffered until a newline; call Flush to emit a trailing unterminated line.
func NewApptainerFilter ¶ added in v1.5.1
func NewApptainerFilter(w io.Writer, dropPrefixes ...string) *ApptainerFilter
NewApptainerFilter wraps w, dropping lines that start with any of dropPrefixes.
func (*ApptainerFilter) Flush ¶ added in v1.5.1
func (f *ApptainerFilter) Flush() error
Flush emits any buffered line that has no trailing newline.
type CondaSearchResult ¶ added in v1.4.0
type CondaSearchResult struct {
Name string `json:"name"`
Channel string `json:"owner"` // anaconda.org uses "owner" for the channel name
Summary string `json:"summary"`
Versions []string `json:"versions"`
Platforms []string `json:"conda_platforms"` // supported conda platforms, e.g. ["linux-64", "osx-arm64"]
}
CondaSearchResult holds a single result from the anaconda.org search API.
func SearchCondaPackages ¶ added in v1.4.0
func SearchCondaPackages(name string, channels []string, fuzzy bool, limit int) ([]CondaSearchResult, bool, error)
SearchCondaPackages looks up conda packages on anaconda.org.
Exact match (default): queries /package/<channel>/<name> for each channel in order and returns the first hit — matching install behaviour.
Fuzzy match (fuzzy=true): issues two requests to /search?name=<query> — one for the current platform (e.g. linux-64) and one for noarch — then merges and deduplicates the results. Two requests are required because the API only accepts a single platform value and silently drops noarch-only packages when a platform filter is set. Returns capped=true if either request hit the limit (results may be incomplete).
Versions within each result are sorted descending.
type PlaceholderDef ¶ added in v1.4.0
type PlaceholderDef struct {
Name string
Values []string // sorted desc concrete values; last element is "*" if Open
Open bool // true if * was present in the original list
}
PlaceholderDef holds a single #PL: declaration from a build script. Values are sorted descending (natural version sort); if Open is true, the last element of Values is "*" indicating any input is accepted.
func GetPlaceholdersFromScript ¶ added in v1.4.0
func GetPlaceholdersFromScript(scriptPath string) ([]PlaceholderDef, error)
GetPlaceholdersFromScript parses a build script and returns all #PL: declarations in declaration order. Values are sorted descending; if the list contained "*" the last element is "*" and Open is true.