librarian-puppet-maestrodev 0.9.7

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.
Files changed (115) hide show
  1. data/.gitignore +3 -0
  2. data/LICENSE +20 -0
  3. data/README.md +187 -0
  4. data/bin/librarian-puppet +9 -0
  5. data/lib/librarian/puppet.rb +13 -0
  6. data/lib/librarian/puppet/cli.rb +85 -0
  7. data/lib/librarian/puppet/dsl.rb +16 -0
  8. data/lib/librarian/puppet/environment.rb +54 -0
  9. data/lib/librarian/puppet/extension.rb +41 -0
  10. data/lib/librarian/puppet/lockfile/parser.rb +53 -0
  11. data/lib/librarian/puppet/source.rb +4 -0
  12. data/lib/librarian/puppet/source/forge.rb +279 -0
  13. data/lib/librarian/puppet/source/git.rb +114 -0
  14. data/lib/librarian/puppet/source/githubtarball.rb +234 -0
  15. data/lib/librarian/puppet/source/local.rb +57 -0
  16. data/lib/librarian/puppet/source/path.rb +12 -0
  17. data/lib/librarian/puppet/templates/Puppetfile +10 -0
  18. data/lib/librarian/puppet/version.rb +5 -0
  19. data/vendor/librarian/CHANGELOG.md +185 -0
  20. data/vendor/librarian/Gemfile +6 -0
  21. data/vendor/librarian/MIT-LICENSE +20 -0
  22. data/vendor/librarian/README.md +403 -0
  23. data/vendor/librarian/Rakefile +34 -0
  24. data/vendor/librarian/bin/librarian-chef +7 -0
  25. data/vendor/librarian/bin/librarian-mock +7 -0
  26. data/vendor/librarian/config/cucumber.yaml +1 -0
  27. data/vendor/librarian/features/chef/cli/init.feature +11 -0
  28. data/vendor/librarian/features/chef/cli/install.feature +64 -0
  29. data/vendor/librarian/features/chef/cli/show.feature +77 -0
  30. data/vendor/librarian/features/chef/cli/version.feature +11 -0
  31. data/vendor/librarian/features/support/env.rb +9 -0
  32. data/vendor/librarian/lib/librarian.rb +19 -0
  33. data/vendor/librarian/lib/librarian/action.rb +5 -0
  34. data/vendor/librarian/lib/librarian/action/base.rb +24 -0
  35. data/vendor/librarian/lib/librarian/action/clean.rb +44 -0
  36. data/vendor/librarian/lib/librarian/action/ensure.rb +24 -0
  37. data/vendor/librarian/lib/librarian/action/install.rb +99 -0
  38. data/vendor/librarian/lib/librarian/action/resolve.rb +81 -0
  39. data/vendor/librarian/lib/librarian/action/update.rb +78 -0
  40. data/vendor/librarian/lib/librarian/chef.rb +1 -0
  41. data/vendor/librarian/lib/librarian/chef/cli.rb +48 -0
  42. data/vendor/librarian/lib/librarian/chef/dsl.rb +15 -0
  43. data/vendor/librarian/lib/librarian/chef/environment.rb +27 -0
  44. data/vendor/librarian/lib/librarian/chef/extension.rb +9 -0
  45. data/vendor/librarian/lib/librarian/chef/integration/knife.rb +42 -0
  46. data/vendor/librarian/lib/librarian/chef/manifest_reader.rb +59 -0
  47. data/vendor/librarian/lib/librarian/chef/source.rb +3 -0
  48. data/vendor/librarian/lib/librarian/chef/source/git.rb +25 -0
  49. data/vendor/librarian/lib/librarian/chef/source/local.rb +69 -0
  50. data/vendor/librarian/lib/librarian/chef/source/path.rb +12 -0
  51. data/vendor/librarian/lib/librarian/chef/source/site.rb +446 -0
  52. data/vendor/librarian/lib/librarian/chef/templates/Cheffile +15 -0
  53. data/vendor/librarian/lib/librarian/cli.rb +205 -0
  54. data/vendor/librarian/lib/librarian/cli/manifest_presenter.rb +79 -0
  55. data/vendor/librarian/lib/librarian/config.rb +7 -0
  56. data/vendor/librarian/lib/librarian/config/database.rb +205 -0
  57. data/vendor/librarian/lib/librarian/config/file_source.rb +47 -0
  58. data/vendor/librarian/lib/librarian/config/hash_source.rb +33 -0
  59. data/vendor/librarian/lib/librarian/config/source.rb +149 -0
  60. data/vendor/librarian/lib/librarian/dependency.rb +91 -0
  61. data/vendor/librarian/lib/librarian/dsl.rb +108 -0
  62. data/vendor/librarian/lib/librarian/dsl/receiver.rb +48 -0
  63. data/vendor/librarian/lib/librarian/dsl/target.rb +172 -0
  64. data/vendor/librarian/lib/librarian/environment.rb +134 -0
  65. data/vendor/librarian/lib/librarian/error.rb +4 -0
  66. data/vendor/librarian/lib/librarian/helpers.rb +13 -0
  67. data/vendor/librarian/lib/librarian/lockfile.rb +29 -0
  68. data/vendor/librarian/lib/librarian/lockfile/compiler.rb +66 -0
  69. data/vendor/librarian/lib/librarian/lockfile/parser.rb +100 -0
  70. data/vendor/librarian/lib/librarian/logger.rb +46 -0
  71. data/vendor/librarian/lib/librarian/manifest.rb +132 -0
  72. data/vendor/librarian/lib/librarian/manifest_set.rb +153 -0
  73. data/vendor/librarian/lib/librarian/mock.rb +1 -0
  74. data/vendor/librarian/lib/librarian/mock/cli.rb +19 -0
  75. data/vendor/librarian/lib/librarian/mock/dsl.rb +15 -0
  76. data/vendor/librarian/lib/librarian/mock/environment.rb +24 -0
  77. data/vendor/librarian/lib/librarian/mock/extension.rb +9 -0
  78. data/vendor/librarian/lib/librarian/mock/source.rb +1 -0
  79. data/vendor/librarian/lib/librarian/mock/source/mock.rb +97 -0
  80. data/vendor/librarian/lib/librarian/mock/source/mock/registry.rb +83 -0
  81. data/vendor/librarian/lib/librarian/resolution.rb +44 -0
  82. data/vendor/librarian/lib/librarian/resolver.rb +78 -0
  83. data/vendor/librarian/lib/librarian/resolver/implementation.rb +118 -0
  84. data/vendor/librarian/lib/librarian/source.rb +2 -0
  85. data/vendor/librarian/lib/librarian/source/git.rb +150 -0
  86. data/vendor/librarian/lib/librarian/source/git/repository.rb +217 -0
  87. data/vendor/librarian/lib/librarian/source/local.rb +61 -0
  88. data/vendor/librarian/lib/librarian/source/path.rb +74 -0
  89. data/vendor/librarian/lib/librarian/spec.rb +13 -0
  90. data/vendor/librarian/lib/librarian/spec_change_set.rb +173 -0
  91. data/vendor/librarian/lib/librarian/specfile.rb +18 -0
  92. data/vendor/librarian/lib/librarian/support/abstract_method.rb +21 -0
  93. data/vendor/librarian/lib/librarian/ui.rb +64 -0
  94. data/vendor/librarian/lib/librarian/version.rb +3 -0
  95. data/vendor/librarian/librarian.gemspec +34 -0
  96. data/vendor/librarian/spec/functional/chef/source/git_spec.rb +432 -0
  97. data/vendor/librarian/spec/functional/chef/source/site_spec.rb +215 -0
  98. data/vendor/librarian/spec/functional/source/git/repository_spec.rb +149 -0
  99. data/vendor/librarian/spec/unit/action/base_spec.rb +18 -0
  100. data/vendor/librarian/spec/unit/action/clean_spec.rb +102 -0
  101. data/vendor/librarian/spec/unit/action/ensure_spec.rb +37 -0
  102. data/vendor/librarian/spec/unit/action/install_spec.rb +111 -0
  103. data/vendor/librarian/spec/unit/config/database_spec.rb +319 -0
  104. data/vendor/librarian/spec/unit/dependency_spec.rb +36 -0
  105. data/vendor/librarian/spec/unit/dsl_spec.rb +194 -0
  106. data/vendor/librarian/spec/unit/environment_spec.rb +9 -0
  107. data/vendor/librarian/spec/unit/lockfile/parser_spec.rb +162 -0
  108. data/vendor/librarian/spec/unit/lockfile_spec.rb +65 -0
  109. data/vendor/librarian/spec/unit/manifest_set_spec.rb +202 -0
  110. data/vendor/librarian/spec/unit/manifest_spec.rb +36 -0
  111. data/vendor/librarian/spec/unit/mock/source/mock_spec.rb +22 -0
  112. data/vendor/librarian/spec/unit/resolver_spec.rb +192 -0
  113. data/vendor/librarian/spec/unit/source/git_spec.rb +29 -0
  114. data/vendor/librarian/spec/unit/spec_change_set_spec.rb +169 -0
  115. metadata +227 -0
@@ -0,0 +1,4 @@
1
+ require 'librarian/puppet/source/path'
2
+ require 'librarian/puppet/source/git'
3
+ require 'librarian/puppet/source/forge'
4
+ require 'librarian/puppet/source/githubtarball'
@@ -0,0 +1,279 @@
1
+ require 'uri'
2
+ require 'net/http'
3
+ require 'json'
4
+
5
+ module Librarian
6
+ module Puppet
7
+ module Source
8
+ class Forge
9
+ class Repo
10
+
11
+ attr_accessor :source, :name
12
+ private :source=, :name=
13
+
14
+ def initialize(source, name)
15
+ self.source = source
16
+ self.name = name
17
+ end
18
+
19
+ def versions
20
+ data = api_call("#{name}.json")
21
+ if data.nil?
22
+ raise Error, "Unable to find module '#{name}' on #{source}"
23
+ end
24
+
25
+ data['releases'].map { |r| r['version'] }.sort.reverse
26
+ end
27
+
28
+ def dependencies(version)
29
+ data = api_call("api/v1/releases.json?module=#{name}&version=#{version}")
30
+ data[name].first['dependencies']
31
+ end
32
+
33
+ def manifests
34
+ versions.map do |version|
35
+ Manifest.new(source, name, version)
36
+ end
37
+ end
38
+
39
+ def install_version!(version, install_path)
40
+ if environment.local? && !vendored?(name, version)
41
+ raise Error, "Could not find a local copy of #{name} at #{version}."
42
+ end
43
+
44
+ if environment.vendor?
45
+ vendor_cache(name, version) unless vendored?(name, version)
46
+ end
47
+
48
+ cache_version_unpacked! version
49
+
50
+ if install_path.exist?
51
+ install_path.rmtree
52
+ end
53
+
54
+ unpacked_path = version_unpacked_cache_path(version).join(name.split('/').last)
55
+
56
+ unless unpacked_path.exist?
57
+ raise Error, "#{unpacked_path} does not exist, something went wrong. Try removing it manually"
58
+ else
59
+ FileUtils.cp_r(unpacked_path, install_path)
60
+ end
61
+
62
+ end
63
+
64
+ def environment
65
+ source.environment
66
+ end
67
+
68
+ def cache_path
69
+ @cache_path ||= source.cache_path.join(name)
70
+ end
71
+
72
+ def version_unpacked_cache_path(version)
73
+ cache_path.join('version').join(hexdigest(version.to_s))
74
+ end
75
+
76
+ def hexdigest(value)
77
+ Digest::MD5.hexdigest(value)
78
+ end
79
+
80
+ def cache_version_unpacked!(version)
81
+ path = version_unpacked_cache_path(version)
82
+ return if path.directory?
83
+
84
+ # The puppet module command is only available from puppet versions >= 2.7.13
85
+ #
86
+ # Specifying the version in the gemspec would force people to upgrade puppet while it's still usable for git
87
+ # So we do some more clever checking
88
+ #
89
+ # Executing older versions or via puppet-module tool gives an exit status = 0 .
90
+ #
91
+ check_puppet_module_options
92
+
93
+ path.mkpath
94
+
95
+ target = vendored?(name, version) ? vendored_path(name, version) : name
96
+
97
+
98
+ command = "puppet module install --version #{version} --target-dir '#{path}' --modulepath '#{path}' --ignore-dependencies '#{target}'"
99
+ output = `#{command}`
100
+
101
+ # Check for bad exit code
102
+ unless $? == 0
103
+ # Rollback the directory if the puppet module had an error
104
+ path.unlink
105
+ raise Error, "Error executing puppet module install:\n#{command}\nError:\n#{output}"
106
+ end
107
+
108
+ end
109
+
110
+ def check_puppet_module_options
111
+ min_version = Gem::Version.create('2.7.13')
112
+ puppet_version = Gem::Version.create(`puppet --version`.strip)
113
+
114
+ if puppet_version < min_version
115
+ raise Error, "To get modules from the forge, we use the puppet faces module command. For this you need at least puppet version 2.7.13 and you have #{puppet_version}"
116
+ end
117
+ end
118
+
119
+ def vendored?(name, version)
120
+ vendored_path(name, version).exist?
121
+ end
122
+
123
+ def vendored_path(name, version)
124
+ environment.vendor_cache.join("#{name.sub("/", "-")}-#{version}.tar.gz")
125
+ end
126
+
127
+ def vendor_cache(name, version)
128
+ File.open(vendored_path(name, version).to_s, 'w') do |f|
129
+ download(name, version) do |data|
130
+ f << data
131
+ end
132
+ end
133
+ end
134
+
135
+ def download(name, version, &block)
136
+ data = api_call("api/v1/releases.json?module=#{name}&version=#{version}")
137
+
138
+ info = data[name].detect {|h| h['version'] == version.to_s }
139
+
140
+ stream(info['file'], &block)
141
+ end
142
+
143
+ def stream(file, &block)
144
+ Net::HTTP.get_response(URI.parse("#{source}#{file}")) do |res|
145
+ res.code
146
+
147
+ res.read_body(&block)
148
+ end
149
+ end
150
+
151
+ private
152
+
153
+ def api_call(path)
154
+ base_url = source.to_s
155
+ resp = Net::HTTP.get_response(URI.parse("#{base_url}/#{path}"))
156
+ if resp.code.to_i != 200
157
+ nil
158
+ else
159
+ data = resp.body
160
+ JSON.parse(data)
161
+ end
162
+ end
163
+ end
164
+
165
+ class << self
166
+ LOCK_NAME = 'FORGE'
167
+
168
+ def lock_name
169
+ LOCK_NAME
170
+ end
171
+
172
+ def from_lock_options(environment, options)
173
+ new(environment, options[:remote], options.reject { |k, v| k == :remote })
174
+ end
175
+
176
+ def from_spec_args(environment, uri, options)
177
+ recognised_options = []
178
+ unrecognised_options = options.keys - recognised_options
179
+ unless unrecognised_options.empty?
180
+ raise Error, "unrecognised options: #{unrecognised_options.join(", ")}"
181
+ end
182
+
183
+ new(environment, uri, options)
184
+ end
185
+ end
186
+
187
+ attr_accessor :environment
188
+ private :environment=
189
+ attr_reader :uri
190
+
191
+ def initialize(environment, uri, options = {})
192
+ self.environment = environment
193
+ @uri = uri
194
+ @cache_path = nil
195
+ end
196
+
197
+ def to_s
198
+ uri
199
+ end
200
+
201
+ def ==(other)
202
+ other &&
203
+ self.class == other.class &&
204
+ self.uri == other.uri
205
+ end
206
+
207
+ def to_spec_args
208
+ [uri, {}]
209
+ end
210
+
211
+ def to_lock_options
212
+ {:remote => uri}
213
+ end
214
+
215
+ def pinned?
216
+ false
217
+ end
218
+
219
+ def unpin!
220
+ end
221
+
222
+ def install!(manifest)
223
+ manifest.source == self or raise ArgumentError
224
+
225
+ name = manifest.name
226
+ version = manifest.version
227
+ install_path = install_path(name)
228
+ repo = repo(name)
229
+
230
+ repo.install_version! version, install_path
231
+ end
232
+
233
+ def manifest(name, version, dependencies)
234
+ manifest = Manifest.new(self, name)
235
+ manifest.version = version
236
+ manifest.dependencies = dependencies
237
+ manifest
238
+ end
239
+
240
+ def cache_path
241
+ @cache_path ||= begin
242
+ dir = Digest::MD5.hexdigest(uri)
243
+ environment.cache_path.join("source/puppet/forge/#{dir}")
244
+ end
245
+ end
246
+
247
+ def install_path(name)
248
+ environment.install_path.join(name.split('/').last)
249
+ end
250
+
251
+ def fetch_version(name, version_uri)
252
+ versions = repo(name).versions
253
+ if versions.include? version_uri
254
+ version_uri
255
+ else
256
+ versions.first
257
+ end
258
+ end
259
+
260
+ def fetch_dependencies(name, version, version_uri)
261
+ repo(name).dependencies(version).map do |k, v|
262
+ Dependency.new(k, v, nil)
263
+ end
264
+ end
265
+
266
+ def manifests(name)
267
+ repo(name).manifests
268
+ end
269
+
270
+ private
271
+
272
+ def repo(name)
273
+ @repo ||= {}
274
+ @repo[name] ||= Repo.new(self, name)
275
+ end
276
+ end
277
+ end
278
+ end
279
+ end
@@ -0,0 +1,114 @@
1
+ require 'librarian/source/git'
2
+ require 'librarian/puppet/source/local'
3
+
4
+ module Librarian
5
+ module Source
6
+ class Git
7
+ class Repository
8
+ def hash_from(remote, reference)
9
+ branch_names = remote_branch_names[remote]
10
+ if branch_names.include?(reference)
11
+ reference = "#{remote}/#{reference}"
12
+ end
13
+
14
+ command = %W(rev-parse #{reference}^{commit} --quiet)
15
+ run!(command, :chdir => true).strip
16
+ end
17
+
18
+ # Naming this method 'version' causes an exception to be raised.
19
+ def module_version
20
+ return '0.0.1' unless modulefile?
21
+
22
+ metadata = ::Puppet::ModuleTool::Metadata.new
23
+ ::Puppet::ModuleTool::ModulefileReader.evaluate(metadata, modulefile)
24
+
25
+ metadata.version
26
+ end
27
+
28
+ def dependencies
29
+ return {} unless modulefile?
30
+
31
+ metadata = ::Puppet::ModuleTool::Metadata.new
32
+
33
+ ::Puppet::ModuleTool::ModulefileReader.evaluate(metadata, modulefile)
34
+
35
+ metadata.dependencies.inject({}) do |h, dependency|
36
+ name = dependency.instance_variable_get(:@full_module_name)
37
+ version = dependency.instance_variable_get(:@version_requirement)
38
+ h.update(name => version)
39
+ end
40
+ end
41
+
42
+ def modulefile
43
+ File.join(path, 'Modulefile')
44
+ end
45
+
46
+ def modulefile?
47
+ File.exists?(modulefile)
48
+ end
49
+ end
50
+ end
51
+ end
52
+
53
+ module Puppet
54
+ module Source
55
+ class Git < Librarian::Source::Git
56
+ include Local
57
+
58
+ def cache!
59
+ return vendor_checkout! if vendor_cached?
60
+
61
+ if environment.local?
62
+ raise Error, "Could not find a local copy of #{uri} at #{sha}."
63
+ end
64
+
65
+ super
66
+
67
+ cache_in_vendor(repository.path) if environment.vendor?
68
+ end
69
+
70
+ def vendor_tgz
71
+ environment.vendor_source + "#{sha}.tar.gz"
72
+ end
73
+
74
+ def vendor_cached?
75
+ vendor_tgz.exist?
76
+ end
77
+
78
+ def vendor_checkout!
79
+ repository.path.rmtree if repository.path.exist?
80
+ repository.path.mkpath
81
+
82
+ Dir.chdir(repository.path.to_s) do
83
+ %x{tar xzf #{vendor_tgz}}
84
+ end
85
+
86
+ repository_cached!
87
+ end
88
+
89
+ def cache_in_vendor(tmp_path)
90
+ Dir.chdir(tmp_path.to_s) do
91
+ %x{git archive #{sha} | gzip > #{vendor_tgz}}
92
+ end
93
+ end
94
+
95
+ def fetch_version(name, extra)
96
+ cache!
97
+ found_path = found_path(name)
98
+ repository.module_version
99
+ end
100
+
101
+ def fetch_dependencies(name, version, extra)
102
+ repository.dependencies.map do |k, v|
103
+ Dependency.new(k, v, forge_source)
104
+ end
105
+ end
106
+
107
+ def forge_source
108
+ Forge.from_lock_options(environment, :remote=>"http://forge.puppetlabs.com")
109
+ end
110
+
111
+ end
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,234 @@
1
+ require 'uri'
2
+ require 'net/https'
3
+ require 'json'
4
+
5
+ module Librarian
6
+ module Puppet
7
+ module Source
8
+ class GitHubTarball
9
+ class Repo
10
+
11
+ attr_accessor :source, :name
12
+ private :source=, :name=
13
+
14
+ def initialize(source, name)
15
+ self.source = source
16
+ self.name = name
17
+ end
18
+
19
+ def versions
20
+ data = api_call("/repos/#{source.uri}/tags")
21
+ if data.nil?
22
+ raise Error, "Unable to find module '#{source.uri}' on https://github.com"
23
+ end
24
+
25
+ all_versions = data.map { |r| r['name'] }.sort.reverse
26
+ all_versions.reject { |version| version =~ /^v/ }.compact
27
+ end
28
+
29
+ def manifests
30
+ versions.map do |version|
31
+ Manifest.new(source, name, version)
32
+ end
33
+ end
34
+
35
+ def install_version!(version, install_path)
36
+ if environment.local? && !vendored?(source.uri, version)
37
+ raise Error, "Could not find a local copy of #{source.uri} at #{version}."
38
+ end
39
+
40
+ vendor_cache(source.uri, version) unless vendored?(source.uri, version)
41
+
42
+ cache_version_unpacked! version
43
+
44
+ if install_path.exist?
45
+ install_path.rmtree
46
+ end
47
+
48
+ unpacked_path = version_unpacked_cache_path(version).children.first
49
+ FileUtils.cp_r(unpacked_path, install_path)
50
+ end
51
+
52
+ def environment
53
+ source.environment
54
+ end
55
+
56
+ def cache_path
57
+ @cache_path ||= source.cache_path.join(name)
58
+ end
59
+
60
+ def version_unpacked_cache_path(version)
61
+ cache_path.join('version').join(hexdigest(version.to_s))
62
+ end
63
+
64
+ def hexdigest(value)
65
+ Digest::MD5.hexdigest(value)
66
+ end
67
+
68
+ def cache_version_unpacked!(version)
69
+ path = version_unpacked_cache_path(version)
70
+ return if path.directory?
71
+
72
+ path.mkpath
73
+
74
+ target = vendored?(source.uri, version) ? vendored_path(source.uri, version) : name
75
+
76
+ `tar xzf #{target} -C #{path}`
77
+ end
78
+
79
+ def vendored?(name, version)
80
+ vendored_path(name, version).exist?
81
+ end
82
+
83
+ def vendored_path(name, version)
84
+ environment.vendor_cache.mkpath
85
+ environment.vendor_cache.join("#{name.sub("/", "-")}-#{version}.tar.gz")
86
+ end
87
+
88
+ def vendor_cache(name, version)
89
+ clean_up_old_cached_versions(name)
90
+
91
+ url = "https://api.github.com/repos/#{name}/tarball/#{version}"
92
+ url << "?access_token=#{ENV['GITHUB_API_TOKEN']}" if ENV['GITHUB_API_TOKEN']
93
+ `curl #{url} -o #{vendored_path(name, version).to_s} -L 2>&1`
94
+ end
95
+
96
+ def clean_up_old_cached_versions(name)
97
+ Dir["#{environment.vendor_cache}/#{name.sub('/', '-')}*.tar.gz"].each do |old_version|
98
+ FileUtils.rm old_version
99
+ end
100
+ end
101
+
102
+ private
103
+
104
+ def api_call(path)
105
+ url = "https://api.github.com#{path}"
106
+ url << "?access_token=#{ENV['GITHUB_API_TOKEN']}" if ENV['GITHUB_API_TOKEN']
107
+ uri = URI.parse(url)
108
+ http = Net::HTTP.new(uri.host, uri.port)
109
+ http.use_ssl = true
110
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
111
+ request = Net::HTTP::Get.new(uri.request_uri)
112
+ resp = http.request(request)
113
+ if resp.code.to_i != 200
114
+ nil
115
+ else
116
+ data = resp.body
117
+ JSON.parse(data)
118
+ end
119
+ end
120
+ end
121
+
122
+ class << self
123
+ LOCK_NAME = 'GITHUBTARBALL'
124
+
125
+ def lock_name
126
+ LOCK_NAME
127
+ end
128
+
129
+ def from_lock_options(environment, options)
130
+ new(environment, options[:remote], options.reject { |k, v| k == :remote })
131
+ end
132
+
133
+ def from_spec_args(environment, uri, options)
134
+ recognised_options = []
135
+ unrecognised_options = options.keys - recognised_options
136
+ unless unrecognised_options.empty?
137
+ raise Error, "unrecognised options: #{unrecognised_options.join(", ")}"
138
+ end
139
+
140
+ new(environment, uri, options)
141
+ end
142
+ end
143
+
144
+ attr_accessor :environment
145
+ private :environment=
146
+ attr_reader :uri
147
+
148
+ def initialize(environment, uri, options = {})
149
+ self.environment = environment
150
+ @uri = uri
151
+ @cache_path = nil
152
+ end
153
+
154
+ def to_s
155
+ uri
156
+ end
157
+
158
+ def ==(other)
159
+ other &&
160
+ self.class == other.class &&
161
+ self.uri == other.uri
162
+ end
163
+
164
+ def to_spec_args
165
+ [uri, {}]
166
+ end
167
+
168
+ def to_lock_options
169
+ {:remote => uri}
170
+ end
171
+
172
+ def pinned?
173
+ false
174
+ end
175
+
176
+ def unpin!
177
+ end
178
+
179
+ def install!(manifest)
180
+ manifest.source == self or raise ArgumentError
181
+
182
+ name = manifest.name
183
+ version = manifest.version
184
+ install_path = install_path(name)
185
+ repo = repo(name)
186
+
187
+ repo.install_version! version, install_path
188
+ end
189
+
190
+ def manifest(name, version, dependencies)
191
+ manifest = Manifest.new(self, name)
192
+ manifest.version = version
193
+ manifest.dependencies = dependencies
194
+ manifest
195
+ end
196
+
197
+ def cache_path
198
+ @cache_path ||= begin
199
+ dir = Digest::MD5.hexdigest(uri)
200
+ environment.cache_path.join("source/puppet/githubtarball/#{dir}")
201
+ end
202
+ end
203
+
204
+ def install_path(name)
205
+ environment.install_path.join(name.split('/').last)
206
+ end
207
+
208
+ def fetch_version(name, version_uri)
209
+ versions = repo(name).versions
210
+ if versions.include? version_uri
211
+ version_uri
212
+ else
213
+ versions.first
214
+ end
215
+ end
216
+
217
+ def fetch_dependencies(name, version, version_uri)
218
+ {}
219
+ end
220
+
221
+ def manifests(name)
222
+ repo(name).manifests
223
+ end
224
+
225
+ private
226
+
227
+ def repo(name)
228
+ @repo ||= {}
229
+ @repo[name] ||= Repo.new(self, name)
230
+ end
231
+ end
232
+ end
233
+ end
234
+ end