Skip to content

Better support for overriding options programmatically #805

@ameir

Description

@ameir

Hello,

I am currently setting options from a file, similar to what is described in #413.

An issue I am having is that the options loaded in this way bypass validation, so bogus parameters can be inserted, and (more importantly for my case), type validation is not attempted. For example, if a Thor option is changed from a string to an array, if the config file sets that option as a string, it will remain as a string in the options hash. If code is dependent on this option being an array, things begin to fall apart.

If there's a way to instead merge a hash with the hash from

def parse(args) # rubocop:disable Metrics/MethodLength
@pile = args.dup
@is_treated_as_value = false
@parsing_options = true
while peek
if parsing_options?
match, is_switch = current_is_switch?
shifted = shift
if is_switch
case shifted
when SHORT_SQ_RE
unshift($1.split("").map { |f| "-#{f}" })
next
when EQ_RE
unshift($2, :is_value => true)
switch = $1
when SHORT_NUM
unshift($2)
switch = $1
when LONG_RE, SHORT_RE
switch = $1
end
switch = normalize_switch(switch)
option = switch_option(switch)
result = parse_peek(switch, option)
assign_result!(option, result)
elsif @stop_on_unknown
@parsing_options = false
@extra << shifted
@stopped_parsing_after_extra_index ||= @extra.size
@extra << shift while peek
break
elsif match
@extra << shifted
@extra << shift while peek && peek !~ /^-/
else
@extra << shifted
end
else
@extra << shift
end
end
check_requirement! unless @disable_required_check
assigns = Thor::CoreExt::HashWithIndifferentAccess.new(@assigns)
assigns.freeze
assigns
end
, that would probably work (i.e. override that method and merge one hash over the other). One issue with this (and the original method) is that defaults are resolved without us knowing if option values are default or user-provided. If there's a way to provide the initial hash before defaults are resolved, that would be ideal.

Thank you!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions