Class: Git::Commands::Arguments Private
- Inherits:
-
Object
- Object
- Git::Commands::Arguments
- Defined in:
- lib/git/commands/arguments.rb
Overview
This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.
This class provides a DSL for mapping Ruby method arguments to git command-line arguments.
Overview
This class provides a DSL for defining how arguments passed to #bind should be mapped to git CLI argument arrays. The process follows four phases:
- Definition of expected CLI arguments and their constraints
- Binding of method arguments to the definition
- Validation of values against argument constraints
- Building of the CLI argument array
See Init for a usage example.
Example: Defining arguments for a command
# 1. Definition of expected CLI arguments and their constraints
args_def = Arguments.define do
flag_option :force
value_option :branch
operand :repository, required: true
end
# 2. Binding of method arguments to the definition
# 3. Validation of values against argument constraints
args = args_def.bind('https://github.com/user/repo', force: true, branch: 'main')
# 4. Building of the CLI argument array
args.to_a # => ['--force', '--branch', 'main', 'https://github.com/user/repo']
# Bonus: accessing bound values
args.force? # => true
args.branch # => 'main'
args.repository # => 'https://github.com/user/repo'
Terminology
This class bridges CLI and Ruby interfaces. While both use the term "arguments" for values passed to commands/methods, they differ in terminology for specific argument types:
| CLI (POSIX) | Ruby Interface | Description |
|---|---|---|
| argument specification | DSL definition | Declared command inputs and constraints |
| arguments | arguments | Values passed when calling a command/method |
| operands | positional arguments | Arguments identified by position |
| options | keyword arguments | Arguments identified by name (--force / force:) |
The following sections explain each interface in detail.
CLI Interface (POSIX)
An argument specification declares what command inputs are accepted and their constraints.
Example:
git branch (--set-upstream-to=<upstream>|-u <upstream>) [<branch-name>]
When a command is invoked, arguments are the values passed to it:
- Arguments: Values passed when calling the command (everything after the command name)
- Operands: Arguments identified by position
- Options: Arguments identified by name (prefixed with
-or--)
Example:
git branch --set-upstream-to=origin/main main
- Operands:
main - Options:
--set-upstream-to=origin/main
Ruby Interface
A DSL definition declares what arguments the #bind method accepts and how they map to CLI arguments.
Example:
Arguments.define do
literal 'branch'
value_option %i[set_upstream_to u], inline: true # primary name with short alias :u
operand :branch_name
end
When #bind is called, arguments are the values passed to it:
- Arguments: Values passed to #bind
- Positional arguments: Arguments identified by position
- Keyword arguments: Arguments identified by name
Example:
args_def.bind('main', set_upstream_to: 'origin/main')
- Positional argument:
'main' - Keyword argument:
set_upstream_to: 'origin/main'
Calling Bound#to_a on the bound result produces the CLI argument array:
args_def.bind('main', set_upstream_to: 'origin/main').to_a
# => ['branch', '--set-upstream-to=origin/main', 'main']
Design
The class operates in two stages:
Definition stage: DSL methods (#flag_option, #value_option, #operand, etc.) record argument definitions in internal data structures.
Bind stage: #bind binds Ruby values and validates them against constraints, returning a Bound object.
The returned Bound object provides accessor methods for the bound values and handles the building phase, converting bound values to CLI arguments via Bound#to_a.
Key internal components:
- +@ordered_definitions+: Array tracking all definitions in definition order
- +@option_definitions+: Hash mapping option names to their definitions
- +@operand_definitions+: Array of operand (positional argument) definitions
- +@alias_map+: Maps option aliases to their primary names
- +BUILDERS+: Hash of lambdas that convert values to CLI arguments by type
- OperandAllocator: Handles Ruby-like operand allocation
Argument Ordering
Arguments are rendered in the exact order they are defined in the DSL block,
regardless of type (options, operands, or static flags). This is important
for git commands where argument order matters, such as when using -- to
separate options from pathspecs.
Use #end_of_options to emit -- only when at least one following operand
produces output, or #literal with '--' when -- must always be present.
Short Option Detection
Option names are automatically formatted using POSIX conventions:
- Single-character names use single-dash prefix:
:f→-f - Multi-character names use double-dash prefix:
:force→--force
For inline values (inline: true), the separator also follows POSIX
conventions:
- Short options use no separator:
-n3 - Long options use
=separator:--name=value
Negated flags always use double-dash format (e.g., -f → --no-f when false).
The as: parameter can override this automatic detection when needed.
Option Types
The DSL supports several option types with modifiers:
Primary Option Types
- #flag_option - Boolean flag (--flag when true, with
negatable: truefor --no-flag) - #value_option - Valued option (--flag value, with
inline: truefor --flag=value, oras_operand: truefor operands) - #flag_or_value_option - Flag or value (--flag when true, --flag value when string,
with
inline: trueand/ornegatable: truemodifiers) - #key_value_option - Key-value option that can be repeated (--trailer key=value)
- #literal - Literal string always included in output
- #custom_option - Custom option with builder block
- #execution_option - Execution option (not included in CLI output, forwarded to command execution)
#value_option supports a repeatable: true parameter that allows the option to accept
an array of values. This repeats the flag for each value (or outputs each as an
operand when using as_operand: true):
Repeatable options:
value_option :config, repeatable: true
# config: ['a=b', 'c=d'] => ['--config', 'a=b', '--config', 'c=d']
value_option :sort, inline: true, repeatable: true
# sort: ['refname', '-committerdate'] => ['--sort=refname', '--sort=-committerdate']
value_option :pathspecs, as_operand: true, repeatable: true
# pathspecs: ['file1.txt', 'file2.txt'] => ['--', 'file1.txt', 'file2.txt']
Common Option Parameters
Most option types support parameters that affect input validation (checked during #bind):
- required: - When true, the option key must be present in the provided opts. Raises ArgumentError if the key is missing. Defaults to false.
Supported by: #flag_option, #value_option, #flag_or_value_option, #key_value_option, #custom_option, #operand.
- allow_nil: - When false (with required: true), the value cannot be nil. Raises ArgumentError if a nil value is provided. Defaults to true for options, false for operands.
Supported by: same as required:.
- type: - Validates the value is an instance of the specified class(es). Accepts a single class or an array of classes. Raises ArgumentError if type doesn't match. This parameter only performs type checking during validation; the conversion of values to CLI argument strings is handled separately during the build phase — see the String Conversion section below. Defaults to nil (no validation).
Supported by: #flag_option, #value_option, #flag_or_value_option.
Note: #literal and #execution_option do not support these validation parameters.
These parameters affect output generation (what CLI arguments are produced):
as: - Override the CLI argument(s) derived from the option name Can be a String or an Array. Default is nil (derives from name).
allow_empty: - (#value_option only) When true, output the option even if the value is an empty string. Default is false (empty strings skipped).
repeatable: - (#value_option, #flag_or_value_option, and #operand only) Output an option or operand for each array element. Default is false.
skip_cli: - (#operand only) Bind, validate, and expose an operand accessor without emitting that operand in Bound#to_a. Default is false.
Operands (Positional Arguments)
Operands are mapped using Ruby-like semantics:
- Post-repeatable required operands are reserved first (from the end)
- Pre-repeatable operands are filled with remaining values (required first, then optional)
- Optional operands (with defaults) get values only if extras are available
- Repeatable operand gets whatever is left in the middle
This matches Ruby's parameter binding behavior, including patterns like def
foo(a = default, *rest, b) where the required b is filled before optional
a.
Nil Handling for Operands
When nil values are allowed (see required: and allow_nil: above), they have
special output behavior:
- For non-repeating operands: nil values consume an operand slot during binding but are omitted from the resulting command-line arguments array
- For repeatable operands: nil values within the array raise an error
Option-like Operand Rejection
Operands that appear before a -- separator boundary in the argument
definition are automatically validated to ensure their values don't start
with -. This prevents user-supplied strings like '-s' from being
misinterpreted as git flags when passed as positional arguments.
The -- boundary can come from:
- A
literal '--'definition - An
end_of_optionsdeclaration
Operands after the -- boundary are not validated (they represent
paths/filenames which may legitimately start with -). If no --
boundary exists in the definition, all operands are validated.
Options After Separator
Options that produce CLI flags (e.g. flag_option, value_option,
key_value_option, custom_option) cannot be defined after a --
separator boundary. Git treats everything after -- as operands, so
flags emitted there would be misinterpreted.
Only value_option with as_operand: true and execution_option are allowed
after the boundary because they do not produce flag-prefixed output.
For example, this will raise +ArgumentError+ during definition:
Arguments.define do
literal '--'
flag_option :verbose
end #=> raises ArgumentError
Type Validation
The type: parameter provides declarative type validation for option values.
When validation fails, an ArgumentError is raised with a descriptive message.
String Conversion
During the build phase, value-bearing option types (value_option,
flag_or_value_option, key_value_option) and operand definitions convert
their bound values to CLI argument strings by calling #to_s. This means any
object with a meaningful #to_s implementation — Integer, Float,
Pathname, etc. — can be passed as a value without the DSL needing to know
about the type.
Note: flag_option values control presence or absence of a flag and are not
stringified. custom_option builders receive the raw value and are responsible
for producing CLI strings themselves.
The type: parameter does not affect this conversion; it only validates the
Ruby class of the value before stringification.
Conflict Detection
Use #conflicts to declare mutually exclusive arguments. Names may refer to options (flag, value, flag-or-value, etc.) or operands (positional arguments) interchangeably. When #bind is called, if more than one argument in a conflict group is "present", an ArgumentError is raised.
An argument is considered present when its value is not nil, false,
[], or ''.
Forbidden Value Combinations
#conflicts is presence-based — it cannot distinguish between semantically equivalent and contradictory combinations of negatable flags. Use #forbid_values to declare specific exact-value tuples that are invalid.
A forbid_values declaration matches only when every listed name has a
bound value equal to the declared value (Ruby ==). Only matching tuples raise
ArgumentError; all other value combinations are permitted. Names may be options
or operands; aliases are canonicalized before comparison.
This is most useful for negatable flags where some value-pairings are contradictory but others are semantically equivalent and should remain valid.
The error message has the form:
"cannot specify :name1=value1 with :name2=value2"
At-Least-One Presence Validation
Use #requires_one_of to declare groups of arguments where at least one must be present. Names may refer to options (flag, value, flag-or-value, etc.) or operands (positional arguments) interchangeably. When #bind is called, if none of the arguments in a group is present, an ArgumentError is raised.
Conditional Argument Requirements
Use #requires and the when: form of #requires_one_of to declare that an
argument (or at least one of a group) must be present only when a specific
trigger argument is present. These constraints are evaluated during #bind: if
the trigger is absent the check is skipped entirely.
An ArgumentError is raised at definition time if either the required name(s) or the trigger name are not known arguments, catching typos early.
Value Constraints
In addition to presence-based validation (#conflicts, #requires_one_of, and #requires) and value-combination constraints (#forbid_values), you can restrict the set of acceptable values for any value-type option using #allowed_values. If a bound value falls outside the configured set, #bind raises ArgumentError with a descriptive message.
This is typically used to model git options that accept only a fixed list of modes or strategies.
Defined Under Namespace
Classes: Bound
Constant Summary collapse
- OPTION_TYPES_AFTER_SEPARATOR =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
Option types allowed after a '--' separator boundary (they do not produce CLI flags)
%i[value_as_operand execution_option].freeze
- VALUE_OPTION_TYPES_FOR_ALLOWED_VALUES =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
Option types that accept a string value — eligible for
allowed_valuesconstraints %i[ value inline_value value_as_operand flag_or_value flag_or_inline_value ].freeze
- FLAG_OR_VALUE_OPTION_TYPES =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
The subset of VALUE_OPTION_TYPES_FOR_ALLOWED_VALUES whose boolean values carry semantic meaning (true = emit flag, false = suppress flag) and must skip allowed_values validation rather than being compared against the set.
%i[ flag_or_value flag_or_inline_value ].freeze
Class Method Summary collapse
-
.define { ... } ⇒ Arguments
private
Define a new Arguments instance using the DSL.
Instance Method Summary collapse
-
#allowed_values(name, in:)
private
Restrict a value option to a fixed set of accepted strings.
-
#bind(*positionals, **opts) ⇒ Bound
private
Bind positionals and options, returning a Bound object with accessor methods.
-
#conflicts(*names)
private
Declare that arguments conflict with each other (mutually exclusive).
-
#custom_option(names, required: false, allow_nil: true) {|value| ... }
private
Define a custom option with a custom builder block.
-
#end_of_options(as: '--')
private
Conditionally emit an options terminator only when at least one following argument produces output.
-
#execution_option(names)
private
Define an execution option (not included in CLI output, forwarded to command execution).
-
#flag_option(names, as: nil, negatable: false, required: false, allow_nil: true, max_times: nil)
private
Define a boolean flag option (--flag when true).
-
#flag_or_value_option(names, as: nil, type: nil, negatable: false, inline: false, repeatable: false, required: false, allow_nil: true)
private
Define a flag or value option.
-
#forbid_values(**pairs)
private
Declare that an exact combination of argument values is forbidden.
-
#initialize ⇒ Arguments
constructor
private
A new instance of Arguments.
-
#key_value_option(names, as: nil, key_separator: '=', inline: false, required: false, allow_nil: true)
private
Define a key-value option that can be specified multiple times.
-
#literal(flag_string)
private
Define a literal string that is always included in the output.
-
#operand(name, required: false, repeatable: false, default: nil, allow_nil: false, skip_cli: false)
private
Define an operand (positional argument in Ruby terminology).
-
#requires(name, **kwargs)
private
Declare that name must be present whenever the trigger argument when: is present.
-
#requires_exactly_one_of(*names)
private
Declare that exactly one of the named arguments must be present when binding.
-
#requires_one_of(*names, **kwargs)
private
Declare that at least one of the named arguments must be present when binding.
-
#value_option(names, as: nil, type: nil, inline: false, as_operand: false, allow_empty: false, repeatable: false, required: false, allow_nil: true)
private
Define a valued option (--flag value as separate arguments).
Constructor Details
#initialize ⇒ Arguments
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns a new instance of Arguments.
614 615 616 617 618 619 620 621 622 623 624 625 |
# File 'lib/git/commands/arguments.rb', line 614 def initialize @option_definitions = {} @alias_map = {} # Maps alias keys to primary keys @operand_definitions = [] @conflicts = [] # Array of conflicting option pairs/groups @forbidden_values = [] # Array of forbidden exact-value tuples @requires_one_of = [] # Array of "at least one must be present" groups @ordered_definitions = [] # Tracks all definitions in definition order @past_separator = false # Tracks whether a '--' boundary has been defined @end_of_options_declared = false # Guards against duplicate end_of_options calls @negatable_companions = Set.new # Synthesized :no_<name> companion entries end |
Class Method Details
.define { ... } ⇒ Arguments
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Define a new Arguments instance using the DSL
608 609 610 611 612 |
# File 'lib/git/commands/arguments.rb', line 608 def self.define(&block) args = new args.instance_eval(&block) if block args end |
Instance Method Details
#allowed_values(name, in:)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
This method returns an undefined value.
Restrict a value option to a fixed set of accepted strings
Declares that the named option must only receive values from the given list
when a value is provided. Validation runs during #bind, after type checking.
nil and absent values are always skipped. Empty strings are skipped when
allow_empty: true is set on the option. For repeatable: true options
each element of the array is validated individually.
For {#flag_or_value_option} variants (including +negatable: true+), boolean values (+true+ / +false+) are skipped by this check because they control flag-emission behavior rather than representing candidate string values.
1638 1639 1640 1641 1642 |
# File 'lib/git/commands/arguments.rb', line 1638 def allowed_values(name, in:) sym = name.to_sym defn = validate_allowed_values_definition!(sym) defn[:allowed_values] = coerce_allowed_values_set!(sym, binding.local_variable_get(:in)) end |
#bind(*positionals, **opts) ⇒ Bound
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Bind positionals and options, returning a Bound object with accessor methods
Unlike the internal build method which returns a raw Array, this method returns a Bound object that:
- Provides accessor methods for all defined options and positional arguments
- Automatically normalizes option aliases to their canonical names
- Supports splatting via
to_aryfor seamless use withcommand(*bound)
1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 |
# File 'lib/git/commands/arguments.rb', line 1809 def bind(*positionals, **opts) normalized_opts = (opts) allocated_positionals = allocate_and_validate_positionals(positionals) validate_bind_inputs!(normalized_opts, allocated_positionals) args_array = build_ordered_arguments(allocated_positionals, normalized_opts) = (normalized_opts) execution_option_names = option_names_by_type(:execution_option) flag_names = option_names_by_type(:flag) Bound.new(args_array, , allocated_positionals, execution_option_names, flag_names) end |
#conflicts(*names)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
This method returns an undefined value.
Declare that arguments conflict with each other (mutually exclusive)
Each call to #conflicts defines a separate group of mutually exclusive arguments. Names may refer to options (flag, value, flag-or-value, etc.) or operands (positional arguments). When #bind is called, if more than one argument in the same conflict group is "present", an ArgumentError is raised.
Presence semantics — an argument is present when its value is not nil,
[], or ''. false is always treated as absent for all option types.
An ArgumentError is raised at definition time if any name given to +conflicts+ is not a known option or operand, catching typos early.
The error message has the general form:
"cannot specify :name1 and :name2"
1273 1274 1275 1276 1277 1278 1279 1280 1281 |
# File 'lib/git/commands/arguments.rb', line 1273 def conflicts(*names) names.each do |name| sym = name.to_sym next if known_argument?(sym) raise ArgumentError, "unknown argument :#{sym} in conflicts declaration" end @conflicts << names.map(&:to_sym) end |
#custom_option(names, required: false, allow_nil: true) {|value| ... }
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
This method returns an undefined value.
Define a custom option with a custom builder block
1195 1196 1197 |
# File 'lib/git/commands/arguments.rb', line 1195 def custom_option(names, required: false, allow_nil: true, &block) register_option(names, type: :custom, builder: block, required: required, allow_nil: allow_nil) end |
#end_of_options(as: '--')
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
This method returns an undefined value.
Conditionally emit an options terminator only when at least one following argument produces output
This is the canonical form for declaring the options/operands boundary in a
command definition. Unlike #literal with '--' which always emits the
separator, end_of_options emits its terminator string only when at least one
argument defined after it will be emitted as part of the CLI (for example
operands or value_option ... as_operand: true). This avoids a trailing bare
terminator when no pathspecs or other post-separator arguments are provided.
end_of_options also acts as an always-active validation boundary: operands
defined before it are always validated for option-like values (starting with
-), regardless of whether the terminator will ultimately be emitted.
1157 1158 1159 1160 1161 1162 1163 1164 |
# File 'lib/git/commands/arguments.rb', line 1157 def (as: '--') raise ArgumentError, 'end_of_options cannot be declared twice' if @end_of_options_declared @ordered_definitions << { kind: :end_of_options } @end_of_options_declared = true @end_of_options_as = as @past_separator = true end |
#execution_option(names)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
This method returns an undefined value.
Define an execution option (not included in CLI output, forwarded to command execution)
Execution options are omitted from the CLI argument array produced by Git::Commands::Arguments::Bound#to_a, but their values are still accessible on the Bound object. This is useful for options that control Ruby-side execution context (e.g., working directory) rather than git flags.
1218 1219 1220 |
# File 'lib/git/commands/arguments.rb', line 1218 def execution_option(names) register_option(names, type: :execution_option) end |
#flag_option(names, as: nil, negatable: false, required: false, allow_nil: true, max_times: nil)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
This method returns an undefined value.
Define a boolean flag option (--flag when true)
725 726 727 728 729 730 731 732 733 734 735 736 |
# File 'lib/git/commands/arguments.rb', line 725 def flag_option(names, as: nil, negatable: false, required: false, allow_nil: true, max_times: nil) primary = Array(names).first validate_max_times!(primary, max_times) if negatable register_negatable_flag_pair(names, as: as, required: required, allow_nil: allow_nil, max_times: max_times) else register_option(names, type: :flag, as: as, expected_type: nil, validator: nil, required: required, allow_nil: allow_nil, max_times: max_times) end end |
#flag_or_value_option(names, as: nil, type: nil, negatable: false, inline: false, repeatable: false, required: false, allow_nil: true)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
This method returns an undefined value.
Define a flag or value option
This is a flexible option type that outputs:
- Just the flag (--flag) when value is true
- Nothing when value is false
- Flag with value when value is any non-boolean, non-nil object (stringified via #to_s; e.g., --flag value or --flag=value if inline: true)
- Nothing when value is nil
980 981 982 983 984 985 986 987 988 989 990 991 |
# File 'lib/git/commands/arguments.rb', line 980 def flag_or_value_option(names, as: nil, type: nil, negatable: false, inline: false, repeatable: false, required: false, allow_nil: true) if negatable register_negatable_flag_or_value_pair(names, as: as, type: type, inline: inline, repeatable: repeatable, required: required, allow_nil: allow_nil) else option_type = inline ? :flag_or_inline_value : :flag_or_value register_option(names, type: option_type, as: as, expected_type: type, repeatable: repeatable, required: required, allow_nil: allow_nil) end end |
#forbid_values(**pairs)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
This method returns an undefined value.
Declare that an exact combination of argument values is forbidden
Each call to #forbid_values defines one forbidden tuple. A tuple matches
when every listed name is present (has a bound value after alias
normalization) and each value equals the declared value exactly (Ruby
==). When a tuple matches, #bind raises ArgumentError.
This fills the gap left by #conflicts, which only checks presence.
forbid_values is useful for negatable flags whose combinations can be
semantically equivalent or contradictory depending on the actual boolean
values — presence-based exclusion would be too coarse.
Names may refer to options (flag, value, flag-or-value, etc.) or operands (positional arguments). Alias names are accepted and canonicalized to their primary names.
An ArgumentError is raised at definition time if any name is not a known option or operand.
The error message has the form:
"cannot specify :name1=value1 with :name2=value2"
1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 |
# File 'lib/git/commands/arguments.rb', line 1334 def forbid_values(**pairs) raise ArgumentError, 'forbid_values must be given at least one name-value pair' if pairs.empty? pairs.each_key do |name| sym = name.to_sym next if known_argument?(sym) raise ArgumentError, "unknown argument :#{sym} in forbid_values declaration" end canonical = pairs.transform_keys { |k| @alias_map[k] || k } @forbidden_values << canonical end |
#key_value_option(names, as: nil, key_separator: '=', inline: false, required: false, allow_nil: true)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
This method returns an undefined value.
Define a key-value option that can be specified multiple times
This is useful for git options like --trailer that take key=value pairs and can be repeated. Accepts Hash or Array of arrays for flexible input.
1073 1074 1075 1076 1077 |
# File 'lib/git/commands/arguments.rb', line 1073 def key_value_option(names, as: nil, key_separator: '=', inline: false, required: false, allow_nil: true) option_type = inline ? :inline_key_value : :key_value register_option(names, type: option_type, as: as, key_separator: key_separator, required: required, allow_nil: allow_nil) end |
#literal(flag_string)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
This method returns an undefined value.
Define a literal string that is always included in the output
Literals are output at their definition position (not grouped at the start). This allows precise control over argument ordering, which is important for git commands where argument position matters.
1107 1108 1109 1110 |
# File 'lib/git/commands/arguments.rb', line 1107 def literal(flag_string) @ordered_definitions << { kind: :static, flag: flag_string } @past_separator = true if flag_string == '--' end |
#operand(name, required: false, repeatable: false, default: nil, allow_nil: false, skip_cli: false)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
This method returns an undefined value.
Define an operand (positional argument in Ruby terminology)
Operands are mapped to values following Ruby method signature semantics. Required operands before a repeatable are filled left-to-right, required operands after a repeatable are filled from the end, and the repeatable gets whatever remains in the middle.
1762 1763 1764 1765 1766 |
# File 'lib/git/commands/arguments.rb', line 1762 def operand(name, required: false, repeatable: false, default: nil, allow_nil: false, skip_cli: false) validate_single_repeatable!(name) if repeatable add_operand_definition(name, required, repeatable, default, allow_nil, skip_cli) end |
#requires(name, **kwargs)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
This method returns an undefined value.
Declare that name must be present whenever the trigger argument when: is present
When #bind is called, if the trigger argument is present and name is absent, an ArgumentError is raised. If the trigger is absent, the check is skipped.
Presence semantics — two slightly different rules apply:
when:trigger — the trigger is considered present when its value is notnil,false,[], or''. A value offalseis treated as absent. If you need an explicit negative form for a negatable flag, use itsno_<name>companion key instead.- Required argument — name is considered present when its value is
not
nil,false,[], or''.
An ArgumentError is raised at definition time if either name or the when:
trigger is not a known option or operand, catching typos early.
The error message has the form:
":trigger requires :name"
1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 |
# File 'lib/git/commands/arguments.rb', line 1567 def requires(name, **kwargs) condition = kwargs.delete(:when) raise ArgumentError, 'requires: `when:` keyword is required' unless condition raise ArgumentError, "requires: unknown keyword arguments: #{kwargs.keys.inspect}" unless kwargs.empty? sym = name.to_sym validate_requires_name!(sym) canonical_trigger = resolve_requires_condition(condition) @requires_one_of << { names: [@alias_map[sym] || sym], condition: canonical_trigger, single: true } end |
#requires_exactly_one_of(*names)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
This method returns an undefined value.
Declare that exactly one of the named arguments must be present when binding
This is a convenience composite that combines #requires_one_of (at least one must be present) and #conflicts (at most one may be present). Use it when a group of arguments is mutually exclusive and the caller must supply precisely one of them.
The call:
requires_exactly_one_of :a, :b, :c
is exactly equivalent to:
requires_one_of :a, :b, :c conflicts :a, :b, :c
Presence semantics — inherits the rules from the constituent methods. See #requires_one_of and #conflicts for the full details.
An ArgumentError is raised at definition time if any name is not a known option or operand, catching typos early.
Error messages reuse the formats from the constituent methods:
"at least one of :a, :b, :c must be provided" # zero present "cannot specify :a and :b" # two or more present
1506 1507 1508 1509 |
# File 'lib/git/commands/arguments.rb', line 1506 def requires_exactly_one_of(*names) requires_one_of(*names) conflicts(*names) end |
#requires_one_of(*names, **kwargs)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
This method returns an undefined value.
Declare that at least one of the named arguments must be present when binding
Each call to #requires_one_of defines an independent "at least one" group. When #bind is called, if none of the arguments in the group is present, an ArgumentError is raised.
Conditional form — when when: is given, the check is only performed if
the named trigger argument is present. If the trigger is absent the group is
skipped entirely.
Presence semantics — two slightly different rules apply:
when:trigger — the trigger is considered present when its value is notnil,false,[], or''. A flag set tofalsemeans absent, so the trigger does not fire.- Satisfied-by check — a group member is considered present when its
value is not
nil,false,[], or''.falseis treated as absent for all option types under the companion-key model.
Names may refer to options (flag, value, flag-or-value, etc.) or operands (positional arguments) interchangeably. Alias resolution happens before the check, so supplying an alias for one of the named options counts as that option being present.
An ArgumentError is raised at definition time if any name (including the
when: trigger) is not a known option or operand, catching typos early.
The error message has the general form (unconditional):
"at least one of :name1, :name2 must be provided"
The error message has the general form (conditional, when: given):
":trigger requires at least one of :name1, :name2"
1445 1446 1447 1448 1449 1450 1451 1452 1453 |
# File 'lib/git/commands/arguments.rb', line 1445 def requires_one_of(*names, **kwargs) condition = kwargs.delete(:when) raise ArgumentError, "requires_one_of: unknown keyword arguments: #{kwargs.keys.inspect}" unless kwargs.empty? raise ArgumentError, 'requires_one_of must be given at least one argument name' if names.empty? canonical_group = canonicalize_requires_names(names) canonical_condition = resolve_requires_condition(condition) @requires_one_of << { names: canonical_group, condition: canonical_condition, single: false } end |
#value_option(names, as: nil, type: nil, inline: false, as_operand: false, allow_empty: false, repeatable: false, required: false, allow_nil: true)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
This method returns an undefined value.
Define a valued option (--flag value as separate arguments)
This option type supports three output modes controlled by inline: and as_operand::
- Default:
--flag value(flag and value as separate arguments) - Inline:
--flag=value(single argument withinline: true) - Operand:
value(no flag, just the value withas_operand: true)
863 864 865 866 867 868 869 870 871 |
# File 'lib/git/commands/arguments.rb', line 863 def value_option(names, as: nil, type: nil, inline: false, as_operand: false, allow_empty: false, repeatable: false, required: false, allow_nil: true) validate_value_modifiers!(names, inline, as_operand) option_type = determine_value_option_type(inline, as_operand) register_option(names, type: option_type, as: as, expected_type: type, allow_empty: allow_empty, repeatable: repeatable, required: required, allow_nil: allow_nil) end |