MuranoCLI 3.2.0.beta.1 → 3.2.0.beta.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (111) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +4 -1
  3. data/.trustme.plugin +137 -0
  4. data/.trustme.sh +217 -117
  5. data/.trustme.vim +9 -3
  6. data/Gemfile +9 -3
  7. data/MuranoCLI.gemspec +8 -5
  8. data/Rakefile +1 -0
  9. data/dockers/Dockerfile.2.2.9 +6 -3
  10. data/dockers/Dockerfile.2.3.6 +6 -3
  11. data/dockers/Dockerfile.2.4.3 +6 -3
  12. data/dockers/Dockerfile.2.5.0 +6 -3
  13. data/dockers/Dockerfile.GemRelease +10 -8
  14. data/dockers/Dockerfile.m4 +23 -5
  15. data/dockers/docker-test.sh +65 -28
  16. data/docs/completions/murano_completion-bash +751 -57
  17. data/docs/develop.rst +10 -9
  18. data/lib/MrMurano/AccountBase.rb +95 -6
  19. data/lib/MrMurano/Commander-Entry.rb +9 -4
  20. data/lib/MrMurano/Config-Migrate.rb +2 -0
  21. data/lib/MrMurano/Config.rb +94 -26
  22. data/lib/MrMurano/Content.rb +1 -1
  23. data/lib/MrMurano/Exchange.rb +77 -42
  24. data/lib/MrMurano/Gateway.rb +1 -1
  25. data/lib/MrMurano/HttpAuthed.rb +20 -7
  26. data/lib/MrMurano/Logs.rb +10 -1
  27. data/lib/MrMurano/ProjectFile.rb +1 -1
  28. data/lib/MrMurano/ReCommander.rb +129 -73
  29. data/lib/MrMurano/Solution-ServiceConfig.rb +18 -11
  30. data/lib/MrMurano/Solution-Services.rb +78 -50
  31. data/lib/MrMurano/Solution-Users.rb +1 -1
  32. data/lib/MrMurano/Solution.rb +13 -63
  33. data/lib/MrMurano/SyncUpDown-Core.rb +185 -77
  34. data/lib/MrMurano/SyncUpDown-Item.rb +29 -4
  35. data/lib/MrMurano/SyncUpDown.rb +11 -11
  36. data/lib/MrMurano/Webservice-Cors.rb +1 -1
  37. data/lib/MrMurano/Webservice-Endpoint.rb +28 -17
  38. data/lib/MrMurano/Webservice-File.rb +103 -43
  39. data/lib/MrMurano/commands/domain.rb +1 -0
  40. data/lib/MrMurano/commands/element.rb +585 -0
  41. data/lib/MrMurano/commands/exchange.rb +211 -204
  42. data/lib/MrMurano/commands/gb.rb +1 -0
  43. data/lib/MrMurano/commands/globals.rb +17 -7
  44. data/lib/MrMurano/commands/init.rb +115 -101
  45. data/lib/MrMurano/commands/keystore.rb +1 -1
  46. data/lib/MrMurano/commands/logs.rb +2 -1
  47. data/lib/MrMurano/commands/postgresql.rb +17 -7
  48. data/lib/MrMurano/commands/service.rb +572 -0
  49. data/lib/MrMurano/commands/show.rb +7 -3
  50. data/lib/MrMurano/commands/solution.rb +2 -1
  51. data/lib/MrMurano/commands/solution_picker.rb +31 -15
  52. data/lib/MrMurano/commands/status.rb +205 -169
  53. data/lib/MrMurano/commands/sync.rb +70 -38
  54. data/lib/MrMurano/commands/token.rb +59 -14
  55. data/lib/MrMurano/commands/usage.rb +1 -0
  56. data/lib/MrMurano/commands.rb +2 -0
  57. data/lib/MrMurano/hash.rb +91 -0
  58. data/lib/MrMurano/http.rb +55 -6
  59. data/lib/MrMurano/makePretty.rb +47 -0
  60. data/lib/MrMurano/optparse.rb +60 -45
  61. data/lib/MrMurano/variegated/TruthyFalsey.rb +48 -0
  62. data/lib/MrMurano/variegated/ruby_dig.rb +64 -0
  63. data/lib/MrMurano/verbosing.rb +113 -3
  64. data/lib/MrMurano/version.rb +1 -1
  65. data/spec/Account_spec.rb +34 -20
  66. data/spec/Business_spec.rb +12 -9
  67. data/spec/Config_spec.rb +7 -1
  68. data/spec/Content_spec.rb +17 -1
  69. data/spec/GatewayBase_spec.rb +5 -2
  70. data/spec/GatewayDevice_spec.rb +4 -2
  71. data/spec/GatewayResource_spec.rb +4 -1
  72. data/spec/GatewaySettings_spec.rb +4 -1
  73. data/spec/HttpAuthed_spec.rb +73 -0
  74. data/spec/Http_spec.rb +32 -35
  75. data/spec/ProjectFile_spec.rb +1 -1
  76. data/spec/Solution-ServiceConfig_spec.rb +4 -1
  77. data/spec/Solution-ServiceEventHandler_spec.rb +6 -3
  78. data/spec/Solution-ServiceModules_spec.rb +4 -1
  79. data/spec/Solution-UsersRoles_spec.rb +4 -1
  80. data/spec/Solution_spec.rb +4 -1
  81. data/spec/SyncUpDown_spec.rb +1 -1
  82. data/spec/Webservice-Cors_spec.rb +4 -1
  83. data/spec/Webservice-Endpoint_spec.rb +9 -6
  84. data/spec/Webservice-File_spec.rb +17 -4
  85. data/spec/Webservice-Setting_spec.rb +6 -2
  86. data/spec/_workspace.rb +2 -0
  87. data/spec/cmd_common.rb +42 -13
  88. data/spec/cmd_content_spec.rb +17 -7
  89. data/spec/cmd_device_spec.rb +1 -1
  90. data/spec/cmd_domain_spec.rb +2 -2
  91. data/spec/cmd_element_spec.rb +400 -0
  92. data/spec/cmd_exchange_spec.rb +2 -2
  93. data/spec/cmd_init_spec.rb +59 -25
  94. data/spec/cmd_keystore_spec.rb +6 -3
  95. data/spec/cmd_link_spec.rb +10 -5
  96. data/spec/cmd_logs_spec.rb +1 -1
  97. data/spec/cmd_setting_application_spec.rb +18 -15
  98. data/spec/cmd_setting_product_spec.rb +7 -7
  99. data/spec/cmd_status_spec.rb +27 -17
  100. data/spec/cmd_syncdown_application_spec.rb +30 -3
  101. data/spec/cmd_syncdown_both_spec.rb +72 -18
  102. data/spec/cmd_syncup_spec.rb +71 -5
  103. data/spec/cmd_token_spec.rb +2 -2
  104. data/spec/cmd_usage_spec.rb +2 -2
  105. data/spec/dry_run_formatter.rb +27 -0
  106. data/spec/fixtures/dumped_config +8 -0
  107. data/spec/fixtures/exchange_element/element-show.json +1 -0
  108. data/spec/fixtures/exchange_element/swagger-mur-6407__10k.yaml +282 -0
  109. data/spec/fixtures/exchange_element/swagger-mur-6407__20k.yaml +588 -0
  110. data/spec/variegated_TruthyFalsey_spec.rb +29 -0
  111. metadata +51 -25
data/docs/develop.rst CHANGED
@@ -174,7 +174,7 @@ If you use ``chruby``, tell it what version of ruby you want:
174
174
 
175
175
  .. code-block:: bash
176
176
 
177
- cd /exo/clients/exosite/MuranoCLI
177
+ cd /path/to/MuranoCLI
178
178
  echo "ruby-2.3" > .ruby-version
179
179
 
180
180
  (You can also do this for ``rvm``, which recognizes the
@@ -184,7 +184,7 @@ Now tell chruby to load the version of ruby you want:
184
184
 
185
185
  .. code-block:: bash
186
186
 
187
- cd /exo/clients/exosite/MuranoCLI
187
+ cd /path/to/MuranoCLI
188
188
  chruby $(cat .ruby-version)
189
189
 
190
190
  Install dependencies
@@ -213,7 +213,7 @@ Install the gems listed in the MuranoCLI Gemfile:
213
213
 
214
214
  .. code-block:: bash
215
215
 
216
- cd /exo/clients/exosite/MuranoCLI
216
+ cd /path/to/MuranoCLI
217
217
  bundle install --path $(ruby -rubygems -e 'puts Gem.dir') --with test
218
218
 
219
219
  Build and Install MuranoCLI
@@ -223,7 +223,7 @@ Build and install the Gem locally to your local gem directory.
223
223
 
224
224
  .. code-block:: bash
225
225
 
226
- cd /exo/clients/exosite/MuranoCLI
226
+ cd /path/to/MuranoCLI
227
227
 
228
228
  rake install:user
229
229
 
@@ -263,10 +263,11 @@ so I enable ``curldebug`` and redirect the verbose output to a file,
263
263
  id = xxxxxxxxxxxxxxxx
264
264
 
265
265
  [tool]
266
- #curldebug = false
266
+ developer = true
267
+ no-page = true
268
+ curlfile = "/path/to/MuranoCLI/curldebug.out"
267
269
  curldebug = true
268
-
269
- curlfile = "/exo/clients/exosite/MuranoCLI/curldebug.out"
270
+ curlfancy = true
270
271
 
271
272
  Save the file outside the MuranoCLI repo, e.g., to
272
273
  ``/exo/clients/exosite/.murano.test``
@@ -304,7 +305,7 @@ under your business.
304
305
 
305
306
  .. code-block:: bash
306
307
 
307
- cd /exo/clients/exosite/MuranoCLI
308
+ cd /path/to/MuranoCLI
308
309
 
309
310
  rake test_clean_up
310
311
 
@@ -365,7 +366,7 @@ Run All Tests and Capture Colorful Output to HTML
365
366
 
366
367
  rspec --format html \
367
368
  --out report/index-$( \
368
- ruby -e 'require "/exo/clients/exosite/MuranoCLI/lib/MrMurano/version.rb"; \
369
+ ruby -e 'require "/path/to/MuranoCLI/lib/MrMurano/version.rb"; \
369
370
  puts MrMurano::VERSION').html
370
371
  --format documentation \
371
372
  --tag '~not_in_okami' \
@@ -39,8 +39,8 @@ module MrMurano
39
39
  MrMurano::HttpAuthed.instance.ensure_token!
40
40
  end
41
41
 
42
- def token_reset
43
- MrMurano::HttpAuthed.instance.token_reset
42
+ def token_reset(new_token='')
43
+ MrMurano::HttpAuthed.instance.token_reset(new_token)
44
44
  end
45
45
 
46
46
  # ---------------------------------------------------------------------
@@ -53,15 +53,15 @@ module MrMurano
53
53
  ).strip.gsub(/^\s+/, '')
54
54
 
55
55
  def login_info
56
+ verify_cfg_auth!
56
57
  # (lb): This is a little hokey, but someone has to init the Singleton,
57
58
  # so we make sure it's ready anytime a new AccountBase instance is created.
58
59
  email_pwd = MrMurano::HttpAuthed.instance.login_info
59
60
  return email_pwd unless email_pwd.nil?
60
- verify_cfg_auth!
61
61
  @warned_once = false
62
62
  ask_for_user! if user.empty?
63
63
  # Do not prompt for password if using token.
64
- if !@logging_on && $cfg['auth.scheme-token']
64
+ if !MrMurano::HttpAuthed.instance.logging_on && $cfg['auth.scheme-token']
65
65
  token = MrMurano::HttpAuthed.instance.token_resolve
66
66
  return unless token.to_s.empty?
67
67
  end
@@ -73,6 +73,10 @@ module MrMurano
73
73
  MrMurano::HttpAuthed.instance.login_info = email_pwd
74
74
  end
75
75
 
76
+ def credentials_reset
77
+ MrMurano::HttpAuthed.instance.credentials_reset
78
+ end
79
+
76
80
  def ask_for_user!
77
81
  prologue = 'No Murano user account found.'
78
82
  must_prompt_if_logged_off!(prologue)
@@ -145,7 +149,7 @@ module MrMurano
145
149
  # ---------------------------------------------------------------------
146
150
 
147
151
  def logout(keep_user: false, keep_password: false, no_invalidate: false)
148
- @logging_on = true
152
+ MrMurano::HttpAuthed.instance.logging_on = true
149
153
 
150
154
  token = MrMurano::HttpAuthed.instance.token_lookup
151
155
  invalidate_token(token) unless no_invalidate
@@ -162,7 +166,7 @@ module MrMurano
162
166
 
163
167
  cfg_clear_user_and_business(net_host, user_name) unless keep_user
164
168
 
165
- @logging_on = false
169
+ MrMurano::HttpAuthed.instance.logging_on = false
166
170
  end
167
171
 
168
172
  def invalidate_token(tok)
@@ -209,6 +213,91 @@ module MrMurano
209
213
  end
210
214
  cfg_val
211
215
  end
216
+
217
+ # ---------------------------------------------------------------------
218
+
219
+ # Handle pagination for all commands derived from this class.
220
+ def get(path='', query=nil, &block)
221
+ aggregate = nil
222
+ total = nil
223
+ remaining = -1
224
+ first_count = nil
225
+ orig_query = (query || []).dup
226
+ while remaining != 0
227
+ ret = super
228
+ return nil if ret.nil?
229
+ # Return now if not paginating.
230
+ if (!ret.is_a?(Hash) ||
231
+ !ret.key?(:items) ||
232
+ !(ret.key?(:total) || ret.key?(:count))
233
+ )
234
+ # ret is not a hash, or it's missing :items or :total/:count.
235
+ unless aggregate.nil?
236
+ warning %(Unexpected: aggregate set: #{aggregate} / ret: #{ret})
237
+ end
238
+ aggregate = ret
239
+ remaining = 0
240
+ break
241
+ end
242
+ query = orig_query.dup
243
+ if ret.key?(:total)
244
+ if total.nil?
245
+ total = ret[:total]
246
+ remaining = total
247
+ # The response also includes a hint of how to get the next page.
248
+ # ret[:next] == "/api/v1/eventhandler?query={\
249
+ # \"solution_id\":\"XXXXXXXXXXXXXXXX\"}&limit=20&offset=20"
250
+ # But note that the URL we use is a little different
251
+ # https://bizapi.hosted.exosite.io/api:1/solution/<sid>/eventhandler
252
+ elsif total != ret[:total]
253
+ warning %(
254
+ Unexpected subsequence total: #{ret[:total]} != #{total}
255
+ ).strip
256
+ end
257
+ remaining -= ret[:items].length
258
+ else
259
+ # This should be true:
260
+ # assert(ret.key?(:count))
261
+ # assert(ret[:count] == ret[:items].length)
262
+ # Not all pageable commands indicate :total (ahem, /exchange/).
263
+ if total.nil?
264
+ first_count = ret[:items].length
265
+ total = first_count
266
+ elsif ret[:items].length < first_count
267
+ # Last batch!
268
+ first_count = 0
269
+ end
270
+ # Our next command will grab the next batch of limit size.
271
+ total += ret[:items].length
272
+ remaining = first_count
273
+ end
274
+ if remaining > 0
275
+ # DEVS: You can test pagination, e.g.,
276
+ # query.push ['limit', 5]
277
+ query.push ['offset', total - remaining]
278
+ elsif remaining != 0
279
+ warning %(Unexpected: negative remaining: #{fancy_ticks(total)})
280
+ remaining = 0
281
+ end
282
+ if aggregate.nil?
283
+ aggregate = ret
284
+ else
285
+ aggregate[:items].concat ret[:items]
286
+ aggregate[:count] = aggregate[:items].length
287
+ end
288
+ end
289
+ aggregate
290
+ end
291
+
292
+ def self.warn_configfile_env_maybe
293
+ if !$cfg.get('business.id', :env).to_s.empty? &&
294
+ !$cfg.get('business.id', :project).to_s.empty? &&
295
+ $cfg.get('business.id', :env) != $cfg.get('business.id', :project)
296
+ MrMurano::Verbose.warning %(
297
+ NOTE: MURANO_CONFIGFILE specifies different business.id than local project file
298
+ ).strip
299
+ end
300
+ end
212
301
  end
213
302
  end
214
303
 
@@ -5,10 +5,10 @@
5
5
  # vim:tw=0:ts=2:sw=2:et:ai
6
6
  # Unauthorized copying of this file is strictly prohibited.
7
7
 
8
- require 'commander/import'
9
8
  require 'dotenv'
10
9
  require 'English'
11
10
  require 'highline'
11
+ require 'murano-cli-commander/import'
12
12
  require 'pathname'
13
13
  #require 'pp'
14
14
  require 'rainbow'
@@ -36,15 +36,20 @@ program :description, %(
36
36
  Manage Applications and Products in Exosite's Murano
37
37
  ).strip
38
38
 
39
+ def argv_push_option(switch)
40
+ # Put the --switch before the -- positional argument delimiter, if any.
41
+ i_positional = ARGV.index('--') || -1
42
+ ARGV.insert(i_positional, switch)
43
+ end
39
44
  # If being piped, e.g.,
40
45
  # murano command ... | ...
41
46
  # or
42
47
  # VAR=$(murano command ...)
43
48
  # etc., then do not do progress.
44
49
  # TEST/2017-08-23: Does this work on Windows?
45
- ARGV.push('--no-progress') unless $stdout.tty? || ARGV.include?('--no-progress')
46
- ARGV.push('--ascii') unless $stdout.tty? || ARGV.include?('--ascii')
47
- ARGV.push('--ascii') if ''.encode('ASCII').encoding == __ENCODING__
50
+ argv_push_option('--no-progress') unless $stdout.tty? || ARGV.include?('--no-progress')
51
+ argv_push_option('--ascii') unless $stdout.tty? || ARGV.include?('--ascii')
52
+ argv_push_option('--ascii') if ''.encode('ASCII').encoding == __ENCODING__
48
53
 
49
54
  default_command :help
50
55
 
@@ -7,6 +7,8 @@
7
7
 
8
8
  require 'pathname'
9
9
  require 'yaml'
10
+ require 'MrMurano/Passwords'
11
+ require 'MrMurano/verbosing'
10
12
 
11
13
  module MrMurano
12
14
  class ConfigMigrate
@@ -30,7 +30,7 @@ module MrMurano
30
30
 
31
31
  CFG_HOST_BIZAPI = 'bizapi.hosted.exosite.io'
32
32
 
33
- ConfigFile = Struct.new(:kind, :path, :data) do
33
+ ConfigFile = Struct.new(:kind, :path, :cfg, :data) do
34
34
  def load
35
35
  return if kind == :internal
36
36
  return if kind == :defaults
@@ -45,7 +45,7 @@ module MrMurano
45
45
  def write
46
46
  return if kind == :internal
47
47
  return if kind == :defaults
48
- if defined?($cfg) && !$cfg.nil? && $cfg['tool.dry']
48
+ if !self[:cfg].nil? && self[:cfg]['tool.dry']
49
49
  # $cfg.nil? when run from spec tests that don't load it with:
50
50
  # include_context "CI_CMD"
51
51
  warning('--dry: Not writing config file')
@@ -120,11 +120,15 @@ module MrMurano
120
120
  end
121
121
 
122
122
  def initialize(cmd_runner=nil)
123
+ # Be sneaky: Avoid warning if init code looks at $cfg.
124
+ # "warning: global variable `$cfg' not initialized"
125
+ $cfg = nil
126
+
123
127
  @runner = cmd_runner
124
128
  @curlfile_f = nil
125
129
 
126
130
  @paths = []
127
- @paths << ConfigFile.new(:internal, nil, IniFile.new)
131
+ @paths << ConfigFile.new(:internal, nil, self, IniFile.new)
128
132
  # :specified --configfile FILE goes here. (see load_specific)
129
133
 
130
134
  migrate_old_env
@@ -132,7 +136,7 @@ module MrMurano
132
136
  # if it exists, must be a file
133
137
  # if it doesn't exist, that's ok
134
138
  ep = Pathname.new(ENV[CFG_ENV_NAME])
135
- @paths << ConfigFile.new(:env, ep) if ep.file? || !ep.exist?
139
+ @paths << ConfigFile.new(:env, ep, self) if ep.file? || !ep.exist?
136
140
  end
137
141
 
138
142
  @project_dir, @project_exists = find_project_dir
@@ -144,11 +148,11 @@ module MrMurano
144
148
  @project_exists = false
145
149
  end
146
150
  end
147
- @paths << ConfigFile.new(:project, @project_dir + CFG_FILE_NAME)
151
+ @paths << ConfigFile.new(:project, @project_dir + CFG_FILE_NAME, self)
148
152
 
149
- @paths << ConfigFile.new(:user, Pathname.new(Dir.home) + CFG_FILE_NAME)
153
+ @paths << ConfigFile.new(:user, Pathname.new(Dir.home) + CFG_FILE_NAME, self)
150
154
 
151
- @paths << ConfigFile.new(:defaults, nil, IniFile.new)
155
+ @paths << ConfigFile.new(:defaults, nil, self, IniFile.new)
152
156
 
153
157
  # The user can exclude certain scopes.
154
158
  @exclude_scopes = []
@@ -164,17 +168,42 @@ module MrMurano
164
168
  # All these set()'s are against the :defaults config.
165
169
  # So no disk writing ensues. And these serve as defaults
166
170
  # unless, say, a SolutionFile says otherwise.
167
-
171
+ set_defaults_tool
172
+ set_defaults_net
173
+ set_defaults_auth
174
+ set_defaults_location
175
+ set_defaults_sync
176
+ set_defaults_files
177
+ set_defaults_endpoints
178
+ set_defaults_eventhandler
179
+ set_defaults_modules
180
+ set_defaults_diff
181
+ set_defaults_postgresql
182
+ end
183
+
184
+ def set_defaults_tool
168
185
  set('tool.verbose', false, :defaults)
169
186
  set('tool.debug', false, :defaults)
187
+ set('tool.developer', false, :defaults)
170
188
  set('tool.dry', false, :defaults)
171
189
  set('tool.fullerror', false, :defaults)
172
190
  set('tool.outformat', 'best', :defaults)
191
+ set('tool.ascii', false, :defaults)
192
+ set('tool.curldebug', false, :defaults)
193
+ set('tool.curlfile', '', :defaults)
194
+ set('tool.curlfancy', false, :defaults)
195
+ set('tool.no-page', false, :defaults)
196
+ set('tool.no-progress', false, :defaults)
197
+ set('tool.show-password', false, :defaults)
198
+ end
173
199
 
200
+ def set_defaults_net
174
201
  set('net.host', CFG_HOST_BIZAPI, :defaults)
175
202
  set('net.protocol', 'https', :defaults)
176
203
  @value_options['net.protocol'] = CFG_NET_PROTOCOLS
204
+ end
177
205
 
206
+ def set_defaults_auth
178
207
  set('auth.ttl', nil, :defaults)
179
208
  # See global options --[no-]token and --[no-]basic.
180
209
  set('auth.scheme-token', nil, :defaults)
@@ -182,7 +211,9 @@ module MrMurano
182
211
  # See global options --[no-]login and --[no-]cache.
183
212
  set('auth.persist-token', nil, :defaults)
184
213
  set('auth.persist-basic', nil, :defaults)
214
+ end
185
215
 
216
+ def set_defaults_location
186
217
  set('location.base', @project_dir, :defaults) unless @project_dir.nil?
187
218
  set('location.files', 'files', :defaults)
188
219
  set('location.endpoints', 'routes', :defaults)
@@ -190,15 +221,32 @@ module MrMurano
190
221
  set('location.eventhandlers', 'services', :defaults)
191
222
  set('location.resources', 'specs/resources.yaml', :defaults)
192
223
  set('location.cors', 'cors.yaml', :defaults)
224
+ # MUR-6562/MUR-6329: Changing defaults: files => assets; routes => endpoints.
225
+ set_defaults_location_MUR_6562('location.files', 'files', 'assets')
226
+ set_defaults_location_MUR_6562('location.endpoints', 'routes', 'endpoints')
227
+ end
193
228
 
194
- if defined? SyncRoot
195
- set('sync.bydefault', SyncRoot.instance.bydefault.join(' '), :defaults)
229
+ # rubocop:disable Style/MethodName: Use snake_case for method names.
230
+ def set_defaults_location_MUR_6562(key, formerly, currently)
231
+ if @project_dir && !@project_dir.join(formerly).exist?
232
+ set(key, currently, :defaults)
233
+ elsif @project_dir.join(currently).exist?
234
+ warning %(Conflicting directories exist for #{key}: #{formerly} / #{currently})
196
235
  end
236
+ end
237
+
238
+ def set_defaults_sync
239
+ return unless defined? SyncRoot
240
+ set('sync.bydefault', SyncRoot.instance.bydefault.join(' '), :defaults)
241
+ end
197
242
 
243
+ def set_defaults_files
198
244
  set('files.default_page', 'index.html', :defaults)
199
245
  set('files.searchFor', '**/*', :defaults)
200
246
  set('files.ignoring', '', :defaults)
247
+ end
201
248
 
249
+ def set_defaults_endpoints
202
250
  set('endpoints.searchFor', %w[
203
251
  {,../endpoints}/*.lua
204
252
  {,../endpoints}s/*/*.lua
@@ -208,7 +256,9 @@ module MrMurano
208
256
  *_spec.lua
209
257
  .*
210
258
  ].join(' '), :defaults)
259
+ end
211
260
 
261
+ def set_defaults_eventhandler
212
262
  set('eventhandler.searchFor', %w[
213
263
  *.lua
214
264
  */*.lua
@@ -242,7 +292,9 @@ module MrMurano
242
292
  tsdb.exportJob
243
293
  user.account
244
294
  ].join(' '), :defaults)
295
+ end
245
296
 
297
+ def set_defaults_modules
246
298
  # 2017-07-26: Nested Lua support: Change '*/*.lua' to '**/*.lua'.
247
299
  # There are similar changes made to the ProjectFile,
248
300
  # to modules.include and modules.exclude, which, if set,
@@ -262,13 +314,17 @@ module MrMurano
262
314
  ].join(' '), :defaults)
263
315
 
264
316
  set('modules.no-nesting', false, :defaults)
317
+ end
265
318
 
319
+ def set_defaults_diff
266
320
  if Gem.win_platform?
267
321
  set('diff.cmd', 'fc', :defaults)
268
322
  else
269
323
  set('diff.cmd', 'diff -u', :defaults)
270
324
  end
325
+ end
271
326
 
327
+ def set_defaults_postgresql
272
328
  set('postgresql.migrations_dir', 'sql-migrations', :defaults)
273
329
  end
274
330
 
@@ -318,18 +374,17 @@ module MrMurano
318
374
  Please change to a project directory, or run `murano init` to create a new project.
319
375
  ).strip
320
376
 
321
- def validate_cmd(cmd=nil)
322
- return unless validate_cmd_business_and_project(cmd)
377
+ def validate_cmd
323
378
  migrate_old_config(@project_dir)
324
379
  migrate_old_config(Pathname.new(Dir.home))
325
380
  end
326
381
 
327
- def validate_cmd_business_and_project(cmd)
382
+ def validate_cmd_business_and_project(the_cmd)
328
383
  # Most commands should be run from within a Murano project (sub-)directory.
329
384
  # If user is running a project command not within a project directory,
330
385
  # we'll print a message now and exit the app from run_active_command later.
331
386
  unless @runner.nil?
332
- the_cmd = @runner.active_command if cmd.nil?
387
+ the_cmd = @runner.active_command if the_cmd.nil?
333
388
  the_cmd = command(cmd) if the_cmd.nil?
334
389
  the_cmd.project_not_required = false unless defined?(the_cmd.project_not_required)
335
390
  if the_cmd.name != 'help' && !the_cmd.project_not_required && !@project_exists
@@ -363,10 +418,8 @@ module MrMurano
363
418
  root = nil
364
419
  when :project
365
420
  root = @project_dir + CFG_DIR_NAME
366
- verbose %(file_at: @project_dir: #{@project_dir} / + #{CFG_DIR_NAME} / #{root})
367
421
  when :user
368
422
  root = Pathname.new(Dir.home) + CFG_DIR_NAME
369
- verbose %(file_at: Dir.home: #{Dir.home} / + #{CFG_DIR_NAME} / #{root})
370
423
  when :defaults
371
424
  root = nil
372
425
  end
@@ -411,15 +464,22 @@ module MrMurano
411
464
  # If user wants curl commands dumped to a file, open that file.
412
465
  init_curl_file
413
466
  # If user doesn't want paging, disable it.
414
- program :help_paging, !$cfg['tool.no-page'] unless $cfg['tool.no-page'].nil?
467
+ # The program method is not available when called via rspec.
468
+ unless !defined?(program) || self['tool.no-page'].nil?
469
+ program :help_paging, !self['tool.no-page']
470
+ end
415
471
  # Check for errors.
416
472
  must_be_valid_values!
417
473
  end
418
474
 
475
+ def unload(scope)
476
+ @paths = @paths.reject { |path| path.kind == scope }
477
+ end
478
+
419
479
  ## Load specified file into the config stack
420
480
  # This can be called multiple times and each will get loaded into the config
421
481
  def load_specific(file)
422
- spc = ConfigFile.new(:specified, Pathname.new(file))
482
+ spc = ConfigFile.new(:specified, Pathname.new(file), self)
423
483
  spc.load
424
484
  @paths.insert(1, spc)
425
485
  end
@@ -687,8 +747,16 @@ module MrMurano
687
747
  open_curl_file
688
748
  return if @curlfile_f.nil?
689
749
  # MEH: Call @curlfile_f.close() at some point? Or let Ruby do on exit.
690
- @curlfile_f << Time.now.to_s + "\n"
691
- @curlfile_f << "murano #{ARGV.join(' ')}\n"
750
+ if self['tool.curlfancy']
751
+ was_enabled = Rainbow.enabled
752
+ Rainbow.enabled = true
753
+ @curlfile_f << Rainbow(
754
+ "#############################################################\n\n"
755
+ ).foreground(:white).background(:red)
756
+ Rainbow.enabled = was_enabled
757
+ end
758
+ @curlfile_f << Time.now.to_s + "\n\n"
759
+ @curlfile_f << "murano #{ARGV.join(' ')}\n\n"
692
760
  @curlfile_f.flush
693
761
  end
694
762
  elsif !@curlfile_f.nil?
@@ -709,17 +777,17 @@ module MrMurano
709
777
  def set_net_host(url_or_host, scope=:internal)
710
778
  return if url_or_host.nil?
711
779
  if url_or_host.to_s.empty?
712
- $cfg.set('net.protocol', 'https', scope)
713
- $cfg.set('net.host', CFG_HOST_BIZAPI, scope)
780
+ set('net.protocol', 'https', scope)
781
+ set('net.host', CFG_HOST_BIZAPI, scope)
714
782
  return
715
783
  end
716
784
  protocol_or_host, host_maybe = url_or_host.split('://', 2)
717
785
  if !host_maybe.nil?
718
- $cfg.set('net.protocol', protocol_or_host, scope)
719
- $cfg.set('net.host', host_maybe, scope)
786
+ set('net.protocol', protocol_or_host, scope)
787
+ set('net.host', host_maybe, scope)
720
788
  else
721
- $cfg.set('net.protocol', 'https', scope)
722
- $cfg.set('net.host', protocol_or_host, scope)
789
+ set('net.protocol', 'https', scope)
790
+ set('net.host', protocol_or_host, scope)
723
791
  end
724
792
  end
725
793
  end
@@ -65,7 +65,7 @@ module MrMurano
65
65
 
66
66
  # Get details of a single item in content area
67
67
  # @param name [String] Name of content
68
- def fetch(name)
68
+ def fetch(name, _untainted=false)
69
69
  get("/#{CGI.escape(name)}")
70
70
  end
71
71
  alias info fetch