r10k 3.9.1 → 3.11.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.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/rspec_tests.yml +1 -1
  3. data/.travis.yml +0 -10
  4. data/CHANGELOG.mkd +28 -0
  5. data/README.mkd +6 -0
  6. data/doc/dynamic-environments/configuration.mkd +21 -0
  7. data/doc/puppetfile.mkd +15 -1
  8. data/integration/Rakefile +3 -1
  9. data/integration/tests/user_scenario/basic_workflow/negative/neg_specify_deleted_forge_module.rb +3 -9
  10. data/integration/tests/user_scenario/basic_workflow/single_env_purge_unmanaged_modules.rb +21 -25
  11. data/integration/tests/user_scenario/complex_workflow/multi_env_add_change_remove.rb +3 -3
  12. data/integration/tests/user_scenario/complex_workflow/multi_env_remove_re-add.rb +3 -3
  13. data/integration/tests/user_scenario/complex_workflow/multi_env_unamanaged.rb +3 -3
  14. data/lib/r10k/action/base.rb +6 -3
  15. data/lib/r10k/action/deploy/display.rb +6 -3
  16. data/lib/r10k/action/deploy/environment.rb +15 -4
  17. data/lib/r10k/action/deploy/module.rb +37 -8
  18. data/lib/r10k/action/runner.rb +45 -10
  19. data/lib/r10k/cli/deploy.rb +4 -0
  20. data/lib/r10k/git.rb +3 -0
  21. data/lib/r10k/git/cache.rb +1 -1
  22. data/lib/r10k/git/rugged/credentials.rb +77 -0
  23. data/lib/r10k/git/stateful_repository.rb +1 -0
  24. data/lib/r10k/initializers.rb +10 -0
  25. data/lib/r10k/module/base.rb +37 -0
  26. data/lib/r10k/module/forge.rb +7 -2
  27. data/lib/r10k/module/git.rb +2 -1
  28. data/lib/r10k/module/svn.rb +2 -1
  29. data/lib/r10k/module_loader/puppetfile.rb +206 -0
  30. data/lib/r10k/module_loader/puppetfile/dsl.rb +37 -0
  31. data/lib/r10k/puppetfile.rb +83 -160
  32. data/lib/r10k/settings.rb +47 -2
  33. data/lib/r10k/settings/definition.rb +1 -1
  34. data/lib/r10k/source/base.rb +10 -0
  35. data/lib/r10k/source/git.rb +5 -0
  36. data/lib/r10k/source/svn.rb +4 -0
  37. data/lib/r10k/util/purgeable.rb +70 -8
  38. data/lib/r10k/version.rb +1 -1
  39. data/locales/r10k.pot +129 -57
  40. data/r10k.gemspec +2 -0
  41. data/spec/fixtures/unit/action/r10k_forge_auth.yaml +4 -0
  42. data/spec/fixtures/unit/action/r10k_forge_auth_no_url.yaml +3 -0
  43. data/spec/fixtures/unit/util/purgeable/managed_one/managed_subdir_1/managed_subdir_2/ignored_1 +0 -0
  44. data/spec/fixtures/unit/util/purgeable/managed_two/.hidden/unmanaged_3 +0 -0
  45. data/spec/unit/action/deploy/environment_spec.rb +25 -0
  46. data/spec/unit/action/deploy/module_spec.rb +216 -14
  47. data/spec/unit/action/runner_spec.rb +129 -25
  48. data/spec/unit/git/cache_spec.rb +14 -0
  49. data/spec/unit/git/rugged/credentials_spec.rb +29 -0
  50. data/spec/unit/git/stateful_repository_spec.rb +5 -0
  51. data/spec/unit/module/base_spec.rb +46 -0
  52. data/spec/unit/module/forge_spec.rb +27 -1
  53. data/spec/unit/module/git_spec.rb +17 -8
  54. data/spec/unit/module/svn_spec.rb +18 -0
  55. data/spec/unit/module_loader/puppetfile_spec.rb +343 -0
  56. data/spec/unit/module_spec.rb +28 -0
  57. data/spec/unit/puppetfile_spec.rb +127 -191
  58. data/spec/unit/settings_spec.rb +24 -2
  59. data/spec/unit/util/purgeable_spec.rb +38 -6
  60. metadata +23 -2
@@ -50,7 +50,7 @@ class R10K::Module::SVN < R10K::Module::Base
50
50
  :revision => :expected_revision,
51
51
  :username => :self,
52
52
  :password => :self
53
- })
53
+ }, :raise_on_unhandled => false)
54
54
 
55
55
  @working_dir = R10K::SVN::WorkingDir.new(@path, :username => @username, :password => @password)
56
56
  end
@@ -80,6 +80,7 @@ class R10K::Module::SVN < R10K::Module::Base
80
80
  when :outdated
81
81
  update
82
82
  end
83
+ maybe_delete_spec_dir
83
84
  end
84
85
  end
85
86
 
@@ -0,0 +1,206 @@
1
+ require 'r10k/logging'
2
+
3
+ module R10K
4
+ module ModuleLoader
5
+ class Puppetfile
6
+
7
+ include R10K::Logging
8
+
9
+ DEFAULT_MODULEDIR = 'modules'
10
+ DEFAULT_PUPPETFILE_NAME = 'Puppetfile'
11
+ DEFAULT_FORGE_API = 'forgeapi.puppetlabs.com'
12
+
13
+ attr_accessor :default_branch_override, :environment
14
+ attr_reader :modules, :moduledir, :puppetfile_path,
15
+ :managed_directories, :desired_contents, :purge_exclusions
16
+
17
+ # @param basedir [String] The path that contains the moduledir &
18
+ # Puppetfile by default. May be an environment, project, or
19
+ # simple directory.
20
+ # @param puppetfile [String] The path to the Puppetfile, either an
21
+ # absolute full path or a relative path with regards to the basedir.
22
+ # @param moduledir [String] The path to the moduledir, either an
23
+ # absolute full path or a relative path with regards to the basedir.
24
+ # @param forge [String] The url (without protocol) to the Forge
25
+ # @param overrides [Hash] Configuration for loaded modules' behavior
26
+ # @param environment [R10K::Environment] When provided, the environment
27
+ # in which loading takes place
28
+ def initialize(basedir:,
29
+ moduledir: DEFAULT_MODULEDIR,
30
+ puppetfile: DEFAULT_PUPPETFILE_NAME,
31
+ forge: DEFAULT_FORGE_API,
32
+ overrides: {},
33
+ environment: nil)
34
+
35
+ @basedir = cleanpath(basedir)
36
+ @moduledir = resolve_path(@basedir, moduledir)
37
+ @puppetfile_path = resolve_path(@basedir, puppetfile)
38
+ @forge = forge
39
+ @overrides = overrides
40
+ @environment = environment
41
+ @default_branch_override = @overrides.dig(:environments, :default_branch_override)
42
+
43
+ @modules = []
44
+
45
+ @managed_directories = []
46
+ @desired_contents = []
47
+ @purge_exclusions = []
48
+
49
+ logger.info _("Using Puppetfile '%{puppetfile}'") % {puppetfile: @puppetfile_path}
50
+ logger.debug _("Using moduledir '%{moduledir}'") % {moduledir: @moduledir}
51
+ end
52
+
53
+ def load
54
+ dsl = R10K::ModuleLoader::Puppetfile::DSL.new(self)
55
+ dsl.instance_eval(puppetfile_content(@puppetfile_path), @puppetfile_path)
56
+
57
+ validate_no_duplicate_names(@modules)
58
+ @modules
59
+
60
+ managed_content = @modules.group_by(&:dirname)
61
+
62
+ @managed_directories = determine_managed_directories(managed_content)
63
+ @desired_contents = determine_desired_contents(managed_content)
64
+ @purge_exclusions = determine_purge_exclusions(@managed_directories)
65
+
66
+ {
67
+ modules: @modules,
68
+ managed_directories: @managed_directories,
69
+ desired_contents: @desired_contents,
70
+ purge_exclusions: @purge_exclusions
71
+ }
72
+
73
+ rescue SyntaxError, LoadError, ArgumentError, NameError => e
74
+ raise R10K::Error.wrap(e, _("Failed to evaluate %{path}") % {path: @puppetfile_path})
75
+ end
76
+
77
+
78
+ ##
79
+ ## set_forge, set_moduledir, and add_module are used directly by the DSL class
80
+ ##
81
+
82
+ # @param [String] forge
83
+ def set_forge(forge)
84
+ @forge = forge
85
+ end
86
+
87
+ # @param [String] moduledir
88
+ def set_moduledir(moduledir)
89
+ @moduledir = resolve_path(@basedir, moduledir)
90
+ end
91
+
92
+ # @param [String] name
93
+ # @param [Hash, String, Symbol, nil] module_info Calling with
94
+ # anything but a Hash is deprecated. The DSL will now convert
95
+ # String and Symbol versions to Hashes of the shape
96
+ # { version: <String or Symbol> }
97
+ #
98
+ # String inputs should be valid module versions, the Symbol
99
+ # `:latest` is allowed, as well as `nil`.
100
+ #
101
+ # Non-Hash inputs are only ever used by Forge modules. In
102
+ # future versions this method will require the caller (the
103
+ # DSL class, not the Puppetfile author) to do this conversion
104
+ # itself.
105
+ #
106
+ def add_module(name, module_info)
107
+ if !module_info.is_a?(Hash)
108
+ module_info = { version: module_info }
109
+ end
110
+
111
+ module_info[:overrides] = @overrides
112
+
113
+ spec_deletable = false
114
+
115
+ if install_path = module_info.delete(:install_path)
116
+ install_path = resolve_path(@basedir, install_path)
117
+ validate_install_path(install_path, name)
118
+ else
119
+ install_path = @moduledir
120
+ spec_deletable = true
121
+ end
122
+
123
+ if @default_branch_override
124
+ module_info[:default_branch_override] = @default_branch_override
125
+ end
126
+
127
+ mod = R10K::Module.new(name, install_path, module_info, @environment)
128
+ mod.origin = :puppetfile
129
+ mod.spec_deletable = spec_deletable
130
+
131
+ # Do not save modules if they would conflict with the attached
132
+ # environment
133
+ if @environment && @environment.module_conflicts?(mod)
134
+ return @modules
135
+ end
136
+
137
+ @modules << mod
138
+ end
139
+
140
+ private
141
+
142
+ # @param [Array<R10K::Module>] modules
143
+ def validate_no_duplicate_names(modules)
144
+ dupes = modules
145
+ .group_by { |mod| mod.name }
146
+ .select { |_, mods| mods.size > 1 }
147
+ .map(&:first)
148
+ unless dupes.empty?
149
+ msg = _('Puppetfiles cannot contain duplicate module names.')
150
+ msg += ' '
151
+ msg += _("Remove the duplicates of the following modules: %{dupes}" % { dupes: dupes.join(' ') })
152
+ raise R10K::Error.new(msg)
153
+ end
154
+ end
155
+
156
+ def resolve_path(base, path)
157
+ if Pathname.new(path).absolute?
158
+ cleanpath(path)
159
+ else
160
+ cleanpath(File.join(base, path))
161
+ end
162
+ end
163
+
164
+ def validate_install_path(path, modname)
165
+ unless /^#{Regexp.escape(@basedir)}.*/ =~ path
166
+ raise R10K::Error.new("Puppetfile cannot manage content '#{modname}' outside of containing environment: #{path} is not within #{@basedir}")
167
+ end
168
+
169
+ true
170
+ end
171
+
172
+ def determine_managed_directories(managed_content)
173
+ managed_content.keys.reject { |dir| dir == @basedir }
174
+ end
175
+
176
+ # Returns an array of the full paths to all the content being managed.
177
+ # @return [Array<String>]
178
+ def determine_desired_contents(managed_content)
179
+ managed_content.flat_map do |install_path, mods|
180
+ mods.collect { |mod| File.join(install_path, mod.name) }
181
+ end
182
+ end
183
+
184
+ def determine_purge_exclusions(managed_dirs)
185
+ if environment && environment.respond_to?(:desired_contents)
186
+ managed_dirs + environment.desired_contents
187
+ else
188
+ managed_dirs
189
+ end
190
+ end
191
+
192
+ # .cleanpath is as close to a canonical path as we can do without touching
193
+ # the filesystem. The .realpath methods will choke if some of the
194
+ # intermediate paths are missing, even though in some cases we will create
195
+ # them later as needed.
196
+ def cleanpath(path)
197
+ Pathname.new(path).cleanpath.to_s
198
+ end
199
+
200
+ # For testing purposes only
201
+ def puppetfile_content(path)
202
+ File.read(path)
203
+ end
204
+ end
205
+ end
206
+ end
@@ -0,0 +1,37 @@
1
+ module R10K
2
+ module ModuleLoader
3
+ class Puppetfile
4
+ class DSL
5
+ # A barebones implementation of the Puppetfile DSL
6
+ #
7
+ # @api private
8
+
9
+ def initialize(librarian)
10
+ @librarian = librarian
11
+ end
12
+
13
+ def mod(name, args = nil)
14
+ if args.is_a?(Hash)
15
+ opts = args
16
+ else
17
+ opts = { version: args }
18
+ end
19
+
20
+ @librarian.add_module(name, opts)
21
+ end
22
+
23
+ def forge(location)
24
+ @librarian.set_forge(location)
25
+ end
26
+
27
+ def moduledir(location)
28
+ @librarian.set_moduledir(location)
29
+ end
30
+
31
+ def method_missing(method, *args)
32
+ raise NoMethodError, _("unrecognized declaration '%{method}'") % {method: method}
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -4,10 +4,17 @@ require 'r10k/module'
4
4
  require 'r10k/util/purgeable'
5
5
  require 'r10k/errors'
6
6
  require 'r10k/content_synchronizer'
7
+ require 'r10k/module_loader/puppetfile/dsl'
8
+ require 'r10k/module_loader/puppetfile'
7
9
 
8
10
  module R10K
11
+
12
+ # Deprecated, use R10K::ModuleLoader::Puppetfile#load to load content,
13
+ # provide the `:modules` key of the returned Hash to
14
+ # R10K::ContentSynchronizer (either the `serial_sync` or `concurrent_sync`)
15
+ # and the remaining keys (`:managed_directories`, `:desired_contents`, and
16
+ # `:purge_exclusions`) to R10K::Util::Cleaner.
9
17
  class Puppetfile
10
- # Defines the data members of a Puppetfile
11
18
 
12
19
  include R10K::Settings::Mixin
13
20
 
@@ -19,25 +26,13 @@ class Puppetfile
19
26
  # @return [String] The URL to use for the Puppet Forge
20
27
  attr_reader :forge
21
28
 
22
- # @!attribute [r] modules
23
- # @return [Array<R10K::Module>]
24
- attr_reader :modules
25
-
26
29
  # @!attribute [r] basedir
27
30
  # @return [String] The base directory that contains the Puppetfile
28
31
  attr_reader :basedir
29
32
 
30
- # @!attribute [r] moduledir
31
- # @return [String] The directory to install the modules #{basedir}/modules
32
- attr_reader :moduledir
33
-
34
- # @!attrbute [r] puppetfile_path
35
- # @return [String] The path to the Puppetfile
36
- attr_reader :puppetfile_path
37
-
38
- # @!attribute [rw] environment
33
+ # @!attribute [r] environment
39
34
  # @return [R10K::Environment] Optional R10K::Environment that this Puppetfile belongs to.
40
- attr_accessor :environment
35
+ attr_reader :environment
41
36
 
42
37
  # @!attribute [rw] force
43
38
  # @return [Boolean] Overwrite any locally made changes
@@ -47,6 +42,10 @@ class Puppetfile
47
42
  # @return [Hash] Various settings overridden from normal configs
48
43
  attr_reader :overrides
49
44
 
45
+ # @!attribute [r] loader
46
+ # @return [R10K::ModuleLoader::Puppetfile] The internal module loader
47
+ attr_reader :loader
48
+
50
49
  # @param [String] basedir
51
50
  # @param [Hash, String, nil] options_or_moduledir The directory to install the modules or a Hash of options.
52
51
  # Usage as moduledir is deprecated. Only use as options, defaults to nil
@@ -65,144 +64,123 @@ class Puppetfile
65
64
 
66
65
  @force = deprecated_force_arg || options.delete(:force) || false
67
66
  @moduledir = deprecated_moduledir_arg || options.delete(:moduledir) || File.join(basedir, 'modules')
68
- @puppetfile_name = deprecated_name_arg || options.delete(:puppetfile_name) || 'Puppetfile'
69
- @puppetfile_path = deprecated_path_arg || options.delete(:puppetfile_path) || File.join(basedir, @puppetfile_name)
67
+ puppetfile_name = deprecated_name_arg || options.delete(:puppetfile_name) || 'Puppetfile'
68
+ puppetfile_path = deprecated_path_arg || options.delete(:puppetfile_path)
69
+ @puppetfile = puppetfile_path || puppetfile_name
70
+ @environment = options.delete(:environment)
70
71
 
71
72
  @overrides = options.delete(:overrides) || {}
73
+ @default_branch_override = @overrides.dig(:environments, :default_branch_override)
72
74
 
73
- logger.info _("Using Puppetfile '%{puppetfile}'") % {puppetfile: @puppetfile_path}
74
-
75
- @modules = []
76
- @managed_content = {}
77
75
  @forge = 'forgeapi.puppetlabs.com'
78
76
 
77
+ @loader = ::R10K::ModuleLoader::Puppetfile.new(
78
+ basedir: @basedir,
79
+ moduledir: @moduledir,
80
+ puppetfile: @puppetfile,
81
+ forge: @forge,
82
+ overrides: @overrides,
83
+ environment: @environment
84
+ )
85
+
86
+ @loaded_content = {
87
+ modules: [],
88
+ managed_directories: [],
89
+ desired_contents: [],
90
+ purge_exclusions: []
91
+ }
92
+
79
93
  @loaded = false
80
94
  end
81
95
 
96
+ # @param [String] default_branch_override The default branch to use
97
+ # instead of one specified in the module declaration, if applicable.
98
+ # Deprecated, use R10K::ModuleLoader::Puppetfile directly and pass
99
+ # the default_branch_override as an option on initialization.
82
100
  def load(default_branch_override = nil)
83
- return true if self.loaded?
84
- if File.readable? @puppetfile_path
85
- self.load!(default_branch_override)
101
+ if self.loaded?
102
+ return @loaded_content
86
103
  else
87
- logger.debug _("Puppetfile %{path} missing or unreadable") % {path: @puppetfile_path.inspect}
104
+ if !File.readable?(puppetfile_path)
105
+ logger.debug _("Puppetfile %{path} missing or unreadable") % {path: puppetfile_path.inspect}
106
+ else
107
+ self.load!(default_branch_override)
108
+ end
88
109
  end
89
110
  end
90
111
 
112
+ # @param [String] default_branch_override The default branch to use
113
+ # instead of one specified in the module declaration, if applicable.
114
+ # Deprecated, use R10K::ModuleLoader::Puppetfile directly and pass
115
+ # the default_branch_override as an option on initialization.
91
116
  def load!(default_branch_override = nil)
92
- @default_branch_override = default_branch_override
93
117
 
94
- dsl = R10K::Puppetfile::DSL.new(self)
95
- dsl.instance_eval(puppetfile_contents, @puppetfile_path)
118
+ if default_branch_override && (default_branch_override != @default_branch_override)
119
+ logger.warn("Mismatch between passed and initialized default branch overrides, preferring passed value.")
120
+ @loader.default_branch_override = default_branch_override
121
+ end
96
122
 
97
- validate_no_duplicate_names(@modules)
123
+ @loaded_content = @loader.load
98
124
  @loaded = true
99
- rescue SyntaxError, LoadError, ArgumentError, NameError => e
100
- raise R10K::Error.wrap(e, _("Failed to evaluate %{path}") % {path: @puppetfile_path})
125
+
126
+ @loaded_content
101
127
  end
102
128
 
103
129
  def loaded?
104
130
  @loaded
105
131
  end
106
132
 
107
- # @param [Array<String>] modules
108
- def validate_no_duplicate_names(modules)
109
- dupes = modules
110
- .group_by { |mod| mod.name }
111
- .select { |_, v| v.size > 1 }
112
- .map(&:first)
113
- unless dupes.empty?
114
- msg = _('Puppetfiles cannot contain duplicate module names.')
115
- msg += ' '
116
- msg += _("Remove the duplicates of the following modules: %{dupes}" % { dupes: dupes.join(' ') })
117
- raise R10K::Error.new(msg)
118
- end
133
+ def modules
134
+ @loaded_content[:modules]
119
135
  end
120
136
 
121
- # @param [String] forge
122
- def set_forge(forge)
123
- @forge = forge
137
+ # @see R10K::ModuleLoader::Puppetfile#add_module for upcoming signature changes
138
+ def add_module(name, args)
139
+ @loader.add_module(name, args)
124
140
  end
125
141
 
126
- # @param [String] moduledir
127
- def set_moduledir(moduledir)
128
- @moduledir = if Pathname.new(moduledir).absolute?
129
- moduledir
130
- else
131
- File.join(basedir, moduledir)
132
- end
142
+ def set_moduledir(dir)
143
+ @loader.set_moduledir(dir)
133
144
  end
134
145
 
135
- # @param [String] name
136
- # @param [Hash, String, Symbol] args Calling with anything but a Hash is
137
- # deprecated. The DSL will now convert String and Symbol versions to
138
- # Hashes of the shape
139
- # { version: <String or Symbol> }
140
- #
141
- def add_module(name, args)
142
- if !args.is_a?(Hash)
143
- args = { version: args }
144
- end
145
-
146
- args[:overrides] = @overrides
147
-
148
- if install_path = args.delete(:install_path)
149
- install_path = resolve_install_path(install_path)
150
- validate_install_path(install_path, name)
151
- else
152
- install_path = @moduledir
153
- end
154
-
155
- if @default_branch_override != nil
156
- args[:default_branch_override] = @default_branch_override
157
- end
158
-
159
-
160
- mod = R10K::Module.new(name, install_path, args, @environment)
161
- mod.origin = :puppetfile
146
+ def set_forge(forge)
147
+ @loader.set_forge(forge)
148
+ end
162
149
 
163
- # Do not load modules if they would conflict with the attached
164
- # environment
165
- if environment && environment.module_conflicts?(mod)
166
- mod = nil
167
- return @modules
168
- end
150
+ def moduledir
151
+ @loader.moduledir
152
+ end
169
153
 
170
- # Keep track of all the content this Puppetfile is managing to enable purging.
171
- @managed_content[install_path] = Array.new unless @managed_content.has_key?(install_path)
172
- @managed_content[install_path] << mod.name
154
+ def puppetfile_path
155
+ @loader.puppetfile_path
156
+ end
173
157
 
174
- @modules << mod
158
+ def environment=(env)
159
+ @loader.environment = env
160
+ @environment = env
175
161
  end
176
162
 
177
163
  include R10K::Util::Purgeable
178
164
 
179
165
  def managed_directories
180
- self.load unless @loaded
166
+ self.load
181
167
 
182
- dirs = @managed_content.keys
183
- dirs.delete(real_basedir)
184
- dirs
168
+ @loaded_content[:managed_directories]
185
169
  end
186
170
 
187
171
  # Returns an array of the full paths to all the content being managed.
188
172
  # @note This implements a required method for the Purgeable mixin
189
173
  # @return [Array<String>]
190
174
  def desired_contents
191
- self.load unless @loaded
175
+ self.load
192
176
 
193
- @managed_content.flat_map do |install_path, modnames|
194
- modnames.collect { |name| File.join(install_path, name) }
195
- end
177
+ @loaded_content[:desired_contents]
196
178
  end
197
179
 
198
180
  def purge_exclusions
199
- exclusions = managed_directories
200
-
201
- if environment && environment.respond_to?(:desired_contents)
202
- exclusions += environment.desired_contents
203
- end
181
+ self.load
204
182
 
205
- exclusions
183
+ @loaded_content[:purge_exclusions]
206
184
  end
207
185
 
208
186
  def accept(visitor)
@@ -225,65 +203,10 @@ class Puppetfile
225
203
 
226
204
  private
227
205
 
228
- def puppetfile_contents
229
- File.read(@puppetfile_path)
230
- end
231
-
232
- def resolve_install_path(path)
233
- pn = Pathname.new(path)
234
-
235
- unless pn.absolute?
236
- pn = Pathname.new(File.join(basedir, path))
237
- end
238
-
239
- # .cleanpath is as good as we can do without touching the filesystem.
240
- # The .realpath methods will also choke if some of the intermediate
241
- # paths are missing, even though we will create them later as needed.
242
- pn.cleanpath.to_s
243
- end
244
-
245
- def validate_install_path(path, modname)
246
- unless /^#{Regexp.escape(real_basedir)}.*/ =~ path
247
- raise R10K::Error.new("Puppetfile cannot manage content '#{modname}' outside of containing environment: #{path} is not within #{real_basedir}")
248
- end
249
-
250
- true
251
- end
252
-
253
206
  def real_basedir
254
207
  Pathname.new(basedir).cleanpath.to_s
255
208
  end
256
209
 
257
- class DSL
258
- # A barebones implementation of the Puppetfile DSL
259
- #
260
- # @api private
261
-
262
- def initialize(librarian)
263
- @librarian = librarian
264
- end
265
-
266
- def mod(name, args = nil)
267
- if args.is_a?(Hash)
268
- opts = args
269
- else
270
- opts = { version: args }
271
- end
272
-
273
- @librarian.add_module(name, opts)
274
- end
275
-
276
- def forge(location)
277
- @librarian.set_forge(location)
278
- end
279
-
280
- def moduledir(location)
281
- @librarian.set_moduledir(location)
282
- end
283
-
284
- def method_missing(method, *args)
285
- raise NoMethodError, _("unrecognized declaration '%{method}'") % {method: method}
286
- end
287
- end
210
+ DSL = R10K::ModuleLoader::Puppetfile::DSL
288
211
  end
289
212
  end