MuranoCLI 3.0.1 → 3.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/.agignore +1 -0
  3. data/.rubocop.yml +67 -5
  4. data/Gemfile +6 -3
  5. data/MuranoCLI.gemspec +14 -10
  6. data/README.markdown +299 -126
  7. data/Rakefile +6 -1
  8. data/bin/murano +2 -2
  9. data/docs/completions/murano_completion-bash +93 -0
  10. data/lib/MrMurano.rb +19 -2
  11. data/lib/MrMurano/Business.rb +22 -19
  12. data/lib/MrMurano/Config.rb +19 -9
  13. data/lib/MrMurano/Content.rb +4 -4
  14. data/lib/MrMurano/Exchange-Element.rb +99 -0
  15. data/lib/MrMurano/Exchange.rb +137 -0
  16. data/lib/MrMurano/Gateway.rb +9 -9
  17. data/lib/MrMurano/Keystore.rb +4 -2
  18. data/lib/MrMurano/ReCommander.rb +3 -5
  19. data/lib/MrMurano/Solution-ServiceConfig.rb +12 -12
  20. data/lib/MrMurano/Solution-Services.rb +15 -14
  21. data/lib/MrMurano/Solution-Users.rb +2 -2
  22. data/lib/MrMurano/Solution.rb +43 -49
  23. data/lib/MrMurano/SolutionId.rb +28 -28
  24. data/lib/MrMurano/SyncUpDown.rb +32 -22
  25. data/lib/MrMurano/Webservice-Endpoint.rb +2 -1
  26. data/lib/MrMurano/Webservice.rb +5 -5
  27. data/lib/MrMurano/commands.rb +2 -1
  28. data/lib/MrMurano/commands/business.rb +21 -19
  29. data/lib/MrMurano/commands/domain.rb +16 -2
  30. data/lib/MrMurano/commands/exchange.rb +272 -0
  31. data/lib/MrMurano/commands/globals.rb +17 -1
  32. data/lib/MrMurano/commands/init.rb +3 -3
  33. data/lib/MrMurano/commands/link.rb +16 -16
  34. data/lib/MrMurano/commands/postgresql.rb +2 -2
  35. data/lib/MrMurano/commands/show.rb +13 -7
  36. data/lib/MrMurano/commands/solution.rb +23 -17
  37. data/lib/MrMurano/commands/solution_picker.rb +49 -44
  38. data/lib/MrMurano/commands/sync.rb +2 -1
  39. data/lib/MrMurano/commands/timeseries.rb +2 -2
  40. data/lib/MrMurano/commands/tsdb.rb +2 -2
  41. data/lib/MrMurano/hash.rb +19 -7
  42. data/lib/MrMurano/http.rb +12 -2
  43. data/lib/MrMurano/orderedhash.rb +200 -0
  44. data/lib/MrMurano/spec_commander.rb +98 -0
  45. data/lib/MrMurano/verbosing.rb +2 -2
  46. data/lib/MrMurano/version.rb +2 -2
  47. data/spec/Business_spec.rb +8 -6
  48. data/spec/Solution-ServiceConfig_spec.rb +1 -1
  49. data/spec/SyncUpDown_spec.rb +6 -6
  50. data/spec/_workspace.rb +9 -4
  51. data/spec/cmd_business_spec.rb +8 -2
  52. data/spec/cmd_common.rb +266 -25
  53. data/spec/cmd_exchange_spec.rb +118 -0
  54. data/spec/cmd_help_spec.rb +54 -13
  55. data/spec/cmd_init_spec.rb +1 -12
  56. data/spec/cmd_link_spec.rb +94 -72
  57. data/spec/spec_helper.rb +11 -16
  58. metadata +23 -17
data/Rakefile CHANGED
@@ -1,4 +1,4 @@
1
- # Last Modified: 2017.08.15 /coding: utf-8
1
+ # Last Modified: 2017.08.29 /coding: utf-8
2
2
  # frozen_string_literal: true
3
3
 
4
4
  # Copyright © 2016-2017 Exosite LLC.
@@ -48,6 +48,11 @@ task :echo do
48
48
  puts built_gem
49
49
  end
50
50
 
51
+ desc 'Tail the CI build file and the curl file'
52
+ task :tail do
53
+ sh %(tail -F .rake_build.out curldebug.out)
54
+ end
55
+
51
56
  desc 'display remind of how to release'
52
57
  task :release_reminder do
53
58
  reminder = %(
data/bin/murano CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
- # Last Modified: 2017.08.23 /coding: utf-8
2
+ # Last Modified: 2017.08.30 /coding: utf-8
3
3
  # frozen_string_literal: true
4
4
 
5
5
  # Copyright © 2016-2017 Exosite LLC.
@@ -43,7 +43,7 @@ program :description, %(
43
43
  # VAR=$(murano command ...)
44
44
  # etc., then do not do progress.
45
45
  # TEST/2017-08-23: Does this work on Windows?
46
- ARGV.push('--no-progress') unless $stdout.tty?
46
+ ARGV.push('--no-progress') unless $stdout.tty? || ARGV.include?('--no-progress')
47
47
 
48
48
  default_command :help
49
49
 
@@ -10,6 +10,10 @@ __app_switches=(
10
10
  --configfile
11
11
  --curl
12
12
  --dry
13
+ --csv
14
+ --json
15
+ --yaml
16
+ --pp
13
17
  --exclude-scopes
14
18
  --no-page
15
19
  --no-plugins
@@ -78,6 +82,7 @@ function _murano () {
78
82
  devices
79
83
  diff
80
84
  domain
85
+ exchange
81
86
  find
82
87
  gwe
83
88
  help
@@ -163,6 +168,9 @@ function _murano () {
163
168
  (domain)
164
169
  __murano-domain "$cmd1" "$cmd2" "${used_switches[@]}"
165
170
  ;;
171
+ (exchange)
172
+ __murano-exchange "$cmd1" "$cmd2" "${used_switches[@]}"
173
+ ;;
166
174
  (find)
167
175
  __murano-find "$cmd1" "$cmd2" "${used_switches[@]}"
168
176
  ;;
@@ -1398,6 +1406,91 @@ function __murano-domain () {
1398
1406
  COMPREPLY=($(compgen -W '${comp_list[@]}' -- "${last}"))
1399
1407
  }
1400
1408
 
1409
+ # Completion for subcommand: "exchange".
1410
+ function __murano-exchange () {
1411
+ local subcmd1="$1"
1412
+ local subcmd2="$2"
1413
+ #local subcmdn="$3"
1414
+ local used_switches="${@:3}"
1415
+ local last="${COMP_WORDS[COMP_CWORD]}"
1416
+ local len=$(($COMP_CWORD - 1))
1417
+
1418
+ local -a more_switches
1419
+
1420
+ local -a comp_list
1421
+
1422
+ #>&2 echo -e "\nsubcmd1=$subcmd1 / subcmd2=$subcmd2 / last=$last / len=$len"
1423
+ #>&2 echo "used_switches=$used_switches"
1424
+ #>&2 echo "more_switches=$more_switches"
1425
+
1426
+ # NOTE: Not doing anything special for ${subcmd2}.
1427
+ # Are there sub-sub-commands we shoud list?
1428
+ if [[ -z ${subcmd1} || ${len} -eq 1 ]]; then
1429
+ comp_list=(
1430
+ add
1431
+ buy
1432
+ list
1433
+ purchase
1434
+ )
1435
+ else
1436
+ case $subcmd1 in
1437
+ (add)
1438
+ more_switches=(
1439
+ {--trace}
1440
+ )
1441
+ ;;
1442
+ (buy)
1443
+ more_switches=(
1444
+ {--trace}
1445
+ )
1446
+ ;;
1447
+ (list)
1448
+ more_switches=(
1449
+ {--trace}
1450
+ )
1451
+ ;;
1452
+ (purchase)
1453
+ more_switches=(
1454
+ {--trace}
1455
+ )
1456
+ ;;
1457
+ esac
1458
+ fi
1459
+
1460
+ # Add unused application-wide flags.
1461
+ local idx
1462
+ for ((idx = 0; idx < ${#__app_switches[@]}; idx++)); do
1463
+ local switch=${__app_switches[$idx]}
1464
+ if ! contains_element "$switch" "${used_switches[@]}"; then
1465
+ comp_list+=("$switch")
1466
+ fi
1467
+ done
1468
+ # Add unused subcommand flags.
1469
+ for ((idx = 0; idx < ${#more_switches[@]}; idx++)); do
1470
+ local switch=${more_switches[$idx]}
1471
+ comp_list+=("$switch")
1472
+ done
1473
+
1474
+ # If there are only --flags, <TAB> will put the common prefix,
1475
+ # "--", but maybe the user doesn't want to add a flag after all.
1476
+ if [[ -z ${last} ]]; then
1477
+ local flags_only=true
1478
+ for ((idx = 0; idx < ${#comp_list[@]}; idx++)); do
1479
+ local switch=${comp_list[$idx]}
1480
+ if [[ ${switch} != --* ]]; then
1481
+ flags_only=false
1482
+ break
1483
+ fi
1484
+ done
1485
+ if ${flags_only}; then
1486
+ # Use two Unicode en spaces to prevent compgen from prefixing "--".
1487
+ comp_list+=("  ")
1488
+ fi
1489
+ fi
1490
+
1491
+ COMPREPLY=($(compgen -W '${comp_list[@]}' -- "${last}"))
1492
+ }
1493
+
1401
1494
  # Completion for subcommand: "find".
1402
1495
  function __murano-find () {
1403
1496
  local subcmd1="$1"
@@ -1,4 +1,4 @@
1
- # Last Modified: 2017.08.16 /coding: utf-8
1
+ # Last Modified: 2017.08.29 /coding: utf-8
2
2
  # frozen_string_literal: true
3
3
 
4
4
  # Copyright © 2016-2017 Exosite LLC.
@@ -9,27 +9,44 @@
9
9
  # individual files include all the files they need.
10
10
 
11
11
  require 'MrMurano/version'
12
- require 'MrMurano/verbosing'
12
+
13
13
  require 'MrMurano/hash'
14
14
  require 'MrMurano/http'
15
+ require 'MrMurano/makePretty'
16
+ #require 'MrMurano/optparse'
17
+ require 'MrMurano/progress'
18
+ require 'MrMurano/verbosing'
15
19
 
16
20
  require 'MrMurano/Config'
21
+ require 'MrMurano/Config-Migrate'
17
22
  require 'MrMurano/ProjectFile'
18
23
 
19
24
  require 'MrMurano/Account'
20
25
  require 'MrMurano/Business'
26
+ require 'MrMurano/Exchange'
27
+ require 'MrMurano/Exchange-Element'
28
+ require 'MrMurano/Passwords'
21
29
 
22
30
  require 'MrMurano/Content'
23
31
  require 'MrMurano/Gateway'
32
+ require 'MrMurano/Keystore'
33
+ require 'MrMurano/Mock'
24
34
  require 'MrMurano/Setting'
35
+ require 'MrMurano/SolutionId'
25
36
  require 'MrMurano/Solution'
26
37
  require 'MrMurano/Solution-Services'
27
38
  require 'MrMurano/Solution-ServiceConfig'
28
39
  require 'MrMurano/Solution-Users'
40
+ require 'MrMurano/Webservice'
29
41
  require 'MrMurano/Webservice-Cors'
30
42
  require 'MrMurano/Webservice-Endpoint'
31
43
  require 'MrMurano/Webservice-File'
32
44
 
45
+ require 'MrMurano/SyncAllowed'
46
+ require 'MrMurano/SyncRoot'
47
+ require 'MrMurano/SyncUpDown'
48
+
49
+ require 'MrMurano/SubCmdGroupContext'
33
50
  require 'MrMurano/ReCommander'
34
51
  require 'MrMurano/commands'
35
52
 
@@ -1,4 +1,4 @@
1
- # Last Modified: 2017.08.23 /coding: utf-8
1
+ # Last Modified: 2017.09.11 /coding: utf-8
2
2
  # frozen_string_literal: true
3
3
 
4
4
  # Copyright © 2016-2017 Exosite LLC.
@@ -26,12 +26,11 @@ module MrMurano
26
26
  include Http
27
27
  include Verbose
28
28
 
29
- #attr_accessor :bid
30
- #attr_accessor :name
31
- attr_accessor :role
32
- attr_reader :meta
33
29
  attr_writer :bid
34
30
  attr_writer :name
31
+ attr_accessor :role
32
+ attr_reader :meta
33
+ attr_reader :ometa
35
34
 
36
35
  def initialize(data=nil)
37
36
  @bid = nil
@@ -39,6 +38,7 @@ module MrMurano
39
38
  @valid = false
40
39
  @user_bizes = {}
41
40
  self.meta = data unless data.nil?
41
+ @ometa = nil
42
42
  end
43
43
 
44
44
  def valid?
@@ -155,7 +155,7 @@ or set it interactively using \`#{MrMurano::EXE_NAME} init\`
155
155
  whirly_stop
156
156
  @valid = !data.nil?
157
157
  @name = data[:name] if @valid
158
- @valid
158
+ @ometa = data
159
159
  end
160
160
 
161
161
  # ---------------------------------------------------------------------
@@ -166,7 +166,7 @@ or set it interactively using \`#{MrMurano::EXE_NAME} init\`
166
166
  #ALLOWED_TYPES = [:domain, :onepApi, :dataApi, :application, :product,].freeze
167
167
  ALLOWED_TYPES = %i[application product].freeze
168
168
 
169
- def solutions(type: :all, sid: nil, name: nil, fuzzy: nil, invalidate: false)
169
+ def solutions(type: :all, api_id: nil, name: nil, fuzzy: nil, invalidate: false)
170
170
  debug "Getting all solutions of type #{type}"
171
171
  must_business_id!
172
172
 
@@ -201,16 +201,17 @@ or set it interactively using \`#{MrMurano::EXE_NAME} init\`
201
201
 
202
202
  solz = @user_bizes[type].dup
203
203
 
204
- match_sid = ensure_array(sid)
204
+ match_api_id = ensure_array(api_id)
205
205
  match_name = ensure_array(name)
206
206
  match_fuzzy = ensure_array(fuzzy)
207
- if match_sid.any? || match_name.any? || match_fuzzy.any?
207
+ if match_api_id.any? || match_name.any? || match_fuzzy.any?
208
208
  solz.select! do |sol|
209
209
  (
210
- match_sid.include?(sol[:apiId]) ||
210
+ match_api_id.include?(sol[:apiId]) ||
211
211
  match_name.include?(sol[:name]) ||
212
212
  match_fuzzy.any? do |term|
213
- sol[:name] =~ /#{Regexp.escape(term)}/i || sol[:apiId] =~ /#{Regexp.escape(term)}/i
213
+ sol[:name] =~ /#{Regexp.escape(term)}/i || \
214
+ sol[:apiId] =~ /#{Regexp.escape(term)}/i
214
215
  end
215
216
  )
216
217
  end
@@ -224,7 +225,9 @@ or set it interactively using \`#{MrMurano::EXE_NAME} init\`
224
225
  MrMurano::Product.new(meta)
225
226
  else
226
227
  warning("Unexpected solution type: #{meta[:type]}")
227
- warning('* Please enable Murano for this business') if meta[:type].to_sym == :dataApi
228
+ if meta[:type].to_sym == :dataApi
229
+ warning('* Please enable Murano for this business')
230
+ end
228
231
  MrMurano::Solution.new(meta)
229
232
  end
230
233
  end
@@ -241,14 +244,14 @@ or set it interactively using \`#{MrMurano::EXE_NAME} init\`
241
244
  def solution_from_type!(type)
242
245
  type = type.to_s.to_sym
243
246
  raise "Unknown type(#{type})" unless type.to_s.empty? || ALLOWED_TYPES.include?(type)
244
- sid = MrMurano::Solution::INVALID_SID
247
+ api_id = MrMurano::Solution::INVALID_API_ID
245
248
  if type == :application
246
- sol = MrMurano::Application.new(sid)
249
+ sol = MrMurano::Application.new(api_id)
247
250
  elsif type == :product
248
- sol = MrMurano::Product.new(sid)
251
+ sol = MrMurano::Product.new(api_id)
249
252
  else
250
253
  #raise "Unexpected path: Unrecognized type #{fancy_ticks(type)}"
251
- sol = MrMurano::Solution.new(sid)
254
+ sol = MrMurano::Solution.new(api_id)
252
255
  end
253
256
  sol.biz = self
254
257
  sol
@@ -312,7 +315,7 @@ or set it interactively using \`#{MrMurano::EXE_NAME} init\`
312
315
  error("Unexpected: Solution ID not returned: #{resp}")
313
316
  exit 1
314
317
  end
315
- sol.sid = resp[:id]
318
+ sol.api_id = resp[:id]
316
319
  sol.affirm_valid
317
320
  # 2017-06-29: The code used to hunt for the solution ID, because
318
321
  # POST business/<bizid>/solution/ used to not return anything,
@@ -333,11 +336,11 @@ or set it interactively using \`#{MrMurano::EXE_NAME} init\`
333
336
  # exit 3
334
337
  # end
335
338
  # sol.meta = ret.first
336
- # if sol.sid.to_s.empty? then
339
+ # if sol.api_id.to_s.empty? then
337
340
  # error("New solution created for #{fancy_ticks(sol.name)} missing ID?: #{ret}")
338
341
  # exit 3
339
342
  # end
340
- # sol.sid = sid
343
+ # sol.api_id = api_id
341
344
  #end
342
345
  sol
343
346
  end
@@ -1,4 +1,4 @@
1
- # Last Modified: 2017.08.23 /coding: utf-8
1
+ # Last Modified: 2017.08.31 /coding: utf-8
2
2
  # frozen_string_literal: true
3
3
 
4
4
  # Copyright © 2016-2017 Exosite LLC.
@@ -280,23 +280,33 @@ module MrMurano
280
280
  true
281
281
  end
282
282
 
283
- def validate_cmd
283
+ INVALID_PROJECT_HINT = %(
284
+ Please change to a project directory, or run `murano init` to create a new project.
285
+ ).strip
286
+
287
+ def validate_cmd(cmd=nil)
288
+ return unless validate_cmd_business_and_project(cmd)
289
+ migrate_old_config(@project_dir)
290
+ migrate_old_config(Pathname.new(Dir.home))
291
+ end
292
+
293
+ def validate_cmd_business_and_project(cmd)
284
294
  # Most commands should be run from within a Murano project (sub-)directory.
285
295
  # If user is running a project command not within a project directory,
286
296
  # we'll print a message now and exit the app from run_active_command later.
287
297
  unless @runner.nil?
288
- the_cmd = @runner.active_command
289
- unless the_cmd.name == 'help' || the_cmd.project_not_required || @project_exists
298
+ the_cmd = @runner.active_command if cmd.nil?
299
+ the_cmd = command(cmd) if the_cmd.nil?
300
+ the_cmd.project_not_required = false unless defined?(the_cmd.project_not_required)
301
+ if the_cmd.name != 'help' && !the_cmd.project_not_required && !@project_exists
290
302
  error %(The "#{the_cmd.name}" command only works in a Murano project.)
291
- say %(Please change to a project directory, or run `murano init` to create a new project.)
303
+ say INVALID_PROJECT_HINT
292
304
  # Note that commnander-rb uses an at_exit hook, which we hack around.
293
305
  @runner.command_exit = 1
294
- return
306
+ false
295
307
  end
296
308
  end
297
-
298
- migrate_old_config(@project_dir)
299
- migrate_old_config(Pathname.new(Dir.home))
309
+ true
300
310
  end
301
311
 
302
312
  def self.fix_modes(path)
@@ -1,4 +1,4 @@
1
- # Last Modified: 2017.08.23 /coding: utf-8
1
+ # Last Modified: 2017.09.11 /coding: utf-8
2
2
  # frozen_string_literal: true
3
3
 
4
4
  # Copyright © 2016-2017 Exosite LLC.
@@ -29,9 +29,9 @@ module MrMurano
29
29
 
30
30
  def initialize
31
31
  @solntype = 'product.id'
32
- @uriparts_sidex = 1
33
- init_sid!
34
- @uriparts = [:service, @sid, :content, :item]
32
+ @uriparts_apidex = 1
33
+ init_api_id!
34
+ @uriparts = [:service, @api_id, :content, :item]
35
35
  @itemkey = :id
36
36
  #@locationbase = $cfg['location.base']
37
37
  @location = nil
@@ -0,0 +1,99 @@
1
+ # Last Modified: 2017.08.31 /coding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ # Copyright © 2016-2017 Exosite LLC.
5
+ # License: MIT. See LICENSE.txt.
6
+ # vim:tw=0:ts=2:sw=2:et:ai
7
+
8
+ module MrMurano
9
+ class ExchangeElement
10
+ include HashInit
11
+
12
+ # The meta is the element hash returned from the platform,
13
+ # i.e., all of the other attrs in a Hash.
14
+ attr_reader :meta
15
+
16
+ # The Exchange Element's Business ID context.
17
+ attr_accessor :bizid
18
+
19
+ # The Exchange Element's Element ID.
20
+ attr_accessor :elementId
21
+ #attr_accessor :element_id
22
+
23
+ # The Purchase ID is nil unless the user has added/purchased this element.
24
+ attr_accessor :purchaseId
25
+ #attr_accessor :purchase_id
26
+
27
+ # The <bizId>/exchange/ endpoint returns a list of flat dictionaries.
28
+ # The <bizId>/purchase/ endpoint, on the other hand, puts the remaining
29
+ # items in an object under an "element" key.
30
+
31
+ # The type is one of: download
32
+ attr_accessor :type
33
+ #attr_accessor :action_type
34
+
35
+ # The friendly, descriptive name of the Exchange Element.
36
+ attr_accessor :name
37
+
38
+ # FIXME/EXPLAIN: Is this what the Lua code calls the service?
39
+ attr_accessor :apiServiceName
40
+
41
+ # The image associated with the Exchange Element; not used by the CLI.
42
+ attr_accessor :image
43
+
44
+ # The short description describing the Exchange Element.
45
+ attr_accessor :description
46
+
47
+ # The long description describing the Exchange Element.
48
+ attr_accessor :markdown
49
+
50
+ # The Murano business tiers to which this element applies.
51
+ # One or more of: ["free", "developer", "professional", "enterprise"]
52
+ attr_accessor :tiers
53
+
54
+ # Tags used to describe the Exchange Element.
55
+ attr_accessor :tags
56
+
57
+ # Actions associated with the Exchange Element.
58
+ attr_accessor :actions
59
+ # The actions is an array with one dict element with:
60
+ # 'url', 'type' (e.g., 'download), and 'primary' (bool).
61
+
62
+ # MurCLI-only: Based on purchaseId and tiers, state of Element in Business.
63
+ attr_accessor :statusable
64
+
65
+ ELEM_KEY_TRANSLATE = {
66
+ #type: :action_type,
67
+ #elementId: :element_id,
68
+ }.freeze
69
+
70
+ def initialize(*hash)
71
+ hash = [hash] unless hash.is_a? Array
72
+ camel_cased = {}
73
+ hash.first.each do |key, val|
74
+ if ELEM_KEY_TRANSLATE[key].nil?
75
+ camel_cased[key] = val
76
+ else
77
+ camel_cased[ELEM_KEY_TRANSLATE[key]] = val
78
+ end
79
+ end
80
+ super camel_cased
81
+ @meta = hash.first
82
+ #@meta = camel_cased
83
+ end
84
+
85
+ def status
86
+ case statusable
87
+ when :available
88
+ 'available'
89
+ when :upgrade
90
+ 'available*'
91
+ when :added
92
+ 'added'
93
+ else
94
+ statusable.to_s
95
+ end
96
+ end
97
+ end
98
+ end
99
+