librarian-puppet 1.5.0 → 2.0.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 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