class Git::ArgsBuilder

Takes a hash of user options and a declarative map and produces an array of command-line arguments. Also validates that only supported options are provided based on the map.

@api private

Constants

ARG_BUILDERS

This hash maps an option type to a lambda that knows how to build the corresponding command-line argument. This is a scalable dispatch table.

Public Class Methods

build(opts, option_map) click to toggle source

Main entrypoint to validate options and build arguments

# File lib/git/args_builder.rb, line 29
def self.build(opts, option_map)
  validate!(opts, option_map)
  new(opts, option_map).build
end
new(opts, option_map) click to toggle source
# File lib/git/args_builder.rb, line 40
def initialize(opts, option_map)
  @opts = opts
  @option_map = option_map
end
validate!(opts, option_map) click to toggle source

Public validation method that can be called independently

# File lib/git/args_builder.rb, line 35
def self.validate!(opts, option_map)
  validate_unsupported_keys!(opts, option_map)
  validate_configured_options!(opts, option_map)
end

Private Class Methods

check_for_missing_required_option!(opts, config) click to toggle source
# File lib/git/args_builder.rb, line 82
                     def self.check_for_missing_required_option!(opts, config)
  return unless config[:required]

  key_provided = config[:keys].any? { |k| opts.key?(k) }
  return if key_provided

  raise ArgumentError, "Missing required option: #{config[:keys].first}"
end
validate_configured_options!(opts, option_map) click to toggle source
# File lib/git/args_builder.rb, line 73
                     def self.validate_configured_options!(opts, option_map)
  option_map.each do |config|
    next unless config[:keys] # Skip static flags

    check_for_missing_required_option!(opts, config)
    validate_option_value!(opts, config)
  end
end
validate_option_value!(opts, config) click to toggle source
# File lib/git/args_builder.rb, line 91
                     def self.validate_option_value!(opts, config)
  validator = config[:validator]
  return unless validator

  user_key = config[:keys].find { |k| opts.key?(k) }
  return unless user_key # Don't validate if the user didn't provide the option

  return if validator.call(opts[user_key])

  raise ArgumentError, "Invalid value for option: #{user_key}"
end
validate_unsupported_keys!(opts, option_map) click to toggle source
# File lib/git/args_builder.rb, line 64
                     def self.validate_unsupported_keys!(opts, option_map)
  all_valid_keys = option_map.flat_map { |config| config[:keys] }.compact
  unsupported_keys = opts.keys - all_valid_keys

  return if unsupported_keys.empty?

  raise ArgumentError, "Unsupported options: #{unsupported_keys.map(&:inspect).join(', ')}"
end

Public Instance Methods

build() click to toggle source
# File lib/git/args_builder.rb, line 45
def build
  @option_map.flat_map do |config|
    type = config[:type]
    next config[:flag] if type == :static

    key = config[:keys].find { |k| @opts.key?(k) }
    next [] unless key

    build_arg_for_option(config, @opts[key])
  end.compact
end

Private Instance Methods

build_arg_for_option(config, value) click to toggle source
# File lib/git/args_builder.rb, line 59
def build_arg_for_option(config, value)
  builder = ARG_BUILDERS[config[:type]]
  builder&.call(config, value) || []
end