vop 0.3.1 → 0.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/Gemfile +2 -1
  4. data/Gemfile.lock +34 -33
  5. data/README.md +184 -2
  6. data/bin/console +17 -0
  7. data/bin/setup +8 -0
  8. data/bin/vop.sh +6 -2
  9. data/exe/vop +3 -25
  10. data/lib/boot.rb +3 -0
  11. data/lib/core/meta/commands/new_command.rb +1 -0
  12. data/lib/core/meta/commands/new_plugin.rb +47 -0
  13. data/lib/core/meta/commands/search_gems_for_plugins.rb +38 -0
  14. data/lib/core/meta/commands/search_path.rb +6 -0
  15. data/lib/core/meta/commands/set.rb +12 -0
  16. data/lib/core/meta/commands/show.rb +6 -0
  17. data/lib/core/meta/commands/show_config.rb +9 -0
  18. data/lib/core/meta/commands/who_provides.rb +6 -0
  19. data/lib/core/meta/meta.plugin +1 -0
  20. data/lib/core/shell/commands/change_loglevel.rb +6 -0
  21. data/lib/{vop/plugins/core → core/shell}/commands/clear_context.rb +0 -0
  22. data/lib/core/shell/commands/edit.rb +12 -0
  23. data/lib/core/shell/commands/help.rb +49 -0
  24. data/lib/core/shell/commands/reset.rb +4 -0
  25. data/lib/{vop/plugins/core → core/shell}/commands/show_context.rb +0 -0
  26. data/lib/core/shell/commands/source.rb +21 -0
  27. data/lib/{vop/plugins/core/helpers/plugin_loader/plugin_syntax.rb → core/shell/shell.plugin} +0 -0
  28. data/lib/core/structure/commands/collect_contributions.rb +46 -0
  29. data/lib/core/structure/commands/disable_contributor.rb +16 -0
  30. data/lib/core/structure/commands/generate_entity_commands.rb +52 -0
  31. data/lib/core/structure/commands/generate_invalidation_commands.rb +26 -0
  32. data/lib/core/structure/commands/list_commands.rb +11 -0
  33. data/lib/core/structure/commands/list_contributors.rb +10 -0
  34. data/lib/core/structure/commands/list_entities.rb +3 -0
  35. data/lib/core/structure/commands/list_plugins.rb +3 -0
  36. data/lib/core/structure/commands/register_contributor.rb +14 -0
  37. data/lib/core/structure/structure.plugin +4 -0
  38. data/lib/vop/objects/chain.rb +25 -0
  39. data/lib/vop/objects/command.rb +86 -0
  40. data/lib/vop/objects/command_param.rb +39 -0
  41. data/lib/vop/objects/entities.rb +21 -0
  42. data/lib/vop/objects/entity.rb +75 -0
  43. data/lib/vop/objects/entity_definition.rb +33 -0
  44. data/lib/vop/objects/filter.rb +48 -0
  45. data/lib/vop/objects/plugin.rb +208 -0
  46. data/lib/vop/objects/request.rb +73 -0
  47. data/lib/vop/objects/response.rb +17 -0
  48. data/lib/vop/objects/thing_with_params.rb +17 -0
  49. data/lib/vop/{command_loader.rb → parts/command_loader.rb} +8 -12
  50. data/lib/vop/parts/dependency_resolver.rb +56 -0
  51. data/lib/vop/parts/entity_loader.rb +46 -0
  52. data/lib/vop/parts/executor.rb +155 -0
  53. data/lib/vop/parts/filter_loader.rb +41 -0
  54. data/lib/vop/parts/plugin_finder.rb +46 -0
  55. data/lib/vop/parts/plugin_loader.rb +72 -0
  56. data/lib/vop/shell/shell.rb +221 -0
  57. data/lib/vop/shell/shell_formatter.rb +110 -0
  58. data/lib/vop/shell/shell_input.rb +14 -0
  59. data/lib/vop/shell/shell_input_readline.rb +20 -0
  60. data/lib/vop/shell/shell_input_testable.rb +27 -0
  61. data/lib/vop/syntax/command_syntax.rb +90 -0
  62. data/lib/vop/syntax/entity_syntax.rb +35 -0
  63. data/lib/vop/syntax/filter_syntax.rb +11 -0
  64. data/lib/vop/syntax/plugin_syntax.rb +55 -0
  65. data/lib/vop/util/errors.rb +45 -0
  66. data/lib/vop/util/pluralizer.rb +26 -0
  67. data/lib/vop/util/worker.rb +24 -0
  68. data/lib/vop/version.rb +1 -1
  69. data/lib/vop/vop.rb +216 -0
  70. data/lib/vop.rb +16 -229
  71. data/vop.gemspec +18 -15
  72. metadata +95 -63
  73. data/bin/vop.rb +0 -28
  74. data/lib/vop/command.rb +0 -168
  75. data/lib/vop/entity.rb +0 -61
  76. data/lib/vop/loader.rb +0 -35
  77. data/lib/vop/plugin.rb +0 -141
  78. data/lib/vop/plugin_loader.rb +0 -88
  79. data/lib/vop/plugins/core/commands/collect_contributions.rb +0 -31
  80. data/lib/vop/plugins/core/commands/edit.rb +0 -12
  81. data/lib/vop/plugins/core/commands/help.rb +0 -38
  82. data/lib/vop/plugins/core/commands/identity.rb +0 -4
  83. data/lib/vop/plugins/core/commands/list_contributors.rb +0 -8
  84. data/lib/vop/plugins/core/commands/list_entities.rb +0 -3
  85. data/lib/vop/plugins/core/commands/pry.rb +0 -9
  86. data/lib/vop/plugins/core/commands/reset.rb +0 -5
  87. data/lib/vop/plugins/core/commands/source.rb +0 -5
  88. data/lib/vop/plugins/core/commands/system_call.rb +0 -5
  89. data/lib/vop/plugins/core/core.plugin +0 -4
  90. data/lib/vop/plugins/core/helpers/command_loader/command_syntax.rb +0 -45
  91. data/lib/vop/plugins/core/helpers/command_loader/contributions.rb +0 -28
  92. data/lib/vop/plugins/core/helpers/command_loader/entities.rb +0 -57
  93. data/lib/vop/plugins/core/helpers/helper.rb +0 -3
  94. data/lib/vop/plugins/meta/commands/add_search_path.rb +0 -6
  95. data/lib/vop/plugins/meta/commands/delete_plugin.rb +0 -13
  96. data/lib/vop/plugins/meta/commands/list_commands.rb +0 -17
  97. data/lib/vop/plugins/meta/commands/list_plugins.rb +0 -8
  98. data/lib/vop/plugins/meta/commands/new_command.rb +0 -14
  99. data/lib/vop/plugins/meta/commands/new_plugin.rb +0 -25
  100. data/lib/vop/plugins/meta/commands/show_search_path.rb +0 -3
  101. data/lib/vop/plugins/meta/commands/who_provides.rb +0 -5
  102. data/lib/vop/plugins/meta/meta.plugin +0 -1
  103. data/lib/vop/plugins/ssh/commands/scp.rb +0 -11
  104. data/lib/vop/plugins/ssh/commands/ssh.rb +0 -19
  105. data/lib/vop/plugins/ssh/ssh.plugin +0 -1
  106. data/lib/vop/shell/backend.rb +0 -28
  107. data/lib/vop/shell/base_shell.rb +0 -112
  108. data/lib/vop/shell/formatter.rb +0 -46
  109. data/lib/vop/shell/vop_shell_backend.rb +0 -257
  110. data/lib/vop/shell.rb +0 -52
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 210d42c576321fd27102c17b4a8f43e1cc76497d
4
- data.tar.gz: f40f69a7cb5de67a7cfc0587469f58dda3fe43df
3
+ metadata.gz: 671eba569f41b30868a8026134138d13399d3d5e
4
+ data.tar.gz: 5791e1031450edc74942ddc3b388ba8c27521c87
5
5
  SHA512:
6
- metadata.gz: 6924c43e9ea5ab100f6285c71cb960d6c98da41b826668feee5462ef7dd230b1a78ce3ae488a295f72a63ebaa393d25a7af1fe36bcf216b77f77739e4fcc25c3
7
- data.tar.gz: 3867865eb15607c54d2291f833a0acd363a256ed52f79bfd24ed4e0ec68e9bcf44f73e1b222bae53ef4a62af38c4870b237b0622a7a00bb9f28bfe16e0891e14
6
+ metadata.gz: 2e216682fe3dce4eedbec94ff3d4073084652b405747383085430b16d8abebf0e1b20ecaff2632591592de142db52c34dd98103b27ef31a9df84df2135138549
7
+ data.tar.gz: 62a72d94b60acd3f92dd0d5da33cbc3b14ee02aecb3380a365c5c5d2bffd8400d0adf96962d19474620d0977a52a6b6a687aca3f10203be1d67a77ced488c6bd
data/.gitignore CHANGED
@@ -48,3 +48,5 @@ build-iPhoneSimulator/
48
48
 
49
49
  # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
50
50
  .rvmrc
51
+ .rake_tasks~
52
+ .rspec_status
data/Gemfile CHANGED
@@ -1,3 +1,4 @@
1
- source 'http://rubygems.org'
1
+ source "https://rubygems.org"
2
2
 
3
+ # Specify your gem's dependencies in vop.gemspec
3
4
  gemspec
data/Gemfile.lock CHANGED
@@ -1,37 +1,30 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- vop (0.3.0)
5
- activesupport
6
- docopt
4
+ vop (0.3.4)
7
5
  net-scp
8
6
  net-ssh
9
- pry
7
+ redis
8
+ sidekiq
10
9
  terminal-table
10
+ xml-simple
11
11
 
12
12
  GEM
13
- remote: http://rubygems.org/
13
+ remote: https://rubygems.org/
14
14
  specs:
15
- activesupport (5.0.0.1)
16
- concurrent-ruby (~> 1.0, >= 1.0.2)
17
- i18n (~> 0.7)
18
- minitest (~> 5.1)
19
- tzinfo (~> 1.1)
20
- coderay (1.1.1)
21
- concurrent-ruby (1.0.2)
15
+ concurrent-ruby (1.0.5)
16
+ connection_pool (2.2.1)
22
17
  diff-lcs (1.2.5)
23
- docopt (0.5.0)
24
- i18n (0.7.0)
25
- method_source (0.8.2)
26
- minitest (5.10.1)
18
+ docile (1.1.5)
19
+ json (1.8.6)
27
20
  net-scp (1.2.1)
28
21
  net-ssh (>= 2.6.5)
29
- net-ssh (3.2.0)
30
- pry (0.10.3)
31
- coderay (~> 1.1.0)
32
- method_source (~> 0.8.1)
33
- slop (~> 3.4)
34
- rake (11.3.0)
22
+ net-ssh (4.2.0)
23
+ rack (2.0.3)
24
+ rack-protection (2.0.0)
25
+ rack
26
+ rake (10.5.0)
27
+ redis (4.0.1)
35
28
  rspec (3.4.0)
36
29
  rspec-core (~> 3.4.0)
37
30
  rspec-expectations (~> 3.4.0)
@@ -45,22 +38,30 @@ GEM
45
38
  diff-lcs (>= 1.2.0, < 2.0)
46
39
  rspec-support (~> 3.4.0)
47
40
  rspec-support (3.4.1)
48
- slop (3.6.0)
49
- terminal-table (1.7.3)
50
- unicode-display_width (~> 1.1.1)
51
- thread_safe (0.3.5)
52
- tzinfo (1.2.2)
53
- thread_safe (~> 0.1)
54
- unicode-display_width (1.1.1)
41
+ sidekiq (5.0.5)
42
+ concurrent-ruby (~> 1.0)
43
+ connection_pool (~> 2.2, >= 2.2.0)
44
+ rack-protection (>= 1.5.0)
45
+ redis (>= 3.3.4, < 5)
46
+ simplecov (0.11.2)
47
+ docile (~> 1.1.0)
48
+ json (~> 1.8)
49
+ simplecov-html (~> 0.10.0)
50
+ simplecov-html (0.10.0)
51
+ terminal-table (1.8.0)
52
+ unicode-display_width (~> 1.1, >= 1.1.1)
53
+ unicode-display_width (1.3.0)
54
+ xml-simple (1.1.5)
55
55
 
56
56
  PLATFORMS
57
57
  ruby
58
58
 
59
59
  DEPENDENCIES
60
- bundler (~> 1.10)
61
- rake
62
- rspec
60
+ bundler (~> 1.15)
61
+ rake (~> 10.0)
62
+ rspec (~> 3.0)
63
+ simplecov
63
64
  vop!
64
65
 
65
66
  BUNDLED WITH
66
- 1.10.6
67
+ 1.16.0
data/README.md CHANGED
@@ -1,2 +1,184 @@
1
- # vop
2
- new and improved, now with twice the vitamins!
1
+
2
+
3
+ The vop is a systems automation scripting framework.
4
+
5
+ It organizes (ruby) scripts into commands living in plugins, defines services that can be installed and managed, and comes with a shell and a web interface.
6
+
7
+ # Status: WIP
8
+
9
+ This is work in progress. Do not assume everything you read to be totally accurate and/or stable.
10
+
11
+ # Installation
12
+
13
+ ## as a gem:
14
+
15
+ $ gem install vop
16
+
17
+ # Usage
18
+
19
+ Call `vop` to start the shell.
20
+
21
+ Use the tab key for completion, type "help" for more info, `list_plugins` and `list_commands` for an overview.
22
+
23
+ # Syntax
24
+
25
+ ## Plugins
26
+
27
+ Minimally, a plugin is a folder containing a file called "&lt;name&gt;.plugin". An empty file will do.
28
+
29
+ optional:
30
+ ```
31
+ description "really nice plugin, this one"
32
+
33
+ auto_load false # default is true
34
+ ```
35
+
36
+ dependencies:
37
+ ```
38
+ depends_on :other_plugin
39
+ depends_on [ :many, :other, :plugins ]
40
+ ```
41
+
42
+ hooks:
43
+ ```
44
+ hook :before_execute do |payload|
45
+ request = payload[:request]
46
+ end
47
+
48
+ hook :after_execute do |payload|
49
+ request = payload[:request]
50
+ response = payload[:response]
51
+ end
52
+ ```
53
+
54
+ ## Commands
55
+
56
+ ...are loaded from the `commands` folder in a plugin.
57
+
58
+ minimal:
59
+ ```
60
+ run { 42 }
61
+ ```
62
+
63
+ optional:
64
+ ```
65
+ description "Roses are red."
66
+
67
+ read_only # => cacheable
68
+ ```
69
+
70
+ defining param(eter)s:
71
+ ```
72
+ param "snafoo" # optional
73
+ param! "snafoo" # mandatory
74
+ param! :snafoo # entity
75
+ ```
76
+ param syntax:
77
+ ```
78
+ param[!] ( "name" | :entity ) [, {option: value}]
79
+ ```
80
+ full example:
81
+ ```
82
+ param! "foo",
83
+ description: "it's the foo.",
84
+ multi: true,
85
+ default: [ "snafoo", "footoristic", "foofoo", "foolosophy" ],
86
+ default_param: true,
87
+ lookup: lambda { |params| %w|string array| }
88
+ ```
89
+
90
+ to access param values, use the `params` hash or named block variables:
91
+ ```
92
+ param "foo"
93
+ param "not_really"
94
+
95
+ run do |params, not_really|
96
+ puts params["foo"] unless not_really
97
+ end
98
+ ```
99
+
100
+ entity parameters are resolved from the specified key to the entity:
101
+ ```
102
+ param :machine
103
+
104
+ run do |machine|
105
+ puts machine.name
106
+ end
107
+ ```
108
+
109
+ contribute:
110
+ ```
111
+ contribute to: "other_command" do |params|
112
+ end
113
+ ```
114
+
115
+
116
+ show (display options for shell output):
117
+ ```
118
+ show columns: ["name", "number"]
119
+ show sort: false
120
+ show display_type: :raw
121
+ ```
122
+ `display_type` can be any of:
123
+ ```
124
+ :data
125
+ :raw
126
+ :table
127
+ :list
128
+ :hash
129
+ ```
130
+ (see [`shell/formatter.rb`](https://github.com/virtualop/vop/blob/master/lib/vop/parts/shell_formatter.rb))
131
+
132
+ ## Services
133
+
134
+ Plugin folder: `services`
135
+
136
+ install one or multiple OS packages:
137
+ ```
138
+ deploy package: <foo>
139
+ deploy package: [ <foo>, <bar>, <baz> ]
140
+ ```
141
+
142
+ install (configuration for) a package repository:
143
+ ```
144
+ deploy repository: {
145
+ alias: "funny-name",
146
+ url: "https://package.repository.somewhere.xxx",
147
+ dist: "stable/",
148
+ key: "https://download.somewhere.xxx/the.gpg.key"
149
+ }
150
+ ```
151
+
152
+ run arbitrary vop or ruby code during deployment of a service:
153
+ ```
154
+ deploy do |machine|
155
+
156
+
157
+ end
158
+ ```
159
+
160
+ # Development
161
+
162
+ ## required dependencies
163
+
164
+ * (to checkout sources: git)
165
+ * ruby + headers (e.g. packages `ruby` and `ruby-dev` on Ubuntu)
166
+ * bundler (`gem install bundler`)
167
+
168
+ ## setup
169
+ After checking out the repo, run `bin/setup` to install (gem) dependencies.
170
+ Then, run `bundle exec rake spec` to run the tests.
171
+ You can also run `bin/console` for an interactive prompt that will allow you to experiment.
172
+
173
+ To start the vop from the checked out sources, set the environment variable `VOP_DEV_MODE` to any value, e.g. like this:
174
+ ```
175
+ export VOP_DEV_MODE=1
176
+ ```
177
+ and then run `exe/vop`.
178
+
179
+ ### packaging
180
+ To install the vop from source as a gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
181
+
182
+ # Contributing
183
+
184
+ Bug reports and pull requests are welcome on GitHub at https://github.com/virtualop/vop.
data/bin/console ADDED
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "vop"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ @op = Vop.boot
14
+ puts "A Vop instance is available in @op."
15
+
16
+ require "irb"
17
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/bin/vop.sh CHANGED
@@ -1,4 +1,8 @@
1
1
  #!/bin/bash
2
2
 
3
- DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
4
- ruby $DIR/vop.rb $*
3
+ VOP_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )/.." && pwd )
4
+
5
+ cd $VOP_DIR
6
+ bundle exec exe/vop "$*"
7
+
8
+ cd - >/dev/null
data/exe/vop CHANGED
@@ -1,28 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require 'pathname'
3
+ require "vop"
4
4
 
5
- $: << File.join(Pathname.new(File.join(File.dirname(__FILE__), '..')).realpath, 'lib')
6
-
7
- require 'vop/shell'
8
- require 'docopt'
9
- require 'pp'
10
-
11
- begin
12
- shell = Vop::Shell::setup()
13
- if shell.options["--execute"]
14
- last_response = shell.execute(shell.options["--execute"])
15
- else
16
- last_response = shell.run_cli
17
- end
18
-
19
- # TODO exit_status = last_response && last_response.status == Vop.Status::OK ? 0 : 1
20
- exit 0
21
- rescue => detail
22
- if detail.is_a? Docopt::Exit
23
- puts detail.message
24
- else
25
- $stderr.puts "error : #{detail.message}\n#{detail.backtrace[0..9].join("\n")}"
26
- exit 42
27
- end
28
- end
5
+ @op = Vop.boot()
6
+ Vop::Shell.run(@op)
data/lib/boot.rb ADDED
@@ -0,0 +1,3 @@
1
+ require "vop"
2
+
3
+ @op = Vop.boot()
@@ -0,0 +1 @@
1
+ run { 42 }
@@ -0,0 +1,47 @@
1
+ param! "name"
2
+ param "path"
3
+ param "content"
4
+
5
+ require "fileutils"
6
+
7
+ run do |params|
8
+ unless params["path"]
9
+ # try to find a writable plugin directory
10
+ first_non_usr = @op.plugin_locations.select { |location| not location.start_with? "/usr" }.first
11
+ if first_non_usr.nil?
12
+ raise "no writable plugin location found"
13
+ else
14
+ $logger.info "new_plugin defaulting to first writable plugin location #{first_non_usr}"
15
+ params["path"] = first_non_usr
16
+ end
17
+ end
18
+
19
+ raise "no such path: #{params["path"]}" unless File.exists? params["path"]
20
+
21
+ pp params
22
+
23
+ # a plugin is a directory
24
+ plugin_path = File.join(params["path"], params["name"])
25
+ puts "plugin path : #{plugin_path}"
26
+ Dir.mkdir(plugin_path)
27
+
28
+ # with subfolders for commands and helpers
29
+ %w|commands helpers|.each do |thing|
30
+ Dir.mkdir(File.join(plugin_path, thing))
31
+ end
32
+
33
+ # and a metadata file called "<name>.plugin"
34
+ plugin_file = params["name"] + ".plugin"
35
+ full_name = File.join(plugin_path, plugin_file)
36
+ FileUtils.touch full_name
37
+
38
+ # TODO content is [] - should probably be nil, though
39
+ #puts "content: >>#{params["content"].pretty_inspect}<<"
40
+ unless params["content"].nil?
41
+ IO.write(full_name, params["content"])
42
+ end
43
+
44
+ $logger.info "created new plugin file #{plugin_file}"
45
+
46
+ @op.reset
47
+ end
@@ -0,0 +1,38 @@
1
+ require "rubygems"
2
+ require "find"
3
+ require "digest"
4
+
5
+ contribute to: "search_path" do |params|
6
+ gem_list = `gem list`.split("\n")
7
+ candidates = gem_list.select { |x| x =~ /vop-\w+/ }
8
+
9
+ # TODO cache which gems have already been inspected
10
+ # checksum = Digest::MD5.new
11
+ # candidates.map do |candidate|
12
+ # checksum << [ candidate.name, candidate.version ].join(":")
13
+ # end
14
+ # puts "gemspec md5 : #{checksum.hexdigest}"
15
+
16
+ result = []
17
+
18
+ candidates.each do |candidate|
19
+ $logger.debug "inspecting #{candidate}"
20
+
21
+ matched = /(.+?)\s+\([\d\.]+\)/.match(candidate)
22
+ unless matched
23
+ $logger.warn("unexpected line format : #{candidate}")
24
+ next
25
+ end
26
+
27
+ name = matched.captures.first
28
+ version = matched.captures.last
29
+
30
+ contents = `gem contents #{name}`.split("\n")
31
+
32
+ plugin_files = contents.grep /\.plugin$/
33
+ result += plugin_files.map do |file_name|
34
+ file_name.split("/")[0..-2].join("/")
35
+ end
36
+ end
37
+ result
38
+ end
@@ -0,0 +1,6 @@
1
+ run do |params|
2
+ @op.collect_contributions(
3
+ "command_name" => "search_path",
4
+ "raw_params" => params
5
+ )
6
+ end
@@ -0,0 +1,12 @@
1
+ param! "plugin"
2
+ param! "key"
3
+ param! "value"
4
+
5
+ run do |key, value, params|
6
+ plugin = @op.plugin(params["plugin"])
7
+
8
+ plugin.config[key] = value
9
+ plugin.write_config
10
+
11
+ plugin.config
12
+ end
@@ -0,0 +1,6 @@
1
+ param! "plugin_name"
2
+
3
+ run do |params|
4
+ plugin = @op.plugin(params["plugin_name"])
5
+ plugin.config
6
+ end
@@ -0,0 +1,9 @@
1
+ show display_type: :raw
2
+
3
+ run do
4
+ @op.plugins.map do |plugin|
5
+ { "name" => plugin.name,
6
+ "config" => @op.show("plugin_name" => plugin.name)
7
+ }
8
+ end
9
+ end
@@ -0,0 +1,6 @@
1
+ # TODO would be nice if we had a :command entity
2
+ param! 'command_name', :lookup => lambda { |params| @op.commands.keys }
3
+
4
+ run do |command_name|
5
+ @op.commands[command_name].plugin.name
6
+ end
@@ -0,0 +1 @@
1
+ depends_on :structure
@@ -0,0 +1,6 @@
1
+ param! "level"
2
+
3
+ run do |level|
4
+ new_level = Logger.const_get(level.upcase)
5
+ $logger.level = new_level
6
+ end
@@ -0,0 +1,12 @@
1
+ param! "name", lookup: lambda { @op.commands.keys }
2
+
3
+ run do |params, name|
4
+ has_vim = `which vim`
5
+ editor = ENV["EDITOR"] || "vim" if has_vim
6
+ raise "please set the EDITOR environment variable" unless editor
7
+
8
+ command_file = @op.commands[name].source[:file_name]
9
+ system("#{editor} #{command_file}")
10
+
11
+ @op.reset
12
+ end
@@ -0,0 +1,49 @@
1
+ param! "name",
2
+ description: "a command for which help should be displayed",
3
+ lookup: lambda { |params| @op.list_commands.split }
4
+
5
+ run do |params, name|
6
+ command = @op.commands[params["name"]]
7
+ if command.nil?
8
+ raise "no such command : #{name}"
9
+ end
10
+
11
+ puts
12
+ puts command.name
13
+
14
+ if command.description
15
+ puts " #{command.description}"
16
+ end
17
+
18
+ puts
19
+ puts "syntax:"
20
+
21
+ minimal_syntax = command.short_name
22
+ maximal_syntax = command.short_name
23
+ command.params.each do |p|
24
+ example = if p == command.default_param
25
+ "<#{p.name}>"
26
+ else
27
+ "#{p.name}=<#{p.name}>"
28
+ end
29
+ minimal_syntax << " #{example}" if p.options[:mandatory]
30
+ maximal_syntax << " #{example}"
31
+ end
32
+ puts " #{minimal_syntax}"
33
+ puts " #{maximal_syntax}" unless minimal_syntax == maximal_syntax
34
+
35
+ if command.params.size > 0
36
+ puts
37
+ puts "parameters:"
38
+ max_param_length = command.params.map { |p| p.name.length }.max
39
+ command.params.each do |p|
40
+ default_text = ""
41
+ if p.options.key? :default
42
+ default_text += " (default: #{p.options[:default]})"
43
+ end
44
+ puts " %-#{max_param_length}s\t%s\t%s" % [p.name, p.options[:description], default_text]
45
+ end
46
+ end
47
+
48
+ nil
49
+ end
@@ -0,0 +1,4 @@
1
+ run do
2
+ @op._reset
3
+ [ @op.plugins.size, @op.commands.size ]
4
+ end
@@ -0,0 +1,21 @@
1
+ param! "name", lookup: lambda { @op.commands.keys + @op.entities.keys + @op.filters.keys }
2
+
3
+ run do |name|
4
+ (source, thing) = if @op.commands.keys.include? name
5
+ [ :commands, @op.commands[name] ]
6
+ elsif @op.entities.keys.include? name
7
+ [ :entities, @op.entities[name] ]
8
+ elsif @op.filters.keys.include? name
9
+ [ :filters, @op.filters[name] ]
10
+ end
11
+
12
+ code = thing.source[:code]
13
+
14
+ result = []
15
+ result << " "
16
+ code.lines.each_with_index { |line, idx|
17
+ result << "%02d %s" % [idx+1, line.chomp]
18
+ }
19
+ result << " "
20
+ result.join("\n")
21
+ end
@@ -0,0 +1,46 @@
1
+ description "This is called by a command accepting contributions - it calls all contributors and merges the result"
2
+
3
+ param! "command_name", default_param: true
4
+ param "raw_params", default: {}
5
+
6
+ run do |command_name, raw_params|
7
+ contributors = @op.list_contributors(command_name: command_name)
8
+
9
+ target_name = command_name.split(".").last
10
+ target = @op.commands[target_name]
11
+
12
+ if target.nil?
13
+ raise "contribution target #{target_name} not found"
14
+ end
15
+
16
+ display_type = target.show_options[:display_type] || :table
17
+
18
+ result = case display_type
19
+ when :table
20
+ []
21
+ when :hash
22
+ {}
23
+ else
24
+ raise "contributions not implemented for display_type #{display_type}"
25
+ end
26
+
27
+ contributors.each do |contributor_name|
28
+ short_name = contributor_name.split(".").last
29
+ contributor = @op.commands[short_name]
30
+
31
+ contribution = @op.execute(short_name, raw_params)
32
+
33
+ if contribution.nil?
34
+ $logger.warn "command #{short_name} contributes a nil value"
35
+ else
36
+ case display_type
37
+ when :table
38
+ result += contribution
39
+ when :hash
40
+ result.merge! contribution
41
+ end
42
+ end
43
+ end
44
+
45
+ result
46
+ end