Documentation
¶
Overview ¶
Package shell provides shell script parsing utilities for Dockerfile linting.
Package shell provides shell script parsing utilities for Dockerfile linting.
Package shell provides shell script parsing utilities for Dockerfile linting.
Package shell provides shell script parsing utilities for Dockerfile linting.
Package shell provides shell script parsing utilities for Dockerfile linting. It wraps mvdan.cc/sh/v3/syntax to provide a simple API for extracting command names from shell scripts, similar to how hadolint uses ShellCheck.
Index ¶
- Variables
- func Basename(p string) string
- func CommandNames(script string) []string
- func CommandNamesWithVariant(script string, variant Variant) []string
- func ContainsCommand(script, command string) bool
- func ContainsCommandWithVariant(script, command string, variant Variant) bool
- func CountChainedCommands(script string, variant Variant) int
- func DockerfileRunCommandStartCol(firstLine string) int
- func DownloadOutputFile(cmd *CommandInfo) string
- func DownloadURL(cmd *CommandInfo) string
- func DropQuotes(s string) string
- func ExtractChainSeparators(script string, variant Variant, commandCount int) []string
- func ExtractChainedCommands(script string, variant Variant) []string
- func ExtractCommandsBetweenCds(remaining string, variant Variant) string
- func FormatChainedScript(script string, variant Variant) string
- func FormatOctalMode(mode uint16) string
- func FormatStatement(stmt *syntax.Stmt, variant Variant) string
- func HasCdAtStart(script string, variant Variant) bool
- func HasExitCommand(script string, variant Variant) bool
- func HasPipes(script string, variant Variant) bool
- func HasStandaloneCd(script string, variant Variant) bool
- func IsArchiveFilename(name string) bool
- func IsArchiveURL(s string) bool
- func IsHeredocCandidate(script string, variant Variant, minCommands int) bool
- func IsPureFileCreation(script string, variant Variant) bool
- func IsSimpleScript(script string, variant Variant) bool
- func IsTarExtract(cmd *CommandInfo) bool
- func IsURL(s string) bool
- func IterateWrapperArgs(args []*syntax.Word, wrapperName string, callback func(WrapperArg) bool)
- func LooksLikeJSONExecForm(script string, variant Variant) bool
- func NextShellToken(s string, start int) (string, int)
- func NormalizeShellExecutableName(exe string) string
- func ParseOctalMode(s string) uint16
- func ReconstructSourceText(lines []string, cmdStartCol int, escapeToken rune) string
- func ScriptHasInlineHeredoc(script string, variant Variant) bool
- func SetsErrorFlag(cmd string, variant Variant) bool
- func ShellFromShebang(line string) (string, bool)
- func SkipDockerfileFlagValue(line string, offset int, stopAtLineContinuation bool) int
- func SkipShellTokenSpaces(s string, start int) int
- func SplitSimpleCommand(cmd string, variant Variant) ([]string, bool)
- func TarDestination(cmd *CommandInfo) string
- type CdCommand
- type ChainBoundary
- type ChainPosition
- type ChmodInfo
- type CmdScriptAnalysis
- type CommandInfo
- type CommandMatcher
- type CommandOccurrence
- type ExplicitShellInvocation
- type FileCreationInfo
- type InstallCommand
- type PackageArg
- type PackageInstallInfo
- type PackageManager
- type Variant
- type WrapperArg
Constants ¶
This section is empty.
Variables ¶
var ArchiveExtensions = []string{
".tar.lzma",
".tar.bz2",
".tar.gz",
".tar.xz",
".tar.zst",
".tar.lz",
".tar.Z",
".lzma",
".tbz2",
".tzst",
".tar",
".tbz",
".tb2",
".tgz",
".tlz",
".tpz",
".txz",
".bz2",
".tZ",
".gz",
".lz",
".xz",
".Z",
}
ArchiveExtensions is the unified superset of archive file extensions recognized by both DL3010 (hadolint) and prefer-add-unpack (tally). Sorted longest-first so suffix matching is greedy (e.g. ".tar.gz" is checked before ".gz").
var DownloadCommands = []string{"curl", "wget", invokeWebRequestCommand, iwrCommand}
DownloadCommands lists commands that download remote files.
var ExtractionCommands = []string{
"bunzip2",
"gzcat",
"gunzip",
"uncompress",
"unlzma",
"unxz",
"unzip",
"zcat",
"zgz",
}
ExtractionCommands lists commands that extract archive files (excluding tar, which needs separate flag checking via IsTarExtract).
Functions ¶
func Basename ¶
Basename extracts the filename from a path, stripping quotes and handling both Unix and Windows separators.
func CommandNames ¶
CommandNames extracts all command names from a shell script. Uses VariantBash by default. Use CommandNamesWithVariant for other shells.
func CommandNamesWithVariant ¶
CommandNamesWithVariant extracts all command names from a shell script using the specified shell variant for parsing.
It parses the script and walks the AST to find all CallExpr nodes, returning the first word of each (the command name). It also handles command wrappers (env, nice, xargs, etc.) and shell wrappers (sh -c, bash -c).
This matches hadolint's behavior using ShellCheck.findCommandNames.
func ContainsCommand ¶
ContainsCommand checks if a shell script contains a specific command. Uses VariantBash by default.
func ContainsCommandWithVariant ¶
ContainsCommandWithVariant checks if a shell script contains a specific command using the specified shell variant for parsing.
func CountChainedCommands ¶
CountChainedCommands counts the number of commands in && chains within a shell script. Pipelines (|) count as a single logical command. Top-level statements separated by semicolons or newlines are counted individually.
func DockerfileRunCommandStartCol ¶ added in v0.28.1
DockerfileRunCommandStartCol returns the byte offset where the shell command begins in the first line of a RUN instruction, after RUN and any leading flags.
func DownloadOutputFile ¶
func DownloadOutputFile(cmd *CommandInfo) string
DownloadOutputFile extracts the output filename from a curl or wget CommandInfo. For curl: -o <file>, -o<file>, --output <file>, --output=<file> For wget: -O <file>, -O<file>, --output-document <file>, --output-document=<file> Returns "" if no output file is specified or if output is stdout ("-").
func DownloadURL ¶
func DownloadURL(cmd *CommandInfo) string
DownloadURL extracts the first URL argument (http/https/ftp) from a download CommandInfo. Returns "" if no URL is found.
func DropQuotes ¶
DropQuotes removes surrounding single or double quotes from a string.
func ExtractChainSeparators ¶ added in v0.10.0
ExtractChainSeparators returns the raw separator text between commands in an && chain (for example " && " or " && \\\n "). The result length is commandCount-1 on success; otherwise nil.
func ExtractChainedCommands ¶
ExtractChainedCommands extracts individual command strings from && chains. Each command is formatted cleanly using the shell printer. Returns nil if parsing fails or for non-POSIX shells.
func ExtractCommandsBetweenCds ¶
ExtractCommandsBetweenCds parses the remaining commands after a cd and extracts commands that come before the next cd. This properly handles quoted paths. For "make && cd /tmp && build", if we're looking for commands before "cd /tmp", this returns "make".
func FormatChainedScript ¶ added in v0.11.0
FormatChainedScript formats a shell script so that each top-level &&/|| chain operator starts on its own line. Uses the mvdan.cc/sh/v3 printer with BinaryNextLine for correct shell formatting. Returns the original script text (trimmed) if parsing fails or there are no chain operators.
The output uses tab indentation for continuation lines (Indent(0) = tabs).
func FormatOctalMode ¶
FormatOctalMode formats a chmod mode as a 4-digit octal string. E.g., 0o755 -> "0755", 0o644 -> "0644" Returns empty string for 0 (no mode).
func FormatStatement ¶
FormatStatement formats a single statement using syntax.Printer. Returns a clean, single-line representation of the command.
func HasCdAtStart ¶
HasCdAtStart returns true if the script has cd at the beginning of a command chain.
func HasExitCommand ¶
HasExitCommand checks if a script contains exit commands that would change control flow if merged with other commands.
func HasPipes ¶
HasPipes checks if a shell script contains any pipe operators (| or |&). Returns false for non-POSIX shells or unparseable scripts.
func HasStandaloneCd ¶
HasStandaloneCd returns true if the script contains a standalone cd command (one that isn't chained with other commands).
func IsArchiveFilename ¶
IsArchiveFilename checks if a filename has a recognized archive extension. Extensions are case-sensitive (e.g. .Z and .tZ use uppercase Z for Unix compress format).
func IsArchiveURL ¶
IsArchiveURL checks if a URL string points to an archive file. Strips query/fragment before checking extension. Requires http/https/ftp scheme.
func IsHeredocCandidate ¶
IsHeredocCandidate checks if a shell script would be a good candidate for heredoc conversion by the prefer-run-heredoc rule. This is used by other rules (like DL3003) to avoid generating fixes that would interfere with heredoc conversion.
A script is a heredoc candidate if:
- It uses a POSIX shell
- It has at least minCommands commands (from && chains or separate statements)
- It's a simple script (no complex control flow like if/for/while)
This function parses the script once and reuses the AST for all checks.
func IsPureFileCreation ¶
IsPureFileCreation checks if a shell script is PURELY for creating files. Returns true only if every command in the script is for file creation (echo/cat/printf > file) or chmod on the created file. Returns false if there are any other commands mixed in. This is used by prefer-run-heredoc to yield to prefer-copy-heredoc.
func IsSimpleScript ¶
IsSimpleScript checks if a script contains only simple commands that can be safely merged into a heredoc. Returns false for scripts with compound commands (if, for, while, case), control flow (return, break, continue, exec), functions, or subshells. `exit` is allowed so that common guard patterns like `cd dir || exit` (often suggested by ShellCheck) don't block heredoc conversion.
func IsTarExtract ¶
func IsTarExtract(cmd *CommandInfo) bool
IsTarExtract checks if a tar CommandInfo has extraction flags (-x, --extract, --get).
func IterateWrapperArgs ¶
func IterateWrapperArgs(args []*syntax.Word, wrapperName string, callback func(WrapperArg) bool)
IterateWrapperArgs iterates through wrapper command arguments, skipping flags and their values, and calls the callback for each potential command argument found. This handles the common pattern of finding commands within sudo, env, etc.
The callback should return true to break iteration, false to continue looking for nested wrappers.
func LooksLikeJSONExecForm ¶ added in v0.28.0
LooksLikeJSONExecForm reports whether a shell script fragment appears to be a Docker JSON exec-form attempt that was not valid JSON. It uses the active shell variant's parser to distinguish valid shell syntax from likely exec-form mistakes.
For POSIX shells (bash, sh, etc.), the script is parsed with mvdan.cc/sh and the AST is inspected: a top-level CallExpr whose first word starts with [ or last word ends with ] signals a likely JSON attempt, while proper test constructs (TestClause, BinaryCmd) are recognized as valid shell.
For PowerShell, the tree-sitter grammar is used: if the script parses without errors, it is valid PowerShell (e.g., [ClassName]::Method) and not JSON.
func NextShellToken ¶ added in v0.27.2
NextShellToken returns the next shell-like token starting at or after start.
func NormalizeShellExecutableName ¶ added in v0.27.2
NormalizeShellExecutableName canonicalizes a shell executable path/name to its lowercase basename without a trailing .exe suffix.
func ParseOctalMode ¶
ParseOctalMode parses an octal mode string (e.g., "755", "0755") to uint16. Returns 0 for invalid input.
func ReconstructSourceText ¶ added in v0.11.0
ReconstructSourceText reconstructs the shell command source text from Dockerfile source lines. Backslash-newline continuations are kept intact because the shell parser (mvdan.cc/sh) handles them natively. This preserves line/col positions for mapping back to the Dockerfile.
cmdStartCol is the byte offset in the first line where the command starts (after RUN + flags). Continuation lines are included in full. ReconstructSourceText joins Dockerfile instruction lines into a single string for the shell parser, respecting the Dockerfile escape token.
When the escape token is not backslash (e.g. backtick for Windows Dockerfiles), trailing escape characters on continuation lines are replaced with backslash so the bash shell parser handles line continuations correctly.
func ScriptHasInlineHeredoc ¶ added in v0.11.0
ScriptHasInlineHeredoc checks whether a shell script contains inline heredocs (e.g., cat <<EOF ... EOF && other_cmd). Such scripts should not have their chain boundaries reformatted because the heredoc body positions would break.
func SetsErrorFlag ¶
SetsErrorFlag checks if a command is a "set" builtin that enables the -e flag. Uses shell AST to properly detect any flag combination containing 'e' (e.g., "set -e", "set -ex", "set -euo pipefail").
func ShellFromShebang ¶ added in v0.19.0
ShellFromShebang extracts the shell name from a shebang line. It delegates to fileutil.Shebang for the common cases (sh, bash, mksh, bats, zsh) and adds ksh support for Dockerfile compatibility.
Returns the normalized shell name (e.g., "bash", "sh", "ksh") and true if a known shell shebang was found. The returned name can be passed directly to VariantFromShell.
func SkipDockerfileFlagValue ¶ added in v0.28.1
SkipDockerfileFlagValue advances past a Dockerfile flag token starting at the provided offset. When stopAtLineContinuation is true, a trailing backslash is treated as the end of the token instead of part of the token.
func SkipShellTokenSpaces ¶ added in v0.27.2
SkipShellTokenSpaces advances over whitespace in shell-like command lines.
func SplitSimpleCommand ¶
SplitSimpleCommand parses a shell command string and returns its argv words.
This is intentionally conservative: it only succeeds for a single simple command without redirections, pipelines, boolean operators, variable expansions, command substitutions, or other shell-specific constructs.
This is useful for suggesting "exec form" JSON arrays for Dockerfile instructions like CMD/ENTRYPOINT when the shell form is trivially tokenizable.
func TarDestination ¶
func TarDestination(cmd *CommandInfo) string
TarDestination extracts the target directory from a tar CommandInfo. Checks -C <dir>, --directory=<dir>, --directory <dir>. Returns "" if none found.
Types ¶
type CdCommand ¶
type CdCommand struct {
// TargetDir is the directory argument passed to cd.
TargetDir string
// IsStandalone is true if cd is the only command (not chained with && or ;).
IsStandalone bool
// IsAtStart is true if cd is at the beginning of a command chain.
// e.g., "cd /foo && make" has cd at start, "make && cd /foo" does not.
IsAtStart bool
// PrecedingCommands contains the commands before cd if it's not at the start.
// e.g., for "mkdir /tmp && cd /tmp && make", this would be "mkdir /tmp".
PrecedingCommands string
// RemainingCommands contains the commands after "cd /foo &&" if IsAtStart is true.
// Empty if IsStandalone is true or cd is not at start.
RemainingCommands string
// StartCol is the 0-based column where cd starts.
StartCol int
// Line is the 0-based line number.
Line int
}
CdCommand represents a cd command found in a shell script.
func FindCdCommands ¶
FindCdCommands finds all cd commands in a shell script and analyzes their context.
type ChainBoundary ¶ added in v0.11.0
type ChainBoundary struct {
// LeftEndLine is the 1-based line (in the parsed text) where the left command ends.
LeftEndLine int
// LeftEndCol is the 1-based column where the left command ends.
LeftEndCol int
// OpLine is the 1-based line where the operator (&&/||) starts.
OpLine int
// OpCol is the 1-based column where the operator (&&/||) starts.
OpCol int
// RightStartLine is the 1-based line where the right command starts.
RightStartLine int
// RightStartCol is the 1-based column where the right command starts.
RightStartCol int
// Op is the operator text ("&&" or "||").
Op string
// SameLine is true when left end and right start are on the same source line.
SameLine bool
}
ChainBoundary represents the position of a chain operator (&&/||) between two commands in a shell script's source text.
func CollectChainBoundaries ¶ added in v0.11.0
func CollectChainBoundaries(scriptText string, variant Variant) ([]ChainBoundary, int)
CollectChainBoundaries parses a shell script and returns all top-level chain boundaries (&& and ||) along with the maximum per-chain command count. The per-chain count reflects the longest &&/|| chain in any single statement, not the sum across semicolon-separated statements. This is the correct value for comparing against a minCommands threshold.
The script text should include backslash continuations exactly as they appear in the Dockerfile source so that line/col positions map correctly.
Returns nil, 0 if parsing fails or for non-POSIX shells.
type ChainPosition ¶
type ChainPosition struct {
// IsStandalone is true if this is the only command (not chained).
IsStandalone bool
// HasOtherStatements is true when the script contains multiple top-level
// statements separated by semicolons or newlines. In this case,
// PrecedingCommands and RemainingCommands only cover the chain within
// the matched statement and do NOT include commands from other statements.
// Callers building replacement text for the entire script must not use
// this position alone, as it would silently drop sibling statements.
HasOtherStatements bool
// PrecedingCommands contains the commands before this one in the chain.
// Empty when the command is at the start or standalone.
PrecedingCommands string
// RemainingCommands contains the commands after this one in the chain.
// Empty when the command is at the end or standalone.
RemainingCommands string
}
ChainPosition describes a command's position within a && chain.
func FindCommandInChain ¶
func FindCommandInChain(script string, variant Variant, match CommandMatcher) *ChainPosition
FindCommandInChain locates the first command matching the predicate in a shell script and returns its chain context (preceding/remaining commands). Returns nil if no matching command is found or the script fails to parse.
type ChmodInfo ¶
type ChmodInfo struct {
// Mode is the octal mode (e.g., 0o755, 0o644, 0o4755).
Mode uint16
// Target is the file path being chmod'd.
Target string
}
ChmodInfo describes a standalone chmod command.
func DetectStandaloneChmod ¶
DetectStandaloneChmod checks if a shell script is a standalone chmod command. Returns nil if it's not a pure chmod or if the chmod cannot be converted (e.g., symbolic mode, recursive chmod, multiple commands).
type CmdScriptAnalysis ¶ added in v0.27.2
type CmdScriptAnalysis struct {
Commands []CommandInfo
HasConditionals bool
HasPipes bool
HasRedirections bool
HasControlFlow bool
HasVariableReferences bool
}
CmdScriptAnalysis captures the cmd.exe syntax traits that matter for fix safety when rewriting a stage to PowerShell.
func AnalyzeCmdScript ¶ added in v0.27.2
func AnalyzeCmdScript(script string) *CmdScriptAnalysis
AnalyzeCmdScript parses a cmd.exe script and returns the command list plus shell-feature signals used by Windows-safe autofixes.
func (*CmdScriptAnalysis) HasBatchOnlySyntax ¶ added in v0.27.2
func (a *CmdScriptAnalysis) HasBatchOnlySyntax() bool
HasBatchOnlySyntax reports whether the script uses cmd.exe shell semantics that should block generic rewrites to PowerShell.
type CommandInfo ¶
type CommandInfo struct {
// Variant is the shell variant used to parse this command.
Variant Variant
// Name is the base command name (e.g., "apt-get", "yum").
Name string
// Subcommand is the first non-flag argument (e.g., "install" in "apt-get install").
Subcommand string
// Args contains all arguments including flags.
Args []string
// Position information for the command name.
Line int // 0-based line within the script
StartCol int // 0-based column where command starts
EndCol int // 0-based column where command name ends
// Position information for the subcommand (if present).
// These are only set when Subcommand is non-empty.
SubcommandLine int // 0-based line within the script
SubcommandStartCol int // 0-based column where subcommand starts
SubcommandEndCol int // 0-based column where subcommand ends
}
CommandInfo represents a parsed command with its arguments and flags.
func FindCommands ¶
func FindCommands(script string, variant Variant, names ...string) []CommandInfo
FindCommands extracts all commands matching the given name(s) from a shell script. It returns detailed CommandInfo for each matching command.
func (*CommandInfo) CountFlag ¶
func (c *CommandInfo) CountFlag(flag string) int
CountFlag counts how many times a flag appears in the command. Useful for checking flags like -q -q (equivalent to -qq).
func (*CommandInfo) GetArgValue ¶
func (c *CommandInfo) GetArgValue(flag string) string
GetArgValue returns the value following a flag (e.g., "-q=2" returns "2"). Returns empty string if not found or no value.
func (*CommandInfo) HasAnyArg ¶
func (c *CommandInfo) HasAnyArg(args ...string) bool
HasAnyArg checks if any of the specified arguments are present as the subcommand.
func (*CommandInfo) HasAnyFlag ¶
func (c *CommandInfo) HasAnyFlag(flags ...string) bool
HasAnyFlag checks if the command has any of the specified flags.
func (*CommandInfo) HasFlag ¶
func (c *CommandInfo) HasFlag(flag string) bool
HasFlag checks if the command has a specific flag. Handles both short flags (-y) and long flags (--yes). For short flags, also checks combined flags (e.g., -yq contains -y).
type CommandMatcher ¶
CommandMatcher is a predicate that decides whether a shell call expression is the command to locate. name is the base command name (path stripped), args are all arguments (flags and positional).
type CommandOccurrence ¶
type CommandOccurrence struct {
// Name is the command name (e.g., "apt", "sudo").
Name string
// Subcommand is the first argument if it looks like a subcommand (e.g., "install" in "apt install").
// Empty if the first argument looks like a flag or there are no arguments.
Subcommand string
// StartCol is the 0-based column offset where the command starts.
StartCol int
// EndCol is the 0-based column offset where the command name ends (exclusive).
EndCol int
// Line is the 0-based line number within the script where the command appears.
Line int
}
CommandOccurrence represents a command with its exact position in the script.
func FindAllCommandOccurrences ¶
func FindAllCommandOccurrences(script, command string, variant Variant) []CommandOccurrence
FindAllCommandOccurrences finds all occurrences of a specific command.
func FindCommandOccurrence ¶
func FindCommandOccurrence(script, command string, variant Variant) *CommandOccurrence
FindCommandOccurrence finds the first occurrence of a specific command. Returns nil if the command is not found.
func FindCommandOccurrences ¶
func FindCommandOccurrences(script string, variant Variant) []CommandOccurrence
FindCommandOccurrences extracts all command positions from a shell script. It returns occurrences with precise byte offsets for each command found.
type ExplicitShellInvocation ¶ added in v0.27.2
ExplicitShellInvocation describes a shell wrapper explicitly invoked at the start of a shell-form instruction body, e.g. "pwsh -Command ..." or "cmd /c ...".
func ParseExplicitShellInvocation ¶ added in v0.27.2
func ParseExplicitShellInvocation(script string) (ExplicitShellInvocation, bool)
ParseExplicitShellInvocation detects a leading shell wrapper invocation and returns the wrapper shell plus the payload passed to that shell.
type FileCreationInfo ¶
type FileCreationInfo struct {
// TargetPath is the absolute path to the target file.
TargetPath string
// Content is the literal content to write.
Content string
// ChmodMode is the octal chmod mode (e.g., 0o755, 0o644), or 0 if no chmod.
ChmodMode uint16
// IsAppend is true if ALL writes in the chain use >> (append) mode.
// If true, converting to COPY would lose existing file content.
// A later > (overwrite) clears this flag since content no longer depends on existing data.
IsAppend bool
// HasUnsafeVariables is true if the script uses variables that cannot be
// converted to COPY heredoc (e.g., shell variables, command substitution).
HasUnsafeVariables bool
// PrecedingCommands contains commands before the file creation (for mixed scripts).
// Empty if file creation is at the start or script is pure file creation.
PrecedingCommands string
// RemainingCommands contains commands after the file creation (for mixed scripts).
// Empty if file creation is at the end or script is pure file creation.
RemainingCommands string
}
FileCreationInfo describes a detected file creation pattern in a shell script. This is used to coordinate between prefer-copy-heredoc and prefer-run-heredoc rules.
func DetectFileCreation ¶
func DetectFileCreation(script string, variant Variant, knownVars func(name string) bool) *FileCreationInfo
DetectFileCreation analyzes a shell script for file creation patterns. Returns nil if the script is not primarily a file creation operation.
Detected patterns:
- echo "content" > /path/to/file
- echo "content" >> /path/to/file (append)
- cat <<EOF > /path/to/file ... EOF
- printf "content" > /path/to/file (limited support)
- tee /path/to/file (with heredoc stdin)
Also detects chmod chaining: echo "x" > /file && chmod 0755 /file
The knownVars function is called to check if a variable is a known ARG/ENV. If nil, all variables are considered unsafe.
type InstallCommand ¶ added in v0.20.0
type InstallCommand struct {
Manager string // e.g., "apt-get", "npm", "pip"
Subcommand string // e.g., "install", "add", "require"
Packages []PackageArg // non-flag args after subcommand, with positions
}
InstallCommand represents a detected package install command with per-argument positions.
func FindInstallPackages ¶ added in v0.20.0
func FindInstallPackages(script string, variant Variant) []InstallCommand
FindInstallPackages parses a shell script and extracts install commands with per-argument position information. Positions are 0-based line and column offsets within the source text.
type PackageArg ¶ added in v0.20.0
type PackageArg struct {
// Value is the raw source token text (including any quotes), used for
// round-trip safe edits. The edit span (StartCol..EndCol) covers exactly
// these bytes.
Value string
// Normalized is the unquoted/decoded text used for sorting and comparison.
Normalized string
Line int // 0-based line within the source text
StartCol int // 0-based start column (byte offset)
EndCol int // 0-based end column (byte offset, exclusive)
IsVar bool // true if the argument contains a variable reference ($)
}
PackageArg represents a single package argument with its position in the source text.
type PackageInstallInfo ¶
type PackageInstallInfo struct {
Manager PackageManager
Packages []string
}
PackageInstallInfo represents a detected package installation.
func ExtractPackageInstalls ¶
func ExtractPackageInstalls(script string, variant Variant) []PackageInstallInfo
ExtractPackageInstalls parses a shell script and extracts package installations.
type PackageManager ¶
type PackageManager string
PackageManager identifies a system package manager.
const ( PackageManagerApt PackageManager = "apt" PackageManagerApk PackageManager = "apk" PackageManagerYum PackageManager = "yum" PackageManagerDnf PackageManager = "dnf" PackageManagerZypper PackageManager = "zypper" PackageManagerPacman PackageManager = "pacman" PackageManagerEmerge PackageManager = "emerge" PackageManagerUnknown PackageManager = "" )
type Variant ¶
type Variant int
Variant represents a shell variant for parsing and rule gating. It is a bitset so that capability sets can be defined and tested with a single bitwise AND (mirrors mvdan.cc/sh's LangVariant design).
const ( // VariantBash is the GNU Bash shell (default for Docker Linux containers). VariantBash Variant = 1 << iota // VariantPOSIX is the POSIX-compliant shell (sh, dash, ash). VariantPOSIX // VariantMksh is the MirBSD Korn Shell. VariantMksh // VariantZsh is the Z shell. VariantZsh // VariantPowerShell is PowerShell (cross-platform: powershell on Windows, pwsh on Linux/macOS). VariantPowerShell // VariantCmd is the Windows cmd.exe command interpreter. VariantCmd // VariantUnknown is an unrecognized shell. Treated conservatively: no parser support, // not ShellCheck-compatible, not PowerShell. VariantUnknown Variant = 0 )
func VariantFromShell ¶
VariantFromShell returns the appropriate Variant for a shell name. Common shell mappings:
- bash -> VariantBash
- sh, dash, ash -> VariantPOSIX
- mksh, ksh -> VariantMksh
- zsh -> VariantZsh
- powershell, pwsh -> VariantPowerShell
- cmd -> VariantCmd
- unknown -> VariantUnknown
func VariantFromShellCmd ¶
VariantFromShellCmd returns the appropriate Variant from a SHELL command array. The first element is typically the shell path (e.g., ["/bin/bash", "-c"]).
func (Variant) HasParser ¶ added in v0.24.0
HasParser returns true for shells with any parser backend wired into Tally. Use this to guard generic syntax-tree features such as command extraction.
func (Variant) IsPowerShell ¶ added in v0.19.0
IsPowerShell returns true for PowerShell variants (powershell, pwsh). Use this to gate PowerShell-specific lint rules (tally/powershell/*).
func (Variant) IsShellCheckCompatible ¶ added in v0.19.0
IsShellCheckCompatible returns true for shells that ShellCheck can analyze. Use this to guard ShellCheck WASM invocation.
func (Variant) SupportsHeredoc ¶ added in v0.19.0
SupportsHeredoc returns true for shells compatible with BuildKit heredoc syntax (RUN <<EOF). Use this to guard heredoc suggestions and fixes.
func (Variant) SupportsPOSIXShellAST ¶ added in v0.24.0
SupportsPOSIXShellAST returns true for shells represented by mvdan.cc/sh. Use this to guard helpers that depend on POSIX shell syntax/semantics.
type WrapperArg ¶
type WrapperArg struct {
// Arg is the syntax.Word representing this argument
Arg *syntax.Word
// Index is the position in the args slice
Index int
// Name is the base name of the command (path.Base applied)
Name string
// RemainingArgs are the args after this command
RemainingArgs []*syntax.Word
}
WrapperArg represents a potential command argument found within wrapper arguments.