coral_core 0.2.30 → 0.4.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 +7 -0
- data/Gemfile +2 -8
- data/Gemfile.lock +15 -86
- data/Rakefile +1 -3
- data/VERSION +1 -1
- data/coral_core.gemspec +12 -102
- metadata +18 -239
- data/lib/coral/command/shell.rb +0 -140
- data/lib/coral/machine/fog.rb +0 -215
- data/lib/coral/network/default.rb +0 -26
- data/lib/coral/node/rackspace.rb +0 -23
- data/lib/coral_core/config/collection.rb +0 -57
- data/lib/coral_core/config/options.rb +0 -70
- data/lib/coral_core/config/project.rb +0 -225
- data/lib/coral_core/config.rb +0 -329
- data/lib/coral_core/core.rb +0 -58
- data/lib/coral_core/event/puppet_event.rb +0 -98
- data/lib/coral_core/event/regexp_event.rb +0 -55
- data/lib/coral_core/event.rb +0 -170
- data/lib/coral_core/mixin/config_collection.rb +0 -52
- data/lib/coral_core/mixin/config_ops.rb +0 -51
- data/lib/coral_core/mixin/config_options.rb +0 -38
- data/lib/coral_core/mixin/lookup.rb +0 -211
- data/lib/coral_core/mixin/macro/object_interface.rb +0 -292
- data/lib/coral_core/mixin/macro/plugin_interface.rb +0 -277
- data/lib/coral_core/mixin/settings.rb +0 -46
- data/lib/coral_core/mixin/sub_config.rb +0 -208
- data/lib/coral_core/mod/hash.rb +0 -29
- data/lib/coral_core/mod/hiera_backend.rb +0 -63
- data/lib/coral_core/plugin/command.rb +0 -95
- data/lib/coral_core/plugin/machine.rb +0 -152
- data/lib/coral_core/plugin/network.rb +0 -24
- data/lib/coral_core/plugin/node.rb +0 -184
- data/lib/coral_core/plugin.rb +0 -261
- data/lib/coral_core/plugin_base.rb +0 -147
- data/lib/coral_core/repository.rb +0 -553
- data/lib/coral_core/resource.rb +0 -243
- data/lib/coral_core/template/environment.rb +0 -72
- data/lib/coral_core/template/json.rb +0 -13
- data/lib/coral_core/template/wrapper.rb +0 -13
- data/lib/coral_core/template/yaml.rb +0 -13
- data/lib/coral_core/template.rb +0 -92
- data/lib/coral_core/util/cli.rb +0 -293
- data/lib/coral_core/util/data.rb +0 -389
- data/lib/coral_core/util/disk.rb +0 -105
- data/lib/coral_core/util/git.rb +0 -40
- data/lib/coral_core/util/interface.rb +0 -190
- data/lib/coral_core/util/process.rb +0 -43
- data/lib/coral_core/util/shell.rb +0 -183
- data/lib/coral_core.rb +0 -375
- data/locales/en.yml +0 -8
- data/spec/coral_core/interface_spec.rb +0 -489
- data/spec/coral_mock_input.rb +0 -29
- data/spec/coral_test_kernel.rb +0 -22
- data/spec/spec_helper.rb +0 -15
data/lib/coral_core/plugin.rb
DELETED
@@ -1,261 +0,0 @@
|
|
1
|
-
|
2
|
-
module Coral
|
3
|
-
module Plugin
|
4
|
-
|
5
|
-
#-----------------------------------------------------------------------------
|
6
|
-
# Plugin instances
|
7
|
-
|
8
|
-
@@load_info = {}
|
9
|
-
@@types = {}
|
10
|
-
@@plugins = {}
|
11
|
-
|
12
|
-
#---
|
13
|
-
|
14
|
-
@@gems = {}
|
15
|
-
@@core = nil
|
16
|
-
|
17
|
-
#---
|
18
|
-
|
19
|
-
def self.create_instance(type, provider, options = {})
|
20
|
-
type = type.to_sym
|
21
|
-
provider = provider.to_sym
|
22
|
-
|
23
|
-
return nil unless @@types.has_key?(type)
|
24
|
-
|
25
|
-
options = translate_type(type, options)
|
26
|
-
provider = options.delete(:provider).to_sym if options.has_key?(:provider)
|
27
|
-
info = @@load_info[type][provider] if Util::Data.exists?(@@load_info, [ type, provider ])
|
28
|
-
|
29
|
-
if info
|
30
|
-
options = translate(type, provider, options)
|
31
|
-
instance_name = "#{provider}_" + Coral.sha1(options)
|
32
|
-
|
33
|
-
@@plugins[type] = {} unless @@plugins.has_key?(type)
|
34
|
-
|
35
|
-
unless instance_name && @@plugins[type].has_key?(instance_name)
|
36
|
-
info[:instance_name] = instance_name
|
37
|
-
options[:meta] = info
|
38
|
-
|
39
|
-
plugin = Coral.class_const([ :coral, type, provider ]).new(type, provider, options)
|
40
|
-
|
41
|
-
@@plugins[type][instance_name] = plugin
|
42
|
-
end
|
43
|
-
|
44
|
-
return @@plugins[type][instance_name]
|
45
|
-
end
|
46
|
-
return nil
|
47
|
-
end
|
48
|
-
|
49
|
-
#---
|
50
|
-
|
51
|
-
def self.get_instance(type, name)
|
52
|
-
if @@plugins.has_key?(type)
|
53
|
-
@@plugins[type].each do |instance_name, plugin|
|
54
|
-
return plugin if plugin.name.to_s == name.to_s
|
55
|
-
end
|
56
|
-
end
|
57
|
-
return nil
|
58
|
-
end
|
59
|
-
|
60
|
-
#---
|
61
|
-
|
62
|
-
def self.remove_instance(plugin)
|
63
|
-
if plugin && plugin.is_a?(Plugin::Base) && @@plugins.has_key?(plugin.plugin_type)
|
64
|
-
@@plugins[plugin.plugin_type].delete(plugin.plugin_instance_name)
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
#-----------------------------------------------------------------------------
|
69
|
-
# Plugins and resources
|
70
|
-
|
71
|
-
def self.core
|
72
|
-
return @@core
|
73
|
-
end
|
74
|
-
|
75
|
-
#---
|
76
|
-
|
77
|
-
def self.register_gem(spec)
|
78
|
-
plugin_path = File.join(spec.full_gem_path, 'lib', 'coral')
|
79
|
-
if File.directory?(plugin_path)
|
80
|
-
@@gems[spec.name] = {
|
81
|
-
:lib_dir => plugin_path,
|
82
|
-
:spec => spec
|
83
|
-
}
|
84
|
-
if spec.name == 'coral_core'
|
85
|
-
@@core = spec
|
86
|
-
else
|
87
|
-
register(plugin_path) # Autoload plugins and related files
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
#---
|
93
|
-
|
94
|
-
def self.gems(reset = false)
|
95
|
-
if reset || Util::Data.empty?(@@gems)
|
96
|
-
if defined?(Gem)
|
97
|
-
if ! defined?(Bundler) && Gem::Specification.respond_to?(:latest_specs)
|
98
|
-
Gem::Specification.latest_specs(true).each do |spec|
|
99
|
-
register_gem(spec)
|
100
|
-
end
|
101
|
-
else
|
102
|
-
Gem.loaded_specs.each do |name, spec|
|
103
|
-
register_gem(spec)
|
104
|
-
end
|
105
|
-
end
|
106
|
-
end
|
107
|
-
end
|
108
|
-
return @@gems
|
109
|
-
end
|
110
|
-
|
111
|
-
#-----------------------------------------------------------------------------
|
112
|
-
|
113
|
-
def self.define_type(type_info)
|
114
|
-
if type_info.is_a?(Hash)
|
115
|
-
type_info.each do |type, default_provider|
|
116
|
-
@@types[type.to_sym] = default_provider
|
117
|
-
end
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
#---
|
122
|
-
|
123
|
-
def self.types
|
124
|
-
return @@types.keys
|
125
|
-
end
|
126
|
-
|
127
|
-
#---
|
128
|
-
|
129
|
-
def self.type_default(type)
|
130
|
-
return @@types[type.to_sym]
|
131
|
-
end
|
132
|
-
|
133
|
-
#---
|
134
|
-
|
135
|
-
def self.plugins(type = nil)
|
136
|
-
results = {}
|
137
|
-
|
138
|
-
if type
|
139
|
-
results[type] = @@plugins[type] if @@plugins.has_key?(type)
|
140
|
-
else
|
141
|
-
results = @@plugins
|
142
|
-
end
|
143
|
-
return results
|
144
|
-
end
|
145
|
-
|
146
|
-
#---
|
147
|
-
|
148
|
-
def self.add_build_info(type, file)
|
149
|
-
type = type.to_sym
|
150
|
-
|
151
|
-
@@load_info[type] = {} unless @@load_info.has_key?(type)
|
152
|
-
|
153
|
-
components = file.split(File::SEPARATOR)
|
154
|
-
provider = components.pop.sub(/\.rb/, '').to_sym
|
155
|
-
directory = components.join(File::SEPARATOR)
|
156
|
-
|
157
|
-
puts 'Loading ' + type.to_s + ' plugin: ' + provider.to_s
|
158
|
-
|
159
|
-
unless @@load_info[type].has_key?(provider)
|
160
|
-
data = {
|
161
|
-
:type => type,
|
162
|
-
:provider => provider,
|
163
|
-
:directory => directory,
|
164
|
-
:file => file
|
165
|
-
}
|
166
|
-
@@load_info[type][provider] = data
|
167
|
-
end
|
168
|
-
end
|
169
|
-
|
170
|
-
#-----------------------------------------------------------------------------
|
171
|
-
# Plugin autoloading
|
172
|
-
|
173
|
-
def self.register_type(base_path, plugin_type)
|
174
|
-
base_directory = File.join(base_path, plugin_type.to_s)
|
175
|
-
|
176
|
-
if File.directory?(base_directory)
|
177
|
-
Dir.glob(File.join(base_directory, '*.rb')).each do |file|
|
178
|
-
add_build_info(plugin_type, file)
|
179
|
-
end
|
180
|
-
end
|
181
|
-
end
|
182
|
-
|
183
|
-
#---
|
184
|
-
|
185
|
-
def self.register(base_path)
|
186
|
-
if File.directory?(base_path)
|
187
|
-
Dir.glob(File.join(base_path, '*.rb')).each do |file|
|
188
|
-
require file
|
189
|
-
end
|
190
|
-
|
191
|
-
Dir.entries(base_path).each do |path|
|
192
|
-
unless path.match(/^\.\.?$/)
|
193
|
-
register_type(base_path, path)
|
194
|
-
end
|
195
|
-
end
|
196
|
-
end
|
197
|
-
end
|
198
|
-
|
199
|
-
#---
|
200
|
-
|
201
|
-
def self.autoload
|
202
|
-
@@load_info.keys.each do |type|
|
203
|
-
@@load_info[type].each do |provider, plugin|
|
204
|
-
coral_require(plugin[:directory], provider)
|
205
|
-
end
|
206
|
-
end
|
207
|
-
end
|
208
|
-
|
209
|
-
#---
|
210
|
-
|
211
|
-
@@initialized = false
|
212
|
-
|
213
|
-
#---
|
214
|
-
|
215
|
-
def self.initialize
|
216
|
-
unless @@initialized
|
217
|
-
# Register core plugins
|
218
|
-
register(File.join(File.dirname(__FILE__), '..', 'coral'))
|
219
|
-
|
220
|
-
# Register external Gem defined plugins
|
221
|
-
gems(true)
|
222
|
-
|
223
|
-
# Autoload the registered plugins
|
224
|
-
autoload
|
225
|
-
|
226
|
-
@@initialized = true
|
227
|
-
end
|
228
|
-
end
|
229
|
-
|
230
|
-
#---
|
231
|
-
|
232
|
-
def self.initialized?
|
233
|
-
return @@initialized
|
234
|
-
end
|
235
|
-
|
236
|
-
#-----------------------------------------------------------------------------
|
237
|
-
# Utilities
|
238
|
-
|
239
|
-
def self.translate_type(type, info, method = :translate)
|
240
|
-
klass = Coral.class_const([ :coral, :plugin, type ])
|
241
|
-
info = klass.send(method, info) if klass.respond_to?(method)
|
242
|
-
return info
|
243
|
-
end
|
244
|
-
|
245
|
-
#---
|
246
|
-
|
247
|
-
def self.translate(type, provider, info, method = :translate)
|
248
|
-
klass = Coral.class_const([ :coral, type, provider ])
|
249
|
-
info = klass.send(method, info) if klass.respond_to?(method)
|
250
|
-
return info
|
251
|
-
end
|
252
|
-
|
253
|
-
#-----------------------------------------------------------------------------
|
254
|
-
# Core plugin types
|
255
|
-
|
256
|
-
define_type :network => :default,
|
257
|
-
:node => :rackspace,
|
258
|
-
:machine => :fog,
|
259
|
-
:command => :shell
|
260
|
-
end
|
261
|
-
end
|
@@ -1,147 +0,0 @@
|
|
1
|
-
|
2
|
-
module Coral
|
3
|
-
module Plugin
|
4
|
-
class Base < Core
|
5
|
-
# All Plugin classes should directly or indirectly extend Base
|
6
|
-
|
7
|
-
def initialize(type, provider, options)
|
8
|
-
config = Config.ensure(options)
|
9
|
-
name = Util::Data.ensure_value(config.delete(:name), provider)
|
10
|
-
|
11
|
-
set_meta(config.delete(:meta, Config.new))
|
12
|
-
|
13
|
-
super(config)
|
14
|
-
|
15
|
-
self.name = name
|
16
|
-
|
17
|
-
normalize
|
18
|
-
end
|
19
|
-
|
20
|
-
#---
|
21
|
-
|
22
|
-
def initialized?(options = {})
|
23
|
-
return true
|
24
|
-
end
|
25
|
-
|
26
|
-
#---
|
27
|
-
|
28
|
-
def method_missing(method, *args, &block)
|
29
|
-
return nil
|
30
|
-
end
|
31
|
-
|
32
|
-
#-----------------------------------------------------------------------------
|
33
|
-
# Property accessor / modifiers
|
34
|
-
|
35
|
-
def name
|
36
|
-
return get(:name)
|
37
|
-
end
|
38
|
-
|
39
|
-
#---
|
40
|
-
|
41
|
-
def name=name
|
42
|
-
set(:name, string(name))
|
43
|
-
end
|
44
|
-
|
45
|
-
#---
|
46
|
-
|
47
|
-
def meta
|
48
|
-
return @meta
|
49
|
-
end
|
50
|
-
|
51
|
-
#---
|
52
|
-
|
53
|
-
def set_meta(meta)
|
54
|
-
@meta = Config.ensure(meta)
|
55
|
-
end
|
56
|
-
|
57
|
-
#---
|
58
|
-
|
59
|
-
def plugin_type
|
60
|
-
return meta.get(:type)
|
61
|
-
end
|
62
|
-
|
63
|
-
#---
|
64
|
-
|
65
|
-
def plugin_provider
|
66
|
-
return meta.get(:provider)
|
67
|
-
end
|
68
|
-
|
69
|
-
#---
|
70
|
-
|
71
|
-
def plugin_directory
|
72
|
-
return meta.get(:directory)
|
73
|
-
end
|
74
|
-
|
75
|
-
#---
|
76
|
-
|
77
|
-
def plugin_file
|
78
|
-
return meta.get(:file)
|
79
|
-
end
|
80
|
-
|
81
|
-
#---
|
82
|
-
|
83
|
-
def plugin_instance_name
|
84
|
-
return meta.get(:instance_name)
|
85
|
-
end
|
86
|
-
|
87
|
-
#---
|
88
|
-
|
89
|
-
def plugin_parent=parent
|
90
|
-
meta.set(:parent, parent) if parent.is_a?(Coral::Plugin::Base)
|
91
|
-
end
|
92
|
-
|
93
|
-
#---
|
94
|
-
|
95
|
-
def plugin_parent
|
96
|
-
return meta.get(:parent)
|
97
|
-
end
|
98
|
-
|
99
|
-
#-----------------------------------------------------------------------------
|
100
|
-
# Plugin operations
|
101
|
-
|
102
|
-
def normalize
|
103
|
-
end
|
104
|
-
|
105
|
-
#-----------------------------------------------------------------------------
|
106
|
-
# Utilities
|
107
|
-
|
108
|
-
def self.build_info(type, data)
|
109
|
-
plugins = []
|
110
|
-
|
111
|
-
if data.is_a?(Hash)
|
112
|
-
data = [ data ]
|
113
|
-
end
|
114
|
-
|
115
|
-
if data.is_a?(Array)
|
116
|
-
data.each do |info|
|
117
|
-
unless Util::Data.empty?(info)
|
118
|
-
info = translate(info)
|
119
|
-
|
120
|
-
if Util::Data.empty?(info[:provider])
|
121
|
-
info[:provider] = Plugin.type_default(type)
|
122
|
-
end
|
123
|
-
|
124
|
-
plugins << info
|
125
|
-
end
|
126
|
-
end
|
127
|
-
end
|
128
|
-
return plugins
|
129
|
-
end
|
130
|
-
|
131
|
-
#---
|
132
|
-
|
133
|
-
def self.translate(data)
|
134
|
-
return ( data.is_a?(Hash) ? symbol_map(data) : {} )
|
135
|
-
end
|
136
|
-
|
137
|
-
#---
|
138
|
-
|
139
|
-
def self.ensure_plugin_collection
|
140
|
-
include Mixin::Settings
|
141
|
-
include Mixin::SubConfig
|
142
|
-
|
143
|
-
extend Mixin::Macro::PluginInterface
|
144
|
-
end
|
145
|
-
end
|
146
|
-
end
|
147
|
-
end
|
@@ -1,553 +0,0 @@
|
|
1
|
-
module Coral
|
2
|
-
class Repository < Core
|
3
|
-
|
4
|
-
@@repositories = {}
|
5
|
-
|
6
|
-
#---
|
7
|
-
|
8
|
-
def self.collection
|
9
|
-
return @@repositories
|
10
|
-
end
|
11
|
-
|
12
|
-
#-----------------------------------------------------------------------------
|
13
|
-
# Constructor / Destructor
|
14
|
-
|
15
|
-
def self.init(directory, url, revision, options = {})
|
16
|
-
config = Config.ensure(options)
|
17
|
-
|
18
|
-
return new(config.import({
|
19
|
-
:directory => directory,
|
20
|
-
:origin => url,
|
21
|
-
:revision => revision
|
22
|
-
}))
|
23
|
-
end
|
24
|
-
|
25
|
-
#---
|
26
|
-
|
27
|
-
def self.open(directory, options = {})
|
28
|
-
config = Config.ensure(options)
|
29
|
-
|
30
|
-
directory = Util::Disk.filename(directory)
|
31
|
-
|
32
|
-
if ! @@repositories.has_key?(directory) || config.get(:reset, false)
|
33
|
-
return new(config.import({
|
34
|
-
:directory => directory
|
35
|
-
}))
|
36
|
-
end
|
37
|
-
return @@repositories[directory]
|
38
|
-
end
|
39
|
-
|
40
|
-
#-----------------------------------------------------------------------------
|
41
|
-
|
42
|
-
def initialize(options = {})
|
43
|
-
config = Config.ensure(options)
|
44
|
-
|
45
|
-
super(config)
|
46
|
-
|
47
|
-
set_location(config.get(:directory, Dir.pwd))
|
48
|
-
|
49
|
-
@cloud = config.get(:object_container, nil)
|
50
|
-
@remote_path = config.get(:remote_path, nil)
|
51
|
-
|
52
|
-
@origin = config.get(:origin, nil)
|
53
|
-
@revision = config.get(:revision, nil)
|
54
|
-
|
55
|
-
set_origin(@origin) unless @origin.nil?
|
56
|
-
checkout(@revision) unless @revision.nil?
|
57
|
-
|
58
|
-
pull if config.get(:pull, false)
|
59
|
-
end
|
60
|
-
|
61
|
-
#---
|
62
|
-
|
63
|
-
def inspect
|
64
|
-
"#<#{self.class}: #{directory} : #{@origin} : #{@revision}>"
|
65
|
-
end
|
66
|
-
|
67
|
-
#-----------------------------------------------------------------------------
|
68
|
-
# Location information
|
69
|
-
|
70
|
-
def self.git_dir(path, require_top_level = false)
|
71
|
-
path = File.expand_path(path)
|
72
|
-
git_dir = File.join(path, '.git')
|
73
|
-
|
74
|
-
if File.exist?(git_dir)
|
75
|
-
if File.directory?(git_dir)
|
76
|
-
return git_dir
|
77
|
-
elsif ! require_top_level
|
78
|
-
git_dir = Util::Disk.read(git_dir)
|
79
|
-
unless git_dir.nil?
|
80
|
-
git_dir = git_dir.gsub(/^gitdir\:\s*/, '').strip
|
81
|
-
return git_dir if File.directory?(git_dir)
|
82
|
-
end
|
83
|
-
end
|
84
|
-
elsif File.exist?(path) && (path =~ /\.git$/ && File.exist?(File.join(path, 'HEAD')))
|
85
|
-
return path
|
86
|
-
end
|
87
|
-
return nil
|
88
|
-
end
|
89
|
-
|
90
|
-
#-----------------------------------------------------------------------------
|
91
|
-
# URLs
|
92
|
-
|
93
|
-
def self.url(host, repo, options = {})
|
94
|
-
config = Config.ensure(options)
|
95
|
-
|
96
|
-
user = config.get(:user, 'git')
|
97
|
-
auth = config.get(:auth, true)
|
98
|
-
return user + (auth ? '@' : '://') + host + (auth ? ':' : '/') + repo
|
99
|
-
end
|
100
|
-
|
101
|
-
#---
|
102
|
-
|
103
|
-
def self.edit_url(url, options = {})
|
104
|
-
config = Config.ensure(options)
|
105
|
-
|
106
|
-
if matches = url.strip.match(/^(https?|git)\:\/\/([^\/]+)\/(.+)/)
|
107
|
-
host, path = matches.captures
|
108
|
-
return url(host, path, config.import({ :auth => true }))
|
109
|
-
end
|
110
|
-
return url
|
111
|
-
end
|
112
|
-
|
113
|
-
#-----------------------------------------------------------------------------
|
114
|
-
# Checks
|
115
|
-
|
116
|
-
def ensure_git(reset = false)
|
117
|
-
if reset || ! @git_lib
|
118
|
-
@git_lib = nil
|
119
|
-
unless directory.empty?
|
120
|
-
@git_lib = Git.new(directory)
|
121
|
-
end
|
122
|
-
end
|
123
|
-
return self
|
124
|
-
end
|
125
|
-
protected :ensure_git
|
126
|
-
|
127
|
-
#---
|
128
|
-
|
129
|
-
def can_persist?
|
130
|
-
ensure_git
|
131
|
-
return true if @git_lib
|
132
|
-
return false
|
133
|
-
end
|
134
|
-
|
135
|
-
#---
|
136
|
-
|
137
|
-
def self.top?(path)
|
138
|
-
git_dir = File.join(path, '.git')
|
139
|
-
if File.exist?(git_dir)
|
140
|
-
return true if File.directory?(git_dir)
|
141
|
-
elsif File.exist?(path) && (path =~ /\.git$/ && File.exist?(File.join(path, 'HEAD')))
|
142
|
-
return true
|
143
|
-
end
|
144
|
-
return false
|
145
|
-
end
|
146
|
-
|
147
|
-
#---
|
148
|
-
|
149
|
-
def top?
|
150
|
-
return self.class.top?(directory)
|
151
|
-
end
|
152
|
-
|
153
|
-
#---
|
154
|
-
|
155
|
-
def self.submodule?(path)
|
156
|
-
git_dir = File.join(path, '.git')
|
157
|
-
if File.exist?(git_dir)
|
158
|
-
unless File.directory?(git_dir)
|
159
|
-
git_dir = Util::Disk.read(git_dir)
|
160
|
-
unless git_dir.nil?
|
161
|
-
git_dir = git_dir.gsub(/^gitdir\:\s*/, '').strip
|
162
|
-
return true if File.directory?(git_dir)
|
163
|
-
end
|
164
|
-
end
|
165
|
-
end
|
166
|
-
return false
|
167
|
-
end
|
168
|
-
|
169
|
-
#---
|
170
|
-
|
171
|
-
def submodule?
|
172
|
-
return self.class.submodule?(directory)
|
173
|
-
end
|
174
|
-
|
175
|
-
#-----------------------------------------------------------------------------
|
176
|
-
# Property accessors / modifiers
|
177
|
-
|
178
|
-
attr_reader :directory
|
179
|
-
|
180
|
-
#---
|
181
|
-
|
182
|
-
def path
|
183
|
-
if parent.nil?
|
184
|
-
return directory
|
185
|
-
end
|
186
|
-
return directory.gsub(parent.directory + File::SEPARATOR, '')
|
187
|
-
end
|
188
|
-
|
189
|
-
#---
|
190
|
-
|
191
|
-
def git
|
192
|
-
return @git_lib.git if can_persist?
|
193
|
-
return nil
|
194
|
-
end
|
195
|
-
protected :git
|
196
|
-
|
197
|
-
#---
|
198
|
-
|
199
|
-
def config(name, options = {})
|
200
|
-
config = Config.ensure(options) # Just in case we throw a configuration in
|
201
|
-
return git.config(config.export, name) if can_persist?
|
202
|
-
return nil
|
203
|
-
end
|
204
|
-
|
205
|
-
#---
|
206
|
-
|
207
|
-
def set_config(name, value, options = {})
|
208
|
-
config = Config.ensure(options) # Just in case we throw a configuration in
|
209
|
-
git.config(config.export, name, string(value)) if can_persist?
|
210
|
-
return self
|
211
|
-
end
|
212
|
-
|
213
|
-
#---
|
214
|
-
|
215
|
-
def delete_config(name, options = {})
|
216
|
-
config = Config.ensure(options)
|
217
|
-
git.config(config.import({ :remove_section => true }).options, name) if can_persist?
|
218
|
-
return self
|
219
|
-
end
|
220
|
-
|
221
|
-
#---
|
222
|
-
|
223
|
-
def set_location(directory)
|
224
|
-
@@repositories.delete(@directory) if @directory
|
225
|
-
|
226
|
-
if Util::Data.empty?(directory)
|
227
|
-
@directory = Dir.pwd
|
228
|
-
else
|
229
|
-
@directory = Util::Disk.filename(directory)
|
230
|
-
end
|
231
|
-
|
232
|
-
@@repositories[@directory] = self
|
233
|
-
|
234
|
-
ensure_git(true)
|
235
|
-
|
236
|
-
init_parent
|
237
|
-
init_remotes
|
238
|
-
load_revision
|
239
|
-
return self
|
240
|
-
end
|
241
|
-
|
242
|
-
#-----------------------------------------------------------------------------
|
243
|
-
# Basic Git operations
|
244
|
-
|
245
|
-
attr_reader :parent, :revision
|
246
|
-
|
247
|
-
#---
|
248
|
-
|
249
|
-
def init_parent
|
250
|
-
@parent = nil
|
251
|
-
|
252
|
-
unless top?
|
253
|
-
search_dir = directory
|
254
|
-
|
255
|
-
while File.directory?((search_dir = File.expand_path('..', search_dir)))
|
256
|
-
if self.class.git_dir(search_dir)
|
257
|
-
@parent = self.class.open(search_dir)
|
258
|
-
break;
|
259
|
-
end
|
260
|
-
end
|
261
|
-
end
|
262
|
-
return self
|
263
|
-
end
|
264
|
-
protected :init_parent
|
265
|
-
|
266
|
-
#---
|
267
|
-
|
268
|
-
def load_revision
|
269
|
-
if can_persist?
|
270
|
-
@revision = git.native(:rev_parse, { :abbrev_ref => true }, 'HEAD').strip
|
271
|
-
|
272
|
-
if @revision.empty?
|
273
|
-
@revision = git.native(:rev_parse, {}, 'HEAD').strip
|
274
|
-
end
|
275
|
-
load_submodules
|
276
|
-
end
|
277
|
-
return self
|
278
|
-
end
|
279
|
-
protected :load_revision
|
280
|
-
|
281
|
-
#---
|
282
|
-
|
283
|
-
def checkout(revision)
|
284
|
-
if can_persist?
|
285
|
-
revision = revision.strip
|
286
|
-
|
287
|
-
git.checkout({}, revision) unless @git_lib.bare
|
288
|
-
@revision = revision
|
289
|
-
load_submodules
|
290
|
-
end
|
291
|
-
return self
|
292
|
-
end
|
293
|
-
|
294
|
-
#---
|
295
|
-
|
296
|
-
def commit(files = '.', options = {})
|
297
|
-
config = Config.ensure(options)
|
298
|
-
|
299
|
-
if can_persist?
|
300
|
-
time = Time.new.strftime("%Y-%m-%d %H:%M:%S")
|
301
|
-
user = ENV['USER']
|
302
|
-
message = config.get(:message, 'Saving state')
|
303
|
-
|
304
|
-
user = 'UNKNOWN' unless user && ! user.empty?
|
305
|
-
|
306
|
-
git.reset({}, 'HEAD') # Clear the index so we get a clean commit
|
307
|
-
|
308
|
-
files = array(files)
|
309
|
-
git.add(files) # Get all added and updated files
|
310
|
-
git.add({ :update => true }, files) # Get all deleted files
|
311
|
-
|
312
|
-
git.commit({
|
313
|
-
:m => "#{time} by <#{user}> - #{message}",
|
314
|
-
:author => config.get(:author, false),
|
315
|
-
:allow_empty => config.get(:allow_empty, false)
|
316
|
-
})
|
317
|
-
|
318
|
-
if ! parent.nil? && config.get(:propogate, true)
|
319
|
-
parent.commit(directory, config.import({
|
320
|
-
:message => "Updating submodule #{path} with: #{message}"
|
321
|
-
}))
|
322
|
-
end
|
323
|
-
end
|
324
|
-
return self
|
325
|
-
end
|
326
|
-
|
327
|
-
#-----------------------------------------------------------------------------
|
328
|
-
# Submodule operations
|
329
|
-
|
330
|
-
attr_reader :submodules
|
331
|
-
|
332
|
-
#---
|
333
|
-
|
334
|
-
def load_submodules
|
335
|
-
@submodules = {}
|
336
|
-
|
337
|
-
if can_persist?
|
338
|
-
# Returns a Hash of { <path:String> => { 'url' => <url:String>, 'id' => <id:String> } }
|
339
|
-
# Returns {} if no .gitmodules file was found
|
340
|
-
Grit::Submodule.config(@git_lib, revision).each do |path, data|
|
341
|
-
repo = self.class.open(File.join(directory, path))
|
342
|
-
repo.set_origin(data['url']) # Just a sanity check (might disapear)
|
343
|
-
|
344
|
-
@submodules[path] = repo
|
345
|
-
end
|
346
|
-
end
|
347
|
-
return self
|
348
|
-
end
|
349
|
-
protected :load_submodules
|
350
|
-
|
351
|
-
#---
|
352
|
-
|
353
|
-
def add_submodule(path, url, revision, options = {})
|
354
|
-
if can_persist?
|
355
|
-
git.submodule({ :branch => revision }, 'add', url, path)
|
356
|
-
commit([ '.gitmodules', path ], { :message => "Adding submodule #{url} to #{path}" })
|
357
|
-
load_submodules
|
358
|
-
end
|
359
|
-
end
|
360
|
-
|
361
|
-
#---
|
362
|
-
|
363
|
-
def delete_submodule(path)
|
364
|
-
if can_persist?
|
365
|
-
submodule_key = "submodule.#{path}"
|
366
|
-
|
367
|
-
delete_config(submodule_key)
|
368
|
-
delete_config(submodule_key, { :file => '.gitmodules' })
|
369
|
-
|
370
|
-
git.rm({ :cached => true }, path)
|
371
|
-
FileUtils.rm_rf(File.join(directory, path))
|
372
|
-
FileUtils.rm_rf(File.join(git.git_dir, 'modules', path))
|
373
|
-
|
374
|
-
commit([ '.gitmodules', path ], { :message => "Removing submodule #{url} from #{path}" })
|
375
|
-
load_submodules
|
376
|
-
end
|
377
|
-
end
|
378
|
-
|
379
|
-
#---
|
380
|
-
|
381
|
-
def update_submodules
|
382
|
-
git.submodule({ :init => true, :recursive => true }, 'update') if can_persist?
|
383
|
-
return self
|
384
|
-
end
|
385
|
-
protected :update_submodules
|
386
|
-
|
387
|
-
#---
|
388
|
-
|
389
|
-
def foreach!
|
390
|
-
if can_persist?
|
391
|
-
submodules.each do |path, repo|
|
392
|
-
yield(path, repo)
|
393
|
-
end
|
394
|
-
end
|
395
|
-
return self
|
396
|
-
end
|
397
|
-
|
398
|
-
#-----------------------------------------------------------------------------
|
399
|
-
# Remote operations
|
400
|
-
|
401
|
-
attr_reader :origin, :edit
|
402
|
-
|
403
|
-
#---
|
404
|
-
|
405
|
-
def init_remotes
|
406
|
-
@origin = config('remote.origin.url')
|
407
|
-
set_edit(edit_url(@origin)) unless config('remote.edit.url')
|
408
|
-
return self
|
409
|
-
end
|
410
|
-
protected :init_remotes
|
411
|
-
|
412
|
-
#---
|
413
|
-
|
414
|
-
def set_origin(url)
|
415
|
-
set_remote('origin', url)
|
416
|
-
@origin = url
|
417
|
-
return self
|
418
|
-
end
|
419
|
-
|
420
|
-
#---
|
421
|
-
|
422
|
-
def set_edit(url)
|
423
|
-
set_remote('edit', url)
|
424
|
-
@edit = url
|
425
|
-
return self
|
426
|
-
end
|
427
|
-
|
428
|
-
#---
|
429
|
-
|
430
|
-
def set_remote(name, url)
|
431
|
-
delete_remote(name)
|
432
|
-
git.remote({}, 'add', name.to_s, url) if can_persist?
|
433
|
-
return self
|
434
|
-
end
|
435
|
-
|
436
|
-
#---
|
437
|
-
|
438
|
-
def add_remote_url(name, url, options = {})
|
439
|
-
config = Config.ensure(options)
|
440
|
-
|
441
|
-
if can_persist?
|
442
|
-
git.remote({
|
443
|
-
:add => true,
|
444
|
-
:delete => config.get(:delete, false),
|
445
|
-
:push => config.get(:push, false)
|
446
|
-
}, 'set-url', name.to_s, url)
|
447
|
-
end
|
448
|
-
return self
|
449
|
-
end
|
450
|
-
|
451
|
-
#---
|
452
|
-
|
453
|
-
def set_host_remote(name, hosts, path, options = {})
|
454
|
-
config = Config.ensure(options)
|
455
|
-
|
456
|
-
if can_persist?
|
457
|
-
hosts = array(hosts)
|
458
|
-
|
459
|
-
return self if hosts.empty?
|
460
|
-
|
461
|
-
set_remote(name.to_s, url(hosts.shift, path, config.options))
|
462
|
-
|
463
|
-
unless hosts.empty?
|
464
|
-
hosts.each do |host|
|
465
|
-
add_remote_url(name.to_s, url(host, path, config.options), config)
|
466
|
-
end
|
467
|
-
end
|
468
|
-
end
|
469
|
-
return self
|
470
|
-
end
|
471
|
-
|
472
|
-
#---
|
473
|
-
|
474
|
-
def delete_remote(name)
|
475
|
-
if can_persist? && git.list_remotes.include?(name)
|
476
|
-
git.remote({}, 'rm', name.to_s)
|
477
|
-
end
|
478
|
-
return self
|
479
|
-
end
|
480
|
-
|
481
|
-
#-----------------------------------------------------------------------------
|
482
|
-
# SSH operations
|
483
|
-
|
484
|
-
def pull!(remote = :origin, options = {})
|
485
|
-
config = Config.ensure(options)
|
486
|
-
success = false
|
487
|
-
|
488
|
-
if can_persist?
|
489
|
-
success = Command.new({
|
490
|
-
:command => :git,
|
491
|
-
:data => { 'git-dir=' => git.git_dir },
|
492
|
-
:subcommand => {
|
493
|
-
:command => :pull,
|
494
|
-
:flags => ( config.get(:tags, true) ? :tags : '' ),
|
495
|
-
:args => [ remote, config.get(:branch, '') ]
|
496
|
-
}
|
497
|
-
}).exec!(config) do |line|
|
498
|
-
block_given? ? yield(line) : true
|
499
|
-
end
|
500
|
-
|
501
|
-
update_submodules
|
502
|
-
|
503
|
-
if success && ! parent.nil? && config.get(:propogate, true)
|
504
|
-
parent.commit(directory, config.import({
|
505
|
-
:message => "Pulling updates for submodule #{path}",
|
506
|
-
:allow_empty => true
|
507
|
-
}))
|
508
|
-
end
|
509
|
-
end
|
510
|
-
return success
|
511
|
-
end
|
512
|
-
|
513
|
-
#---
|
514
|
-
|
515
|
-
def pull(remote = :origin, options = {})
|
516
|
-
return pull!(remote, options)
|
517
|
-
end
|
518
|
-
|
519
|
-
#---
|
520
|
-
|
521
|
-
def push!(remote = :edit, options = {})
|
522
|
-
config = Config.ensure(options)
|
523
|
-
success = false
|
524
|
-
|
525
|
-
if can_persist?
|
526
|
-
success = Command.new({
|
527
|
-
:command => :git,
|
528
|
-
:data => { 'git-dir=' => git.git_dir },
|
529
|
-
:subcommand => {
|
530
|
-
:command => :push,
|
531
|
-
:flags => ( config.get(:tags, true) ? :tags : '' ),
|
532
|
-
:args => [ remote, config.get(:branch, '') ]
|
533
|
-
}
|
534
|
-
}).exec!(config) do |line|
|
535
|
-
block_given? ? yield(line) : true
|
536
|
-
end
|
537
|
-
|
538
|
-
if success && config.get(:propogate, true)
|
539
|
-
foreach! do |path, repo|
|
540
|
-
repo.push(remote, config)
|
541
|
-
end
|
542
|
-
end
|
543
|
-
end
|
544
|
-
return success
|
545
|
-
end
|
546
|
-
|
547
|
-
#---
|
548
|
-
|
549
|
-
def push(remote = :edit, options = {})
|
550
|
-
return push!(remote, options)
|
551
|
-
end
|
552
|
-
end
|
553
|
-
end
|