puppet-library 0.0.1 → 0.0.2
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 +4 -4
- data/.licenseignore +1 -0
- data/Rakefile +12 -0
- data/TODO.yml +5 -0
- data/bin/puppet-library +1 -33
- data/config.ru +2 -0
- data/lib/puppet_library.rb +8 -2
- data/lib/puppet_library/module_metadata.rb +67 -0
- data/lib/puppet_library/{module_repo.rb → module_repo/directory.rb} +4 -2
- data/lib/puppet_library/module_repo/multi.rb +43 -0
- data/lib/puppet_library/puppet_library.rb +102 -0
- data/lib/puppet_library/server.rb +66 -83
- data/lib/puppet_library/util.rb +31 -0
- data/lib/puppet_library/version.rb +1 -1
- data/spec/{module_repo_spec.rb → module_repo/directory_spec.rb} +3 -3
- data/spec/module_repo/multi_spec.rb +97 -0
- data/spec/puppet_library_spec.rb +95 -0
- data/spec/util_spec.rb +33 -0
- metadata +16 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 038f863a597766d136e7db4d8f71245844334d7c
|
4
|
+
data.tar.gz: 0f98e71f5110f3875d4c03a401446bf400faa0bc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 210fbe7f939854063796aacf44bcdd00da819f3ce97ede62ed58d00ad8c7cd787630aba645bbd460064a5f142da86613b65c920f7995bade1ded406fa049d6b6
|
7
|
+
data.tar.gz: 4978484237188df4973d38aa8880dbfe3829d17753714f8f20cbb29bf85fbbb6426facb137fb71aefe4125e34dcf690142adf45747c5bffc869009abdb825458
|
data/.licenseignore
CHANGED
data/Rakefile
CHANGED
@@ -48,3 +48,15 @@ task "version" do
|
|
48
48
|
puts PuppetLibrary::VERSION
|
49
49
|
end
|
50
50
|
|
51
|
+
desc "Release Puppet Library"
|
52
|
+
task "push-release" => ["check-license", :verify] do
|
53
|
+
puts "Releasing #{PuppetLibrary::VERSION}"
|
54
|
+
Rake::Task[:release].invoke
|
55
|
+
|
56
|
+
major, minor, patch = PuppetLibrary::VERSION.split(".").map {|n| n.to_i}
|
57
|
+
new_version = "#{major}.#{minor + 1}.0"
|
58
|
+
puts "Updating version number to #{new_version}"
|
59
|
+
system(%q[sed -i '' -E 's/VERSION = ".*"/VERSION = "] + new_version + %q["/' lib/puppet_library/version.rb]) or fail "Couldn't update version"
|
60
|
+
PuppetLibrary::VERSION.replace new_version
|
61
|
+
system "git commit lib/puppet_library/version.rb --message='[release] Incremented version number'" or fail "Couldn't commit new version number"
|
62
|
+
end
|
data/TODO.yml
ADDED
data/bin/puppet-library
CHANGED
@@ -22,37 +22,5 @@ require "puppet_library"
|
|
22
22
|
require 'optparse'
|
23
23
|
|
24
24
|
module PuppetLibrary
|
25
|
-
|
26
|
-
OptionParser.new do |opts|
|
27
|
-
opts.banner = "Usage: #{File.basename $0} [options]"
|
28
|
-
|
29
|
-
options[:port] = "9292"
|
30
|
-
opts.on("-p", "--port [PORT]", "Port to listen on (defaults to #{options[:port]}") do |port|
|
31
|
-
options[:port] = port
|
32
|
-
end
|
33
|
-
|
34
|
-
options[:hostname] = "0.0.0.0"
|
35
|
-
opts.on("-b", "--bind-host [HOSTNAME]", "Host name to bind to (defaults to #{options[:hostname]}") do |hostname|
|
36
|
-
options[:hostname] = hostname
|
37
|
-
end
|
38
|
-
|
39
|
-
options[:module_dir] = "./modules"
|
40
|
-
opts.on("-m", "--module-dir [DIR]", "Directory containing the modules (defaults to #{options[:module_dir]})") do |module_dir|
|
41
|
-
options[:module_dir] = module_dir
|
42
|
-
end
|
43
|
-
end.parse!
|
44
|
-
|
45
|
-
server = Server.new(ModuleRepo.new(options[:module_dir]))
|
46
|
-
|
47
|
-
dispatch = Rack::Builder.app do
|
48
|
-
map '/' do
|
49
|
-
run Server.new
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
Rack::Server.start({
|
54
|
-
app: dispatch,
|
55
|
-
Host: options[:hostname],
|
56
|
-
Port: options[:port]
|
57
|
-
})
|
25
|
+
PuppetLibrary.new.go(ARGV)
|
58
26
|
end
|
data/config.ru
CHANGED
@@ -15,6 +15,8 @@
|
|
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 'rubygems'
|
18
19
|
require 'puppet_library'
|
19
20
|
|
21
|
+
PuppetLibrary::Server.set :module_repo, ModuleRepo::Directory.new("/var/puppet-library/modules")
|
20
22
|
run PuppetLibrary::Server
|
data/lib/puppet_library.rb
CHANGED
@@ -15,5 +15,11 @@
|
|
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
|
19
|
-
|
18
|
+
require 'puppet_library/version'
|
19
|
+
|
20
|
+
require 'puppet_library/puppet_library'
|
21
|
+
require 'puppet_library/server'
|
22
|
+
require 'puppet_library/module_metadata'
|
23
|
+
require 'puppet_library/module_repo/directory'
|
24
|
+
require 'puppet_library/module_repo/multi'
|
25
|
+
require 'puppet_library/util'
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
# Puppet Library
|
3
|
+
# Copyright (C) 2013 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
|
19
|
+
class ModuleMetadata
|
20
|
+
|
21
|
+
def initialize(metadata)
|
22
|
+
@metadata = metadata
|
23
|
+
end
|
24
|
+
|
25
|
+
def author
|
26
|
+
@metadata["name"][/^[^-]+/]
|
27
|
+
end
|
28
|
+
|
29
|
+
def name
|
30
|
+
@metadata["name"].sub(/^[^-]+-/, "")
|
31
|
+
end
|
32
|
+
|
33
|
+
def full_name
|
34
|
+
@metadata["name"].sub("-", "/")
|
35
|
+
end
|
36
|
+
|
37
|
+
def version
|
38
|
+
@metadata["version"]
|
39
|
+
end
|
40
|
+
|
41
|
+
def dependencies
|
42
|
+
@metadata["dependencies"]
|
43
|
+
end
|
44
|
+
|
45
|
+
def dependency_names
|
46
|
+
dependencies.map {|d| d["name"]}
|
47
|
+
end
|
48
|
+
|
49
|
+
def to_info
|
50
|
+
{
|
51
|
+
"author" => author,
|
52
|
+
"full_name" => full_name,
|
53
|
+
"name" => name,
|
54
|
+
"desc" => @metadata["description"],
|
55
|
+
"releases" => [ { "version" => version } ]
|
56
|
+
}
|
57
|
+
end
|
58
|
+
|
59
|
+
def to_version
|
60
|
+
{
|
61
|
+
"file" => "/modules/#{author}-#{name}-#{version}.tar.gz",
|
62
|
+
"version" => version,
|
63
|
+
"dependencies" => dependencies.map {|m| [ m["name"], m["version_requirement"] ]}
|
64
|
+
}
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -13,11 +13,13 @@
|
|
13
13
|
#
|
14
14
|
# You should have received a copy of the GNU General Public License
|
15
15
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
16
|
+
|
17
|
+
require 'json'
|
16
18
|
require 'rubygems/package'
|
17
19
|
require 'zlib'
|
18
20
|
|
19
|
-
module PuppetLibrary
|
20
|
-
class
|
21
|
+
module PuppetLibrary::ModuleRepo
|
22
|
+
class Directory
|
21
23
|
def initialize(module_dir)
|
22
24
|
@module_dir = module_dir
|
23
25
|
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
# Puppet Library
|
3
|
+
# Copyright (C) 2013 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::ModuleRepo
|
19
|
+
class Multi
|
20
|
+
def repos
|
21
|
+
@repos ||= []
|
22
|
+
end
|
23
|
+
|
24
|
+
def add_repo(repo)
|
25
|
+
repos << repo
|
26
|
+
end
|
27
|
+
|
28
|
+
def get_module(author, name, version)
|
29
|
+
repos.each do |repo|
|
30
|
+
mod = repo.get_module(author, name, version)
|
31
|
+
return mod unless mod.nil?
|
32
|
+
end
|
33
|
+
return nil
|
34
|
+
end
|
35
|
+
|
36
|
+
def get_metadata(author, name)
|
37
|
+
metadata_list = repos.inject([]) do |metadata_list, repo|
|
38
|
+
metadata_list + repo.get_metadata(author, name)
|
39
|
+
end
|
40
|
+
metadata_list.unique_by { |metadata| metadata["version"] }
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
# Puppet Library
|
3
|
+
# Copyright (C) 2013 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 'rack'
|
19
|
+
require 'puppet_library/module_repo/directory'
|
20
|
+
require 'puppet_library/module_repo/multi'
|
21
|
+
|
22
|
+
module PuppetLibrary
|
23
|
+
class PuppetLibrary
|
24
|
+
def initialize(log = STDERR)
|
25
|
+
@log = log
|
26
|
+
end
|
27
|
+
|
28
|
+
def go(args)
|
29
|
+
options = parse_options(args)
|
30
|
+
server = build_server(options)
|
31
|
+
announce_server_start(options)
|
32
|
+
|
33
|
+
start_server(server, options)
|
34
|
+
rescue ExpectedError => error
|
35
|
+
@log.puts "Error: #{error}"
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
def parse_options(args)
|
40
|
+
options = {}
|
41
|
+
option_parser = OptionParser.new do |opts|
|
42
|
+
opts.banner = "Usage: #{File.basename $0} [options]"
|
43
|
+
|
44
|
+
options[:port] = "9292"
|
45
|
+
opts.on("-p", "--port [PORT]", "Port to listen on (defaults to #{options[:port]})") do |port|
|
46
|
+
options[:port] = port
|
47
|
+
end
|
48
|
+
|
49
|
+
options[:hostname] = "0.0.0.0"
|
50
|
+
opts.on("-b", "--bind-host [HOSTNAME]", "Host name to bind to (defaults to #{options[:hostname]})") do |hostname|
|
51
|
+
options[:hostname] = hostname
|
52
|
+
end
|
53
|
+
|
54
|
+
options[:module_dirs] = []
|
55
|
+
opts.on("-m", "--module-dir [DIR]", "Directory containing the modules (can be specified multiple times. Defaults to './modules')") do |module_dir|
|
56
|
+
options[:module_dirs] << module_dir
|
57
|
+
end
|
58
|
+
end
|
59
|
+
begin
|
60
|
+
option_parser.parse(args)
|
61
|
+
rescue OptionParser::InvalidOption => parse_error
|
62
|
+
raise ExpectedError, parse_error.message + "\n" + option_parser.help
|
63
|
+
end
|
64
|
+
|
65
|
+
if options[:module_dirs].empty?
|
66
|
+
options[:module_dirs] << "./modules"
|
67
|
+
end
|
68
|
+
|
69
|
+
return options
|
70
|
+
end
|
71
|
+
|
72
|
+
def build_server(options)
|
73
|
+
module_repo = ModuleRepo::Multi.new
|
74
|
+
options[:module_dirs].each do |dir|
|
75
|
+
subrepo = ModuleRepo::Directory.new(dir)
|
76
|
+
module_repo.add_repo(subrepo)
|
77
|
+
end
|
78
|
+
Server.new(module_repo)
|
79
|
+
end
|
80
|
+
|
81
|
+
def announce_server_start(options)
|
82
|
+
@log.puts "Starting Puppet Library server:"
|
83
|
+
@log.puts " |- Port: #{options[:port]}"
|
84
|
+
@log.puts " |- Host: #{options[:hostname]}"
|
85
|
+
@log.puts " `- Module dirs:"
|
86
|
+
options[:module_dirs].each do |dir|
|
87
|
+
@log.puts " - #{dir}"
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def start_server(server, options)
|
92
|
+
Rack::Server.start(
|
93
|
+
:app => server,
|
94
|
+
:Host => options[:hostname],
|
95
|
+
:Port => options[:port]
|
96
|
+
)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
class ExpectedError < StandardError
|
101
|
+
end
|
102
|
+
end
|
@@ -14,10 +14,19 @@
|
|
14
14
|
#
|
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 'sinatra/base'
|
18
|
-
require 'json'
|
19
19
|
|
20
|
-
require 'puppet_library/
|
20
|
+
require 'puppet_library/module_metadata'
|
21
|
+
require 'puppet_library/module_repo/multi'
|
22
|
+
|
23
|
+
class Array
|
24
|
+
def deep_merge
|
25
|
+
inject({}) do |merged, map|
|
26
|
+
merged.deep_merge(map)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
21
30
|
|
22
31
|
class Hash
|
23
32
|
def deep_merge(other)
|
@@ -32,61 +41,11 @@ class Hash
|
|
32
41
|
end
|
33
42
|
|
34
43
|
module PuppetLibrary
|
35
|
-
|
36
|
-
class ModuleMetadata
|
37
|
-
|
38
|
-
def initialize(metadata)
|
39
|
-
@metadata = metadata
|
40
|
-
end
|
41
|
-
|
42
|
-
def author
|
43
|
-
@metadata["name"][/^[^-]+/]
|
44
|
-
end
|
45
|
-
|
46
|
-
def name
|
47
|
-
@metadata["name"].sub(/^[^-]+-/, "")
|
48
|
-
end
|
49
|
-
|
50
|
-
def full_name
|
51
|
-
@metadata["name"].sub("-", "/")
|
52
|
-
end
|
53
|
-
|
54
|
-
def version
|
55
|
-
@metadata["version"]
|
56
|
-
end
|
57
|
-
|
58
|
-
def dependencies
|
59
|
-
@metadata["dependencies"]
|
60
|
-
end
|
61
|
-
|
62
|
-
def dependency_names
|
63
|
-
dependencies.map {|d| d["name"]}
|
64
|
-
end
|
65
|
-
|
66
|
-
def to_info
|
67
|
-
{
|
68
|
-
"author" => author,
|
69
|
-
"full_name" => full_name,
|
70
|
-
"name" => name,
|
71
|
-
"desc" => @metadata["description"],
|
72
|
-
"releases" => [ { "version" => version } ]
|
73
|
-
}
|
74
|
-
end
|
75
|
-
|
76
|
-
def to_version
|
77
|
-
{
|
78
|
-
"file" => "/modules/#{author}-#{name}-#{version}.tar.gz",
|
79
|
-
"version" => version,
|
80
|
-
"dependencies" => dependencies.map {|m| [ m["name"], m["version_requirement"] ]}
|
81
|
-
}
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
44
|
class Server < Sinatra::Base
|
86
45
|
|
87
|
-
def initialize(module_repo = ModuleRepo.new
|
46
|
+
def initialize(module_repo = ModuleRepo::Multi.new)
|
88
47
|
super(nil)
|
89
|
-
@repo = module_repo
|
48
|
+
@repo = settings.respond_to?(:module_repo) ? settings.module_repo : module_repo
|
90
49
|
end
|
91
50
|
|
92
51
|
configure do
|
@@ -96,37 +55,22 @@ module PuppetLibrary
|
|
96
55
|
get "/:author/:module.json" do
|
97
56
|
author = params[:author]
|
98
57
|
module_name = params[:module]
|
99
|
-
|
100
|
-
|
58
|
+
|
59
|
+
begin
|
60
|
+
get_module_metadata(author, module_name).to_json
|
61
|
+
rescue ModuleNotFound
|
101
62
|
status 410
|
102
63
|
{"error" => "Could not find module \"#{module_name}\""}.to_json
|
103
|
-
else
|
104
|
-
modules.map do |metadata|
|
105
|
-
metadata.to_info
|
106
|
-
end.inject({}) do |merged, map|
|
107
|
-
merged.deep_merge(map)
|
108
|
-
end.to_json
|
109
64
|
end
|
110
65
|
end
|
111
66
|
|
112
67
|
get "/api/v1/releases.json" do
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
next if modules_versions[module_full_name]
|
118
|
-
author, module_name = module_full_name.split "/"
|
119
|
-
module_versions = get_metadata(author, module_name)
|
120
|
-
dependencies = module_versions.map {|v| v.dependency_names }.flatten
|
121
|
-
module_queue += dependencies
|
122
|
-
modules_versions[module_full_name] = module_versions.map { |v| v.to_version }
|
123
|
-
end
|
124
|
-
|
125
|
-
if modules_versions.values == [[]]
|
68
|
+
author, module_name = params[:module].split "/"
|
69
|
+
begin
|
70
|
+
get_module_metadata_with_dependencies(author, module_name).to_json
|
71
|
+
rescue ModuleNotFound
|
126
72
|
status 410
|
127
|
-
{"error" => "Module #{
|
128
|
-
else
|
129
|
-
modules_versions.to_json
|
73
|
+
{"error" => "Module #{author}/#{module_name} not found"}.to_json
|
130
74
|
end
|
131
75
|
end
|
132
76
|
|
@@ -134,18 +78,57 @@ module PuppetLibrary
|
|
134
78
|
author = params[:author]
|
135
79
|
name = params[:module]
|
136
80
|
version = params[:version]
|
137
|
-
|
81
|
+
|
138
82
|
content_type "application/octet-stream"
|
139
|
-
|
83
|
+
|
84
|
+
begin
|
85
|
+
get_module_buffer(author, name, version).tap do
|
86
|
+
attachment "#{author}-#{name}-#{version}.tar.gz"
|
87
|
+
end
|
88
|
+
rescue ModuleNotFound
|
140
89
|
status 404
|
141
|
-
else
|
142
|
-
attachment "#{author}-#{name}-#{version}.tar.gz"
|
143
|
-
buffer
|
144
90
|
end
|
145
91
|
end
|
146
92
|
|
93
|
+
private
|
94
|
+
def get_module_metadata(author, name)
|
95
|
+
modules = get_metadata(author, name)
|
96
|
+
raise ModuleNotFound if modules.empty?
|
97
|
+
|
98
|
+
module_infos = modules.map { |m| m.to_info }
|
99
|
+
module_infos.deep_merge
|
100
|
+
end
|
101
|
+
|
102
|
+
def get_module_metadata_with_dependencies(author, name)
|
103
|
+
full_name = "#{author}/#{name}"
|
104
|
+
|
105
|
+
module_queue = []
|
106
|
+
modules_versions = {}
|
107
|
+
module_queue << full_name
|
108
|
+
until module_queue.empty?
|
109
|
+
module_full_name = module_queue.shift
|
110
|
+
already_added = modules_versions.include? module_full_name
|
111
|
+
unless already_added
|
112
|
+
author, module_name = module_full_name.split "/"
|
113
|
+
module_versions = get_metadata(author, module_name)
|
114
|
+
dependencies = module_versions.map {|v| v.dependency_names }.flatten
|
115
|
+
module_queue += dependencies
|
116
|
+
modules_versions[module_full_name] = module_versions.map { |v| v.to_version }
|
117
|
+
end
|
118
|
+
end
|
119
|
+
raise ModuleNotFound if modules_versions.values == [[]]
|
120
|
+
modules_versions
|
121
|
+
end
|
122
|
+
|
123
|
+
def get_module_buffer(author, name, version)
|
124
|
+
@repo.get_module(author, name, version) or raise ModuleNotFound
|
125
|
+
end
|
126
|
+
|
147
127
|
def get_metadata(author, module_name)
|
148
128
|
@repo.get_metadata(author, module_name).map {|metadata| ModuleMetadata.new(metadata)}
|
149
129
|
end
|
150
130
|
end
|
151
131
|
end
|
132
|
+
|
133
|
+
class ModuleNotFound < Exception
|
134
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
# Puppet Library
|
3
|
+
# Copyright (C) 2013 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
|
+
class Array
|
19
|
+
# Like 'uniq' with a block, but also works on Ruby < 1.9
|
20
|
+
def unique_by
|
21
|
+
attr_to_element = {}
|
22
|
+
select do |element|
|
23
|
+
attribute = yield(element)
|
24
|
+
is_duplicate = attr_to_element.include? attribute
|
25
|
+
unless is_duplicate
|
26
|
+
attr_to_element[yield(element)] = element
|
27
|
+
end
|
28
|
+
!is_duplicate
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -16,12 +16,12 @@
|
|
16
16
|
|
17
17
|
require 'spec_helper'
|
18
18
|
|
19
|
-
module PuppetLibrary
|
20
|
-
describe
|
19
|
+
module PuppetLibrary::ModuleRepo
|
20
|
+
describe Directory do
|
21
21
|
include ModuleSpecHelper
|
22
22
|
|
23
23
|
let(:module_dir) { "/tmp/#{$$}" }
|
24
|
-
let(:module_repo) {
|
24
|
+
let(:module_repo) { Directory.new(module_dir) }
|
25
25
|
|
26
26
|
before do
|
27
27
|
FileUtils.mkdir_p module_dir
|
@@ -0,0 +1,97 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
# Puppet Library
|
3
|
+
# Copyright (C) 2013 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::ModuleRepo
|
21
|
+
describe Multi do
|
22
|
+
let(:subrepo_one) { double('subrepo_one').as_null_object }
|
23
|
+
let(:subrepo_two) { double('subrepo_two').as_null_object }
|
24
|
+
let(:multi_repo) do
|
25
|
+
repo = Multi.new
|
26
|
+
repo.add_repo(subrepo_one)
|
27
|
+
repo.add_repo(subrepo_two)
|
28
|
+
return repo
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "#get_module" do
|
32
|
+
before do
|
33
|
+
end
|
34
|
+
|
35
|
+
context "when the module is found in a subrepository" do
|
36
|
+
it "returns the module from the first subrepo it's found in" do
|
37
|
+
expect(subrepo_one).to receive(:get_module).with("puppetlabs", "apache", "1.0.0").and_return("puppetlabs/apache module: 1.0.0")
|
38
|
+
expect(subrepo_two).not_to receive(:get_module)
|
39
|
+
|
40
|
+
mod = multi_repo.get_module("puppetlabs", "apache", "1.0.0")
|
41
|
+
|
42
|
+
expect(mod).to eq "puppetlabs/apache module: 1.0.0"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
context "when the module is not found in any subrepository" do
|
47
|
+
it "returns nil" do
|
48
|
+
expect(subrepo_one).to receive(:get_module).with("puppetlabs", "nonexistant", "1.0.0").and_return(nil)
|
49
|
+
expect(subrepo_two).to receive(:get_module).with("puppetlabs", "nonexistant", "1.0.0").and_return(nil)
|
50
|
+
|
51
|
+
mod = multi_repo.get_module("puppetlabs", "nonexistant", "1.0.0")
|
52
|
+
|
53
|
+
expect(mod).to be_nil
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe "#get_metadata" do
|
59
|
+
context "when versions of the module are found in subrepositories" do
|
60
|
+
it "returns the metadata in an array" do
|
61
|
+
apache_module_metadata_one = { "name" => "apache", "version" => "1.0.0" }
|
62
|
+
apache_module_metadata_two = { "name" => "apache", "version" => "2.0.0" }
|
63
|
+
expect(subrepo_one).to receive(:get_metadata).with("puppetlabs", "apache").and_return([apache_module_metadata_one])
|
64
|
+
expect(subrepo_two).to receive(:get_metadata).with("puppetlabs", "apache").and_return([apache_module_metadata_two])
|
65
|
+
|
66
|
+
metadata_list = multi_repo.get_metadata("puppetlabs", "apache")
|
67
|
+
|
68
|
+
expect(metadata_list).to eq [ apache_module_metadata_one, apache_module_metadata_two ]
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
context "when no versions of the module are found in any subrepository" do
|
73
|
+
it "returns an empty array" do
|
74
|
+
expect(subrepo_one).to receive(:get_metadata).with("puppetlabs", "apache").and_return([])
|
75
|
+
expect(subrepo_two).to receive(:get_metadata).with("puppetlabs", "apache").and_return([])
|
76
|
+
|
77
|
+
metadata_list = multi_repo.get_metadata("puppetlabs", "apache")
|
78
|
+
|
79
|
+
expect(metadata_list).to be_empty
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
context "when the same version of a module is found in multiple repositories" do
|
84
|
+
it "returns the one from the first repository it appears in" do
|
85
|
+
apache_module_metadata_one = { "name" => "apache", "version" => "1.0.0", "repo" => "one" }
|
86
|
+
apache_module_metadata_two = { "name" => "apache", "version" => "1.0.0", "repo" => "two" }
|
87
|
+
expect(subrepo_one).to receive(:get_metadata).with("puppetlabs", "apache").and_return([apache_module_metadata_one])
|
88
|
+
expect(subrepo_two).to receive(:get_metadata).with("puppetlabs", "apache").and_return([apache_module_metadata_two])
|
89
|
+
|
90
|
+
metadata_list = multi_repo.get_metadata("puppetlabs", "apache")
|
91
|
+
|
92
|
+
expect(metadata_list).to eq [ apache_module_metadata_one ]
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
# Puppet Library
|
3
|
+
# Copyright (C) 2013 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
|
21
|
+
describe PuppetLibrary do
|
22
|
+
let(:module_repo) do
|
23
|
+
module_repo = double(ModuleRepo::Multi)
|
24
|
+
allow(ModuleRepo::Multi).to receive(:new).and_return(module_repo)
|
25
|
+
return module_repo
|
26
|
+
end
|
27
|
+
let(:server) do
|
28
|
+
server = double(Server)
|
29
|
+
allow(Server).to receive(:new).and_return(server)
|
30
|
+
return server
|
31
|
+
end
|
32
|
+
let(:log) { double('log').as_null_object }
|
33
|
+
let(:library) { PuppetLibrary.new(log) }
|
34
|
+
let(:default_options) {{ :app => server, :Host => "0.0.0.0", :Port => "9292"}}
|
35
|
+
before do
|
36
|
+
allow(Rack::Server).to receive(:start)
|
37
|
+
end
|
38
|
+
|
39
|
+
def default_options_with(substitutions)
|
40
|
+
default_options.clone.tap do |options|
|
41
|
+
substitutions.each do |k, v|
|
42
|
+
options[k] = v
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe "#go" do
|
48
|
+
context "when specifying a bad option" do
|
49
|
+
it "prints the usage" do
|
50
|
+
expect(log).to receive(:puts).with(/invalid option: --die\nUsage:/)
|
51
|
+
|
52
|
+
library.go(["--die"])
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context "when specifying no options" do
|
57
|
+
it "runs the server with the default options" do
|
58
|
+
expect(Rack::Server).to receive(:start).with(default_options)
|
59
|
+
|
60
|
+
library.go([])
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
context "when specifying --port option" do
|
65
|
+
it "runs the server with the specified port" do
|
66
|
+
expect(Rack::Server).to receive(:start).with(default_options_with(:Port => "8080"))
|
67
|
+
|
68
|
+
library.go(["--port", "8080"])
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
context "when specifying --bind-host option" do
|
73
|
+
it "runs the server with the specified bind host" do
|
74
|
+
expect(Rack::Server).to receive(:start).with(default_options_with(:Host => "localhost"))
|
75
|
+
|
76
|
+
library.go(["--bind-host", "localhost"])
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
it "adds a module repository to the server for each module directory" do
|
81
|
+
expect(Server).to receive(:new).with(module_repo).and_return(server)
|
82
|
+
expect(module_repo).to receive(:add_repo).twice
|
83
|
+
expect(Rack::Server).to receive(:start).with(default_options)
|
84
|
+
|
85
|
+
library.go(["--module-dir", "dir1", "--module-dir", "dir2"])
|
86
|
+
end
|
87
|
+
|
88
|
+
it "logs the server options" do
|
89
|
+
expect(log).to receive(:puts).with(/Port: 9292/)
|
90
|
+
expect(log).to receive(:puts).with(/Host: 0\.0\.0\.0/)
|
91
|
+
library.go([])
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
data/spec/util_spec.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
# Puppet Library
|
3
|
+
# Copyright (C) 2013 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
|
+
describe 'util' do
|
21
|
+
describe Array do
|
22
|
+
describe "#unique_by" do
|
23
|
+
it "behaves like #uniq with a block, but works with Ruby < 1.9" do
|
24
|
+
son = { "name" => "john", "age" => 10 }
|
25
|
+
dad = { "name" => "john", "age" => 40 }
|
26
|
+
mom = { "name" => "jane", "age" => 40 }
|
27
|
+
|
28
|
+
family = [son, dad, mom]
|
29
|
+
expect(family.unique_by {|p| p["name"]}).to eq [son, mom]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: puppet-library
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- drrb
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2014-01-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sinatra
|
@@ -166,17 +166,25 @@ files:
|
|
166
166
|
- LICENSE.txt
|
167
167
|
- README.md
|
168
168
|
- Rakefile
|
169
|
+
- TODO.yml
|
169
170
|
- bin/puppet-library
|
170
171
|
- config.ru
|
171
172
|
- lib/puppet_library.rb
|
172
|
-
- lib/puppet_library/
|
173
|
+
- lib/puppet_library/module_metadata.rb
|
174
|
+
- lib/puppet_library/module_repo/directory.rb
|
175
|
+
- lib/puppet_library/module_repo/multi.rb
|
176
|
+
- lib/puppet_library/puppet_library.rb
|
173
177
|
- lib/puppet_library/server.rb
|
178
|
+
- lib/puppet_library/util.rb
|
174
179
|
- lib/puppet_library/version.rb
|
175
180
|
- puppet-library.gemspec
|
176
|
-
- spec/
|
181
|
+
- spec/module_repo/directory_spec.rb
|
182
|
+
- spec/module_repo/multi_spec.rb
|
177
183
|
- spec/module_spec_helper.rb
|
184
|
+
- spec/puppet_library_spec.rb
|
178
185
|
- spec/server_spec.rb
|
179
186
|
- spec/spec_helper.rb
|
187
|
+
- spec/util_spec.rb
|
180
188
|
homepage: https://github.com/drrb/puppet-library
|
181
189
|
licenses:
|
182
190
|
- GPL-3
|
@@ -202,7 +210,10 @@ signing_key:
|
|
202
210
|
specification_version: 4
|
203
211
|
summary: Puppet Library is a private Puppet module server that's compatible with librarian-puppet.
|
204
212
|
test_files:
|
205
|
-
- spec/
|
213
|
+
- spec/module_repo/directory_spec.rb
|
214
|
+
- spec/module_repo/multi_spec.rb
|
206
215
|
- spec/module_spec_helper.rb
|
216
|
+
- spec/puppet_library_spec.rb
|
207
217
|
- spec/server_spec.rb
|
208
218
|
- spec/spec_helper.rb
|
219
|
+
- spec/util_spec.rb
|