commit 92b89648b2a2ddc9130d4715bf583f48390fd2e1
parent 42d1fd7912b7773cb10664fe3f68eef195b400d2
Author: Daniel Barlow <dan@telent.net>
Date: Thu, 12 Aug 2021 00:00:05 +0100
check command line parameters
Diffstat:
3 files changed, 36 insertions(+), 12 deletions(-)
diff --git a/features/moss.feature b/features/moss.feature
@@ -115,3 +115,7 @@ Feature: command-line password management
Then I see the string "Store and retrieve encrypted secrets"
And I see the string "Usage: moss \[command\] \[parameters\]"
And I see the string "add a secret to the store"
+
+ Scenario: argument checking
+ When I run "moss cat"
+ Then it complains that the wrong arguments were given
diff --git a/features/step_definitions/steps.rb b/features/step_definitions/steps.rb
@@ -190,7 +190,14 @@ Then("my identity file is readable only by me") do
expect(mode & 077).to be_zero
end
-When("I run \"moss help\"") do
- @i_see = shell "#{MOSS} help"
+When("I run {string}") do |command|
+ # don't fail if error returns, as we need to test that
+ @i_see = IO.popen(["bash", "-c", "#{command.sub(/\Amoss/, MOSS)} 2>&1"],
+ "r") do |f| f.read end
+ @exit_status = $?.exitstatus
end
+Then("it complains that the wrong arguments were given") do
+ expect(@exit_status).to be > 0
+ expect(@i_see).to match /usage: moss cat \<file\>/
+end
diff --git a/moss.rb b/moss.rb
@@ -169,30 +169,38 @@ class CLI
class << self
def command(name, docstring, &blk)
- @@commands[name] = { name: name, doc: docstring, block: blk }
+ @@commands[name] = { name: name, doc: docstring }
+ # we use methods here instead of blocks, because blocks
+ # don't have required parameters
+ define_method name, &blk
end
-
+
def dispatch(name, *parameters)
- @@commands.fetch(name.to_sym)[:block].call(*parameters)
- true
+ command = @@commands[name.to_sym]
+ instance = new
+ instance.public_send(command[:name], *parameters)
+ rescue ArgumentError => e
+ meth = instance.method(command[:name])
+ params = meth.parameters.map {|p| "<#{p[1]}>" }.join(" ")
+ raise "usage: moss #{name} #{params}"
end
def aka(command, command_alias)
@@commands[command_alias] = @@commands[command]
end
-
- def usage
+
+ def usage(instance)
puts "Store and retrieve encrypted secrets\n\n"
puts "Usage: moss [command] [parameters]...\n\n"
@@commands.each do |name, command|
next unless name == command[:name] # skip aliases
- meth = command[:block]
+ meth = instance.method(command[:name])
params = meth.parameters
printf " %-40s - %s \n",
([command[:name]] + params.map {|p| p[1].to_s }).join(" "),
command[:doc]
end
- end
+ end
end
command :generate, "generate a random secret" do |filename, length|
@@ -250,8 +258,13 @@ class CLI
end
command :help, "display this help text" do
- self.usage
+ self.class.usage(self)
end
end
-CLI.dispatch(* ARGV)
+begin
+ CLI.dispatch(* ARGV)
+rescue StandardError => e
+ warn e.message
+ exit 1
+end