puppet-library 0.6.0 → 0.7.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 +13 -5
- data/CHANGELOG.yml +6 -1
- data/README.md +4 -0
- data/Rakefile +9 -1
- data/TODO.yml +3 -4
- data/lib/puppet_library/forge.rb +1 -0
- data/lib/puppet_library/forge/cache.rb +27 -0
- data/lib/puppet_library/forge/directory.rb +2 -0
- data/lib/puppet_library/forge/proxy.rb +26 -9
- data/lib/puppet_library/http/cache.rb +1 -0
- data/lib/puppet_library/http/cache/disk.rb +53 -0
- data/lib/puppet_library/http/url.rb +10 -1
- data/lib/puppet_library/puppet_library.rb +37 -6
- data/lib/puppet_library/server.rb +8 -4
- data/lib/puppet_library/version.rb +1 -1
- data/spec/forge/cache_spec.rb +67 -0
- data/spec/forge/directory_spec.rb +26 -6
- data/spec/forge/proxy_spec.rb +5 -22
- data/spec/http/cache/disk_spec.rb +57 -0
- data/spec/http/cache/in_memory_spec.rb +1 -1
- data/spec/http/url_spec.rb +16 -0
- data/spec/puppet_library_spec.rb +35 -2
- data/spec/server_spec.rb +9 -0
- data/spec/spec_helper.rb +18 -0
- data/test/librarian_puppet_integration_test.rb +97 -19
- metadata +45 -39
checksums.yaml
CHANGED
@@ -1,7 +1,15 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
ZWU3ZDcxMTYwNTRlYzU4MmI0M2UxN2Y1NWJjZDBmZTdmNjEzNTQzMg==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
Yzc2ZGY1NDNmZGRiYzI5ZjBjYzRkZDhlNmI4YmMyNmEwYThlZWM5Zg==
|
5
7
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
OTBlNjVhZjI2ZGVlZDUyMDllNGNhODkxODQ4NzVlYmY2MjM0YmNmMGJlNzMy
|
10
|
+
MTBlMjFjOTZkYjM0MjcwY2UxNjllN2U2ZDg2MTliYjEwYzc5NWQxMzRiZjUw
|
11
|
+
MDg1YzMwMzEzZTJmYzY2ZTBjYjllYmM3ZTc1MzkxYzliMTFmZGI=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
MmE5MjdiYjViMDYxYTU1ZTY5MDIwYzdhZDBkZGI5MmRlYTIyYzIwMDFmZjc4
|
14
|
+
OTY0ZmFkNGUyODE0ZDdjNzI0YzVjNzU4MWQ5NzE0OWE2MDEyMDY1YzA1ZDcy
|
15
|
+
YzlhOWY3NDhmZDIzN2Q0YjJmNTc1ZGQ2YmQyZTIyNWM0ZWY0ZTg=
|
data/CHANGELOG.yml
CHANGED
@@ -42,6 +42,11 @@
|
|
42
42
|
- Added module search field to web UI
|
43
43
|
- tag: v0.6.0
|
44
44
|
changes:
|
45
|
-
-
|
45
|
+
- Added config API for running with Passenger
|
46
46
|
- Load configuration from a config file
|
47
47
|
- Fixed version number bug that made the app crash with some Rubygems versions
|
48
|
+
- tag: v0.7.0
|
49
|
+
changes:
|
50
|
+
- Added new proxy forge that caches downloaded modules on disk
|
51
|
+
- Added `--cache-basedir` CLI option to make proxies cache downloaded modules on disk
|
52
|
+
- Fixed issue with forge proxying (#1)
|
data/README.md
CHANGED
@@ -66,6 +66,10 @@ Serve modules from a remote forge as a proxy
|
|
66
66
|
|
67
67
|
$ puppet-library --proxy http://forge.puppetlabs.com
|
68
68
|
|
69
|
+
Proxy a remote forge, caching downloaded modules on disk
|
70
|
+
|
71
|
+
$ puppet-library --proxy http://forge.puppetlabs.com --cache-basedir
|
72
|
+
|
69
73
|
Serve modules on a specific port
|
70
74
|
|
71
75
|
$ puppet-library --port 8888
|
data/Rakefile
CHANGED
@@ -54,6 +54,13 @@ def ruby_version_supports_acceptance_tests?(version = RUBY_VERSION)
|
|
54
54
|
end
|
55
55
|
end
|
56
56
|
|
57
|
+
def offline?
|
58
|
+
Net::HTTP.get_response(URI.parse("http://forge.puppetlabs.com"))
|
59
|
+
return false
|
60
|
+
rescue
|
61
|
+
return true
|
62
|
+
end
|
63
|
+
|
57
64
|
Coveralls::RakeTask.new
|
58
65
|
|
59
66
|
desc "Run the specs"
|
@@ -78,6 +85,7 @@ if ruby_version_supports_integration_test?
|
|
78
85
|
desc "Run the integration tests"
|
79
86
|
RSpec::Core::RakeTask.new(:integration_test) do |rspec|
|
80
87
|
rspec.pattern = "test/**/*_integration_test.rb"
|
88
|
+
rspec.rspec_opts = "--tag ~online" if offline?
|
81
89
|
end
|
82
90
|
else
|
83
91
|
task :integration_test do
|
@@ -185,7 +193,7 @@ task "register-release", [:version] do |task, args|
|
|
185
193
|
end
|
186
194
|
|
187
195
|
def upload_release_notes(version)
|
188
|
-
puts "Registering release notes for #{
|
196
|
+
puts "Registering release notes for #{version}"
|
189
197
|
github = Github.new
|
190
198
|
|
191
199
|
unless version =~ /\d+\.\d+\.\d+/
|
data/TODO.yml
CHANGED
@@ -1,13 +1,10 @@
|
|
1
1
|
features:
|
2
2
|
- disk cache:
|
3
|
-
-
|
3
|
+
- use disk cache to respond to queries if remote API calls fail
|
4
4
|
- |
|
5
5
|
Accept --cache-dir option to specify a parent cache directory (people
|
6
6
|
will need to embed the server or use a config file for more control)
|
7
|
-
- Validate repo dirs (make sure they're readable)
|
8
|
-
- Allow failover between module repositories
|
9
7
|
- Web UI: asynchronous (index page loads too slowly)
|
10
|
-
- Look in /etc/puppet-library.yml for config by default
|
11
8
|
- Named subforges:
|
12
9
|
- per-subforge queries
|
13
10
|
- upload modules (web form and API)
|
@@ -18,3 +15,5 @@ features:
|
|
18
15
|
|
19
16
|
dubious_features:
|
20
17
|
- Make proxy cache TTL configurable
|
18
|
+
- Allow failover between module repositories
|
19
|
+
- Look in /etc/puppet-library.yml for config by default
|
data/lib/puppet_library/forge.rb
CHANGED
@@ -0,0 +1,27 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
# Puppet Library
|
3
|
+
# Copyright (C) 2014 drrb
|
4
|
+
#
|
5
|
+
# This program is free software: you can redistribute it and/or modify
|
6
|
+
# it under the terms of the GNU General Public License as published by
|
7
|
+
# the Free Software Foundation, either version 3 of the License, or
|
8
|
+
# (at your option) any later version.
|
9
|
+
#
|
10
|
+
# This program is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
# GNU General Public License for more details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU General Public License
|
16
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
|
18
|
+
require 'puppet_library/forge/proxy'
|
19
|
+
require 'puppet_library/http/http_client'
|
20
|
+
|
21
|
+
module PuppetLibrary::Forge
|
22
|
+
class Cache < Proxy
|
23
|
+
def initialize(url, cache_dir, http_client = PuppetLibrary::Http::HttpClient.new)
|
24
|
+
super(url, PuppetLibrary::Http::Cache::InMemory.new, PuppetLibrary::Http::Cache::Disk.new(cache_dir), http_client)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -23,6 +23,8 @@ module PuppetLibrary::Forge
|
|
23
23
|
class Directory < PuppetLibrary::Forge::Abstract
|
24
24
|
def initialize(module_dir)
|
25
25
|
super(self)
|
26
|
+
raise "Module directory '#{module_dir}' doesn't exist" unless File.directory? module_dir
|
27
|
+
raise "Module directory '#{module_dir}' isn't readable" unless File.executable? module_dir
|
26
28
|
@module_dir = module_dir
|
27
29
|
end
|
28
30
|
|
@@ -18,7 +18,6 @@
|
|
18
18
|
require 'puppet_library/http/http_client'
|
19
19
|
require 'puppet_library/http/cache/in_memory'
|
20
20
|
require 'puppet_library/http/cache/noop'
|
21
|
-
require 'puppet_library/http/url'
|
22
21
|
|
23
22
|
module PuppetLibrary::Forge
|
24
23
|
class Proxy
|
@@ -26,7 +25,7 @@ module PuppetLibrary::Forge
|
|
26
25
|
query_cache = PuppetLibrary::Http::Cache::InMemory.new,
|
27
26
|
download_cache = PuppetLibrary::Http::Cache::NoOp.new,
|
28
27
|
http_client = PuppetLibrary::Http::HttpClient.new)
|
29
|
-
@url =
|
28
|
+
@url = url
|
30
29
|
@http_client = http_client
|
31
30
|
@query_cache = query_cache
|
32
31
|
@download_cache = download_cache
|
@@ -42,7 +41,7 @@ module PuppetLibrary::Forge
|
|
42
41
|
begin
|
43
42
|
version_info = get_module_version(author, name, version)
|
44
43
|
raise ModuleNotFound if version_info.nil?
|
45
|
-
|
44
|
+
download_module(author, name, version, version_info["file"])
|
46
45
|
rescue OpenURI::HTTPError
|
47
46
|
raise ModuleNotFound
|
48
47
|
end
|
@@ -59,7 +58,9 @@ module PuppetLibrary::Forge
|
|
59
58
|
|
60
59
|
def get_module_metadata_with_dependencies(author, name, version)
|
61
60
|
begin
|
62
|
-
look_up_releases(author, name, version)
|
61
|
+
look_up_releases(author, name, version) do |full_name, release_info|
|
62
|
+
release_info["file"] = module_path_for(full_name, release_info["version"])
|
63
|
+
end
|
63
64
|
rescue OpenURI::HTTPError
|
64
65
|
raise ModuleNotFound
|
65
66
|
end
|
@@ -78,15 +79,31 @@ module PuppetLibrary::Forge
|
|
78
79
|
versions["#{author}/#{name}"]
|
79
80
|
end
|
80
81
|
|
81
|
-
def look_up_releases(author, name, version = nil)
|
82
|
+
def look_up_releases(author, name, version = nil, &block)
|
82
83
|
version_query = version ? "&version=#{version}" : ""
|
83
84
|
url = "/api/v1/releases.json?module=#{author}/#{name}#{version_query}"
|
84
|
-
|
85
|
-
JSON.parse(
|
85
|
+
response_text = get(url)
|
86
|
+
response = JSON.parse(response_text)
|
87
|
+
process_releases_response(response, &block)
|
86
88
|
end
|
87
89
|
|
88
|
-
def
|
89
|
-
|
90
|
+
def process_releases_response(response)
|
91
|
+
if block_given?
|
92
|
+
response.each do |full_name, release_infos|
|
93
|
+
release_infos.each do |release_info|
|
94
|
+
yield(full_name, release_info)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
return response
|
99
|
+
end
|
100
|
+
|
101
|
+
def module_path_for(full_name, version)
|
102
|
+
"/modules/#{full_name.sub("/", "-")}-#{version}.tar.gz"
|
103
|
+
end
|
104
|
+
|
105
|
+
def download_module(author, name, version, file)
|
106
|
+
@download_cache.get("#{author}-#{name}-#{version}.tar.gz") do
|
90
107
|
@http_client.download(url(file))
|
91
108
|
end
|
92
109
|
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
# Puppet Library
|
3
|
+
# Copyright (C) 2014 drrb
|
4
|
+
#
|
5
|
+
# This program is free software: you can redistribute it and/or modify
|
6
|
+
# it under the terms of the GNU General Public License as published by
|
7
|
+
# the Free Software Foundation, either version 3 of the License, or
|
8
|
+
# (at your option) any later version.
|
9
|
+
#
|
10
|
+
# This program is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
# GNU General Public License for more details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU General Public License
|
16
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
|
18
|
+
module PuppetLibrary::Http::Cache
|
19
|
+
class Disk
|
20
|
+
def initialize(directory)
|
21
|
+
@directory = directory
|
22
|
+
end
|
23
|
+
|
24
|
+
def get(path)
|
25
|
+
unless include? path
|
26
|
+
buffer = yield
|
27
|
+
save(path, buffer)
|
28
|
+
end
|
29
|
+
retrieve(path)
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
def include?(path)
|
34
|
+
File.exist? entry_path(path)
|
35
|
+
end
|
36
|
+
|
37
|
+
def save(path, buffer)
|
38
|
+
file_path = entry_path(path)
|
39
|
+
FileUtils.mkdir_p File.dirname(file_path)
|
40
|
+
File.open(file_path, "w") do |file|
|
41
|
+
file.write buffer.read
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def retrieve(path)
|
46
|
+
File.open(entry_path(path))
|
47
|
+
end
|
48
|
+
|
49
|
+
def entry_path(path)
|
50
|
+
File.join(@directory, path)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -15,10 +15,19 @@
|
|
15
15
|
# You should have received a copy of the GNU General Public License
|
16
16
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
17
17
|
|
18
|
+
require 'uri'
|
19
|
+
|
18
20
|
module PuppetLibrary::Http
|
19
21
|
class Url
|
20
22
|
def self.normalize(uri_string)
|
21
|
-
|
23
|
+
begin
|
24
|
+
url = URI.parse(uri_string)
|
25
|
+
rescue URI::InvalidURIError => e
|
26
|
+
raise PuppetLibrary::ExpectedError, "Invalid URL '#{uri_string}': #{e.message}"
|
27
|
+
end
|
28
|
+
if url.scheme
|
29
|
+
raise PuppetLibrary::ExpectedError, "Invalid URL '#{uri_string}': unsupported protocol '#{url.scheme}'" unless url.scheme =~ /^https?$/
|
30
|
+
else
|
22
31
|
uri_string = "http://#{uri_string}"
|
23
32
|
end
|
24
33
|
uri_string.sub /\/$/, ""
|
@@ -42,6 +42,7 @@ module PuppetLibrary
|
|
42
42
|
options = {}
|
43
43
|
option_parser = OptionParser.new do |opts|
|
44
44
|
opts.banner = "Usage: #{File.basename $0} [options]"
|
45
|
+
opts.version = VERSION
|
45
46
|
|
46
47
|
opts.on("-c", "--config-file FILE", "Config file to read config values from") do |config_file|
|
47
48
|
options[:config_file] = config_file
|
@@ -73,7 +74,11 @@ module PuppetLibrary
|
|
73
74
|
options[:forges] << [Forge::Directory, module_dir]
|
74
75
|
end
|
75
76
|
opts.on("-x", "--proxy URL", "Remote forge to proxy (can be specified multiple times)") do |url|
|
76
|
-
options[:forges] << [Forge::Proxy, url]
|
77
|
+
options[:forges] << [Forge::Proxy, sanitize_url(url)]
|
78
|
+
end
|
79
|
+
|
80
|
+
opts.on("--cache-basedir DIR", "Cache all proxies' downloaded modules under this directory") do |cache_basedir|
|
81
|
+
options[:cache_basedir] = cache_basedir
|
77
82
|
end
|
78
83
|
end
|
79
84
|
begin
|
@@ -87,14 +92,15 @@ module PuppetLibrary
|
|
87
92
|
|
88
93
|
def build_server(options)
|
89
94
|
if options[:config_file]
|
90
|
-
load_config(options)
|
95
|
+
load_config!(options)
|
91
96
|
end
|
92
97
|
|
93
|
-
load_defaults(options)
|
98
|
+
load_defaults!(options)
|
99
|
+
process_options!(options)
|
94
100
|
|
95
101
|
Server.set_up do |server|
|
96
102
|
options[:forges].each do |(forge_type, config)|
|
97
|
-
subforge = forge_type.new(config)
|
103
|
+
subforge = forge_type.new(*config)
|
98
104
|
server.forge subforge
|
99
105
|
end
|
100
106
|
end
|
@@ -126,7 +132,7 @@ module PuppetLibrary
|
|
126
132
|
)
|
127
133
|
end
|
128
134
|
|
129
|
-
def load_config(options)
|
135
|
+
def load_config!(options)
|
130
136
|
config = read_yaml_file(options[:config_file])
|
131
137
|
options[:daemonize] = config["daemonize"]
|
132
138
|
options[:port] = config["port"]
|
@@ -140,7 +146,7 @@ module PuppetLibrary
|
|
140
146
|
options[:forges] = configured_forges + options[:forges]
|
141
147
|
end
|
142
148
|
|
143
|
-
def load_defaults(options)
|
149
|
+
def load_defaults!(options)
|
144
150
|
options[:daemonize] ||= false
|
145
151
|
options[:pidfile] ||= nil
|
146
152
|
if options[:forges].empty?
|
@@ -148,9 +154,34 @@ module PuppetLibrary
|
|
148
154
|
end
|
149
155
|
end
|
150
156
|
|
157
|
+
def process_options!(options)
|
158
|
+
options[:forges].map! do |(forge_type, config)|
|
159
|
+
if forge_type == Forge::Proxy
|
160
|
+
end
|
161
|
+
if forge_type == Forge::Proxy && options[:cache_basedir]
|
162
|
+
cache_dir = File.join(options[:cache_basedir], url_hostname(config))
|
163
|
+
[ Forge::Cache, [ config, sanitize_path(cache_dir) ] ]
|
164
|
+
else
|
165
|
+
[ forge_type, config ]
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
151
170
|
def read_yaml_file(path)
|
152
171
|
YAML.load_file(File.expand_path(path)) || {}
|
153
172
|
end
|
173
|
+
|
174
|
+
def sanitize_url(url)
|
175
|
+
Http::Url.normalize(url)
|
176
|
+
end
|
177
|
+
|
178
|
+
def sanitize_path(path)
|
179
|
+
File.expand_path path
|
180
|
+
end
|
181
|
+
|
182
|
+
def url_hostname(url)
|
183
|
+
URI.parse(Http::Url.normalize(url)).host
|
184
|
+
end
|
154
185
|
end
|
155
186
|
|
156
187
|
class ExpectedError < StandardError
|
@@ -68,12 +68,15 @@ module PuppetLibrary
|
|
68
68
|
begin
|
69
69
|
@forge.get_module_metadata(author, module_name).to_json
|
70
70
|
rescue Forge::ModuleNotFound
|
71
|
-
|
72
|
-
{"error" => "Could not find module \"#{module_name}\""}.to_json
|
71
|
+
halt 410, {"error" => "Could not find module \"#{module_name}\""}.to_json
|
73
72
|
end
|
74
73
|
end
|
75
74
|
|
76
75
|
get "/api/v1/releases.json" do
|
76
|
+
unless params[:module]
|
77
|
+
halt 400, {"error" => "The number of version constraints in the query does not match the number of module names"}.to_json
|
78
|
+
end
|
79
|
+
|
77
80
|
author, module_name = params[:module].split "/"
|
78
81
|
version = params[:version]
|
79
82
|
begin
|
@@ -92,11 +95,12 @@ module PuppetLibrary
|
|
92
95
|
content_type "application/octet-stream"
|
93
96
|
|
94
97
|
begin
|
95
|
-
@forge.get_module_buffer(author, name, version).tap do
|
98
|
+
buffer = @forge.get_module_buffer(author, name, version).tap do
|
96
99
|
attachment "#{author}-#{name}-#{version}.tar.gz"
|
97
100
|
end
|
101
|
+
[ 200, { "Content-Length" => buffer.size.to_s }, buffer ]
|
98
102
|
rescue Forge::ModuleNotFound
|
99
|
-
|
103
|
+
halt 404
|
100
104
|
end
|
101
105
|
end
|
102
106
|
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
# Puppet Library
|
3
|
+
# Copyright (C) 2014 drrb
|
4
|
+
#
|
5
|
+
# This program is free software: you can redistribute it and/or modify
|
6
|
+
# it under the terms of the GNU General Public License as published by
|
7
|
+
# the Free Software Foundation, either version 3 of the License, or
|
8
|
+
# (at your option) any later version.
|
9
|
+
#
|
10
|
+
# This program is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
# GNU General Public License for more details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU General Public License
|
16
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
|
18
|
+
require 'spec_helper'
|
19
|
+
|
20
|
+
module PuppetLibrary::Forge
|
21
|
+
describe Cache do
|
22
|
+
let(:cache_dir) { Tempdir.create("module-cache") }
|
23
|
+
let(:http_client) { double(PuppetLibrary::Http::HttpClient) }
|
24
|
+
let(:forge) { Cache.new("http://forge.example.com", cache_dir, http_client) }
|
25
|
+
|
26
|
+
it "is a proxy" do
|
27
|
+
expect(forge).to be_a Proxy
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "#get_module_buffer" do
|
31
|
+
before do
|
32
|
+
allow(http_client).to receive(:get).
|
33
|
+
with("http://forge.example.com/api/v1/releases.json?module=puppetlabs/apache").
|
34
|
+
and_return('{"puppetlabs/apache":[{"version":"1.0.0","file":"/puppetlabs/apache.tgz","dependencies":[["puppetlabs/concat",">= 1.0.0"],["puppetlabs/stdlib","~> 2.0.0"]]},{"version":"2.0.0","dependencies":[]}]}')
|
35
|
+
end
|
36
|
+
|
37
|
+
context "the first time it's called" do
|
38
|
+
it "downloads the module to disk and serves it" do
|
39
|
+
file_buffer = StringIO.new("apache module")
|
40
|
+
expect(http_client).to receive(:download).
|
41
|
+
with("http://forge.example.com/puppetlabs/apache.tgz").
|
42
|
+
and_return(file_buffer)
|
43
|
+
|
44
|
+
buffer = forge.get_module_buffer("puppetlabs", "apache", "1.0.0")
|
45
|
+
|
46
|
+
downloaded_file = File.join(cache_dir, "puppetlabs-apache-1.0.0.tar.gz")
|
47
|
+
expect(File.read downloaded_file).to eq "apache module"
|
48
|
+
expect(buffer.read).to eq "apache module"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
context "the second time it's called" do
|
53
|
+
it "serves the cached module from the disk" do
|
54
|
+
cached_module = File.join(cache_dir, "puppetlabs-apache-1.0.0.tar.gz")
|
55
|
+
File.open(cached_module, "w") do |file|
|
56
|
+
file.write "apache module"
|
57
|
+
end
|
58
|
+
expect(http_client).not_to receive(:download)
|
59
|
+
|
60
|
+
buffer = forge.get_module_buffer("puppetlabs", "apache", "1.0.0")
|
61
|
+
|
62
|
+
expect(buffer.read).to eq "apache module"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -19,18 +19,38 @@ require 'spec_helper'
|
|
19
19
|
module PuppetLibrary::Forge
|
20
20
|
describe Directory do
|
21
21
|
include ModuleSpecHelper
|
22
|
-
include FileUtils
|
23
22
|
|
24
|
-
let(:module_dir) {
|
23
|
+
let(:module_dir) { Tempdir.create("module_dir") }
|
25
24
|
let(:module_repo) { Directory.new(module_dir) }
|
26
25
|
|
27
|
-
|
26
|
+
after do
|
28
27
|
rm_rf module_dir
|
29
|
-
mkdir_p module_dir
|
30
28
|
end
|
31
29
|
|
32
|
-
|
33
|
-
|
30
|
+
describe "#initialize" do
|
31
|
+
context "when the module directory doesn't exist" do
|
32
|
+
before do
|
33
|
+
rm_rf module_dir
|
34
|
+
end
|
35
|
+
|
36
|
+
it "raises an error" do
|
37
|
+
expect {
|
38
|
+
Directory.new(module_dir)
|
39
|
+
}.to raise_error /Module directory .* doesn't exist/
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
context "when the module directory isn't readable" do
|
44
|
+
before do
|
45
|
+
chmod 0400, module_dir
|
46
|
+
end
|
47
|
+
|
48
|
+
it "raises an error" do
|
49
|
+
expect {
|
50
|
+
Directory.new(module_dir)
|
51
|
+
}.to raise_error /Module directory .* isn't readable/
|
52
|
+
end
|
53
|
+
end
|
34
54
|
end
|
35
55
|
|
36
56
|
describe "#get_module" do
|
data/spec/forge/proxy_spec.rb
CHANGED
@@ -24,24 +24,6 @@ module PuppetLibrary::Forge
|
|
24
24
|
let(:download_cache) { PuppetLibrary::Http::Cache::InMemory.new }
|
25
25
|
let(:forge) { Proxy.new("http://puppetforge.example.com", query_cache, download_cache, http_client) }
|
26
26
|
|
27
|
-
describe "url" do
|
28
|
-
it "defaults to HTTP, when protocol not specified" do
|
29
|
-
forge = Proxy.new("forge.puppetlabs.com", query_cache, download_cache, http_client)
|
30
|
-
|
31
|
-
expect(http_client).to receive(:get).with("http:\/\/forge.puppetlabs.com/puppetlabs/apache.json").and_return('{"puppetlabs/apache":[]}')
|
32
|
-
|
33
|
-
forge.get_module_metadata("puppetlabs", "apache")
|
34
|
-
end
|
35
|
-
|
36
|
-
it "copes with a trailing slash" do
|
37
|
-
forge = Proxy.new("forge.puppetlabs.com/", query_cache, download_cache, http_client)
|
38
|
-
|
39
|
-
expect(http_client).to receive(:get).with("http:\/\/forge.puppetlabs.com/puppetlabs/apache.json").and_return('{"puppetlabs/apache":[]}')
|
40
|
-
|
41
|
-
forge.get_module_metadata("puppetlabs", "apache")
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
27
|
describe "#search_modules" do
|
46
28
|
it "forwards the request directly" do
|
47
29
|
search_results = '["a","b","c"]'
|
@@ -180,15 +162,16 @@ module PuppetLibrary::Forge
|
|
180
162
|
end
|
181
163
|
|
182
164
|
context "when the module is found" do
|
183
|
-
it "forwards the request directly" do
|
184
|
-
|
165
|
+
it "forwards the request directly, but adjusts the module download locations" do
|
166
|
+
original_response = '{"puppetlabs/apache":[{"version":"1.0.0","file":"/puppetlabs/apache/1.0.0.tar.gz","dependencies":[["puppetlabs/concat",">= 1.0.0"],["puppetlabs/stdlib","~> 2.0.0"]]},{"version":"2.0.0","file":"/puppetlabs/apache/2.0.0.tar.gz","dependencies":[]}]}'
|
167
|
+
doctored_response = '{"puppetlabs/apache":[{"version":"1.0.0","file":"/modules/puppetlabs-apache-1.0.0.tar.gz","dependencies":[["puppetlabs/concat",">= 1.0.0"],["puppetlabs/stdlib","~> 2.0.0"]]},{"version":"2.0.0","file":"/modules/puppetlabs-apache-2.0.0.tar.gz","dependencies":[]}]}'
|
185
168
|
expect(http_client).to receive(:get).
|
186
169
|
with("http://puppetforge.example.com/api/v1/releases.json?module=puppetlabs/apache&version=1.0.0").
|
187
|
-
and_return(
|
170
|
+
and_return(original_response)
|
188
171
|
|
189
172
|
result = forge.get_module_metadata_with_dependencies("puppetlabs", "apache", "1.0.0")
|
190
173
|
|
191
|
-
expect(result).to eq JSON.parse(
|
174
|
+
expect(result).to eq JSON.parse(doctored_response)
|
192
175
|
end
|
193
176
|
|
194
177
|
it "caches the result" do
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
# Puppet Library
|
3
|
+
# Copyright (C) 2014 drrb
|
4
|
+
#
|
5
|
+
# This program is free software: you can redistribute it and/or modify
|
6
|
+
# it under the terms of the GNU General Public License as published by
|
7
|
+
# the Free Software Foundation, either version 3 of the License, or
|
8
|
+
# (at your option) any later version.
|
9
|
+
#
|
10
|
+
# This program is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
# GNU General Public License for more details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU General Public License
|
16
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
|
18
|
+
require 'spec_helper'
|
19
|
+
|
20
|
+
module PuppetLibrary::Http::Cache
|
21
|
+
describe Disk do
|
22
|
+
let(:cache_dir) { Tempdir.new("modulecache").path }
|
23
|
+
let(:cache) { Disk.new(cache_dir) }
|
24
|
+
|
25
|
+
after do
|
26
|
+
rm_rf cache_dir
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "#get" do
|
30
|
+
context "the first time it's called" do
|
31
|
+
it "returns the value from the block" do
|
32
|
+
buffer = StringIO.new "hello"
|
33
|
+
|
34
|
+
result = cache.get("my-file") { buffer }
|
35
|
+
|
36
|
+
expect(result.read).to eq "hello"
|
37
|
+
end
|
38
|
+
|
39
|
+
it "saves the content to disk" do
|
40
|
+
buffer = StringIO.new "hello"
|
41
|
+
|
42
|
+
result = cache.get("dir/my-file") { buffer }
|
43
|
+
|
44
|
+
path = File.join(cache_dir, "dir", "my-file")
|
45
|
+
expect(File.read(path)).to eq "hello"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context "the second time it's called" do
|
50
|
+
it "reads the config from the disk" do
|
51
|
+
cache.get("my-file") { StringIO.new "hello" }
|
52
|
+
result = cache.get("my-file") { raise "shouldn't be called" }
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -34,7 +34,7 @@ module PuppetLibrary::Http::Cache
|
|
34
34
|
context "the second time it's called" do
|
35
35
|
it "returns the cached value" do
|
36
36
|
cache.get("greeting") { "hello" }
|
37
|
-
greeting = cache.get("greeting") { "
|
37
|
+
greeting = cache.get("greeting") { raise "shouldn't be called" }
|
38
38
|
|
39
39
|
expect(greeting).to eq "hello"
|
40
40
|
end
|
data/spec/http/url_spec.rb
CHANGED
@@ -34,6 +34,22 @@ module PuppetLibrary::Http
|
|
34
34
|
result = Url.normalize "http://localhost/"
|
35
35
|
expect(result).to eq "http://localhost"
|
36
36
|
end
|
37
|
+
|
38
|
+
context "when the URL has an invalid scheme" do
|
39
|
+
it "raises an error" do
|
40
|
+
expect {
|
41
|
+
Url.normalize "ftp://example.com"
|
42
|
+
}.to raise_exception /Invalid URL/
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
context "when the URL is invalid" do
|
47
|
+
it "raises an error" do
|
48
|
+
expect {
|
49
|
+
Url.normalize "a b"
|
50
|
+
}.to raise_exception /Invalid URL/
|
51
|
+
end
|
52
|
+
end
|
37
53
|
end
|
38
54
|
end
|
39
55
|
end
|
data/spec/puppet_library_spec.rb
CHANGED
@@ -140,6 +140,39 @@ module PuppetLibrary
|
|
140
140
|
|
141
141
|
library.go(["--proxy", "http://forge1.example.com", "--proxy", "http://forge2.example.com"])
|
142
142
|
end
|
143
|
+
|
144
|
+
context "when no protocol is specified" do
|
145
|
+
it "defaults to HTTP" do
|
146
|
+
expect(Forge::Proxy).to receive(:new).with("http://forge.example.com")
|
147
|
+
|
148
|
+
library.go(["--proxy", "forge.example.com"])
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
context "when the URL contains a trailing slash" do
|
153
|
+
it "removes the slash" do
|
154
|
+
expect(Forge::Proxy).to receive(:new).with("http://forge.example.com")
|
155
|
+
|
156
|
+
library.go(["--proxy", "http://forge.example.com/"])
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
context "when using --cache-basedir option" do
|
162
|
+
it "uses the specified directory to hold cache directories for all proxies" do
|
163
|
+
proxy1 = double('proxy')
|
164
|
+
expect(Forge::Cache).to receive(:new).with("http://forge1.example.com", "/var/modules/forge1.example.com").and_return(proxy1)
|
165
|
+
expect(forge).to receive(:add_forge).with(proxy1)
|
166
|
+
expect(Rack::Server).to receive(:start).with(default_options)
|
167
|
+
|
168
|
+
library.go(["--proxy", "http://forge1.example.com", "--cache-basedir", "/var/modules"])
|
169
|
+
end
|
170
|
+
|
171
|
+
it "expands the path specified" do
|
172
|
+
expect(Forge::Cache).to receive(:new).with("http://forge1.example.com", "/var/modules/forge1.example.com")
|
173
|
+
|
174
|
+
library.go(["--proxy", "http://forge1.example.com", "--cache-basedir", "/var/../var/modules"])
|
175
|
+
end
|
143
176
|
end
|
144
177
|
|
145
178
|
context "when using --module-dir option" do
|
@@ -172,8 +205,8 @@ module PuppetLibrary
|
|
172
205
|
expect(log).to receive(:puts).with(/Host: default/)
|
173
206
|
expect(log).to receive(:puts).with(/Server: default/)
|
174
207
|
expect(log).to receive(:puts).with(/Forges:/)
|
175
|
-
expect(log).to receive(:puts).with(/- PuppetLibrary::Forge::
|
176
|
-
library.go(["--
|
208
|
+
expect(log).to receive(:puts).with(/- PuppetLibrary::Forge::Proxy: http:\/\/forge.example.com/)
|
209
|
+
library.go(["--proxy", "http://forge.example.com"])
|
177
210
|
end
|
178
211
|
end
|
179
212
|
end
|
data/spec/server_spec.rb
CHANGED
@@ -196,6 +196,15 @@ module PuppetLibrary
|
|
196
196
|
end
|
197
197
|
|
198
198
|
describe "GET /api/v1/releases.json" do
|
199
|
+
context "when module parameter not specified" do
|
200
|
+
it "returns an error" do
|
201
|
+
get "/api/v1/releases.json"
|
202
|
+
|
203
|
+
expect(last_response.body).to eq('{"error":"The number of version constraints in the query does not match the number of module names"}')
|
204
|
+
expect(last_response.status).to eq(400)
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
199
208
|
it "gets metadata for module and dependencies" do
|
200
209
|
metadata = {
|
201
210
|
"puppetlabs/apache" => [
|
data/spec/spec_helper.rb
CHANGED
@@ -21,3 +21,21 @@ require 'module_spec_helper'
|
|
21
21
|
require 'pry'
|
22
22
|
require 'rack'
|
23
23
|
require 'tempfile'
|
24
|
+
require 'fileutils'
|
25
|
+
|
26
|
+
include FileUtils
|
27
|
+
|
28
|
+
class Tempdir
|
29
|
+
attr_reader :path
|
30
|
+
|
31
|
+
def self.create(name)
|
32
|
+
Tempdir.new(name).path
|
33
|
+
end
|
34
|
+
|
35
|
+
def initialize(name)
|
36
|
+
file = Tempfile.new(name)
|
37
|
+
@path = file.path
|
38
|
+
file.unlink
|
39
|
+
FileUtils.mkdir @path
|
40
|
+
end
|
41
|
+
end
|
@@ -18,13 +18,32 @@
|
|
18
18
|
require 'spec_helper'
|
19
19
|
require 'open-uri'
|
20
20
|
|
21
|
+
|
22
|
+
RSpec::Matchers.define :be_cached do
|
23
|
+
match do |mod_file|
|
24
|
+
! Dir[File.join(cache_dir, mod_file)].empty?
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
RSpec::Matchers.define :be_installed do
|
29
|
+
match do |mod_name|
|
30
|
+
File.directory?(File.join(project_dir, "modules", mod_name))
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def write_puppetfile(content)
|
35
|
+
File.open("#{project_dir}/Puppetfile", "w") do |puppetfile|
|
36
|
+
puppetfile.puts content
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
21
40
|
module PuppetLibrary
|
22
|
-
describe "
|
41
|
+
describe "offline proxy" do
|
23
42
|
include ModuleSpecHelper
|
24
|
-
include FileUtils
|
25
43
|
|
26
|
-
let(:module_dir) {
|
27
|
-
let(:project_dir) {
|
44
|
+
let(:module_dir) { Tempdir.create("module_dir") }
|
45
|
+
let(:project_dir) { Tempdir.create("project_dir") }
|
46
|
+
let(:cache_dir) { Tempdir.create("cache_dir") }
|
28
47
|
let(:start_dir) { pwd }
|
29
48
|
let(:disk_forge) { Forge::Directory.new(module_dir) }
|
30
49
|
let(:disk_server) do
|
@@ -45,7 +64,7 @@ module PuppetLibrary
|
|
45
64
|
disk_rack_server.start
|
46
65
|
end
|
47
66
|
end
|
48
|
-
let(:proxy_forge) { Forge::
|
67
|
+
let(:proxy_forge) { Forge::Cache.new("http://localhost:9000", cache_dir) }
|
49
68
|
let(:proxy_server) do
|
50
69
|
Server.set_up do |server|
|
51
70
|
server.forge proxy_forge
|
@@ -66,10 +85,6 @@ module PuppetLibrary
|
|
66
85
|
end
|
67
86
|
|
68
87
|
before do
|
69
|
-
rm_rf module_dir
|
70
|
-
rm_rf project_dir
|
71
|
-
mkdir_p module_dir
|
72
|
-
mkdir_p project_dir
|
73
88
|
# Initialize to catch wiring errors
|
74
89
|
disk_rack_server
|
75
90
|
proxy_rack_server
|
@@ -84,15 +99,10 @@ module PuppetLibrary
|
|
84
99
|
after do
|
85
100
|
rm_rf module_dir
|
86
101
|
rm_rf project_dir
|
102
|
+
rm_rf cache_dir
|
87
103
|
cd start_dir
|
88
104
|
end
|
89
105
|
|
90
|
-
def write_puppetfile(content)
|
91
|
-
File.open("#{project_dir}/Puppetfile", "w") do |puppetfile|
|
92
|
-
puppetfile.puts content
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
106
|
it "queries, downloads and searches through a proxy to a directory" do
|
97
107
|
add_module("puppetlabs", "apache", "1.0.0") do |metadata|
|
98
108
|
metadata["dependencies"] << { "name" => "puppetlabs/concat", "version_requirement" => ">= 2.0.0" }
|
@@ -108,10 +118,13 @@ module PuppetLibrary
|
|
108
118
|
|
109
119
|
# Install modules through the proxy
|
110
120
|
system "librarian-puppet install" or fail "call to puppet-library failed"
|
111
|
-
expect(
|
112
|
-
expect(
|
113
|
-
expect(
|
114
|
-
|
121
|
+
expect("apache").to be_installed
|
122
|
+
expect("concat").to be_installed
|
123
|
+
expect("stdlib").to be_installed
|
124
|
+
|
125
|
+
expect("puppetlabs-apache-1.0.0.tar.gz").to be_cached
|
126
|
+
expect("puppetlabs-concat-2.0.0.tar.gz").to be_cached
|
127
|
+
expect("puppetlabs-stdlib-3.0.0.tar.gz").to be_cached
|
115
128
|
|
116
129
|
# Search through the proxy
|
117
130
|
search_results = JSON.parse(open("http://localhost:9001/modules.json").read)
|
@@ -123,4 +136,69 @@ module PuppetLibrary
|
|
123
136
|
expect(found_modules["puppetlabs/stdlib"]).to eq "3.0.0"
|
124
137
|
end
|
125
138
|
end
|
139
|
+
|
140
|
+
describe "online proxy", :online => true do
|
141
|
+
include ModuleSpecHelper
|
142
|
+
|
143
|
+
let(:project_dir) { Tempdir.create("project_dir") }
|
144
|
+
let(:module_dir) { Tempdir.create("module_dir") }
|
145
|
+
let(:cache_dir) { Tempdir.create("cache_dir") }
|
146
|
+
let(:start_dir) { pwd }
|
147
|
+
let(:proxy_server) do
|
148
|
+
Server.set_up do |server|
|
149
|
+
server.forge Forge::Directory.new(module_dir)
|
150
|
+
server.forge Forge::Cache.new("http://forge.puppetlabs.com", cache_dir)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
let(:proxy_rack_server) do
|
154
|
+
Rack::Server.new(
|
155
|
+
:app => proxy_server,
|
156
|
+
:Host => "localhost",
|
157
|
+
:Port => 9002,
|
158
|
+
:server => "webrick"
|
159
|
+
)
|
160
|
+
end
|
161
|
+
let(:proxy_server_runner) do
|
162
|
+
Thread.new do
|
163
|
+
proxy_rack_server.start
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
before do
|
168
|
+
# Initialize to catch wiring errors
|
169
|
+
proxy_rack_server
|
170
|
+
|
171
|
+
# Start the server
|
172
|
+
proxy_server_runner
|
173
|
+
start_dir
|
174
|
+
cd project_dir
|
175
|
+
end
|
176
|
+
|
177
|
+
after do
|
178
|
+
rm_rf module_dir
|
179
|
+
rm_rf project_dir
|
180
|
+
rm_rf cache_dir
|
181
|
+
cd start_dir
|
182
|
+
end
|
183
|
+
|
184
|
+
it "queries, downloads and searches through a proxy to a directory" do
|
185
|
+
add_module("drrb", "tomcat", "1.0.0") do |metadata|
|
186
|
+
metadata["dependencies"] << { "name" => "puppetlabs/apache", "version_requirement" => "0.9.0" }
|
187
|
+
end
|
188
|
+
|
189
|
+
write_puppetfile <<-EOF
|
190
|
+
forge 'http://localhost:9002'
|
191
|
+
mod 'drrb/tomcat'
|
192
|
+
EOF
|
193
|
+
|
194
|
+
# Install modules through the proxy
|
195
|
+
system "librarian-puppet install" or fail "call to puppet-library failed"
|
196
|
+
expect("tomcat").to be_installed
|
197
|
+
expect("apache").to be_installed
|
198
|
+
expect("concat").to be_installed
|
199
|
+
expect("stdlib").to be_installed
|
200
|
+
|
201
|
+
expect("puppetlabs-apache-*.tar.gz").to be_cached
|
202
|
+
end
|
203
|
+
end
|
126
204
|
end
|
metadata
CHANGED
@@ -1,55 +1,55 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: puppet-library
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- drrb
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-02-
|
11
|
+
date: 2014-02-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sinatra
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - '>='
|
17
|
+
- - ! '>='
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - '>='
|
24
|
+
- - ! '>='
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: json
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - '>='
|
31
|
+
- - ! '>='
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '0'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - '>='
|
38
|
+
- - ! '>='
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: haml
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- - '>='
|
45
|
+
- - ! '>='
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: '0'
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- - '>='
|
52
|
+
- - ! '>='
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
@@ -70,42 +70,42 @@ dependencies:
|
|
70
70
|
name: coveralls
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- - '>='
|
73
|
+
- - ! '>='
|
74
74
|
- !ruby/object:Gem::Version
|
75
75
|
version: '0'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- - '>='
|
80
|
+
- - ! '>='
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: gitsu
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
-
- - '>='
|
87
|
+
- - ! '>='
|
88
88
|
- !ruby/object:Gem::Version
|
89
89
|
version: '0'
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
|
-
- - '>='
|
94
|
+
- - ! '>='
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: librarian-puppet
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
|
-
- - '>='
|
101
|
+
- - ! '>='
|
102
102
|
- !ruby/object:Gem::Version
|
103
103
|
version: '0'
|
104
104
|
type: :development
|
105
105
|
prerelease: false
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
|
-
- - '>='
|
108
|
+
- - ! '>='
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '0'
|
111
111
|
- !ruby/object:Gem::Dependency
|
@@ -126,14 +126,14 @@ dependencies:
|
|
126
126
|
name: pry
|
127
127
|
requirement: !ruby/object:Gem::Requirement
|
128
128
|
requirements:
|
129
|
-
- - '>='
|
129
|
+
- - ! '>='
|
130
130
|
- !ruby/object:Gem::Version
|
131
131
|
version: '0'
|
132
132
|
type: :development
|
133
133
|
prerelease: false
|
134
134
|
version_requirements: !ruby/object:Gem::Requirement
|
135
135
|
requirements:
|
136
|
-
- - '>='
|
136
|
+
- - ! '>='
|
137
137
|
- !ruby/object:Gem::Version
|
138
138
|
version: '0'
|
139
139
|
- !ruby/object:Gem::Dependency
|
@@ -154,140 +154,140 @@ dependencies:
|
|
154
154
|
name: rack-test
|
155
155
|
requirement: !ruby/object:Gem::Requirement
|
156
156
|
requirements:
|
157
|
-
- - '>='
|
157
|
+
- - ! '>='
|
158
158
|
- !ruby/object:Gem::Version
|
159
159
|
version: '0'
|
160
160
|
type: :development
|
161
161
|
prerelease: false
|
162
162
|
version_requirements: !ruby/object:Gem::Requirement
|
163
163
|
requirements:
|
164
|
-
- - '>='
|
164
|
+
- - ! '>='
|
165
165
|
- !ruby/object:Gem::Version
|
166
166
|
version: '0'
|
167
167
|
- !ruby/object:Gem::Dependency
|
168
168
|
name: rake
|
169
169
|
requirement: !ruby/object:Gem::Requirement
|
170
170
|
requirements:
|
171
|
-
- - '>='
|
171
|
+
- - ! '>='
|
172
172
|
- !ruby/object:Gem::Version
|
173
173
|
version: '0'
|
174
174
|
type: :development
|
175
175
|
prerelease: false
|
176
176
|
version_requirements: !ruby/object:Gem::Requirement
|
177
177
|
requirements:
|
178
|
-
- - '>='
|
178
|
+
- - ! '>='
|
179
179
|
- !ruby/object:Gem::Version
|
180
180
|
version: '0'
|
181
181
|
- !ruby/object:Gem::Dependency
|
182
182
|
name: rspec
|
183
183
|
requirement: !ruby/object:Gem::Requirement
|
184
184
|
requirements:
|
185
|
-
- - '>='
|
185
|
+
- - ! '>='
|
186
186
|
- !ruby/object:Gem::Version
|
187
187
|
version: '0'
|
188
188
|
type: :development
|
189
189
|
prerelease: false
|
190
190
|
version_requirements: !ruby/object:Gem::Requirement
|
191
191
|
requirements:
|
192
|
-
- - '>='
|
192
|
+
- - ! '>='
|
193
193
|
- !ruby/object:Gem::Version
|
194
194
|
version: '0'
|
195
195
|
- !ruby/object:Gem::Dependency
|
196
196
|
name: simplecov
|
197
197
|
requirement: !ruby/object:Gem::Requirement
|
198
198
|
requirements:
|
199
|
-
- - '>='
|
199
|
+
- - ! '>='
|
200
200
|
- !ruby/object:Gem::Version
|
201
201
|
version: '0'
|
202
202
|
type: :development
|
203
203
|
prerelease: false
|
204
204
|
version_requirements: !ruby/object:Gem::Requirement
|
205
205
|
requirements:
|
206
|
-
- - '>='
|
206
|
+
- - ! '>='
|
207
207
|
- !ruby/object:Gem::Version
|
208
208
|
version: '0'
|
209
209
|
- !ruby/object:Gem::Dependency
|
210
210
|
name: guard
|
211
211
|
requirement: !ruby/object:Gem::Requirement
|
212
212
|
requirements:
|
213
|
-
- - '>='
|
213
|
+
- - ! '>='
|
214
214
|
- !ruby/object:Gem::Version
|
215
215
|
version: '0'
|
216
216
|
type: :development
|
217
217
|
prerelease: false
|
218
218
|
version_requirements: !ruby/object:Gem::Requirement
|
219
219
|
requirements:
|
220
|
-
- - '>='
|
220
|
+
- - ! '>='
|
221
221
|
- !ruby/object:Gem::Version
|
222
222
|
version: '0'
|
223
223
|
- !ruby/object:Gem::Dependency
|
224
224
|
name: guard-rspec
|
225
225
|
requirement: !ruby/object:Gem::Requirement
|
226
226
|
requirements:
|
227
|
-
- - '>='
|
227
|
+
- - ! '>='
|
228
228
|
- !ruby/object:Gem::Version
|
229
229
|
version: '0'
|
230
230
|
type: :development
|
231
231
|
prerelease: false
|
232
232
|
version_requirements: !ruby/object:Gem::Requirement
|
233
233
|
requirements:
|
234
|
-
- - '>='
|
234
|
+
- - ! '>='
|
235
235
|
- !ruby/object:Gem::Version
|
236
236
|
version: '0'
|
237
237
|
- !ruby/object:Gem::Dependency
|
238
238
|
name: terminal-notifier-guard
|
239
239
|
requirement: !ruby/object:Gem::Requirement
|
240
240
|
requirements:
|
241
|
-
- - '>='
|
241
|
+
- - ! '>='
|
242
242
|
- !ruby/object:Gem::Version
|
243
243
|
version: '0'
|
244
244
|
type: :development
|
245
245
|
prerelease: false
|
246
246
|
version_requirements: !ruby/object:Gem::Requirement
|
247
247
|
requirements:
|
248
|
-
- - '>='
|
248
|
+
- - ! '>='
|
249
249
|
- !ruby/object:Gem::Version
|
250
250
|
version: '0'
|
251
251
|
- !ruby/object:Gem::Dependency
|
252
252
|
name: capybara
|
253
253
|
requirement: !ruby/object:Gem::Requirement
|
254
254
|
requirements:
|
255
|
-
- - '>='
|
255
|
+
- - ! '>='
|
256
256
|
- !ruby/object:Gem::Version
|
257
257
|
version: '0'
|
258
258
|
type: :development
|
259
259
|
prerelease: false
|
260
260
|
version_requirements: !ruby/object:Gem::Requirement
|
261
261
|
requirements:
|
262
|
-
- - '>='
|
262
|
+
- - ! '>='
|
263
263
|
- !ruby/object:Gem::Version
|
264
264
|
version: '0'
|
265
265
|
- !ruby/object:Gem::Dependency
|
266
266
|
name: nokogiri
|
267
267
|
requirement: !ruby/object:Gem::Requirement
|
268
268
|
requirements:
|
269
|
-
- - '>='
|
269
|
+
- - ! '>='
|
270
270
|
- !ruby/object:Gem::Version
|
271
271
|
version: '0'
|
272
272
|
type: :development
|
273
273
|
prerelease: false
|
274
274
|
version_requirements: !ruby/object:Gem::Requirement
|
275
275
|
requirements:
|
276
|
-
- - '>='
|
276
|
+
- - ! '>='
|
277
277
|
- !ruby/object:Gem::Version
|
278
278
|
version: '0'
|
279
279
|
- !ruby/object:Gem::Dependency
|
280
280
|
name: cucumber
|
281
281
|
requirement: !ruby/object:Gem::Requirement
|
282
282
|
requirements:
|
283
|
-
- - '>='
|
283
|
+
- - ! '>='
|
284
284
|
- !ruby/object:Gem::Version
|
285
285
|
version: '0'
|
286
286
|
type: :development
|
287
287
|
prerelease: false
|
288
288
|
version_requirements: !ruby/object:Gem::Requirement
|
289
289
|
requirements:
|
290
|
-
- - '>='
|
290
|
+
- - ! '>='
|
291
291
|
- !ruby/object:Gem::Version
|
292
292
|
version: '0'
|
293
293
|
description: A Puppet module server
|
@@ -323,12 +323,14 @@ files:
|
|
323
323
|
- lib/puppet_library/app/views/module_not_found.haml
|
324
324
|
- lib/puppet_library/forge.rb
|
325
325
|
- lib/puppet_library/forge/abstract.rb
|
326
|
+
- lib/puppet_library/forge/cache.rb
|
326
327
|
- lib/puppet_library/forge/directory.rb
|
327
328
|
- lib/puppet_library/forge/multi.rb
|
328
329
|
- lib/puppet_library/forge/proxy.rb
|
329
330
|
- lib/puppet_library/forge/search_result.rb
|
330
331
|
- lib/puppet_library/http.rb
|
331
332
|
- lib/puppet_library/http/cache.rb
|
333
|
+
- lib/puppet_library/http/cache/disk.rb
|
332
334
|
- lib/puppet_library/http/cache/in_memory.rb
|
333
335
|
- lib/puppet_library/http/cache/noop.rb
|
334
336
|
- lib/puppet_library/http/http_client.rb
|
@@ -339,9 +341,11 @@ files:
|
|
339
341
|
- lib/puppet_library/version.rb
|
340
342
|
- puppet-library.gemspec
|
341
343
|
- spec/forge/abstract_spec.rb
|
344
|
+
- spec/forge/cache_spec.rb
|
342
345
|
- spec/forge/directory_spec.rb
|
343
346
|
- spec/forge/multi_spec.rb
|
344
347
|
- spec/forge/proxy_spec.rb
|
348
|
+
- spec/http/cache/disk_spec.rb
|
345
349
|
- spec/http/cache/in_memory_spec.rb
|
346
350
|
- spec/http/cache/noop_spec.rb
|
347
351
|
- spec/http/http_client_spec.rb
|
@@ -362,17 +366,17 @@ require_paths:
|
|
362
366
|
- lib
|
363
367
|
required_ruby_version: !ruby/object:Gem::Requirement
|
364
368
|
requirements:
|
365
|
-
- - '>='
|
369
|
+
- - ! '>='
|
366
370
|
- !ruby/object:Gem::Version
|
367
371
|
version: '0'
|
368
372
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
369
373
|
requirements:
|
370
|
-
- - '>='
|
374
|
+
- - ! '>='
|
371
375
|
- !ruby/object:Gem::Version
|
372
376
|
version: '0'
|
373
377
|
requirements: []
|
374
378
|
rubyforge_project:
|
375
|
-
rubygems_version: 2.
|
379
|
+
rubygems_version: 2.2.1
|
376
380
|
signing_key:
|
377
381
|
specification_version: 4
|
378
382
|
summary: Puppet Library is a private Puppet module server that's compatible with librarian-puppet.
|
@@ -383,9 +387,11 @@ test_files:
|
|
383
387
|
- features/step_definitions/sinatra_steps.rb
|
384
388
|
- features/support/env.rb
|
385
389
|
- spec/forge/abstract_spec.rb
|
390
|
+
- spec/forge/cache_spec.rb
|
386
391
|
- spec/forge/directory_spec.rb
|
387
392
|
- spec/forge/multi_spec.rb
|
388
393
|
- spec/forge/proxy_spec.rb
|
394
|
+
- spec/http/cache/disk_spec.rb
|
389
395
|
- spec/http/cache/in_memory_spec.rb
|
390
396
|
- spec/http/cache/noop_spec.rb
|
391
397
|
- spec/http/http_client_spec.rb
|