MrMurano 1.0.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.
@@ -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: []