nucleon 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (141) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -0
  3. data/Gemfile.lock +2 -0
  4. data/VERSION +1 -1
  5. data/lib/core/config.rb +21 -20
  6. data/lib/core/environment.rb +2 -2
  7. data/lib/core/facade.rb +15 -0
  8. data/lib/core/mixin/action/registration.rb +84 -0
  9. data/lib/core/mixin/sub_config.rb +5 -5
  10. data/lib/core/plugin/action.rb +66 -10
  11. data/lib/core/plugin/base.rb +100 -19
  12. data/lib/core/plugin/command.rb +4 -0
  13. data/lib/core/util/cache.rb +13 -1
  14. data/lib/core/util/cli.rb +77 -11
  15. data/lib/core/util/console.rb +55 -72
  16. data/lib/core/util/data.rb +19 -9
  17. data/lib/core/util/logger.rb +16 -6
  18. data/lib/core/util/shell.rb +3 -1
  19. data/lib/core/util/ssh.rb +28 -25
  20. data/lib/nucleon/translator/JSON.rb +2 -2
  21. data/lib/nucleon/translator/YAML.rb +2 -2
  22. data/lib/nucleon_base.rb +22 -8
  23. data/nucleon.gemspec +122 -2
  24. data/rdoc/site/0.2.0/ARCHITECTURE_rdoc.html +638 -0
  25. data/rdoc/site/0.2.0/Hash.html +351 -0
  26. data/rdoc/site/0.2.0/Kernel.html +416 -0
  27. data/rdoc/site/0.2.0/Nucleon.html +607 -0
  28. data/rdoc/site/0.2.0/Nucleon/Action.html +284 -0
  29. data/rdoc/site/0.2.0/Nucleon/Action/Extract.html +455 -0
  30. data/rdoc/site/0.2.0/Nucleon/Action/Project.html +283 -0
  31. data/rdoc/site/0.2.0/Nucleon/Action/Project/Add.html +500 -0
  32. data/rdoc/site/0.2.0/Nucleon/Action/Project/Create.html +457 -0
  33. data/rdoc/site/0.2.0/Nucleon/Action/Project/Remove.html +503 -0
  34. data/rdoc/site/0.2.0/Nucleon/Action/Project/Save.html +476 -0
  35. data/rdoc/site/0.2.0/Nucleon/Action/Project/Update.html +423 -0
  36. data/rdoc/site/0.2.0/Nucleon/Codes.html +567 -0
  37. data/rdoc/site/0.2.0/Nucleon/Command.html +279 -0
  38. data/rdoc/site/0.2.0/Nucleon/Command/Bash.html +548 -0
  39. data/rdoc/site/0.2.0/Nucleon/Config.html +1631 -0
  40. data/rdoc/site/0.2.0/Nucleon/Config/Collection.html +513 -0
  41. data/rdoc/site/0.2.0/Nucleon/Config/Options.html +493 -0
  42. data/rdoc/site/0.2.0/Nucleon/Core.html +639 -0
  43. data/rdoc/site/0.2.0/Nucleon/Environment.html +1208 -0
  44. data/rdoc/site/0.2.0/Nucleon/Errors.html +279 -0
  45. data/rdoc/site/0.2.0/Nucleon/Errors/BatchError.html +285 -0
  46. data/rdoc/site/0.2.0/Nucleon/Errors/NucleonError.html +661 -0
  47. data/rdoc/site/0.2.0/Nucleon/Errors/SSHUnavailable.html +285 -0
  48. data/rdoc/site/0.2.0/Nucleon/Event.html +279 -0
  49. data/rdoc/site/0.2.0/Nucleon/Event/Regex.html +471 -0
  50. data/rdoc/site/0.2.0/Nucleon/Facade.html +2409 -0
  51. data/rdoc/site/0.2.0/Nucleon/Gems.html +639 -0
  52. data/rdoc/site/0.2.0/Nucleon/Manager.html +1860 -0
  53. data/rdoc/site/0.2.0/Nucleon/Mixin.html +288 -0
  54. data/rdoc/site/0.2.0/Nucleon/Mixin/Action.html +281 -0
  55. data/rdoc/site/0.2.0/Nucleon/Mixin/Action/Commit.html +385 -0
  56. data/rdoc/site/0.2.0/Nucleon/Mixin/Action/Project.html +399 -0
  57. data/rdoc/site/0.2.0/Nucleon/Mixin/Action/Push.html +375 -0
  58. data/rdoc/site/0.2.0/Nucleon/Mixin/Colors.html +549 -0
  59. data/rdoc/site/0.2.0/Nucleon/Mixin/ConfigCollection.html +485 -0
  60. data/rdoc/site/0.2.0/Nucleon/Mixin/ConfigOptions.html +453 -0
  61. data/rdoc/site/0.2.0/Nucleon/Mixin/Macro.html +280 -0
  62. data/rdoc/site/0.2.0/Nucleon/Mixin/Macro/ObjectInterface.html +699 -0
  63. data/rdoc/site/0.2.0/Nucleon/Mixin/Macro/PluginInterface.html +686 -0
  64. data/rdoc/site/0.2.0/Nucleon/Mixin/Settings.html +485 -0
  65. data/rdoc/site/0.2.0/Nucleon/Mixin/SubConfig.html +891 -0
  66. data/rdoc/site/0.2.0/Nucleon/Parallel.html +330 -0
  67. data/rdoc/site/0.2.0/Nucleon/Parallel/ClassMethods.html +329 -0
  68. data/rdoc/site/0.2.0/Nucleon/Parallel/InstanceMethods.html +456 -0
  69. data/rdoc/site/0.2.0/Nucleon/Plugin.html +286 -0
  70. data/rdoc/site/0.2.0/Nucleon/Plugin/Action.html +1829 -0
  71. data/rdoc/site/0.2.0/Nucleon/Plugin/Action/Option.html +463 -0
  72. data/rdoc/site/0.2.0/Nucleon/Plugin/Base.html +1803 -0
  73. data/rdoc/site/0.2.0/Nucleon/Plugin/Command.html +725 -0
  74. data/rdoc/site/0.2.0/Nucleon/Plugin/Event.html +446 -0
  75. data/rdoc/site/0.2.0/Nucleon/Plugin/Extension.html +285 -0
  76. data/rdoc/site/0.2.0/Nucleon/Plugin/Project.html +2898 -0
  77. data/rdoc/site/0.2.0/Nucleon/Plugin/Template.html +480 -0
  78. data/rdoc/site/0.2.0/Nucleon/Plugin/Translator.html +375 -0
  79. data/rdoc/site/0.2.0/Nucleon/Project.html +280 -0
  80. data/rdoc/site/0.2.0/Nucleon/Project/Git.html +1805 -0
  81. data/rdoc/site/0.2.0/Nucleon/Project/Github.html +553 -0
  82. data/rdoc/site/0.2.0/Nucleon/Template.html +281 -0
  83. data/rdoc/site/0.2.0/Nucleon/Template/JSON.html +333 -0
  84. data/rdoc/site/0.2.0/Nucleon/Template/Wrapper.html +333 -0
  85. data/rdoc/site/0.2.0/Nucleon/Template/YAML.html +333 -0
  86. data/rdoc/site/0.2.0/Nucleon/Translator.html +280 -0
  87. data/rdoc/site/0.2.0/Nucleon/Translator/JSON.html +370 -0
  88. data/rdoc/site/0.2.0/Nucleon/Translator/YAML.html +370 -0
  89. data/rdoc/site/0.2.0/Nucleon/Util.html +289 -0
  90. data/rdoc/site/0.2.0/Nucleon/Util/CLI.html +392 -0
  91. data/rdoc/site/0.2.0/Nucleon/Util/CLI/Parser.html +1250 -0
  92. data/rdoc/site/0.2.0/Nucleon/Util/Cache.html +784 -0
  93. data/rdoc/site/0.2.0/Nucleon/Util/Console.html +1318 -0
  94. data/rdoc/site/0.2.0/Nucleon/Util/Data.html +1411 -0
  95. data/rdoc/site/0.2.0/Nucleon/Util/Disk.html +526 -0
  96. data/rdoc/site/0.2.0/Nucleon/Util/Git.html +365 -0
  97. data/rdoc/site/0.2.0/Nucleon/Util/Liquid.html +369 -0
  98. data/rdoc/site/0.2.0/Nucleon/Util/Logger.html +810 -0
  99. data/rdoc/site/0.2.0/Nucleon/Util/Package.html +562 -0
  100. data/rdoc/site/0.2.0/Nucleon/Util/SSH.html +1033 -0
  101. data/rdoc/site/0.2.0/Nucleon/Util/SSH/Keypair.html +605 -0
  102. data/rdoc/site/0.2.0/Nucleon/Util/Shell.html +693 -0
  103. data/rdoc/site/0.2.0/Nucleon/Util/Shell/Result.html +501 -0
  104. data/rdoc/site/0.2.0/README_rdoc.html +316 -0
  105. data/rdoc/site/0.2.0/TODO_rdoc.html +265 -0
  106. data/rdoc/site/0.2.0/created.rid +61 -0
  107. data/rdoc/site/0.2.0/images/add.png +0 -0
  108. data/rdoc/site/0.2.0/images/brick.png +0 -0
  109. data/rdoc/site/0.2.0/images/brick_link.png +0 -0
  110. data/rdoc/site/0.2.0/images/bug.png +0 -0
  111. data/rdoc/site/0.2.0/images/bullet_black.png +0 -0
  112. data/rdoc/site/0.2.0/images/bullet_toggle_minus.png +0 -0
  113. data/rdoc/site/0.2.0/images/bullet_toggle_plus.png +0 -0
  114. data/rdoc/site/0.2.0/images/date.png +0 -0
  115. data/rdoc/site/0.2.0/images/delete.png +0 -0
  116. data/rdoc/site/0.2.0/images/find.png +0 -0
  117. data/rdoc/site/0.2.0/images/loadingAnimation.gif +0 -0
  118. data/rdoc/site/0.2.0/images/macFFBgHack.png +0 -0
  119. data/rdoc/site/0.2.0/images/package.png +0 -0
  120. data/rdoc/site/0.2.0/images/page_green.png +0 -0
  121. data/rdoc/site/0.2.0/images/page_white_text.png +0 -0
  122. data/rdoc/site/0.2.0/images/page_white_width.png +0 -0
  123. data/rdoc/site/0.2.0/images/plugin.png +0 -0
  124. data/rdoc/site/0.2.0/images/ruby.png +0 -0
  125. data/rdoc/site/0.2.0/images/tag_blue.png +0 -0
  126. data/rdoc/site/0.2.0/images/tag_green.png +0 -0
  127. data/rdoc/site/0.2.0/images/transparent.png +0 -0
  128. data/rdoc/site/0.2.0/images/wrench.png +0 -0
  129. data/rdoc/site/0.2.0/images/wrench_orange.png +0 -0
  130. data/rdoc/site/0.2.0/images/zoom.png +0 -0
  131. data/rdoc/site/0.2.0/index.html +315 -0
  132. data/rdoc/site/0.2.0/js/darkfish.js +155 -0
  133. data/rdoc/site/0.2.0/js/jquery.js +18 -0
  134. data/rdoc/site/0.2.0/js/navigation.js +142 -0
  135. data/rdoc/site/0.2.0/js/search.js +94 -0
  136. data/rdoc/site/0.2.0/js/search_index.js +1 -0
  137. data/rdoc/site/0.2.0/js/searcher.js +228 -0
  138. data/rdoc/site/0.2.0/rdoc.css +543 -0
  139. data/rdoc/site/0.2.0/table_of_contents.html +1657 -0
  140. data/spec/core/util/console_spec.rb +50 -18
  141. metadata +133 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 538f4bb7721e53ea65e86fcd9dabe27a3def5f67
4
- data.tar.gz: 4fa312d8415f9db8d1b29537c95749358252a598
3
+ metadata.gz: 8c8807425d4796bbacc3ab9b91273fce43c75dad
4
+ data.tar.gz: acc2ebd35998fb5d9beab4c83bca35a67e6cadc5
5
5
  SHA512:
6
- metadata.gz: afe85d0df90e8f5114d1d929e9806c01077ea5bbb293c4cef5aa886dc8a678e8a29baf653de081306a1873f9702f0da1d99f7776976b603600b3c4e283b1fb11
7
- data.tar.gz: cd73b96970c6fc5ce2e29e1965bccd66b32c26d051f542c707de49bd0f99063bcd0c0f83d56eb7528cb794d5f62d4dfb57e4ec899db76ae8b1a8c936d66eef86
6
+ metadata.gz: 66642c1e07a8c2387fb6bc761dc1986019d56ae1ecb0267745343be0df59cec44c9e6c39f5d6cdf20b7f4f11d7e917acde82e8098845ac156bba70cf3ec59cb6
7
+ data.tar.gz: 9e887f1c8b8f9df44e6d2b64eeb4b98ed3b25574e52889170870764e274b30529120db7c3b4256bcb7ec785d32f4b17a929a0ec69e2bf4f62bcbab9baee7abf5
data/Gemfile CHANGED
@@ -4,6 +4,7 @@ gem "log4r", "~> 1.1"
4
4
  gem "i18n", "~> 0.6"
5
5
  gem "netrc", "~> 0.7"
6
6
  gem "highline", "~> 1.6"
7
+ gem "erubis", "~> 2.7"
7
8
 
8
9
  gem "deep_merge", "~> 1.0"
9
10
  gem "multi_json", "~> 1.7"
@@ -22,6 +22,7 @@ GEM
22
22
  descendants_tracker (0.0.4)
23
23
  thread_safe (~> 0.3, >= 0.3.1)
24
24
  diff-lcs (1.2.5)
25
+ erubis (2.7.0)
25
26
  faraday (0.9.0)
26
27
  multipart-post (>= 1.2, < 3)
27
28
  ffi (1.9.3)
@@ -106,6 +107,7 @@ DEPENDENCIES
106
107
  celluloid (~> 0.15)
107
108
  childprocess (~> 0.5)
108
109
  deep_merge (~> 1.0)
110
+ erubis (~> 2.7)
109
111
  highline (~> 1.6)
110
112
  i18n (~> 0.6)
111
113
  jeweler (~> 2.0)
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.0
1
+ 0.2.1
@@ -11,37 +11,38 @@ class Config
11
11
  #-----------------------------------------------------------------------------
12
12
  # Instance generators
13
13
 
14
- def self.ensure(config)
14
+ def self.ensure(config, defaults = {}, force = true, basic_merge = true)
15
15
  case config
16
16
  when Nucleon::Config
17
- return config
17
+ return config.defaults(defaults)
18
18
  when Hash
19
- return new(config)
19
+ return new(config, defaults, force, basic_merge)
20
20
  end
21
- return new
21
+ return new({}, defaults, force, basic_merge)
22
22
  end
23
23
 
24
24
  #---
25
25
 
26
- def self.init(options, contexts = [], hierarchy = [], defaults = {})
26
+ def self.init(options, contexts = [], hierarchy = [], defaults = {}, force = true, basic_merge = true)
27
27
  contexts = contexts(contexts, hierarchy)
28
- config = new(get_options(contexts), defaults)
28
+ config = new(get_options(contexts), defaults, force, basic_merge)
29
29
  config.import(options) unless Util::Data.empty?(options)
30
30
  return config
31
31
  end
32
32
 
33
33
  #---
34
34
 
35
- def self.init_flat(options, contexts = [], defaults = {})
36
- return init(options, contexts, [], defaults)
35
+ def self.init_flat(options, contexts = [], defaults = {}, force = true, basic_merge = true)
36
+ return init(options, contexts, [], defaults, force, basic_merge)
37
37
  end
38
38
 
39
39
  #-----------------------------------------------------------------------------
40
40
  # Constructor / Destructor
41
41
 
42
- def initialize(data = {}, defaults = {}, force = true)
43
- @force = force
44
- @properties = {}
42
+ def initialize(data = {}, defaults = {}, force = true, basic_merge = true)
43
+ @force = force
44
+ @basic_merge = basic_merge
45
+ @properties = {}
45
46
 
46
47
  if defaults.is_a?(Hash) && ! defaults.empty?
47
48
  defaults = symbol_map(defaults.clone)
@@ -49,12 +50,12 @@ class Config
49
50
 
50
51
  case data
51
52
  when Nucleon::Config
52
- @properties = Util::Data.merge([ defaults, data.export ], force)
53
+ @properties = Util::Data.merge([ defaults, data.export ], force, basic_merge)
53
54
  when Hash
54
55
  @properties = {}
55
56
  if data.is_a?(Hash)
56
- @properties = Util::Data.merge([ defaults, symbol_map(data.clone) ], force)
57
- end
57
+ @properties = Util::Data.merge([ defaults, symbol_map(data.clone) ], force, basic_merge)
58
+ end
58
59
  end
59
60
  end
60
61
 
@@ -103,7 +104,7 @@ class Config
103
104
 
104
105
  #---
105
106
 
106
- def modify(data, keys, value = nil)
107
+ def modify(data, keys, value = nil, delete_nil = false)
107
108
  if keys.is_a?(String) || keys.is_a?(Symbol)
108
109
  keys = [ keys ]
109
110
  end
@@ -119,7 +120,7 @@ class Config
119
120
  if keys.empty?
120
121
  existing[:value] = data[key] if has_key
121
122
 
122
- if value.nil?
123
+ if value.nil? && delete_nil
123
124
  data.delete(key) if has_key
124
125
  else
125
126
  data[key] = value
@@ -170,8 +171,8 @@ class Config
170
171
 
171
172
  #---
172
173
 
173
- def set(keys, value)
174
- modify(@properties, array(keys).flatten, value)
174
+ def set(keys, value, delete_nil = false)
175
+ modify(@properties, array(keys).flatten, value, delete_nil)
175
176
  return self
176
177
  end
177
178
 
@@ -184,7 +185,7 @@ class Config
184
185
  #---
185
186
 
186
187
  def delete(keys, default = nil)
187
- existing = modify(@properties, array(keys).flatten, nil)
188
+ existing = modify(@properties, array(keys).flatten, nil, true)
188
189
  return existing[:value] unless existing[:value].nil?
189
190
  return default
190
191
  end
@@ -200,7 +201,7 @@ class Config
200
201
  # Import / Export
201
202
 
202
203
  def import_base(properties, options = {})
203
- config = Config.new(options, { :force => @force }).set(:context, :hash)
204
+ config = Config.new(options, { :force => @force, :basic => @basic_merge }).set(:context, :hash)
204
205
  import_type = config.get(:import_type, :override)
205
206
 
206
207
  properties = properties.export if properties.is_a?(Nucleon::Config)
@@ -306,13 +306,13 @@ class Environment
306
306
 
307
307
  def parse_plugin_info(namespace, plugin_type, base_path, file)
308
308
  dir_components = base_path.split(File::SEPARATOR)
309
- file_components = file.split(File::SEPARATOR)
309
+ file_components = file.split(File::SEPARATOR)
310
310
 
311
311
  file_name = file_components.pop.sub(/\.rb/, '')
312
312
  directory = file_components.join(File::SEPARATOR)
313
313
 
314
314
  file_class = sanitize_class(file_name)
315
- group_components = file_components - dir_components
315
+ group_components = directory.sub(/^#{base_path}#{File::SEPARATOR}?/, '').split(File::SEPARATOR)
316
316
 
317
317
  class_components = [ sanitize_class(namespace), sanitize_class(plugin_type) ]
318
318
 
@@ -602,6 +602,21 @@ module Facade
602
602
  def render_object(data)
603
603
  require 'pp'
604
604
  PP.pp(data, "").strip
605
+ end
606
+
607
+ #---
608
+
609
+ def render_tree(data, logger, state = :debug, padding = '')
610
+ if data.is_a?(Hash) || data.is_a?(Nucleon::Config)
611
+ data = data.export if data.is_a?(Nucleon::Config)
612
+ data.each do |key, value|
613
+ logger.send(state, "#{padding}#{key}")
614
+ if value.is_a?(Hash) || value.is_a?(Nucleon::Config)
615
+ value = value.export if value.is_a?(Nucleon::Config)
616
+ render_tree(value, logger, state, "#{padding} ")
617
+ end
618
+ end
619
+ end
605
620
  end
606
621
  end
607
622
  end
@@ -0,0 +1,84 @@
1
+
2
+ module Nucleon
3
+ module Mixin
4
+ module Action
5
+ module Registration
6
+
7
+ #-----------------------------------------------------------------------------
8
+ # Options
9
+
10
+ def register_file(name, default = nil)
11
+ name = name.to_sym
12
+
13
+ register name, :str, default do |value|
14
+ validate_file(value)
15
+ end
16
+ end
17
+
18
+ #---
19
+
20
+ def register_directory(name, default = nil)
21
+ name = name.to_sym
22
+
23
+ register name, :str, default do |value|
24
+ validate_directory(value)
25
+ end
26
+ end
27
+
28
+ #---
29
+
30
+ def register_project(name, default = nil)
31
+ name = name.to_sym
32
+
33
+ register name, :str, default do |value|
34
+ validate_plugins(:nucleon, :project, name, value)
35
+ end
36
+ end
37
+
38
+ #---
39
+
40
+ def register_projects(name, default = nil)
41
+ name = name.to_sym
42
+
43
+ register name, :array, default do |values|
44
+ validate_plugins(:nucleon, :project, name, values)
45
+ end
46
+ end
47
+
48
+ #---
49
+
50
+ def register_translator(name, default = nil)
51
+ name = name.to_sym
52
+
53
+ register name, :str, default do |value|
54
+ validate_plugins(:nucleon, :translator, name, value)
55
+ end
56
+ end
57
+
58
+ #---
59
+
60
+ def register_translators(name, default = nil)
61
+ name = name.to_sym
62
+
63
+ register name, :array, default do |values|
64
+ validate_plugins(:nucleon, :translator, name, values)
65
+ end
66
+ end
67
+
68
+ #-----------------------------------------------------------------------------
69
+ # Validators
70
+
71
+ def validate_file(file_name)
72
+ file_name.nil? || File.exists?(file_name)
73
+ end
74
+
75
+ #---
76
+
77
+ def validate_directory(dir_name)
78
+ dir_name.nil? || File.directory?(dir_name)
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
84
+
@@ -58,22 +58,22 @@ module SubConfig
58
58
 
59
59
  #---
60
60
 
61
- def _set(keys, value = '')
62
- modify(@properties, array(keys).flatten, value)
61
+ def _set(keys, value = '', delete_nil = false)
62
+ modify(@properties, array(keys).flatten, value, delete_nil)
63
63
  end
64
64
  protected :_set
65
65
 
66
66
  #---
67
67
 
68
- def set(keys, value = '')
68
+ def set(keys, value = '', delete_nil = false)
69
69
  init_subconfig
70
- config.set(keys, value)
70
+ config.set(keys, value, delete_nil)
71
71
  end
72
72
 
73
73
  #---
74
74
 
75
75
  def _delete(keys, default = nil)
76
- existing = modify(@properties, array(keys).flatten, nil)
76
+ existing = modify(@properties, array(keys).flatten, nil, true)
77
77
  return existing[:value] if existing[:value]
78
78
  return default
79
79
  end
@@ -9,6 +9,10 @@ class Action < Nucleon.plugin_class(:nucleon, :base)
9
9
  # Info
10
10
 
11
11
  def self.describe(group = nil, action = 'unknown', weight = -1000, description = nil, help = nil)
12
+ describe_base(group, action, weight, description, help)
13
+ end
14
+
15
+ def self.describe_base(group = nil, action = 'unknown', weight = -1000, description = nil, help = nil)
12
16
  if group
13
17
  group_name = Util::Data.array(group).join('.')
14
18
  description_id = "#{namespace}.action.#{group_name}.#{action}.description"
@@ -43,7 +47,7 @@ class Action < Nucleon.plugin_class(:nucleon, :base)
43
47
  @name = name
44
48
  @type = type
45
49
  @default = default
46
- @locale = locale.nil? ? "#{namespace}.actions.#{provider}.options.#{name}" : locale
50
+ @locale = locale.nil? ? "#{namespace}.action.#{provider.to_s.gsub('_', '.')}.options.#{name}" : locale
47
51
  @validator = validator if validator
48
52
  end
49
53
 
@@ -76,7 +80,7 @@ class Action < Nucleon.plugin_class(:nucleon, :base)
76
80
  action = Nucleon.action(provider, options)
77
81
  exit_status = action.execute
78
82
  action_result = action.result
79
-
83
+
80
84
  rescue => error
81
85
  logger.error("Nucleon action #{provider} experienced an error:")
82
86
  logger.error(error.inspect)
@@ -105,7 +109,7 @@ class Action < Nucleon.plugin_class(:nucleon, :base)
105
109
 
106
110
  def normalize(reload)
107
111
  args = array(delete(:args, []))
108
-
112
+
109
113
  @action_interface = Util::Liquid.new do |method, method_args|
110
114
  options = {}
111
115
  options = method_args[0] if method_args.length > 0
@@ -136,6 +140,12 @@ class Action < Nucleon.plugin_class(:nucleon, :base)
136
140
  #-----------------------------------------------------------------------------
137
141
  # Checks
138
142
 
143
+ def strict?
144
+ true # Override in providers if needed (allow extra options if false)
145
+ end
146
+
147
+ #---
148
+
139
149
  def processed?
140
150
  get(:processed, false)
141
151
  end
@@ -180,12 +190,12 @@ class Action < Nucleon.plugin_class(:nucleon, :base)
180
190
 
181
191
  #---
182
192
 
183
- def register(name, type, default, locale = nil)
193
+ def register(name, type, default = nil, locale = nil, &code)
184
194
  name = name.to_sym
185
195
 
186
- if block_given?
196
+ if code
187
197
  option = Option.new(namespace, plugin_provider, name, type, default, locale) do |value, success|
188
- yield(value, success)
198
+ code.call(value, success)
189
199
  end
190
200
  else
191
201
  option = Option.new(namespace, plugin_provider, name, type, default, locale)
@@ -197,6 +207,28 @@ class Action < Nucleon.plugin_class(:nucleon, :base)
197
207
 
198
208
  #---
199
209
 
210
+ def register_bool(name, default = false, locale = nil, &code)
211
+ register(name, :bool, default, locale, &code)
212
+ end
213
+
214
+ def register_int(name, default = nil, locale = nil, &code)
215
+ register(name, :int, default, locale, &code)
216
+ end
217
+
218
+ def register_float(name, default = nil, locale = nil, &code)
219
+ register(name, :float, default, locale, &code)
220
+ end
221
+
222
+ def register_str(name, default = '', locale = nil, &code)
223
+ register(name, :str, default, locale, &code)
224
+ end
225
+
226
+ def register_array(name, default = [], locale = nil, &code)
227
+ register(name, :array, default, locale, &code)
228
+ end
229
+
230
+ #---
231
+
200
232
  def remove(names)
201
233
  Util::Data.rm_keys(config, names)
202
234
  Util::Data.rm_keys(settings, names)
@@ -290,6 +322,8 @@ class Action < Nucleon.plugin_class(:nucleon, :base)
290
322
  end
291
323
 
292
324
  @parser = Util::CLI::Parser.new(args, usage, "\n#{help_text}\n") do |parser|
325
+ parser.strict = strict?
326
+
293
327
  parse(parser)
294
328
  extension(:parse, { :parser => parser, :config => config })
295
329
  end
@@ -297,7 +331,7 @@ class Action < Nucleon.plugin_class(:nucleon, :base)
297
331
  if @parser
298
332
  if @parser.processed
299
333
  set(:processed, true)
300
- settings.import(Util::Data.merge([ @parser.options, @parser.arguments ], true))
334
+ settings.import(Util::Data.merge([ @parser.extra, @parser.options, @parser.arguments ], true))
301
335
  logger.debug("Parse successful")
302
336
 
303
337
  elsif @parser.options[:help] && ! quiet?
@@ -316,11 +350,15 @@ class Action < Nucleon.plugin_class(:nucleon, :base)
316
350
 
317
351
  #---
318
352
 
353
+ def parse_types
354
+ [ :bool, :int, :float, :str, :array ]
355
+ end
356
+
319
357
  def parse(parser)
320
358
 
321
359
  generate = lambda do |format, name|
322
360
  formats = [ :option, :arg ]
323
- types = [ :bool, :int, :float, :str, :array ]
361
+ types = parse_types
324
362
  name = name.to_sym
325
363
 
326
364
  if config.export.has_key?(name) && formats.include?(format.to_sym)
@@ -414,7 +452,7 @@ class Action < Nucleon.plugin_class(:nucleon, :base)
414
452
 
415
453
  if processed? && status != code.success
416
454
  logger.warn("Execution failed for #{plugin_provider} with status #{status}")
417
- alert(Codes.render_index(status))
455
+ warn(Codes.render_index(status), { :i18n => false })
418
456
  end
419
457
 
420
458
  status
@@ -447,6 +485,24 @@ class Action < Nucleon.plugin_class(:nucleon, :base)
447
485
  #-----------------------------------------------------------------------------
448
486
  # Utilities
449
487
 
488
+ def validate_plugins(namespace, type, name, values)
489
+ plugin_class = Nucleon.plugin_class(namespace, type)
490
+ loaded_plugins = Nucleon.loaded_plugins(namespace, type)
491
+ success = true
492
+
493
+ array(values).each do |value|
494
+ if info = plugin_class.translate_reference(value)
495
+ if ! loaded_plugins.keys.include?(info[:provider].to_sym)
496
+ warn("corl.action.#{plugin_name.to_s.gsub('_', '.')}.errors.#{name}", Util::Data.merge([ info, { :value => value } ]))
497
+ success = false
498
+ end
499
+ end
500
+ end
501
+ success
502
+ end
503
+
504
+ #---
505
+
450
506
  def self.components(search)
451
507
  components = []
452
508
 
@@ -523,7 +579,7 @@ class Action < Nucleon.plugin_class(:nucleon, :base)
523
579
  action_id_pattern = action_id.gsub('::', ':.*:')
524
580
 
525
581
  action_index.each do |loaded_action_id, loaded_action_info|
526
- if loaded_action_id.match(/#{action_id_pattern}/)
582
+ if loaded_action_id.match(/(^|\:)#{action_id_pattern.gsub(/\-/, '\-')}(\:|$)/)
527
583
  loaded_action_info[:action_id] = loaded_action_id
528
584
  actions_found << loaded_action_info
529
585
  end