vagrant-devcommands 0.4.2 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3fcb38ef1de935682eb7936180d0751237b8af1a
4
- data.tar.gz: a43fd04b478b34cee2d0526803493b3ab122e8ed
3
+ metadata.gz: 264d76e5ba1857747eeb893b4c41ed6a907e8c30
4
+ data.tar.gz: 8333fdbe0a699481c5bc4e56dea0000394aca710
5
5
  SHA512:
6
- metadata.gz: 192a3deea7cfee00afb89e743efc3556e0cba8b9c252c1092e68f089c8a551622d20899c6576b5bfdf02f670e04d13c78fb870a4cfe65b4bbd04bfd79a75ce23
7
- data.tar.gz: a1eab7b292767c1d421d1674579e0a49164640fc408e12e2ba807b3b2cbee9fb6cc22851023fa38922133228fa94318516a083750bc57da86e909ce4d88f14d8
6
+ metadata.gz: 2712542700027f4d3c4e5f33b9e902d7cf237489bf9ee26c9a54cbb5fda6c91e6628195820fa8aad15b39c7f9054f62323814dc627cbd47bec1390c9e213aef2
7
+ data.tar.gz: 8c2f25a37e8385d6933dabad95d5453343b92214a9c753eedb10c640b60e9c57a9911632b37cf1a8c2214a89b70967c8f87937bb2b28673fdde770bc2e5881e1
data/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # Changelog
2
2
 
3
+ ## v0.5.0 (2015-03-21)
4
+
5
+ - Enhancements
6
+ - Commands can define a detailed help message
7
+ - Commands can define a custom usage string
8
+ - Commands can be defined using a lambda/proc
9
+ - Commands can be defined with additional named parameters to be interpolated
10
+ - Internal commands are included in the command listing (help)
11
+ - Script parameters can be optional
12
+
13
+ - Backwards incompatible changes
14
+ - Positional parameters have been replaced with named parameters
15
+
16
+ - Bug fixes
17
+ - Displays actual command name when an error occurs due to missing arguments
18
+
3
19
  ## v0.4.2 (2015-12-15)
4
20
 
5
21
  - Bug fixes
data/README.md CHANGED
@@ -5,6 +5,23 @@ Runs vagrant commands from a Commandfile.
5
5
 
6
6
  ## Usage
7
7
 
8
+ ### Command Listing
9
+
10
+ ```shell
11
+ vagrant run
12
+ ```
13
+
14
+ ### Command Execution
15
+
16
+ ```shell
17
+ # single-vm environment
18
+ # or multi-vm environment with :box option
19
+ vagrant run your_command
20
+
21
+ # multi-vm environment
22
+ vagrant run your_box your_command
23
+ ```
24
+
8
25
  ### Command Definition
9
26
 
10
27
  Add to a `Commandfile` besides your `Vagrantfile`:
@@ -15,46 +32,74 @@ command 'basic', 'hostname'
15
32
  command 'with_options',
16
33
  box: :my_box,
17
34
  desc: 'executes "hostname" on the box "my_box"',
18
- script: 'hostname'
35
+ script: 'hostname',
36
+ usage: 'vagrant run %{command}',
37
+ help: <<-eoh
38
+ I am the help message for the command "with_options".
39
+ I get displayed when running "vagrant run help with_options".
40
+
41
+ The usage printed above the help can interpolate the name
42
+ of the command name using %{command}.
43
+ eoh
19
44
  ```
20
45
 
21
- #### Command Definition (parameters)
46
+ _Note_: If you are defining literal `%` (percent sign) in your commands you
47
+ have to escape them using a second `%`. For example `date "+%%Y-%%m-%%d"`.
48
+
49
+ #### Experimental: Command Definition (parameters)
22
50
 
23
51
  Passing additional parameters to a command is (minimally) supported using an
24
52
  sprintf syntax:
25
53
 
26
54
  ```ruby
27
- command 'with_param', script: 'echo "%s"'
55
+ command 'with_param',
56
+ parameters: {
57
+ # mandatory parameter
58
+ mdtry: {},
59
+ # parameter with default (implies optional)
60
+ dflt: { default: "always" },
61
+ # optional parameter
62
+ optnl: { optional: true },
63
+ # wrapped option value
64
+ wrppd: { wrap: "--and %s wrapped" }
65
+ },
66
+ script: 'echo %{mdtry} %{dflt} %{optnl} %{wrppd}'
28
67
  ```
29
68
 
30
69
  This allows you to execute the following command:
31
70
 
32
71
  ```shell
33
- # will execute something like 'echo "works"'
34
- vagrant run with_param works
72
+ # will execute 'echo works always'
73
+ vagrant run with_param --mdtry works
74
+
75
+ # will execute 'echo works always like a charm'
76
+ vagrant run with_param --mdtry works --optnl "like a charm"
77
+
78
+ # will execute 'echo works sometimes like a charm --and is wrapped'
79
+ vagrant run with_param \
80
+ --mdtry works \
81
+ --dflt sometimes \
82
+ --optnl "like a charm" \
83
+ --wrppd is
35
84
  ```
36
85
 
37
86
  For now a command expecting one or more parameters will fail if the user does
38
87
  not provide them. Any arguments exceeding the number used are silently
39
88
  discarded.
40
89
 
41
- ### Command Listing
42
-
43
- ```shell
44
- vagrant run
45
- ```
90
+ #### Experimental: Command Definition (lambda/proc)
46
91
 
92
+ You can (more or less) dynamically generate your scripts by defining the
93
+ command with a lambda or proc as its script.
47
94
 
48
- ### Command Execution
95
+ ```ruby
96
+ command 'from_lambda', script: lambda { 'echo "lambda works"' }
97
+ command 'from_proc', script: proc { 'echo "proc works"' }
98
+ ```
49
99
 
50
- ```shell
51
- # single-vm environment
52
- # or multi-vm environment with :box option
53
- vagrant run your_command
100
+ These will be evaluated when running the command.
54
101
 
55
- # multi-vm environment
56
- vagrant run your_box your_command
57
- ```
102
+ Every rule from regular scripts (parameters, escaping "%", ...) still apply.
58
103
 
59
104
 
60
105
  ## Notes for Windows Users
@@ -56,7 +56,7 @@ module VagrantPlugins
56
56
  end
57
57
 
58
58
  def read_commandfile
59
- commandfile = Commandfile.new(@env)
59
+ commandfile = CommandFile.new(@env)
60
60
 
61
61
  unless commandfile.exist?
62
62
  display_error('Missing "Commandfile"')
@@ -71,7 +71,7 @@ module VagrantPlugins
71
71
  def run(command)
72
72
  argv = run_argv
73
73
  box = run_box(command)
74
- script = run_script(command[:script], argv)
74
+ script = run_script(command, argv)
75
75
 
76
76
  return 2 unless script
77
77
 
@@ -87,26 +87,26 @@ module VagrantPlugins
87
87
  def run_argv
88
88
  argv = @argv.dup
89
89
 
90
- argv.shift if @env.machine_index.include?(argv[0])
90
+ argv.shift if @env.machine_index.include?(argv[0].to_s)
91
91
  argv.shift
92
92
  argv
93
93
  end
94
94
 
95
95
  def run_box(cmd)
96
- return cmd[:box].to_s if cmd[:box]
97
- return @argv[0] if @env.machine_index.include?(@argv[0])
96
+ return cmd.box.to_s if cmd.box
97
+ return @argv[0].to_s if @env.machine_index.include?(@argv[0].to_s)
98
98
 
99
99
  nil
100
100
  end
101
101
 
102
102
  def run_internal(command)
103
- Internal.new(@registry).run(command)
103
+ Internal.new(@registry).run(command, run_argv)
104
104
  end
105
105
 
106
- def run_script(script, argv)
107
- script % argv
108
- rescue ArgumentError
109
- error = "Not enough parameters to execute \"command[:name]\"!"
106
+ def run_script(command, argv)
107
+ command.run_script(argv)
108
+ rescue KeyError, OptionParser::InvalidOption
109
+ error = "Invalid/Missing parameters to execute \"#{command.name}\"!"
110
110
 
111
111
  display_error(error)
112
112
 
@@ -0,0 +1,75 @@
1
+ require 'optparse'
2
+
3
+ module VagrantPlugins
4
+ module DevCommands
5
+ # Definition of an executable command
6
+ class CommandDef
7
+ attr_reader :name
8
+ attr_reader :parameters
9
+ attr_reader :script
10
+
11
+ attr_reader :box
12
+ attr_reader :desc
13
+ attr_reader :help
14
+ attr_reader :usage
15
+
16
+ def initialize(spec)
17
+ @name = spec[:name]
18
+ @parameters = spec[:parameters]
19
+ @script = spec[:script]
20
+
21
+ @box = spec[:box]
22
+ @desc = spec[:desc]
23
+ @help = spec[:help]
24
+ @usage = spec[:usage]
25
+ end
26
+
27
+ def run_script(argv)
28
+ script = @script
29
+ script = script.call if script.is_a?(Proc)
30
+
31
+ opts = {}
32
+ opts = parse_argv(argv) if @parameters
33
+
34
+ (script % opts).strip
35
+ end
36
+
37
+ private
38
+
39
+ def parse_argv(argv)
40
+ options = options_with_defaults
41
+
42
+ OptionParser.new do |opts|
43
+ @parameters.each do |key, _conf|
44
+ opts.on("--#{key} OPTION", "Parameter: #{key}") do |o|
45
+ options[key] = o
46
+ end
47
+ end
48
+ end.parse!(argv)
49
+
50
+ wrap_option_values options
51
+ end
52
+
53
+ def options_with_defaults
54
+ options = {}
55
+
56
+ @parameters.each do |key, conf|
57
+ options[key] = '' if conf[:optional]
58
+ options[key] = conf[:default] if conf[:default]
59
+ end
60
+
61
+ options
62
+ end
63
+
64
+ def wrap_option_values(options)
65
+ @parameters.each do |key, conf|
66
+ next if conf[:wrap].nil?
67
+
68
+ options[key] = conf[:wrap] % options[key]
69
+ end
70
+
71
+ options
72
+ end
73
+ end
74
+ end
75
+ end
@@ -1,7 +1,7 @@
1
1
  module VagrantPlugins
2
2
  module DevCommands
3
3
  # Loads and handles the Commandfile
4
- class Commandfile
4
+ class CommandFile
5
5
  def initialize(env)
6
6
  @env = env
7
7
  end
@@ -2,53 +2,23 @@ module VagrantPlugins
2
2
  module DevCommands
3
3
  # Handles internal commands and their execution.
4
4
  class Internal
5
- def initialize(registry)
6
- @registry = registry
7
- end
8
-
9
- def run(command)
10
- case command
11
- when 'help'
12
- print_help
13
- when 'version'
14
- print_version
15
- end
16
-
17
- 0
18
- end
19
-
20
- private
5
+ NAMESPACE = VagrantPlugins::DevCommands::InternalCommand
21
6
 
22
- def print_help
23
- if @registry.commands.empty?
24
- puts 'No commands defined!'
25
- return
26
- end
7
+ COMMANDS = {
8
+ 'help' => CommandDef.new(NAMESPACE::Help::SPEC),
9
+ 'version' => CommandDef.new(NAMESPACE::Version::SPEC)
10
+ }.freeze
27
11
 
28
- display_help_header
29
- display_help_commands
30
- end
31
-
32
- def display_help_commands
33
- pad_to = @registry.commands.keys.map(&:length).max
34
-
35
- @registry.commands.each do |name, command|
36
- if command.key?(:desc)
37
- puts " #{name.ljust(pad_to)} #{command[:desc]}"
38
- else
39
- puts " #{name}"
40
- end
41
- end
42
- end
43
-
44
- def display_help_header
45
- puts 'Usage: vagrant run [box] <command>'
46
- puts ''
47
- puts 'Available commands:'
12
+ def initialize(registry)
13
+ @internal = {
14
+ 'help' => NAMESPACE::Help.new(registry),
15
+ 'version' => NAMESPACE::Version.new
16
+ }
17
+ @registry = registry
48
18
  end
49
19
 
50
- def print_version
51
- puts "vagrant-devcommands, version #{VERSION}"
20
+ def run(command, args)
21
+ @internal[command].execute(args) if @internal.key?(command)
52
22
  end
53
23
  end
54
24
  end
@@ -0,0 +1,118 @@
1
+ module VagrantPlugins
2
+ module DevCommands
3
+ module InternalCommand
4
+ # Internal "help" command
5
+ class Help
6
+ SPEC = {
7
+ desc: 'display this help message',
8
+ name: 'help',
9
+ usage: 'vagrant run %{command} [command]',
10
+ help: <<-eoh
11
+ Display the help of the command given as the first argument if defined.
12
+ Just like this help for the help command!
13
+ eoh
14
+ }.freeze
15
+
16
+ def initialize(registry)
17
+ @registry = registry
18
+ end
19
+
20
+ def execute(argv)
21
+ if @registry.commands.empty?
22
+ puts 'No commands defined!'
23
+ return
24
+ end
25
+
26
+ return plugin_help unless @registry.valid_command?(argv[0])
27
+ return internal_help(argv[0]) if @registry.reserved_command?(argv[0])
28
+
29
+ command_help(argv[0])
30
+ end
31
+
32
+ private
33
+
34
+ def collect_commands
35
+ internal = VagrantPlugins::DevCommands::Internal::COMMANDS
36
+
37
+ @registry.commands.merge internal
38
+ end
39
+
40
+ def command_help(command)
41
+ command_help_header(command)
42
+
43
+ puts ''
44
+
45
+ if @registry.commands[command].help.nil?
46
+ puts 'No detailed help for this command available.'
47
+ else
48
+ puts @registry.commands[command].help
49
+ end
50
+ end
51
+
52
+ def command_help_header(command)
53
+ usage = "vagrant run [box] #{command}"
54
+ usage = usage_params(usage, @registry.commands[command])
55
+
56
+ unless @registry.commands[command].usage.nil?
57
+ usage = @registry.commands[command].usage % { command: command }
58
+ end
59
+
60
+ puts "Usage: #{usage}"
61
+ end
62
+
63
+ def internal_help(command)
64
+ internal_help_header(command)
65
+
66
+ puts ''
67
+ puts VagrantPlugins::DevCommands::Internal::COMMANDS[command].help
68
+ end
69
+
70
+ def internal_help_header(command)
71
+ spec = VagrantPlugins::DevCommands::Internal::COMMANDS[command]
72
+ usage = spec.usage % { command: command }
73
+
74
+ puts "Usage: #{usage}"
75
+ end
76
+
77
+ def plugin_help
78
+ plugin_help_header
79
+ plugin_help_commands
80
+ end
81
+
82
+ def plugin_help_commands
83
+ commands = collect_commands
84
+ pad_to = commands.keys.map(&:length).max
85
+
86
+ commands.each do |name, command|
87
+ if command.desc.nil?
88
+ puts " #{name}"
89
+ else
90
+ puts " #{name.ljust(pad_to)} #{command.desc}"
91
+ end
92
+ end
93
+ end
94
+
95
+ def plugin_help_header
96
+ puts 'Usage: vagrant run [box] <command>'
97
+ puts 'Help: vagrant run help <command>'
98
+ puts ''
99
+ puts 'Available commands:'
100
+ end
101
+
102
+ def usage_params(usage, command)
103
+ return usage if command.parameters.nil?
104
+
105
+ params = command.parameters.collect do |key, opts|
106
+ if opts[:optional]
107
+ "[#{key}]"
108
+ else
109
+ "<#{key}>"
110
+ end
111
+ end
112
+
113
+ "#{usage} #{params.join(' ')}"
114
+ end
115
+ end
116
+ end
117
+ end
118
+ end
@@ -0,0 +1,21 @@
1
+ module VagrantPlugins
2
+ module DevCommands
3
+ module InternalCommand
4
+ # Internal "version" command
5
+ class Version
6
+ SPEC = {
7
+ desc: 'display currently used the plugin version',
8
+ name: 'version',
9
+ usage: 'vagrant run %{command}',
10
+ help: <<-eoh
11
+ Displays the currently installed version the plugin you are using right now.
12
+ eoh
13
+ }.freeze
14
+
15
+ def execute(_args)
16
+ puts "vagrant-devcommands, version #{VERSION}"
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -2,7 +2,7 @@ module VagrantPlugins
2
2
  module DevCommands
3
3
  # Vagrant command registry
4
4
  class Registry
5
- RESERVED_COMMANDS = %w(help version)
5
+ RESERVED_COMMANDS = %w(help version).freeze
6
6
 
7
7
  attr_accessor :commands
8
8
 
@@ -29,12 +29,13 @@ module VagrantPlugins
29
29
  def command(name, options)
30
30
  return reserved_warning(name) if reserved_command?(name)
31
31
 
32
- options = { script: options } if options.is_a?(String)
32
+ options = { script: options } unless options.is_a?(Hash)
33
33
 
34
34
  return script_warning(name) unless options.key?(:script)
35
35
 
36
- @commands[name] = options
37
- @commands[name][:name] = name
36
+ options[:name] = name
37
+
38
+ @commands[name] = CommandDef.new(options)
38
39
  end
39
40
 
40
41
  def script_warning(name)
@@ -1,6 +1,6 @@
1
1
  module VagrantPlugins
2
2
  # Defines the current plugin version
3
3
  module DevCommands
4
- VERSION = '0.4.2'
4
+ VERSION = '0.5.0'.freeze
5
5
  end
6
6
  end
@@ -1,7 +1,11 @@
1
1
  require 'vagrant'
2
2
 
3
+ require 'vagrant/devcommands/internal_command/help'
4
+ require 'vagrant/devcommands/internal_command/version'
5
+
3
6
  require 'vagrant/devcommands/command'
4
- require 'vagrant/devcommands/commandfile'
7
+ require 'vagrant/devcommands/command_def'
8
+ require 'vagrant/devcommands/command_file'
5
9
  require 'vagrant/devcommands/internal'
6
10
  require 'vagrant/devcommands/plugin'
7
11
  require 'vagrant/devcommands/registry'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vagrant-devcommands
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.2
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marc Neudert
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-12-15 00:00:00.000000000 Z
11
+ date: 2016-03-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -99,8 +99,11 @@ files:
99
99
  - README.md
100
100
  - lib/vagrant/devcommands.rb
101
101
  - lib/vagrant/devcommands/command.rb
102
- - lib/vagrant/devcommands/commandfile.rb
102
+ - lib/vagrant/devcommands/command_def.rb
103
+ - lib/vagrant/devcommands/command_file.rb
103
104
  - lib/vagrant/devcommands/internal.rb
105
+ - lib/vagrant/devcommands/internal_command/help.rb
106
+ - lib/vagrant/devcommands/internal_command/version.rb
104
107
  - lib/vagrant/devcommands/plugin.rb
105
108
  - lib/vagrant/devcommands/registry.rb
106
109
  - lib/vagrant/devcommands/version.rb
@@ -125,7 +128,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
125
128
  version: '0'
126
129
  requirements: []
127
130
  rubyforge_project:
128
- rubygems_version: 2.4.5
131
+ rubygems_version: 2.4.8
129
132
  signing_key:
130
133
  specification_version: 4
131
134
  summary: Runs vagrant commands from a Commandfile