MrMurano 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,194 @@
1
+ require 'pathname'
2
+ require 'inifile'
3
+ require 'pp'
4
+
5
+ module MrMurano
6
+ class Config
7
+ ConfigFile = Struct.new(:kind, :path, :data) do
8
+ def load()
9
+ return if kind == :internal
10
+ return if kind == :defaults
11
+ self[:path] = Pathname.new(path) unless path.kind_of? Pathname
12
+ self[:data] = IniFile.new(:filename=>path.to_s) if self[:data].nil?
13
+ self[:data].restore
14
+ end
15
+
16
+ def write()
17
+ return if kind == :internal
18
+ return if kind == :defaults
19
+ self[:path] = Pathname.new(path) unless path.kind_of? Pathname
20
+ self[:data] = IniFile.new(:filename=>path.to_s) if self[:data].nil?
21
+ self[:data].save
22
+ end
23
+ end
24
+
25
+ attr :paths
26
+
27
+ CFG_FILE_NAME = '.mrmuranorc'.freeze
28
+
29
+ def initialize
30
+ @paths = []
31
+ @paths << ConfigFile.new(:internal, nil, IniFile.new())
32
+ # :specified --config FILE goes here. (see load_specific)
33
+ prjfile = findProjectFile()
34
+ @paths << ConfigFile.new(:project, prjfile)
35
+ @paths << ConfigFile.new(:user, Pathname.new(Dir.home) + CFG_FILE_NAME)
36
+ @paths << ConfigFile.new(:system, Pathname.new('/etc') + CFG_FILE_NAME.sub(/^\./,''))
37
+ @paths << ConfigFile.new(:defaults, nil, IniFile.new())
38
+
39
+
40
+ set('tool.verbose', false, :defaults)
41
+ set('tool.dry', false, :defaults)
42
+
43
+ set('net.host', 'bizapi.hosted.exosite.io', :defaults)
44
+
45
+ set('location.base', prjfile.dirname, :defaults)
46
+ set('location.files', 'files', :defaults)
47
+ set('location.endpoints', 'endpoints', :defaults)
48
+ set('location.modules', 'modules', :defaults)
49
+ set('location.eventhandlers', 'eventhandlers', :defaults)
50
+ set('location.roles', 'roles.yaml', :defaults)
51
+ set('location.users', 'users.yaml', :defaults)
52
+
53
+ set('files.default_page', 'index.html', :defaults)
54
+
55
+ set('eventhandler.skiplist', 'websocket webservice', :defaults)
56
+
57
+ set('diff.cmd', 'diff -u', :defaults)
58
+ end
59
+
60
+ # Look at parent directories until HOME
61
+ # Stop at first.
62
+ def findProjectFile()
63
+ result=nil
64
+ home = Pathname.new(Dir.home)
65
+ pwd = Pathname.new(Dir.pwd)
66
+ return a if home == pwd
67
+ pwd.dirname.ascend do |i|
68
+ break if i == home
69
+ if (i + CFG_FILE_NAME).exist? then
70
+ result = i + CFG_FILE_NAME
71
+ break
72
+ end
73
+ end
74
+ # if nothing found, assume it will live in pwd.
75
+ result = Pathname.new(Dir.pwd) + CFG_FILE_NAME if result.nil?
76
+ return result
77
+ end
78
+
79
+ def load()
80
+ # - read/write config file in [Project, User, System] (all are optional)
81
+ @paths.each { |cfg| cfg.load }
82
+ end
83
+
84
+ def load_specific(file)
85
+ spc = ConfigFile.new(:specified, Pathname.new(file))
86
+ @paths.insert(1, spc)
87
+ end
88
+
89
+ # key is <section>.<key>
90
+ def get(key, scope=[:internal, :specified, :project, :user, :system, :defaults])
91
+ scope = [scope] unless scope.kind_of? Array
92
+ paths = @paths.select{|p| scope.include? p.kind}
93
+
94
+ section, ikey = key.split('.')
95
+ paths.each do |path|
96
+ if path.data.has_section?(section) then
97
+ sec = path.data[section]
98
+ return sec if ikey.nil?
99
+ if sec.has_key?(ikey) then
100
+ return sec[ikey]
101
+ end
102
+ end
103
+ end
104
+ return nil
105
+ end
106
+
107
+ def dump()
108
+ # have a fake, merge all into it, then dump it.
109
+ base = IniFile.new()
110
+ @paths.reverse.each do |ini|
111
+ base.merge! ini.data
112
+ end
113
+ base.to_s
114
+ end
115
+
116
+ def set(key, value, scope=:project)
117
+ section, ikey = key.split('.', 2)
118
+ raise "Invalid key" if section.nil?
119
+ if not section.nil? and ikey.nil? then
120
+ # If key isn't dotted, then assume the tool section.
121
+ ikey = section
122
+ section = 'tool'
123
+ end
124
+
125
+ paths = @paths.select{|p| scope == p.kind}
126
+ raise "Unknown scope" if paths.empty?
127
+ cfg = paths.first
128
+ data = cfg.data
129
+ tomod = data[section]
130
+ tomod[ikey] = value unless value.nil?
131
+ tomod.delete(ikey) if value.nil?
132
+ data[section] = tomod
133
+ cfg.write
134
+ end
135
+
136
+ # key is <section>.<key>
137
+ def [](key)
138
+ get(key)
139
+ end
140
+
141
+ # For setting internal, this-run-only values
142
+ def []=(key, value)
143
+ set(key, value, :internal)
144
+ end
145
+
146
+ end
147
+ end
148
+
149
+ command :config do |c|
150
+ c.syntax = %{mr config [options] <key> [<new value>]}
151
+ c.summary = %{Get and set options}
152
+ c.option '--system', 'Use only the system config file'
153
+ c.option '--user', 'Use only the config file in $HOME'
154
+ c.option '--project', 'Use only the config file in the project'
155
+ c.option '--specified', 'Use only the config file from the --config option.'
156
+ c.option '--unset', 'Remove key from config file.'
157
+ c.option '--dump', 'Dump the current combined view of the config'
158
+
159
+ c.action do |args, options|
160
+
161
+ if options.dump then
162
+ say $cfg.dump()
163
+ elsif args.count == 0 then
164
+ say_error "Need a config key"
165
+ elsif args.count == 1 and not options.unset then
166
+ options.defaults :system=>false, :user=>false, :project=>false, :specified=>false
167
+
168
+ # For read, if no scopes, than all. Otherwise just those specified
169
+ scopes = []
170
+ scopes << :system if options.system
171
+ scopes << :user if options.user
172
+ scopes << :project if options.project
173
+ scopes << :specified if options.specified
174
+ scopes = [:internal, :specified, :project, :user, :system, :defaults] if scopes.empty?
175
+
176
+ say $cfg.get(args[0], scopes)
177
+ else
178
+
179
+ options.defaults :system=>false, :user=>false, :project=>true, :specified=>false
180
+ # For write, if scope is specified, only write to that scope.
181
+ scope = :project
182
+ scope = :system if options.system
183
+ scope = :user if options.user
184
+ scope = :project if options.project
185
+ scope = :specified if options.specified
186
+
187
+ args[1] = nil if options.unset
188
+ $cfg.set(args[0], args[1], scope)
189
+ end
190
+ end
191
+
192
+ end
193
+
194
+ # vim: set ai et sw=2 ts=2 :
@@ -0,0 +1,18 @@
1
+
2
+ # from: http://www.any-where.de/blog/ruby-hash-convert-string-keys-to-symbols/
3
+ class Hash
4
+ #take keys of hash and transform those to a symbols
5
+ def self.transform_keys_to_symbols(value)
6
+ return value if not value.is_a?(Hash)
7
+ hash = value.inject({}){|memo,(k,v)| memo[k.to_sym] = Hash.transform_keys_to_symbols(v); memo}
8
+ return hash
9
+ end
10
+ #take keys of hash and transform those to strings
11
+ def self.transform_keys_to_strings(value)
12
+ return value if not value.is_a?(Hash)
13
+ hash = value.inject({}){|memo,(k,v)| memo[k.to_s] = Hash.transform_keys_to_strings(v); memo}
14
+ return hash
15
+ end
16
+ end
17
+
18
+ # vim: set ai et sw=2 ts=2 :
@@ -0,0 +1,43 @@
1
+ require 'pp'
2
+
3
+ # XXX This might not work as a command. May need to be a level deeper.
4
+ command :shelled do |c|
5
+ c.syntax = %{mr <?...> }
6
+ c.summary = %{Search the PATHs for a subcommand.}
7
+
8
+ c.action do |args, options|
9
+ # we are looking for a command in PATH that is longest match to args.
10
+ pp args
11
+ pp options.inspect
12
+
13
+ places = ENV['PATH'].split(':').map {|p| Pathname.new(p)}
14
+ pp places
15
+
16
+ exit 9
17
+ names = args
18
+ args = []
19
+ while names.count > 0
20
+ test = names.join('-')
21
+
22
+ places.each do |bindir|
23
+ if (bindir + test).exist? then
24
+ # Found it.
25
+ # TODO: setup ENV
26
+
27
+ options.each_pair do |opt,val|
28
+ # This could be so much smarter.
29
+ args.push "--#{opt}=#{val}"
30
+ end
31
+ exec (bindir+test).path, *args
32
+
33
+ end
34
+ end
35
+
36
+ args.push names.pop
37
+ end
38
+
39
+ end
40
+
41
+ end
42
+
43
+ # vim: set ai et sw=2 ts=2 :
@@ -0,0 +1,106 @@
1
+
2
+ command :status do |c|
3
+ c.syntax = %{mr status [options]}
4
+ c.description = %{Get the status of files}
5
+ c.option '--all', 'Check everything'
6
+ c.option '-s','--files', %{Static Files}
7
+ c.option '-a','--endpoints', %{Endpoints}
8
+ c.option '-m','--modules', %{Modules}
9
+ c.option '-e','--eventhandlers', %{Event Handlers}
10
+ c.option '--roles', %{Roles}
11
+ c.option '--users', %{Users}
12
+
13
+ c.option '--[no-]asdown', %{Report as if syncdown instead of syncup}
14
+ c.option '--[no-]diff', %{For modified items, show a diff}
15
+ c.option '--[no-]grouped', %{Group all adds, deletes, and mods together}
16
+ c.option '--[no-]showall', %{List unchanged as well}
17
+
18
+ c.action do |args,options|
19
+ options.default :delete=>true, :create=>true, :update=>true, :diff=>false, :grouped => true
20
+
21
+ if options.all then
22
+ options.files = true
23
+ options.endpoints = true
24
+ options.modules = true
25
+ options.roles = true
26
+ options.users = true
27
+ options.eventhandlers = true
28
+ end
29
+
30
+ def fmtr(item)
31
+ if item.has_key? :local_path then
32
+ item[:local_path].relative_path_from(Pathname.pwd()).to_s
33
+ else
34
+ item[:synckey]
35
+ end
36
+ end
37
+ def pretty(ret, options)
38
+ say "Adding:" if options.grouped
39
+ ret[:toadd].each{|item| say " + #{item[:pp_type]} #{fmtr(item)}"}
40
+ say "Deleteing:" if options.grouped
41
+ ret[:todel].each{|item| say " - #{item[:pp_type]} #{fmtr(item)}"}
42
+ say "Changing:" if options.grouped
43
+ ret[:tomod].each{|item|
44
+ say " M #{item[:pp_type]} #{fmtr(item)}"
45
+ say item[:diff] if options.diff
46
+ }
47
+ if options.showall then
48
+ say "Unchanged:" if options.grouped
49
+ ret[:unchg].each{|item| say " #{item[:pp_type]} #{fmtr(item)}"}
50
+ end
51
+ end
52
+
53
+ @grouped = {:toadd=>[],:todel=>[],:tomod=>[], :unchg=>[]}
54
+ def gmerge(ret, type, options)
55
+ if options.grouped then
56
+ [:toadd, :todel, :tomod, :unchg].each do |kind|
57
+ ret[kind].each{|item| item[:pp_type] = type; @grouped[kind] << item}
58
+ end
59
+ else
60
+ pretty(ret, options)
61
+ end
62
+ end
63
+
64
+ if options.endpoints then
65
+ sol = MrMurano::Endpoint.new
66
+ ret = sol.status($cfg['location.base'] + $cfg['location.endpoints'], options)
67
+ gmerge(ret, ' EP ', options)
68
+ end
69
+
70
+ if options.modules then
71
+ sol = MrMurano::Library.new
72
+ ret = sol.status( $cfg['location.base'] + $cfg['location.modules'], options)
73
+ gmerge(ret, 'MOD ', options)
74
+ end
75
+
76
+ if options.eventhandlers then
77
+ sol = MrMurano::EventHandler.new
78
+ ret = sol.status( $cfg['location.base'] + $cfg['location.eventhandlers'], options)
79
+ gmerge(ret, ' EH ', options)
80
+ end
81
+
82
+ if options.roles then
83
+ sol = MrMurano::Role.new
84
+ ret = sol.status( $cfg['location.base'] + $cfg['location.roles'], options)
85
+ gmerge(ret, 'ROLE', options)
86
+ end
87
+
88
+ if options.users then
89
+ sol = MrMurano::User.new
90
+ ret = sol.status( $cfg['location.base'] + $cfg['location.users'], options)
91
+ gmerge(ret, 'USER', options)
92
+ end
93
+
94
+ if options.files then
95
+ sol = MrMurano::File.new
96
+ ret = sol.status( $cfg['location.base'] + $cfg['location.files'], options)
97
+ gmerge(ret, 'FILE', options)
98
+ end
99
+
100
+ pretty(@grouped, options) if options.grouped
101
+ end
102
+ end
103
+
104
+ alias_command :diff, :status, '--diff', '--no-grouped'
105
+
106
+ # vim: set ai et sw=2 ts=2 :
@@ -0,0 +1,132 @@
1
+
2
+ command :syncdown do |c|
3
+ c.syntax = %{mr syncdown [options]}
4
+ c.description = %{Sync project down from Murano}
5
+ c.option '--all', 'Sync everything'
6
+ c.option '-s','--files', %{Sync Static Files}
7
+ c.option '-a','--endpoints', %{Sync Endpoints}
8
+ c.option '-m','--modules', %{Sync Modules}
9
+ c.option '-e','--eventhandlers', %{Sync Event Handlers}
10
+ c.option '--roles', %{Sync Roles}
11
+ c.option '--users', %{Sync Users}
12
+
13
+ c.option '--[no-]delete', %{Don't delete things from server}
14
+ c.option '--[no-]create', %{Don't create things on server}
15
+ c.option '--[no-]update', %{Don't update things on server}
16
+
17
+ c.example %{Make local be like what is on the server}, %{mr syncdown --all}
18
+ c.example %{Pull down new things, but don't delete or modify anything}, %{mr syncdown --all --no-delete --no-update}
19
+ c.example %{Only Pull new static files}, %{mr syncdown --files --no-delete --no-update}
20
+
21
+ c.action do |args,options|
22
+ options.default :delete=>true, :create=>true, :update=>true
23
+
24
+ if options.all then
25
+ options.files = true
26
+ options.endpoints = true
27
+ options.modules = true
28
+ options.roles = true
29
+ options.users = true
30
+ options.eventhandlers = true
31
+ end
32
+
33
+ if options.endpoints then
34
+ sol = MrMurano::Endpoint.new
35
+ sol.syncdown($cfg['location.base'] + $cfg['location.endpoints'], options)
36
+ end
37
+
38
+ if options.modules then
39
+ sol = MrMurano::Library.new
40
+ sol.syncdown( $cfg['location.base'] + $cfg['location.modules'], options)
41
+ end
42
+
43
+ if options.eventhandlers then
44
+ sol = MrMurano::EventHandler.new
45
+ sol.syncdown( $cfg['location.base'] + $cfg['location.eventhandlers'], options)
46
+ end
47
+
48
+ if options.roles then
49
+ sol = MrMurano::Role.new
50
+ sol.syncdown( $cfg['location.base'] + $cfg['location.roles'], options)
51
+ end
52
+
53
+ if options.users then
54
+ sol = MrMurano::User.new
55
+ sol.syncdown( $cfg['location.base'] + $cfg['location.users'], options)
56
+ end
57
+
58
+ if options.files then
59
+ sol = MrMurano::File.new
60
+ sol.syncdown( $cfg['location.base'] + $cfg['location.files'], options)
61
+ end
62
+
63
+ end
64
+ end
65
+ alias_command :pull, :syncdown, '--no-delete'
66
+
67
+ command :syncup do |c|
68
+ c.syntax = %{mr syncup [options]}
69
+ c.description = %{Sync project up into Murano}
70
+ c.option '--all', 'Sync everything'
71
+ c.option '-s','--files', %{Sync Static Files}
72
+ c.option '-a','--endpoints', %{Sync Endpoints}
73
+ c.option '-m','--modules', %{Sync Modules}
74
+ c.option '-e','--eventhandlers', %{Sync Event Handlers}
75
+ c.option '--roles', %{Sync Roles}
76
+ c.option '--users', %{Sync Users}
77
+
78
+ c.option '--[no-]delete', %{Don't delete things from server}
79
+ c.option '--[no-]create', %{Don't create things on server}
80
+ c.option '--[no-]update', %{Don't update things on server}
81
+
82
+ c.example %{Deploy project to server}, %{mr syncup --all}
83
+ c.example %{Update static files}, %{mr syncup --files}
84
+ c.example %{Only add or modify static files}, %{mr syncup --files --no-delete}
85
+
86
+ c.action do |args,options|
87
+ options.default :delete=>true, :create=>true, :update=>true
88
+
89
+ if options.all then
90
+ options.files = true
91
+ options.endpoints = true
92
+ options.modules = true
93
+ options.roles = true
94
+ options.users = true
95
+ options.eventhandlers = true
96
+ end
97
+
98
+ if options.endpoints then
99
+ sol = MrMurano::Endpoint.new
100
+ sol.syncup($cfg['location.base'] + $cfg['location.endpoints'], options)
101
+ end
102
+
103
+ if options.modules then
104
+ sol = MrMurano::Library.new
105
+ sol.syncup( $cfg['location.base'] + $cfg['location.modules'], options)
106
+ end
107
+
108
+ if options.eventhandlers then
109
+ sol = MrMurano::EventHandler.new
110
+ sol.syncup( $cfg['location.base'] + $cfg['location.eventhandlers'], options)
111
+ end
112
+
113
+ if options.roles then
114
+ sol = MrMurano::Role.new
115
+ sol.syncup( $cfg['location.base'] + $cfg['location.roles'], options)
116
+ end
117
+
118
+ if options.users then
119
+ sol = MrMurano::User.new
120
+ sol.syncup( $cfg['location.base'] + $cfg['location.users'], options)
121
+ end
122
+
123
+ if options.files then
124
+ sol = MrMurano::File.new
125
+ sol.syncup( $cfg['location.base'] + $cfg['location.files'], options)
126
+ end
127
+
128
+ end
129
+ end
130
+ alias_command :push, :syncup, '--no-delete'
131
+
132
+ # vim: set ai et sw=2 ts=2 :
@@ -0,0 +1,4 @@
1
+ module MrMurano
2
+ VERSION = '1.0.0'.freeze
3
+ end
4
+
data/lib/MrMurano.rb ADDED
@@ -0,0 +1,13 @@
1
+ require 'MrMurano/version'
2
+ require 'MrMurano/hash.rb'
3
+ require 'MrMurano/configFile'
4
+ require 'MrMurano/Account'
5
+ require 'MrMurano/Solution'
6
+ require 'MrMurano/Solution-Endpoint.rb'
7
+ require 'MrMurano/Solution-File.rb'
8
+ require 'MrMurano/Solution-Services.rb'
9
+ require 'MrMurano/Solution-Users.rb'
10
+ require 'MrMurano/Solution-ServiceConfig.rb'
11
+ require 'MrMurano/sync.rb'
12
+ require 'MrMurano/status.rb'
13
+ #require 'MrMurano/shelledCommand'
metadata ADDED
@@ -0,0 +1,166 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: MrMurano
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Michael Conrad Tadpol Tilstra
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-08-01 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: commander
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: 4.4.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: 4.4.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: inifile
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '3.0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '3.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: netrc
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: 0.11.0
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 0.11.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: http-form_data
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 1.0.1
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: 1.0.1
69
+ - !ruby/object:Gem::Dependency
70
+ name: bundler
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ~>
74
+ - !ruby/object:Gem::Version
75
+ version: 1.7.6
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ~>
81
+ - !ruby/object:Gem::Version
82
+ version: 1.7.6
83
+ - !ruby/object:Gem::Dependency
84
+ name: rspec
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ~>
88
+ - !ruby/object:Gem::Version
89
+ version: '3.2'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ~>
95
+ - !ruby/object:Gem::Version
96
+ version: '3.2'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rake
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - '>='
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ description: "Do more from the command line with Murano\n \n Push and pull data
112
+ from Murano.\n Get status on what things have changed.\n See a diff of the changes
113
+ before you push.\n "
114
+ email:
115
+ - tadpol@tadpol.org
116
+ executables:
117
+ - mr
118
+ extensions: []
119
+ extra_rdoc_files: []
120
+ files:
121
+ - .gitignore
122
+ - Gemfile
123
+ - MrMurano.gemspec
124
+ - README.markdown
125
+ - Rakefile
126
+ - TODO.taskpaper
127
+ - bin/mr
128
+ - lib/MrMurano.rb
129
+ - lib/MrMurano/Account.rb
130
+ - lib/MrMurano/Solution-Endpoint.rb
131
+ - lib/MrMurano/Solution-File.rb
132
+ - lib/MrMurano/Solution-ServiceConfig.rb
133
+ - lib/MrMurano/Solution-Services.rb
134
+ - lib/MrMurano/Solution-Users.rb
135
+ - lib/MrMurano/Solution.rb
136
+ - lib/MrMurano/configFile.rb
137
+ - lib/MrMurano/hash.rb
138
+ - lib/MrMurano/shelledCommand.rb
139
+ - lib/MrMurano/status.rb
140
+ - lib/MrMurano/sync.rb
141
+ - lib/MrMurano/version.rb
142
+ homepage: https://github.com/tadpol/MrMurano
143
+ licenses:
144
+ - MIT
145
+ metadata: {}
146
+ post_install_message:
147
+ rdoc_options: []
148
+ require_paths:
149
+ - lib
150
+ required_ruby_version: !ruby/object:Gem::Requirement
151
+ requirements:
152
+ - - '>='
153
+ - !ruby/object:Gem::Version
154
+ version: '0'
155
+ required_rubygems_version: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - '>='
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ requirements: []
161
+ rubyforge_project:
162
+ rubygems_version: 2.0.14.1
163
+ signing_key:
164
+ specification_version: 4
165
+ summary: Do more from the command line with Murano
166
+ test_files: []