MrMurano 1.9.0 → 1.10.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c1ab13a9e2ec31727024cb8776e466d1764e592f
4
- data.tar.gz: 7a1d7d1f1b6d135b89af5053d0277fa2917c62ea
3
+ metadata.gz: 2c82aba3bbc43dfbfaca479de9eb3387f7aa1e65
4
+ data.tar.gz: 485cb4bec0fbab31b06e00d6af5bc474c346fe8b
5
5
  SHA512:
6
- metadata.gz: 8b51b475707e85b63490e8f547674651cd47666ddb1cade28ade86f3b08724dba7a6df65e850975f9a630161cb1bc0b7b3277ea8c2262a8f5f8315b47fb03e1b
7
- data.tar.gz: 0c61906ec034c36d5551ac790042e4b3df6127c4f8075e5f9f70167f85eb11f6c6925e89d19497ca2d2186fd1f38d41ab19728b6dd16587efa083cc01bfb3cbe
6
+ metadata.gz: 79ba743c1656d07acf3871c7353b4f193be8b10bb2adc67ac377843a4152a0362966e6ab43594272bea3f429873f51c6331c34736d1081a5e8c6afca31c87df4
7
+ data.tar.gz: 644ff5cfcaa83e77384a44996f1e28758e681e19b6ed1491097f97f835c2d88b3ef3d224f01d27c231d30d4c8a675266297eaded396d3ddfbc0b5c45d43dae83
data/.gitignore CHANGED
@@ -10,6 +10,7 @@ tags
10
10
  xcuserdata
11
11
  Pods/
12
12
  pkg/
13
+ report/
13
14
 
14
15
  .mrmurano/
15
16
  .mrmuranorc
data/MrMurano.gemspec CHANGED
@@ -8,7 +8,7 @@ Gem::Specification.new do |s|
8
8
  s.authors = ['Michael Conrad Tadpol Tilstra']
9
9
  s.email = ['tadpol@tadpol.org']
10
10
  s.license = 'MIT'
11
- s.homepage = 'https://github.com/tadpol/MrMurano'
11
+ s.homepage = 'https://github.com/exosite/MrMurano'
12
12
  s.summary = 'Do more from the command line with Murano'
13
13
  s.description = %{Do more from the command line with Murano
14
14
 
data/README.markdown CHANGED
@@ -208,7 +208,8 @@ spec/cico.murano.spec
208
208
 
209
209
  ## Developing
210
210
 
211
- MrMurano uses git flow for managing branches.
211
+ MrMurano uses [git flow](https://github.com/nvie/gitflow#getting-started) for
212
+ [managing branches](http://nvie.com/posts/a-successful-git-branching-model/).
212
213
 
213
214
  MrMurano also uses [bunder](http://bundler.io).
214
215
 
data/Rakefile CHANGED
@@ -29,7 +29,7 @@ task :gempush do
29
29
  sh %{gem push pkg/MrMurano-#{Bundler::GemHelper.gemspec.version}.gem}
30
30
  end
31
31
 
32
- task :gemit do
32
+ task :gemit do
33
33
  mrt=Bundler::GemHelper.gemspec.version
34
34
  sh %{git checkout v#{mrt}}
35
35
  Rake::Task[:build].invoke
@@ -38,14 +38,23 @@ task :gemit do
38
38
  sh %{git checkout develop}
39
39
  end
40
40
 
41
+ task :wexe do
42
+ # Need to find all dlls, because ocra isn't finding them for some reason.
43
+ gemdir = `gem env gemdir`.chomp # XXX can we get that without running commands?
44
+ gemdlls = Dir[File.join(gemdir, 'extensions', '*')]
45
+ sh %{ocra bin/mr #{gemdlls.join(' ')}}
46
+ end
47
+
41
48
  desc "Prints a cmd to test this in another directory"
42
49
  task :testwith do
43
50
  pwd=Dir.pwd.sub(Dir.home, '~')
44
51
  puts "ruby -I#{pwd}/lib #{pwd}/bin/mr "
45
52
  end
46
53
 
54
+ desc 'Run RSpec'
47
55
  task :test do
48
- sh %{rspec}
56
+ Dir.mkdir("report") unless File.directory?("report")
57
+ sh %{rspec --format html --out report/index.html --format progress}
49
58
  end
50
59
 
51
60
  # vim: set sw=4 ts=4 :
@@ -44,6 +44,7 @@ module MrMurano
44
44
  return
45
45
  end
46
46
  def get(host, user)
47
+ return ENV['MR_PASSWORD'] unless ENV['MR_PASSWORD'].nil?
47
48
  return nil unless @data.kind_of? Hash
48
49
  return nil unless @data.has_key? host
49
50
  return nil unless @data[host].kind_of? Hash
@@ -105,6 +106,7 @@ module MrMurano
105
106
  @@token = token[:token]
106
107
  else
107
108
  showHttpError(request, response)
109
+ error "Check to see if username and password are correct."
108
110
  @@token = nil
109
111
  raise response
110
112
  end
@@ -80,6 +80,33 @@ module MrMurano
80
80
  end
81
81
  end
82
82
 
83
+ ## Completely remove an identifier from the product
84
+ # +sn+:: Identifier for a device
85
+ def remove(sn)
86
+ # First drop it from the 1P database
87
+ do_rpc({:id=>1, :procedure=>:drop, :arguments=>[sn_rid(sn)]})
88
+ # Then remove it from the provisioning databases
89
+ psn = ProductSerialNumber.new
90
+ psn.remove_sn(sn)
91
+ end
92
+
93
+ ## Rename a device
94
+ # +sn+:: Identifier for a device
95
+ # +newname+:: The new name of the device
96
+ def rename(sn, newname, rid=nil)
97
+ newname = sn if newname.nil?
98
+ rid = sn_rid(sn) if rid.nil?
99
+ verbose "Setting name of #{sn} to #{newname}"
100
+ debug " Via RID: #{rid}"
101
+ do_rpc({
102
+ :procedure=>:update,
103
+ :arguments=>[
104
+ rid,
105
+ {:name=>newname}
106
+ ]
107
+ })
108
+ end
109
+
83
110
  ## Get a tree of info for a device and its resources.
84
111
  # +sn+:: Identifier for a device
85
112
  def twee(sn)
@@ -50,10 +50,7 @@ module MrMurano
50
50
  # dropped.
51
51
  def do_rpc(calls, cid=model_rid)
52
52
  calls = [calls] unless calls.kind_of?(Array)
53
- r = post('', {
54
- :auth=>{:client_id=>cid},
55
- :calls=>calls
56
- })
53
+ r = do_mrpc(calls, cid)
57
54
  return r if not r.kind_of?(Array) or r.count < 1
58
55
  r = r[0]
59
56
  return r if not r.kind_of?(Hash) or r[:status] != 'ok'
@@ -283,7 +280,6 @@ module MrMurano
283
280
  end
284
281
  end
285
282
 
286
- ## TODO: Determine which of these are expected to be used.
287
283
  class ProductSerialNumber < ProductBase
288
284
  def initialize
289
285
  super
@@ -345,7 +341,8 @@ module MrMurano
345
341
  end
346
342
 
347
343
  def remove_sn(sn)
348
- postf('/', {:sn=>sn, :delete=>true})
344
+ #postf('/', {:sn=>sn, :delete=>true})
345
+ delete("/#{sn}")
349
346
  end
350
347
 
351
348
  def ranges
@@ -65,6 +65,7 @@ module MrMurano
65
65
  return [] if here == false
66
66
 
67
67
  here[:id] = 'cors'
68
+ here[:local_path] = from
68
69
  [ Hash.transform_keys_to_symbols(here) ]
69
70
  end
70
71
 
@@ -36,6 +36,7 @@ module MrMurano
36
36
  end
37
37
 
38
38
  def call(opid, meth=:get, data=nil, id=scid, &block)
39
+ raise "Service '#{@serviceName}' not enabled for this Solution" if id.nil?
39
40
  call = "/#{id.to_s}/call/#{opid.to_s}"
40
41
  debug "Will call: #{call}"
41
42
  case meth
@@ -100,7 +100,7 @@ module MrMurano
100
100
  :sha1=>Digest::SHA1.file(local_path.to_s).hexdigest,
101
101
  :updated_at=>time.to_datetime.iso8601(3)
102
102
  }
103
- cacheFile = $cfg.file_at("cache.#{self.class.to_s}.yaml")
103
+ cacheFile = $cfg.file_at("cache.#{self.class.to_s.gsub(/\W+/,'_')}.yaml")
104
104
  if cacheFile.file? then
105
105
  cacheFile.open('r+') do |io|
106
106
  cache = YAML.load(io)
@@ -120,7 +120,7 @@ module MrMurano
120
120
 
121
121
  def cachedUpdateTimeFor(local_path)
122
122
  cksm = Digest::SHA1.file(local_path.to_s).hexdigest
123
- cacheFile = $cfg.file_at("cache.#{self.class.to_s}.yaml")
123
+ cacheFile = $cfg.file_at("cache.#{self.class.to_s.gsub(/\W+/,'_')}.yaml")
124
124
  return nil unless cacheFile.file?
125
125
  ret = nil
126
126
  cacheFile.open('r') do |io|
@@ -33,6 +33,10 @@ module MrMurano
33
33
  @aliases.include? name.to_s
34
34
  end
35
35
 
36
+ def command(name)
37
+ @commands[name.to_s]
38
+ end
39
+
36
40
  def get_help
37
41
  hf = @runner.program(:help_formatter).new(self)
38
42
  pc = Commander::HelpFormatter::ProgramContext.new(self).get_binding
@@ -0,0 +1,45 @@
1
+ require 'MrMurano/Account'
2
+
3
+ command 'business list' do |c|
4
+ c.syntax = %{mr business list [options]}
5
+ c.description = %{List businesses}
6
+ c.option '--idonly', 'Only return the ids'
7
+ c.option '--[no-]all', 'Show all fields'
8
+ c.option '-o', '--output FILE', %{Download to file instead of STDOUT}
9
+
10
+ c.action do |args, options|
11
+ acc = MrMurano::Account.new
12
+ data = acc.businesses
13
+
14
+ io=nil
15
+ if options.output then
16
+ io = File.open(options.output, 'w')
17
+ end
18
+
19
+ if options.idonly then
20
+ headers = [:bizid]
21
+ data = data.map{|row| [row[:modelId]]}
22
+ elsif not options.all then
23
+ headers = [:bizid, :role, :name]
24
+ data = data.map{|r| [r[:bizid], r[:role], r[:name]]}
25
+ else
26
+ headers = data[0].keys
27
+ data = data.map{|r| headers.map{|h| r[h]}}
28
+ end
29
+
30
+ acc.outf(data, io) do |dd, ios|
31
+ if options.idonly then
32
+ ios.puts dd.join(' ')
33
+ else
34
+ acc.tabularize({
35
+ :headers=>headers.map{|h| h.to_s},
36
+ :rows=>dd
37
+ }, ios)
38
+ end
39
+ end
40
+ io.close unless io.nil?
41
+
42
+ end
43
+ end
44
+
45
+ # vim: set ai et sw=2 ts=2 :
@@ -47,7 +47,7 @@ command :config do |c|
47
47
  say $cfg.get(args[0], scopes)
48
48
  else
49
49
 
50
- options.default :system=>false, :user=>false, :project=>true,
50
+ options.default :system=>false, :user=>false, :project=>false,
51
51
  :specified=>false, :env=>false
52
52
  # For write, if scope is specified, only write to that scope.
53
53
  scope = :project
@@ -11,6 +11,12 @@ command :init do |c|
11
11
 
12
12
  c.action do |args, options|
13
13
  options.default :force=>false, :mkdirs=>true
14
+ acc = MrMurano::Account.new
15
+
16
+ if Pathname.new(Dir.pwd).realpath == Pathname.new(Dir.home).realpath then
17
+ acc.error "Cannot init a project in your HOME directory."
18
+ exit 2
19
+ end
14
20
 
15
21
  if not options.force and ($cfg['location.base'] + 'Solutionfile.json').exist? then
16
22
  y=ask("A Solutionfile.json exists, Do you want exit and run `mr config import` instead? [yN]")
@@ -20,8 +26,6 @@ command :init do |c|
20
26
 
21
27
  # If they have never logged in, then asking for the business.id will also ask
22
28
  # for their username and password.
23
- acc = MrMurano::Account.new
24
-
25
29
 
26
30
  # 1. Get business id
27
31
  if not options.force and not $cfg['business.id'].nil? then
@@ -33,6 +33,10 @@ module MrMurano
33
33
  call(:command, :post, {:key=>key, :command=>cmd, :args=>args})
34
34
  end
35
35
 
36
+ def clearall()
37
+ call(:clear, :post, {})
38
+ end
39
+
36
40
  end
37
41
  end
38
42
 
@@ -48,6 +52,15 @@ set data. As well as calling any of the other supported REDIS commands.}
48
52
  end
49
53
  end
50
54
 
55
+ command 'keystore clearAll' do |c|
56
+ c.syntax = %{mr keystore clearAll}
57
+ c.description = %{Delete all keys in the keystore}
58
+ c.action do |args,options|
59
+ sol = MrMurano::Keystore.new
60
+ sol.clearall
61
+ end
62
+ end
63
+
51
64
  command 'keystore info' do |c|
52
65
  c.syntax = %{mr keystore info}
53
66
  c.description = %{Show info about the Keystore}
@@ -0,0 +1,41 @@
1
+ require 'MrMurano/Solution-ServiceConfig'
2
+
3
+ module MrMurano
4
+ class Postgresql < ServiceConfig
5
+ def initialize
6
+ super
7
+ @serviceName = 'postgresql'
8
+ end
9
+
10
+ def query(query)
11
+ call(:query, :post, {:sql=>query})
12
+ end
13
+ end
14
+ end
15
+
16
+ command :postgresql do |c|
17
+ c.syntax = %{mr postgresql <SQL Commands>}
18
+ c.summary = %{Query the relational database}
19
+
20
+ c.option '-o', '--output FILE', %{Download to file instead of STDOUT}
21
+
22
+ c.action do |args,options|
23
+ pg = MrMurano::Postgresql.new
24
+ ret = pg.query args.join(' ')
25
+
26
+ io=nil
27
+ if options.output then
28
+ io = File.open(options.output, 'w')
29
+ end
30
+
31
+ pg.outf(ret, io) do |dd, ios|
32
+ pg.tabularize({
33
+ :headers=>dd[:columns],
34
+ :rows=>dd[:rows]
35
+ }, ios)
36
+ end
37
+ io.close unless io.nil?
38
+
39
+ end
40
+ end
41
+ # vim: set ai et sw=2 ts=2 :
@@ -64,4 +64,20 @@ command 'product device twee' do |c|
64
64
  end
65
65
  end
66
66
 
67
+ command 'product device delete' do |c|
68
+ c.syntax = %{mr product device delete <identifier>}
69
+ c.summary = %{Delete a device}
70
+
71
+ c.action do |args,options|
72
+ snid = args.shift
73
+ prd = MrMurano::Product1PDevice.new
74
+
75
+ ret = prd.remove(snid)
76
+ prd.outf ret unless ret.empty?
77
+ end
78
+ end
79
+
80
+ # XXX cannot call this here, since 'sn list' doesn't exist yet.
81
+ #alias_command 'product device list', 'sn list'
82
+
67
83
  # vim: set ai et sw=2 ts=2 :
@@ -1,20 +1,8 @@
1
1
  require 'MrMurano/Product'
2
2
  require 'terminal-table'
3
3
 
4
- command :sn do |c|
5
- c.syntax = %{mr sn}
6
- c.summary = %{About Serial Numbers}
7
- c.description = %{The sn sub-commands allow for managing the identifiers (or Serial Numbers) on
8
- a product.}
9
-
10
- c.action do |args, options|
11
- ::Commander::UI.enable_paging
12
- say MrMurano::SubCmdGroupHelp.new(c).get_help
13
- end
14
- end
15
-
16
- command 'sn list' do |c|
17
- c.syntax = %{mr sn list [options]}
4
+ command 'product device list' do |c|
5
+ c.syntax = %{mr product device list [options]}
18
6
  c.summary = %{List serial numbers for a product}
19
7
 
20
8
  c.option '--offset NUMBER', Integer, %{Offset to start listing at}
@@ -31,8 +19,8 @@ command 'sn list' do |c|
31
19
  end
32
20
  end
33
21
 
34
- command 'sn enable' do |c|
35
- c.syntax = %{mr sn enable [<sn>|--file <sns>]}
22
+ command 'product device enable' do |c|
23
+ c.syntax = %{mr product device enable [<sn>|--file <sns>]}
36
24
  c.summary = %{Enable a serial number; Creates device in Murano}
37
25
  c.description = %{Enables serial numbers, creating the digial shadow in Murano.
38
26
 
@@ -58,8 +46,8 @@ the activation call within this time, it will need to be enabled again.
58
46
  end
59
47
  end
60
48
 
61
- command 'sn activate' do |c|
62
- c.syntax = %{mr sn activate <sn>}
49
+ command 'product device activate' do |c|
50
+ c.syntax = %{mr product device activate <sn>}
63
51
  c.summary = %{Activate a serial number, retriving its CIK}
64
52
  c.description = %{Activates a serial number.
65
53
 
@@ -83,4 +71,9 @@ CIK again.
83
71
 
84
72
  end
85
73
  end
74
+
75
+ alias_command 'sn list', 'product device list'
76
+ alias_command 'sn enable', 'product device enable'
77
+ alias_command 'sn activate', 'product device activate'
78
+
86
79
  # vim: set ai et sw=2 ts=2 :
@@ -1,5 +1,4 @@
1
1
  require 'MrMurano/Account'
2
- require 'terminal-table'
3
2
 
4
3
  command 'product list' do |c|
5
4
  c.syntax = %{mr product list [options]}
@@ -1,4 +1,5 @@
1
1
  require 'csv'
2
+ require 'MrMurano/Solution-ServiceConfig'
2
3
 
3
4
  module MrMurano
4
5
  class Timeseries < ServiceConfig
@@ -1,5 +1,6 @@
1
1
  require 'MrMurano/commands/account'
2
2
  require 'MrMurano/commands/assign'
3
+ require 'MrMurano/commands/businessList'
3
4
  require 'MrMurano/commands/config'
4
5
  require 'MrMurano/commands/content'
5
6
  require 'MrMurano/commands/cors'
@@ -8,14 +9,15 @@ require 'MrMurano/commands/exportImport'
8
9
  require 'MrMurano/commands/init'
9
10
  require 'MrMurano/commands/keystore'
10
11
  require 'MrMurano/commands/logs'
12
+ require 'MrMurano/commands/postgresql'
11
13
  require 'MrMurano/commands/product'
12
14
  require 'MrMurano/commands/productCreate'
13
15
  require 'MrMurano/commands/productDelete'
14
16
  require 'MrMurano/commands/productDevice'
17
+ require 'MrMurano/commands/productDeviceIdCmds'
15
18
  require 'MrMurano/commands/productList'
16
19
  require 'MrMurano/commands/productSpec'
17
20
  require 'MrMurano/commands/productWrite'
18
- require 'MrMurano/commands/serialNumberCmds'
19
21
  require 'MrMurano/commands/solution'
20
22
  require 'MrMurano/commands/solutionCreate'
21
23
  require 'MrMurano/commands/solutionDelete'
@@ -1,4 +1,4 @@
1
1
  module MrMurano
2
- VERSION = '1.9.0'.freeze
2
+ VERSION = '1.10.0'.freeze
3
3
  end
4
4
 
@@ -9,9 +9,9 @@ RSpec.describe MrMurano::Passwords, "#pwd" do
9
9
  pwd = MrMurano::Passwords.new( tmpfile )
10
10
  pwd.save
11
11
 
12
- expect( FileTest.exists?(tmpfile) )
12
+ expect( FileTest.exist?(tmpfile) )
13
13
  ensure
14
- File.unlink(tmpfile) if File.exists? tmpfile
14
+ File.unlink(tmpfile) if File.exist? tmpfile
15
15
  end
16
16
  end
17
17
 
@@ -21,9 +21,9 @@ RSpec.describe MrMurano::Passwords, "#pwd" do
21
21
  pwd = MrMurano::Passwords.new( tmpfile )
22
22
  pwd.save
23
23
 
24
- expect( FileTest.exists?(tmpfile) )
24
+ expect( FileTest.exist?(tmpfile) )
25
25
  ensure
26
- File.unlink(tmpfile) if File.exists? tmpfile
26
+ File.unlink(tmpfile) if File.exist? tmpfile
27
27
  end
28
28
  end
29
29
 
@@ -118,6 +118,39 @@ this.is.a.host:
118
118
  end
119
119
  end
120
120
 
121
+ it "Uses ENV instead" do
122
+ Tempfile.open('test') do |tf|
123
+ tf << %{---
124
+ this.is.a.host:
125
+ user: password
126
+ }
127
+ tf.close
128
+
129
+ ENV['MR_PASSWORD'] = 'a test!'
130
+ pwd = MrMurano::Passwords.new( tf.path )
131
+ pwd.load
132
+ ps = pwd.get('this.is.a.host', 'user')
133
+ expect(ps).to eq('a test!')
134
+ ENV['MR_PASSWORD'] = nil
135
+ end
136
+ end
137
+
138
+ it "Uses ENV instead, even with empty file" do
139
+ Tempfile.open('test') do |tf|
140
+ tf.close
141
+
142
+ ENV['MR_PASSWORD'] = 'a test!'
143
+ pwd = MrMurano::Passwords.new( tf.path )
144
+ pwd.load
145
+ ps = pwd.get('this.is.a.host', 'user')
146
+ expect(ps).to eq('a test!')
147
+ ENV['MR_PASSWORD'] = nil
148
+
149
+ data = IO.read(tf.path)
150
+ expect(data).to eq('')
151
+
152
+ end
153
+ end
121
154
 
122
155
  end
123
156
 
@@ -9,9 +9,11 @@ RSpec.describe MrMurano::Config::ConfigFile do
9
9
  cf = MrMurano::Config::ConfigFile.new(:user, tmpfile)
10
10
  cf.write
11
11
 
12
- expect( FileTest.exist?(tmpfile) )
13
- expect(FileTest.world_readable?(tmpfile)).to be(nil)
14
- expect(FileTest.world_writable?(tmpfile)).to be(nil)
12
+ expect(FileTest.exist?(tmpfile))
13
+ unless Gem.win_platform? then
14
+ expect(FileTest.world_readable?(tmpfile)).to be(nil)
15
+ expect(FileTest.world_writable?(tmpfile)).to be(nil)
16
+ end
15
17
  ensure
16
18
  File.unlink(tmpfile) unless tmpfile.nil?
17
19
  end
@@ -70,7 +70,7 @@ RSpec.describe MrMurano::ProductContent, "#product_content" do
70
70
  size = FileTest.size('spec/fixtures/product_spec_files/lightbulb.yaml')
71
71
  stub_request(:post, @urlroot + "/testFor").
72
72
  with(headers: {'Authorization'=>'token TTTTTTTTTT',
73
- 'Content-Type'=>'text/yaml',
73
+ 'Content-Type'=>/text\/(x-)?yaml/,
74
74
  'Content-Length' => size
75
75
  }).
76
76
  to_return(status: 205)
@@ -119,7 +119,7 @@ RSpec.describe MrMurano::Cors do
119
119
  tio.close
120
120
 
121
121
  ret = @srv.localitems(tio.path)
122
- expect(ret).to eq([cors.merge({:id=>'cors'})])
122
+ expect(ret).to eq([cors.merge({:id=>'cors', :local_path=>Pathname.new(tio.path)})])
123
123
  end
124
124
  end
125
125
 
@@ -1,51 +1,88 @@
1
- require 'tmpdir'
2
- require 'open3'
3
1
  require 'fileutils'
2
+ require 'open3'
3
+ require 'pathname'
4
+ require 'shellwords'
5
+ require 'tmpdir'
4
6
 
5
7
  RSpec.describe 'mr config' do
6
8
 
7
- pref = "ruby -Ilib bin/"
9
+ def capcmd(*args)
10
+ args = [args] unless args.kind_of? Array
11
+ args.flatten!
12
+ args[0] = @testdir + 'bin' + args[0]
13
+ args.unshift("ruby", "-I#{(@testdir+'lib').to_s}")
14
+ cmd = Shellwords.join(args)
15
+ #pp cmd
16
+ cmd
17
+ end
18
+
8
19
  around(:example) do |ex|
9
- Dir.mktmpdir do |dir|
10
- @tmpdir = dir
11
- ex.run
20
+ @testdir = Pathname.new(Dir.pwd).realpath
21
+ Dir.mktmpdir do |hdir|
22
+ ENV['HOME'] = hdir
23
+ Dir.chdir(hdir) do
24
+ @tmpdir = File.join(hdir, 'project')
25
+ Dir.mkdir(@tmpdir)
26
+ Dir.chdir(@tmpdir) do
27
+ ex.run
28
+ end
29
+ end
12
30
  end
13
31
  end
14
32
 
15
33
  it "Needs a key" do
16
- out, err, status = Open3.capture3("#{pref}mr config")
34
+ out, err, status = Open3.capture3(capcmd('mr', "config"))
17
35
  expect(status).to eq(0)
18
36
  expect(out).to eq("\e[31mNeed a config key\e[0m\n")
19
37
  expect(err).to eq('')
20
38
  end
21
39
 
22
40
  it "Sets a key" do
23
- out, err, status = Open3.capture3("#{pref}mr config bob build")
41
+ out, err, status = Open3.capture3(capcmd(%w{mr config bob build}))
24
42
  expect(status).to eq(0)
25
43
  expect(out).to eq('')
26
44
  expect(err).to eq('')
45
+
46
+ afile = IO.read(File.join(@tmpdir, '.mrmuranorc'))
47
+ bfile = (@testdir + 'spec' + 'fixtures' + 'mrmuranorc_tool_bob').read
48
+ expect(afile).to eq(bfile)
27
49
  end
28
50
 
29
- it "Reads a key" do
30
- FileUtils.copy_file 'spec/fixtures/.mrmuranorc', File.join(@tmpdir, '.mrmuranorc'), :verbose => true
31
- out, err, status = Open3.capture3("#{pref}mr config --project doThisTest.bob")
51
+ it "Sets a user key" do
52
+ out, err, status = Open3.capture3(capcmd(%w{mr config bob build --user}))
32
53
  expect(status).to eq(0)
33
54
  expect(out).to eq('')
34
55
  expect(err).to eq('')
56
+
57
+ afile = IO.read(File.join(ENV['HOME'], '.mrmuranorc'))
58
+ bfile = (@testdir + 'spec' + 'fixtures' + 'mrmuranorc_tool_bob').read
59
+ expect(afile).to eq(bfile)
60
+ end
61
+
62
+ it "Reads a key" do
63
+ FileUtils.copy_file((@testdir+'spec'+'fixtures'+'.mrmuranorc').to_s,
64
+ File.join(@tmpdir, '.mrmuranorc'),
65
+ :verbose => true)
66
+ out, err, status = Open3.capture3(capcmd(%w{mr config --project doThisTest.bob}))
67
+ expect(status).to eq(0)
68
+ expect(out).to eq("build\n")
69
+ expect(err).to eq('')
35
70
  end
36
71
 
37
72
  it "Removes a key" do
38
73
  rcf = File.join(@tmpdir, '.mrmuranorc')
39
- FileUtils.copy_file 'spec/fixtures/.mrmuranorc', rcf, :verbose => true
40
- out, err, status = Open3.capture3(%{#{pref}mr config --project --unset doThisTest.bob})
74
+ FileUtils.copy_file((@testdir+'spec'+'fixtures'+'.mrmuranorc').to_s,
75
+ rcf, :verbose => true)
76
+ out, err, status = Open3.capture3(capcmd(%w{mr config --project --unset doThisTest.bob}))
41
77
  expect(status).to eq(0)
42
78
  expect(out).to eq('')
43
79
  expect(err).to eq('')
44
80
 
45
81
  afile = IO.read(rcf)
46
- bfile = IO.read('spec/fixtures/.mrmuranorc')
82
+ bfile = (@testdir + 'spec' + 'fixtures' + 'mrmuranorc_deleted_bob').read
47
83
  expect(afile).to eq(bfile)
48
84
  end
85
+
49
86
  end
50
87
 
51
88
  # vim: set ai et sw=2 ts=2 :
@@ -0,0 +1,52 @@
1
+ require 'fileutils'
2
+ require 'open3'
3
+ require 'pathname'
4
+ require 'shellwords'
5
+ require 'tmpdir'
6
+
7
+ RSpec.describe 'mr init' do
8
+
9
+ def capcmd(*args)
10
+ args = [args] unless args.kind_of? Array
11
+ args.flatten!
12
+ args[0] = @testdir + 'bin' + args[0]
13
+ args.unshift("ruby", "-I#{(@testdir+'lib').to_s}")
14
+ cmd = Shellwords.join(args)
15
+ #pp cmd
16
+ cmd
17
+ end
18
+
19
+ around(:example) do |ex|
20
+ @testdir = Pathname.new(Dir.pwd).realpath
21
+ Dir.mktmpdir do |hdir|
22
+ ENV['HOME'] = hdir
23
+ Dir.chdir(hdir) do
24
+ @tmpdir = File.join(hdir, 'project')
25
+ Dir.mkdir(@tmpdir)
26
+ Dir.chdir(@tmpdir) do
27
+ ex.run
28
+ end
29
+ end
30
+ end
31
+ end
32
+
33
+ it "Won't init in HOME (gracefully)" do
34
+ # this is in the project dir. Want to be in HOME
35
+ Dir.chdir(ENV['HOME']) do
36
+ out, err, status = Open3.capture3(capcmd('mr', 'init', '--trace'))
37
+ expect(out).to eq("")
38
+ expect(err).to eq("\e[31mCannot init a project in your HOME directory.\e[0m\n")
39
+ expect(status.exitstatus).to eq(2)
40
+ end
41
+ end
42
+
43
+ it "Asks to import if Solutionfile exists" do
44
+ FileUtils.touch('Solutionfile.json')
45
+ out, err, status = Open3.capture3(capcmd('mr', 'init', '--trace'), :stdin_data=>'y')
46
+ expect(out).to eq("A Solutionfile.json exists, Do you want exit and run `mr config import` instead? [yN]\n")
47
+ expect(err).to eq("")
48
+ expect(status.exitstatus).to eq(0)
49
+ end
50
+
51
+ end
52
+ # vim: set ai et sw=2 ts=2 :
@@ -0,0 +1,3 @@
1
+ [tool]
2
+ bob = build
3
+
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: MrMurano
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.9.0
4
+ version: 1.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Conrad Tadpol Tilstra
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-11-29 00:00:00.000000000 Z
11
+ date: 2016-12-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: commander
@@ -215,6 +215,7 @@ files:
215
215
  - lib/MrMurano/commands.rb
216
216
  - lib/MrMurano/commands/account.rb
217
217
  - lib/MrMurano/commands/assign.rb
218
+ - lib/MrMurano/commands/businessList.rb
218
219
  - lib/MrMurano/commands/completion.rb
219
220
  - lib/MrMurano/commands/config.rb
220
221
  - lib/MrMurano/commands/content.rb
@@ -224,14 +225,15 @@ files:
224
225
  - lib/MrMurano/commands/init.rb
225
226
  - lib/MrMurano/commands/keystore.rb
226
227
  - lib/MrMurano/commands/logs.rb
228
+ - lib/MrMurano/commands/postgresql.rb
227
229
  - lib/MrMurano/commands/product.rb
228
230
  - lib/MrMurano/commands/productCreate.rb
229
231
  - lib/MrMurano/commands/productDelete.rb
230
232
  - lib/MrMurano/commands/productDevice.rb
233
+ - lib/MrMurano/commands/productDeviceIdCmds.rb
231
234
  - lib/MrMurano/commands/productList.rb
232
235
  - lib/MrMurano/commands/productSpec.rb
233
236
  - lib/MrMurano/commands/productWrite.rb
234
- - lib/MrMurano/commands/serialNumberCmds.rb
235
237
  - lib/MrMurano/commands/solution.rb
236
238
  - lib/MrMurano/commands/solutionCreate.rb
237
239
  - lib/MrMurano/commands/solutionDelete.rb
@@ -264,16 +266,18 @@ files:
264
266
  - spec/Solution-ServiceModules_spec.rb
265
267
  - spec/SyncRoot_spec.rb
266
268
  - spec/cmd_config_spec.rb
269
+ - spec/cmd_init_spec.rb
267
270
  - spec/fixtures/.mrmuranorc
268
271
  - spec/fixtures/configfile
269
272
  - spec/fixtures/mrmuranorc_deleted_bob
273
+ - spec/fixtures/mrmuranorc_tool_bob
270
274
  - spec/fixtures/product_spec_files/example.exoline.spec.yaml
271
275
  - spec/fixtures/product_spec_files/example.murano.spec.yaml
272
276
  - spec/fixtures/product_spec_files/gwe.exoline.spec.yaml
273
277
  - spec/fixtures/product_spec_files/gwe.murano.spec.yaml
274
278
  - spec/fixtures/product_spec_files/lightbulb.yaml
275
279
  - spec/spec_helper.rb
276
- homepage: https://github.com/tadpol/MrMurano
280
+ homepage: https://github.com/exosite/MrMurano
277
281
  licenses:
278
282
  - MIT
279
283
  metadata: {}
@@ -315,9 +319,11 @@ test_files:
315
319
  - spec/Solution-ServiceModules_spec.rb
316
320
  - spec/SyncRoot_spec.rb
317
321
  - spec/cmd_config_spec.rb
322
+ - spec/cmd_init_spec.rb
318
323
  - spec/fixtures/.mrmuranorc
319
324
  - spec/fixtures/configfile
320
325
  - spec/fixtures/mrmuranorc_deleted_bob
326
+ - spec/fixtures/mrmuranorc_tool_bob
321
327
  - spec/fixtures/product_spec_files/example.exoline.spec.yaml
322
328
  - spec/fixtures/product_spec_files/example.murano.spec.yaml
323
329
  - spec/fixtures/product_spec_files/gwe.exoline.spec.yaml