Skip to content

Commit

Permalink
Merge pull request #376 from bkeepers/cli2
Browse files Browse the repository at this point in the history
Fixes regression with CLI experience
  • Loading branch information
Andrew Nordman authored Feb 24, 2019
2 parents 914cc3a + ea1ce3e commit c456ea2
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 16 deletions.
57 changes: 41 additions & 16 deletions lib/dotenv/cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@ module Dotenv
# The CLI is a class responsible of handling all the command line interface
# logic.
class CLI
attr_reader :argv
attr_reader :argv, :exec_args, :parser_args, :filenames

def initialize(argv = [])
@argv = argv.dup
@filenames = []
@flag_matchers = []
end

def run
Expand All @@ -20,48 +22,71 @@ def run
rescue Errno::ENOENT => e
abort e.message
else
exec(*@argv) unless @argv.empty?
exec(*@exec_args) unless @exec_args.empty?
end
end

private

def parse_argv!(argv)
@filenames = []

OptionParser.new do |parser|
parser.banner = "Usage: dotenv [options]"
parser.separator ""
add_options(parser)
end.parse!(argv)
parser = create_option_parser
add_options(parser, @flag_matchers)
@parser_args, @exec_args = split_argv(argv.join(" "), @flag_matchers)
parser.parse! @parser_args

@filenames
end

def add_options(parser)
add_files_option(parser)
add_help_option(parser)
add_version_option(parser)
def add_options(parser, flag_matchers)
add_files_option(parser, flag_matchers)
add_help_option(parser, flag_matchers)
add_version_option(parser, flag_matchers)
end

def add_files_option(parser)
def add_files_option(parser, flag_matchers)
flag_matchers.push("-f \\S+")
parser.on("-f FILES", Array, "List of env files to parse") do |list|
@filenames = list
end
end

def add_help_option(parser)
def add_help_option(parser, flag_matchers)
flag_matchers.push("-h", "--help")
parser.on("-h", "--help", "Display help") do
puts parser
exit
end
end

def add_version_option(parser)
def add_version_option(parser, flag_matchers)
flag_matchers.push("-v", "--version")
parser.on("-v", "--version", "Show version") do
puts "dotenv #{Dotenv::VERSION}"
exit
end
end

# Detect dotenv flags vs executable args so we can parse properly and still
# take advantage of OptionParser for dotenv flags
def split_argv(arg_string, matchers)
matcher = /^((?:#{matchers.join("|")})\s?)?(.+)?$/
data = matcher.match(arg_string)
dotenv_args = []
exec_args = []

unless data.nil?
dotenv_args = (!data[1].nil? ? data[1].split(" ") : [])
exec_args = (!data[2].nil? ? data[2].split(" ") : [])
end

[dotenv_args, exec_args]
end

def create_option_parser
OptionParser.new do |parser|
parser.banner = "Usage: dotenv [options]"
parser.separator ""
end
end
end
end
16 changes: 16 additions & 0 deletions spec/dotenv/cli_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,22 @@ def run(*args)
expect(ENV).to have_key("QUOTED")
end

it "does not consume non-dotenv flags by accident" do
cli = Dotenv::CLI.new(["-f", "plain.env", "foo", "--switch"])
cli.send(:parse_argv!, cli.argv)

expect(cli.filenames).to eql(["plain.env"])
expect(cli.exec_args).to eql(["foo", "--switch"])
end

it "does not consume dotenv flags from subcommand" do
cli = Dotenv::CLI.new(["foo", "-f", "something"])
cli.send(:parse_argv!, cli.argv)

expect(cli.filenames).to eql([])
expect(cli.exec_args).to eql(["foo", "-f", "something"])
end

# Capture output to $stdout and $stderr
def capture_output(&_block)
original_stderr = $stderr
Expand Down

0 comments on commit c456ea2

Please sign in to comment.