librarian-puppet 1.5.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 96c873a7d7d2b15106cc615a9b6ddafa733e99d2
4
- data.tar.gz: 84c48adf82430977b0f9c46a352ab5c2a08435cd
3
+ metadata.gz: 83e9713858b646cdf2e4a3bc35a7a4b10d381aed
4
+ data.tar.gz: ea2912415c6e31b96d0b466e4d3cf7d646a37955
5
5
  SHA512:
6
- metadata.gz: c3610a75017822faeb6b0d27462b60a0f456e3085ef22faa50d126d7e451b633eee60b42435c56b1f4c026aa5dadbdfbab98cc047d50a1b8a09185f5d8f31f04
7
- data.tar.gz: 8397daa45bc55835f4f3203385ef95734221162ce2be47d2b3057e2fa547ff24dc732b0ff8fc8a154441220330eeabb39439120db99553481650533fd18db22a
6
+ metadata.gz: e03c1bf94ab9f59051f16a69aa9a17233a40b73c377e23501ffab3e4921694416ebdf152bca5a06912d0c2e388fcd54879471131e4c96f66f35470b59121194c
7
+ data.tar.gz: 0adb68c0f41531740e2e52a604f788b96f0eb55477e6d0a973ab39900849f09d3b81637675bac04bbcc14e6c719ca712d3ad89c77e269381748eaf60a72edad6
data/README.md CHANGED
@@ -7,13 +7,12 @@
7
7
  Librarian-puppet is a bundler for your puppet infrastructure. You can use
8
8
  librarian-puppet to manage the puppet modules your infrastructure depends on,
9
9
  whether the modules come from the [Puppet Forge](https://forge.puppetlabs.com/),
10
- Git repositories or just a path.
10
+ Git repositories or a just a path.
11
11
 
12
12
  * Librarian-puppet can reuse the dependencies listed in your `Modulefile` or `metadata.json`
13
13
  * Forge modules can be installed from [Puppetlabs Forge](https://forge.puppetlabs.com/) or an internal Forge such as [Pulp](http://www.pulpproject.org/)
14
14
  * Git modules can be installed from a branch, tag or specific commit, optionally using a path inside the repository
15
15
  * Modules can be installed from GitHub using tarballs, without needing Git installed
16
- * Modules can be installed from a filesystem path
17
16
  * Module dependencies are resolved transitively without needing to list all the modules explicitly
18
17
 
19
18
 
@@ -70,10 +69,6 @@ as if the Puppetfile contained
70
69
  mod 'puppetlabs-apache', '0.6.0',
71
70
  :github_tarball => 'puppetlabs/puppetlabs-apache'
72
71
 
73
- mod 'acme-mymodule', :path => './some_folder'
74
-
75
- exclusion 'acme-bad_module'
76
-
77
72
 
78
73
  ### Recursive module dependency resolution
79
74
 
@@ -139,21 +134,6 @@ module subdirectory.
139
134
  Our puppet infrastructure repository depends on the `apt` module, which we have
140
135
  stored as a directory under our `puppet-modules` git repos.
141
136
 
142
- mod 'puppetlabs-apache', '0.6.0',
143
- :github_tarball => 'puppetlabs/puppetlabs-apache'
144
-
145
- Our puppet infrastructure repository depends on the `puppetlabs-apache` module,
146
- to be downloaded from GitHub tarball.
147
-
148
- mod 'acme-mymodule', :path => './some_folder'
149
-
150
- Our puppet infrastructure repository depends on the `acme-mymodule` module,
151
- which is already in the filesystem.
152
-
153
- exclusion 'acme-bad_module'
154
-
155
- Exclude the module `acme-bad_module` from resolution and installation.
156
-
157
137
  ## How to Use
158
138
 
159
139
  Install librarian-puppet:
@@ -1,2 +1 @@
1
1
  require "librarian/puppet/action/install"
2
- require "librarian/puppet/action/resolve"
@@ -7,7 +7,6 @@ require 'librarian/puppet/action'
7
7
  module Librarian
8
8
  module Puppet
9
9
  class Cli < Librarian::Cli
10
- include Librarian::Puppet::Util
11
10
 
12
11
  module Particularity
13
12
  def root_module
@@ -70,12 +69,6 @@ module Librarian
70
69
  install!
71
70
  end
72
71
 
73
- # only used to replace / to - in the module names
74
- def update(*names)
75
- warn("Usage of module/name is deprecated, use module-name") if names.any? {|n| n.include?("/")}
76
- super(*names.map{|n| normalize_name(n)})
77
- end
78
-
79
72
  desc "package", "Cache the puppet modules in vendor/puppet/cache."
80
73
  option "quiet", :type => :boolean, :default => false
81
74
  option "verbose", :type => :boolean, :default => false
@@ -100,9 +93,6 @@ module Librarian
100
93
  def install!(options = { })
101
94
  Action::Install.new(environment, options).run
102
95
  end
103
- def resolve!(options = { })
104
- Action::Resolve.new(environment, options).run
105
- end
106
96
  end
107
97
  end
108
98
  end
@@ -1,14 +1,11 @@
1
1
  require 'librarian/dsl'
2
2
  require 'librarian/dsl/target'
3
3
  require 'librarian/puppet/source'
4
- require 'librarian/puppet/dependency'
5
4
 
6
5
  module Librarian
7
6
  module Puppet
8
7
  class Dsl < Librarian::Dsl
9
8
 
10
- FORGE_URL = "http://forge.puppetlabs.com"
11
-
12
9
  dependency :mod
13
10
 
14
11
  source :forge => Source::Forge
@@ -16,25 +13,28 @@ module Librarian
16
13
  source :path => Source::Path
17
14
  source :github_tarball => Source::GitHubTarball
18
15
 
19
- def default_specfile
20
- Proc.new do
21
- forge FORGE_URL
22
- metadata
16
+ # copied from Librarian::Dsl to use our own Receiver
17
+ def run(specfile = nil, sources = [])
18
+ specfile, sources = nil, specfile if specfile.kind_of?(Array) && sources.empty?
19
+
20
+ if specfile.kind_of?(Pathname) and !File.exists?(specfile)
21
+ debug { "Specfile not found, using defaults: #{specfile}" }
22
+ specfile = Proc.new do
23
+ forge "https://forgeapi.puppetlabs.com"
24
+ metadata
25
+ end
23
26
  end
24
- end
25
27
 
26
- def self.dependency_type
27
- Librarian::Puppet::Dependency
28
- end
28
+ Target.new(self).tap do |target|
29
+ target.precache_sources(sources)
30
+ debug_named_source_cache("Pre-Cached Sources", target)
29
31
 
30
- def post_process_target(target)
31
- # save the default forge defined
32
- default_forge = target.sources.select {|s| s.is_a? Librarian::Puppet::Source::Forge}.first
33
- Librarian::Puppet::Source::Forge.default = default_forge || Librarian::Puppet::Source::Forge.from_lock_options(environment, :remote => FORGE_URL)
34
- end
32
+ specfile ||= Proc.new if block_given?
33
+ receiver = Receiver.new(target)
34
+ receiver.run(specfile)
35
35
 
36
- def receiver(target)
37
- Receiver.new(target)
36
+ debug_named_source_cache("Post-Cached Sources", target)
37
+ end.to_spec
38
38
  end
39
39
 
40
40
  class Receiver < Librarian::Dsl::Receiver
@@ -70,12 +70,7 @@ module Librarian
70
70
  raise Error, msg
71
71
  end
72
72
  end
73
- begin
74
- json = JSON.parse(File.read(f))
75
- rescue JSON::ParserError => e
76
- raise Error, "Unable to parse json file #{f}: #{e}"
77
- end
78
- dependencyList = json['dependencies']
73
+ dependencyList = JSON.parse(File.read(f))['dependencies']
79
74
  dependencyList.each do |d|
80
75
  mod(d['name'], d['version_requirement'])
81
76
  end
@@ -1,7 +1,7 @@
1
1
  require "librarian/environment"
2
2
  require "librarian/puppet/dsl"
3
3
  require "librarian/puppet/source"
4
- require "librarian/puppet/lockfile"
4
+ require "librarian/puppet/lockfile/parser"
5
5
 
6
6
  module Librarian
7
7
  module Puppet
@@ -11,14 +11,6 @@ module Librarian
11
11
  "puppet"
12
12
  end
13
13
 
14
- def lockfile
15
- Lockfile.new(self, lockfile_path)
16
- end
17
-
18
- def ephemeral_lockfile
19
- Lockfile.new(self, nil)
20
- end
21
-
22
14
  def tmp_path
23
15
  part = config_db["tmp"] || ".tmp"
24
16
  project_path.join(part)
@@ -6,4 +6,224 @@ module Librarian
6
6
  extend self
7
7
  extend Librarian
8
8
  end
9
+
10
+ class Dependency
11
+ include Librarian::Puppet::Util
12
+
13
+ def initialize(name, requirement, source)
14
+ assert_name_valid! name
15
+
16
+ # Issue #235 fail if forge source is not defined
17
+ raise Error, "forge entry is not defined in Puppetfile" if source.instance_of?(Array) && source.empty?
18
+
19
+ # let's settle on provider-module syntax instead of provider/module
20
+ self.name = normalize_name(name)
21
+ self.requirement = Requirement.new(requirement)
22
+ self.source = source
23
+
24
+ @manifests = nil
25
+ end
26
+
27
+ class Requirement
28
+ def initialize(*args)
29
+ args = initialize_normalize_args(args)
30
+ self.backing = Gem::Requirement.create(puppet_to_gem_versions(args))
31
+ end
32
+
33
+ def puppet_to_gem_versions(args)
34
+ args.map do |arg|
35
+ case arg
36
+ when Array
37
+ arg.map { |v| Librarian::Puppet::Requirement.new(v).gem_requirement }
38
+ when String
39
+ Librarian::Puppet::Requirement.new(arg).gem_requirement
40
+ else
41
+ # Gem::Requirement, convert to string (ie. =1.0) so we can concat later
42
+ # Gem::Requirements can not be concatenated
43
+ arg.requirements.map{|x,y| "#{x}#{y}"}
44
+ end
45
+ end.flatten
46
+ end
47
+ end
48
+
49
+ alias :eql? :==
50
+
51
+ def hash
52
+ self.to_s.hash
53
+ end
54
+ end
55
+
56
+ # Fixes for librarian not yet released in their gem
57
+ module Mock
58
+ module Source
59
+ class Mock
60
+ alias :eql? :==
61
+
62
+ def hash
63
+ self.to_s.hash
64
+ end
65
+ end
66
+ end
67
+ end
68
+ module Source
69
+ class Git
70
+ alias :eql? :==
71
+
72
+ def hash
73
+ self.to_s.hash
74
+ end
75
+ end
76
+
77
+ class Path
78
+ alias :eql? :==
79
+
80
+ def hash
81
+ self.to_s.hash
82
+ end
83
+ end
84
+ end
85
+
86
+ class ManifestSet
87
+ include Librarian::Puppet::Util
88
+
89
+ private
90
+
91
+ # Check if module doesn't exist and fail fast
92
+ def dependencies_of(names)
93
+ names = Array === names ? names.dup : names.to_a
94
+ assert_strings!(names)
95
+
96
+ deps = Set.new
97
+ until names.empty?
98
+ name = normalize_name(names.shift)
99
+ next if deps.include?(name)
100
+
101
+ deps << name
102
+ raise(Error, "Unable to find module #{name}. Your Puppetfile may be out of sync with the lock, try running 'librarian-puppet install' first") if index[name].nil?
103
+ names.concat index[name].dependencies.map(&:name)
104
+ end
105
+ deps.to_a
106
+ end
107
+ end
108
+
109
+ class Manifest
110
+ class PreReleaseVersion
111
+
112
+ # Compares pre-release component ids using Semver 2.0.0 spec
113
+ def self.compare_components(this_id,other_id)
114
+ case # Strings have higher precedence than numbers
115
+ when (this_id.is_a?(Integer) and other_id.is_a?(String))
116
+ -1
117
+ when (this_id.is_a?(String) and other_id.is_a?(Integer))
118
+ 1
119
+ else
120
+ this_id <=> other_id
121
+ end
122
+ end
123
+
124
+ # Parses pre-release components `a.b.c` into an array ``[a,b,c]`
125
+ # Converts numeric components into +Integer+
126
+ def self.parse(prerelease)
127
+ if prerelease.nil?
128
+ []
129
+ else
130
+ prerelease.split('.').collect do |id|
131
+ id = Integer(id) if /^[0-9]+$/ =~ id
132
+ id
133
+ end
134
+ end
135
+ end
136
+
137
+ include Comparable
138
+
139
+ attr_reader :components
140
+
141
+ def initialize(prerelease)
142
+ @prerelease = prerelease
143
+ @components = PreReleaseVersion.parse(prerelease)
144
+ end
145
+
146
+ def to_s
147
+ @prerelease
148
+ end
149
+
150
+ def <=>(other)
151
+ # null-fill zip array to prevent loss of components
152
+ z = Array.new([components.length,other.components.length])
153
+
154
+ # Compare each component against the other
155
+ comp = z.zip(components,other.components).collect do |ids|
156
+ case # All components being equal, the version with more of them takes precedence
157
+ when ids[1].nil? # Self has less elements, other wins
158
+ -1
159
+ when ids[2].nil? # Other has less elements, self wins
160
+ 1
161
+ else
162
+ PreReleaseVersion.compare_components(ids[1],ids[2])
163
+ end
164
+ end
165
+ # Chose the first non-zero comparison or return 0
166
+ comp.delete_if {|c| c == 0}[0] || 0
167
+ end
168
+ end
169
+ class Version
170
+ @@SEMANTIC_VERSION_PATTERN = /^([0-9]+\.[0-9]+(?:\.[0-9]+)?)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?$/
171
+ def self.parse_semver(version_string)
172
+ parsed = @@SEMANTIC_VERSION_PATTERN.match(version_string.strip)
173
+ if parsed
174
+ {
175
+ :full_version => parsed[0],
176
+ :version => parsed[1],
177
+ :prerelease => (PreReleaseVersion.new(parsed[2]) if parsed[2]),
178
+ :build => parsed[3]
179
+ }
180
+ end
181
+ end
182
+
183
+ attr_reader :prerelease
184
+
185
+ def initialize(*args)
186
+ args = initialize_normalize_args(args)
187
+ semver = Version.parse_semver(*args)
188
+ if semver
189
+ self.backing = Gem::Version.new(semver[:version])
190
+ @prerelease = semver[:prerelease]
191
+ @full_version = semver[:full_version]
192
+ else
193
+ self.backing = Gem::Version.new(*args)
194
+ @full_version = to_gem_version.to_s
195
+ end
196
+ end
197
+
198
+ def <=>(other)
199
+ cmp = to_gem_version <=> other.to_gem_version
200
+
201
+ # Should compare pre-release versions?
202
+ if cmp == 0 and not (prerelease.nil? and other.prerelease.nil?)
203
+ case # Versions without prerelease take precedence
204
+ when (prerelease.nil? and not other.prerelease.nil?)
205
+ 1
206
+ when (not prerelease.nil? and other.prerelease.nil?)
207
+ -1
208
+ else
209
+ prerelease <=> other.prerelease
210
+ end
211
+ else
212
+ cmp
213
+ end
214
+ end
215
+
216
+ def to_s
217
+ @full_version
218
+ end
219
+ end
220
+ end
221
+
222
+ class Logger
223
+ def warn(string = nil, &block)
224
+ return unless ui
225
+
226
+ ui.warn(string || yield)
227
+ end
228
+ end
9
229
  end
@@ -0,0 +1,55 @@
1
+ require 'librarian/manifest'
2
+ require 'librarian/dependency'
3
+ require 'librarian/manifest_set'
4
+
5
+ module Librarian
6
+ class Lockfile
7
+ class Parser
8
+ include Librarian::Puppet::Util
9
+
10
+ def parse(string)
11
+ string = string.dup
12
+ source_type_names_map = Hash[dsl_class.source_types.map{|t| [t[1].lock_name, t[1]]}]
13
+ source_type_names = dsl_class.source_types.map{|t| t[1].lock_name}
14
+ lines = string.split(/(\r|\n|\r\n)+/).select{|l| l =~ /\S/}
15
+ sources = []
16
+ while source_type_names.include?(lines.first)
17
+ source = {}
18
+ source_type_name = lines.shift
19
+ source[:type] = source_type_names_map[source_type_name]
20
+ options = {}
21
+ while lines.first =~ /^ {2}([\w\-\/]+):\s+(.+)$/
22
+ lines.shift
23
+ options[$1.to_sym] = $2
24
+ end
25
+ source[:options] = options
26
+ lines.shift # specs
27
+ manifests = {}
28
+ while lines.first =~ /^ {4}([\w\-\/]+) \((.*)\)$/ # This change allows forward slash
29
+ lines.shift
30
+ name, version = normalize_name($1), $2
31
+ manifests[name] = {:version => version, :dependencies => {}}
32
+ while lines.first =~ /^ {6}([\w\-\/]+) \((.*)\)$/
33
+ lines.shift
34
+ manifests[name][:dependencies][$1] = $2.split(/,\s*/)
35
+ end
36
+ end
37
+ source[:manifests] = manifests
38
+ sources << source
39
+ end
40
+ manifests = compile(sources)
41
+ manifests_index = Hash[manifests.map{|m| [m.name, m]}]
42
+ raise StandardError, "Expected DEPENDENCIES topic!" unless lines.shift == "DEPENDENCIES"
43
+ dependencies = []
44
+ while lines.first =~ /^ {2}([\w\-\/]+)(?: \((.*)\))?$/ # This change allows forward slash
45
+ lines.shift
46
+ name, requirement = normalize_name($1), $2.split(/,\s*/)
47
+ dependencies << Dependency.new(name, requirement, manifests_index[name].source)
48
+ end
49
+
50
+ Resolution.new(dependencies, manifests)
51
+ end
52
+
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,35 @@
1
+ module Librarian
2
+ module Puppet
3
+ class Requirement
4
+ attr_reader :requirement
5
+
6
+ def initialize(requirement)
7
+ @requirement = requirement || ">=0"
8
+ end
9
+
10
+ def gem_requirement
11
+ if range_requirement?
12
+ [@range_match[1], @range_match[2]]
13
+ elsif pessimistic_requirement?
14
+ "~> #{@pessimistic_match[1]}.0"
15
+ else
16
+ requirement
17
+ end
18
+ end
19
+
20
+ def to_s
21
+ gem_requirement.to_s
22
+ end
23
+
24
+ private
25
+
26
+ def range_requirement?
27
+ @range_match ||= requirement.match(/(>=? ?\d+(?:\.\d+){0,2}) (<=? ?\d+(?:\.\d+){0,2})/)
28
+ end
29
+
30
+ def pessimistic_requirement?
31
+ @pessimistic_match ||= requirement.match(/(\d+(?:\.\d+)?)\.x/)
32
+ end
33
+ end
34
+ end
35
+ end
@@ -1,3 +1,4 @@
1
+ require 'librarian/puppet/requirement'
1
2
  require 'librarian/puppet/source/path'
2
3
  require 'librarian/puppet/source/git'
3
4
  require 'librarian/puppet/source/forge'
@@ -1,7 +1,7 @@
1
1
  require 'uri'
2
2
  require 'librarian/puppet/util'
3
3
  require 'librarian/puppet/source/forge/repo_v1'
4
- # require 'librarian/puppet/source/forge/repo_v3'
4
+ require 'librarian/puppet/source/forge/repo_v3'
5
5
 
6
6
  module Librarian
7
7
  module Puppet
@@ -12,14 +12,6 @@ module Librarian
12
12
  class << self
13
13
  LOCK_NAME = 'FORGE'
14
14
 
15
- def default=(source)
16
- @@default = source
17
- end
18
-
19
- def default
20
- @@default
21
- end
22
-
23
15
  def lock_name
24
16
  LOCK_NAME
25
17
  end
@@ -61,10 +53,10 @@ module Librarian
61
53
  def initialize(environment, uri, options = {})
62
54
  self.environment = environment
63
55
 
64
- # if uri =~ %r{^http(s)?://forge\.puppetlabs\.com}
65
- # uri = "https://forgeapi.puppetlabs.com"
66
- # warn { "Replacing Puppet Forge API URL to use v3 #{uri}. You should update your Puppetfile" }
67
- # end
56
+ if uri =~ %r{^http(s)?://forge\.puppetlabs\.com}
57
+ uri = "https://forgeapi.puppetlabs.com"
58
+ warn { "Replacing Puppet Forge API URL to use v3 #{uri}. You should update your Puppetfile" }
59
+ end
68
60
 
69
61
  @uri = URI::parse(uri)
70
62
  @cache_path = nil
@@ -143,7 +135,7 @@ module Librarian
143
135
 
144
136
  def fetch_dependencies(name, version, version_uri)
145
137
  repo(name).dependencies(version).map do |k, v|
146
- v = Librarian::Dependency::Requirement.new(v).to_gem_requirement
138
+ v = Requirement.new(v).gem_requirement
147
139
  Dependency.new(k, v, nil)
148
140
  end
149
141
  end
@@ -159,11 +151,11 @@ module Librarian
159
151
 
160
152
  unless @repo[name]
161
153
  # if we are using the official Forge then use API v3, otherwise stick to v1 for now
162
- # if uri.hostname =~ /\.puppetlabs\.com$/ || !environment.use_v1_api
163
- # @repo[name] = RepoV3.new(self, name)
164
- # else
154
+ if uri.hostname =~ /\.puppetlabs\.com$/ || !environment.use_v1_api
155
+ @repo[name] = RepoV3.new(self, name)
156
+ else
165
157
  @repo[name] = RepoV1.new(self, name)
166
- # end
158
+ end
167
159
  end
168
160
  @repo[name]
169
161
  end
@@ -33,9 +33,30 @@ module Librarian
33
33
 
34
34
  private
35
35
 
36
- # convert organization/modulename to organization-modulename
37
- def normalize_dependencies(data)
36
+ # Issue #223 dependencies may be duplicated
37
+ # and convert organization/modulename to organization-modulename
38
+ def clear_duplicated_dependencies(data)
38
39
  return nil if data.nil?
40
+ data.each do |m,versions|
41
+ versions.each do |v|
42
+ if v["dependencies"] and !v["dependencies"].empty?
43
+ # convert organization/modulename to organization-modulename
44
+ v["dependencies"].each {|d| d[0] = normalize_name(d[0])}
45
+
46
+ dependency_names = v["dependencies"].map {|d| d[0]}
47
+ duplicated = dependency_names.select{ |e| dependency_names.count(e) > 1 }
48
+ unless duplicated.empty?
49
+ duplicated.uniq.each do |module_duplicated|
50
+ to_remove = []
51
+ v["dependencies"].each_index{|i| to_remove << i if module_duplicated == v["dependencies"][i][0]}
52
+ warn { "Module #{m}@#{v["version"]} contains duplicated dependencies for #{module_duplicated}, ignoring all but the first of #{to_remove.map {|i| v["dependencies"][i]}}" }
53
+ to_remove.slice(1..-1).reverse.each {|i| v["dependencies"].delete_at(i) }
54
+ v["dependencies"] = v["dependencies"] - to_remove.slice(1..-1)
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
39
60
  # convert organization/modulename to organization-modulename
40
61
  data.keys.each do |m|
41
62
  if m =~ %r{.*/.*}
@@ -50,7 +71,7 @@ module Librarian
50
71
  def api_data(module_name)
51
72
  return @api_data[module_name] if @api_data
52
73
  # call API and cache data
53
- @api_data = normalize_dependencies(api_call(module_name))
74
+ @api_data = clear_duplicated_dependencies(api_call(module_name))
54
75
  if @api_data.nil?
55
76
  raise Error, "Unable to find module '#{name}' on #{source}"
56
77
  end
@@ -62,7 +83,7 @@ module Librarian
62
83
  # if we already got all the versions, find in cached data
63
84
  return @api_data[module_name].detect{|x| x['version'] == version.to_s} if @api_data
64
85
  # otherwise call the api for this version if not cached already
65
- @api_version_data[version] = normalize_dependencies(api_call(name, version)) if @api_version_data[version].nil?
86
+ @api_version_data[version] = clear_duplicated_dependencies(api_call(name, version)) if @api_version_data[version].nil?
66
87
  @api_version_data[version]
67
88
  end
68
89
 
@@ -43,16 +43,19 @@ module Librarian
43
43
  end
44
44
 
45
45
  parsed_metadata['dependencies'].each do |d|
46
- gem_requirement = Librarian::Dependency::Requirement.new(d['version_requirement']).to_gem_requirement
46
+ gem_requirement = Requirement.new(d['version_requirement']).gem_requirement
47
47
  new_dependency = Dependency.new(d['name'], gem_requirement, forge_source)
48
- dependencies << new_dependency
48
+ # Avoid duplicated dependencies with different sources
49
+ unless dependencies.find { |spec_dependency| spec_dependency.name == new_dependency.name && spec_dependency.requirement == new_dependency.requirement }
50
+ dependencies << new_dependency
51
+ end
49
52
  end
50
53
 
51
54
  dependencies
52
55
  end
53
56
 
54
57
  def forge_source
55
- Forge.default
58
+ Forge.from_lock_options(environment, :remote => "https://forgeapi.puppetlabs.com")
56
59
  end
57
60
 
58
61
  private
@@ -102,11 +105,7 @@ module Librarian
102
105
  def parsed_metadata
103
106
  if @metadata.nil?
104
107
  @metadata = if metadata?
105
- begin
106
- JSON.parse(File.read(metadata))
107
- rescue JSON::ParserError => e
108
- raise Error, "Unable to parse json file #{metadata}: #{e}"
109
- end
108
+ JSON.parse(File.read(metadata))
110
109
  elsif modulefile?
111
110
  # translate Modulefile to metadata.json
112
111
  evaluated = evaluate_modulefile(modulefile)
@@ -160,8 +159,8 @@ module Librarian
160
159
  return true if path.join('manifests').exist?
161
160
  return true if path.join('lib').join('puppet').exist?
162
161
  return true if path.join('lib').join('facter').exist?
163
- debug { "Could not find manifests, lib/puppet or lib/facter under #{path}, maybe it is not a puppet module" }
164
- true
162
+ debug { "Could not find manifests, lib/puppet or lib/facter under #{path}, assuming is not a puppet module" }
163
+ false
165
164
  end
166
165
  end
167
166
  end
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
  #^syntax detection
3
3
 
4
- forge "https://forge.puppetlabs.com"
4
+ forge "https://forgeapi.puppetlabs.com"
5
5
 
6
6
  # use dependencies defined in metadata.json
7
7
  metadata
@@ -30,7 +30,7 @@ module Librarian
30
30
  else
31
31
  begin
32
32
  FileUtils.cp_r(src, dest, :preserve => true)
33
- rescue Errno::ENOENT, Errno::EACCES
33
+ rescue Errno::ENOENT
34
34
  debug { "Failed to copy from #{src} to #{dest} preserving file types, trying again without preserving them" }
35
35
  FileUtils.rm_rf(dest)
36
36
  FileUtils.cp_r(src, dest)
@@ -1,5 +1,5 @@
1
1
  module Librarian
2
2
  module Puppet
3
- VERSION = "1.5.0"
3
+ VERSION = "2.0.0"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: librarian-puppet
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.0
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tim Sharpe
@@ -9,160 +9,160 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-03-04 00:00:00.000000000 Z
12
+ date: 2014-10-14 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
- name: librarianp
15
+ name: librarian
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  requirements:
18
- - - ">="
18
+ - - '>='
19
19
  - !ruby/object:Gem::Version
20
- version: 0.5.1
20
+ version: 0.1.2
21
21
  type: :runtime
22
22
  prerelease: false
23
23
  version_requirements: !ruby/object:Gem::Requirement
24
24
  requirements:
25
- - - ">="
25
+ - - '>='
26
26
  - !ruby/object:Gem::Version
27
- version: 0.5.1
27
+ version: 0.1.2
28
28
  - !ruby/object:Gem::Dependency
29
29
  name: rsync
30
30
  requirement: !ruby/object:Gem::Requirement
31
31
  requirements:
32
- - - ">="
32
+ - - '>='
33
33
  - !ruby/object:Gem::Version
34
34
  version: '0'
35
35
  type: :runtime
36
36
  prerelease: false
37
37
  version_requirements: !ruby/object:Gem::Requirement
38
38
  requirements:
39
- - - ">="
39
+ - - '>='
40
40
  - !ruby/object:Gem::Version
41
41
  version: '0'
42
42
  - !ruby/object:Gem::Dependency
43
- name: json
43
+ name: puppet_forge
44
44
  requirement: !ruby/object:Gem::Requirement
45
45
  requirements:
46
- - - ">="
46
+ - - '>='
47
47
  - !ruby/object:Gem::Version
48
48
  version: '0'
49
49
  type: :runtime
50
50
  prerelease: false
51
51
  version_requirements: !ruby/object:Gem::Requirement
52
52
  requirements:
53
- - - ">="
53
+ - - '>='
54
54
  - !ruby/object:Gem::Version
55
55
  version: '0'
56
56
  - !ruby/object:Gem::Dependency
57
57
  name: rake
58
58
  requirement: !ruby/object:Gem::Requirement
59
59
  requirements:
60
- - - ">="
60
+ - - '>='
61
61
  - !ruby/object:Gem::Version
62
62
  version: '0'
63
63
  type: :development
64
64
  prerelease: false
65
65
  version_requirements: !ruby/object:Gem::Requirement
66
66
  requirements:
67
- - - ">="
67
+ - - '>='
68
68
  - !ruby/object:Gem::Version
69
69
  version: '0'
70
70
  - !ruby/object:Gem::Dependency
71
71
  name: rspec
72
72
  requirement: !ruby/object:Gem::Requirement
73
73
  requirements:
74
- - - ">="
74
+ - - '>='
75
75
  - !ruby/object:Gem::Version
76
76
  version: '0'
77
77
  type: :development
78
78
  prerelease: false
79
79
  version_requirements: !ruby/object:Gem::Requirement
80
80
  requirements:
81
- - - ">="
81
+ - - '>='
82
82
  - !ruby/object:Gem::Version
83
83
  version: '0'
84
84
  - !ruby/object:Gem::Dependency
85
85
  name: cucumber
86
86
  requirement: !ruby/object:Gem::Requirement
87
87
  requirements:
88
- - - ">="
88
+ - - '>='
89
89
  - !ruby/object:Gem::Version
90
90
  version: '0'
91
91
  type: :development
92
92
  prerelease: false
93
93
  version_requirements: !ruby/object:Gem::Requirement
94
94
  requirements:
95
- - - ">="
95
+ - - '>='
96
96
  - !ruby/object:Gem::Version
97
97
  version: '0'
98
98
  - !ruby/object:Gem::Dependency
99
99
  name: aruba
100
100
  requirement: !ruby/object:Gem::Requirement
101
101
  requirements:
102
- - - ">="
102
+ - - '>='
103
103
  - !ruby/object:Gem::Version
104
104
  version: '0'
105
105
  type: :development
106
106
  prerelease: false
107
107
  version_requirements: !ruby/object:Gem::Requirement
108
108
  requirements:
109
- - - ">="
109
+ - - '>='
110
110
  - !ruby/object:Gem::Version
111
111
  version: '0'
112
112
  - !ruby/object:Gem::Dependency
113
113
  name: puppet
114
114
  requirement: !ruby/object:Gem::Requirement
115
115
  requirements:
116
- - - ">="
116
+ - - '>='
117
117
  - !ruby/object:Gem::Version
118
118
  version: '0'
119
119
  type: :development
120
120
  prerelease: false
121
121
  version_requirements: !ruby/object:Gem::Requirement
122
122
  requirements:
123
- - - ">="
123
+ - - '>='
124
124
  - !ruby/object:Gem::Version
125
125
  version: '0'
126
126
  - !ruby/object:Gem::Dependency
127
127
  name: minitest
128
128
  requirement: !ruby/object:Gem::Requirement
129
129
  requirements:
130
- - - "~>"
130
+ - - ~>
131
131
  - !ruby/object:Gem::Version
132
132
  version: '5'
133
133
  type: :development
134
134
  prerelease: false
135
135
  version_requirements: !ruby/object:Gem::Requirement
136
136
  requirements:
137
- - - "~>"
137
+ - - ~>
138
138
  - !ruby/object:Gem::Version
139
139
  version: '5'
140
140
  - !ruby/object:Gem::Dependency
141
141
  name: mocha
142
142
  requirement: !ruby/object:Gem::Requirement
143
143
  requirements:
144
- - - ">="
144
+ - - '>='
145
145
  - !ruby/object:Gem::Version
146
146
  version: '0'
147
147
  type: :development
148
148
  prerelease: false
149
149
  version_requirements: !ruby/object:Gem::Requirement
150
150
  requirements:
151
- - - ">="
151
+ - - '>='
152
152
  - !ruby/object:Gem::Version
153
153
  version: '0'
154
154
  - !ruby/object:Gem::Dependency
155
155
  name: simplecov
156
156
  requirement: !ruby/object:Gem::Requirement
157
157
  requirements:
158
- - - ">="
158
+ - - '>='
159
159
  - !ruby/object:Gem::Version
160
160
  version: 0.9.0
161
161
  type: :development
162
162
  prerelease: false
163
163
  version_requirements: !ruby/object:Gem::Requirement
164
164
  requirements:
165
- - - ">="
165
+ - - '>='
166
166
  - !ruby/object:Gem::Version
167
167
  version: 0.9.0
168
168
  description: |-
@@ -177,20 +177,19 @@ executables:
177
177
  extensions: []
178
178
  extra_rdoc_files: []
179
179
  files:
180
- - ".gitignore"
180
+ - .gitignore
181
181
  - LICENSE
182
182
  - README.md
183
183
  - bin/librarian-puppet
184
184
  - lib/librarian/puppet.rb
185
185
  - lib/librarian/puppet/action.rb
186
186
  - lib/librarian/puppet/action/install.rb
187
- - lib/librarian/puppet/action/resolve.rb
188
187
  - lib/librarian/puppet/cli.rb
189
- - lib/librarian/puppet/dependency.rb
190
188
  - lib/librarian/puppet/dsl.rb
191
189
  - lib/librarian/puppet/environment.rb
192
190
  - lib/librarian/puppet/extension.rb
193
- - lib/librarian/puppet/lockfile.rb
191
+ - lib/librarian/puppet/lockfile/parser.rb
192
+ - lib/librarian/puppet/requirement.rb
194
193
  - lib/librarian/puppet/source.rb
195
194
  - lib/librarian/puppet/source/forge.rb
196
195
  - lib/librarian/puppet/source/forge/repo.rb
@@ -215,17 +214,17 @@ require_paths:
215
214
  - lib
216
215
  required_ruby_version: !ruby/object:Gem::Requirement
217
216
  requirements:
218
- - - ">="
217
+ - - '>='
219
218
  - !ruby/object:Gem::Version
220
- version: '0'
219
+ version: 1.9.0
221
220
  required_rubygems_version: !ruby/object:Gem::Requirement
222
221
  requirements:
223
- - - ">="
222
+ - - '>='
224
223
  - !ruby/object:Gem::Version
225
224
  version: '0'
226
225
  requirements: []
227
226
  rubyforge_project:
228
- rubygems_version: 2.4.3
227
+ rubygems_version: 2.2.2
229
228
  signing_key:
230
229
  specification_version: 4
231
230
  summary: Bundler for your Puppet modules
@@ -1,19 +0,0 @@
1
- module Librarian
2
- module Puppet
3
- module Action
4
- class Resolve < Librarian::Action::Resolve
5
- include Librarian::Puppet::Util
6
-
7
- def run
8
- super
9
- manifests = environment.lock.manifests.select{ |m| m.name }
10
- dupes = manifests.group_by{ |m| module_name(m.name) }.select { |k, v| v.size > 1 }
11
- dupes.each do |k,v|
12
- warn("Dependency on module '#{k}' is fullfilled by multiple modules and only one will be used: #{v.map{|m|m.name}}")
13
- end
14
- end
15
-
16
- end
17
- end
18
- end
19
- end
@@ -1,18 +0,0 @@
1
- module Librarian
2
- module Puppet
3
-
4
- class Dependency < Librarian::Dependency
5
-
6
- include Librarian::Puppet::Util
7
-
8
- def initialize(name, requirement, source)
9
- # Issue #235 fail if forge source is not defined
10
- raise Error, "forge entry is not defined in Puppetfile" if source.instance_of?(Array) && source.empty?
11
-
12
- super(normalize_name(name), requirement, source)
13
- end
14
-
15
- end
16
-
17
- end
18
- end
@@ -1,39 +0,0 @@
1
- # Extend Lockfile to normalize module names from acme/mod to acme-mod
2
- module Librarian
3
- module Puppet
4
- class Lockfile < Librarian::Lockfile
5
-
6
- # Extend the parser to normalize module names in old .lock files, converting / to -
7
- class Parser < Librarian::Lockfile::Parser
8
-
9
- include Librarian::Puppet::Util
10
-
11
- def extract_and_parse_sources(lines)
12
- sources = super
13
- sources.each do |source|
14
- source[:manifests] = Hash[source[:manifests].map do |name,manifest|
15
- [normalize_name(name), manifest]
16
- end]
17
- end
18
- sources
19
- end
20
-
21
- def extract_and_parse_dependencies(lines, manifests_index)
22
- # when looking up in manifests_index normalize the name beforehand
23
- class << manifests_index
24
- include Librarian::Puppet::Util
25
- alias_method :old_lookup, :[]
26
- define_method(:[]) { |k| self.old_lookup(normalize_name(k)) }
27
- end
28
- super(lines, manifests_index)
29
- end
30
-
31
- end
32
-
33
- def load(string)
34
- Parser.new(environment).parse(string)
35
- end
36
-
37
- end
38
- end
39
- end