r10k 3.10.0 → 3.13.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (93) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +0 -10
  3. data/CHANGELOG.mkd +33 -0
  4. data/README.mkd +6 -0
  5. data/doc/dynamic-environments/configuration.mkd +25 -7
  6. data/doc/dynamic-environments/usage.mkd +26 -0
  7. data/doc/puppetfile.mkd +18 -5
  8. data/integration/Rakefile +2 -0
  9. data/integration/tests/basic_functionality/basic_deployment.rb +176 -0
  10. data/integration/tests/user_scenario/basic_workflow/single_env_purge_unmanaged_modules.rb +15 -13
  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 +1 -1
  15. data/lib/r10k/action/deploy/deploy_helpers.rb +4 -0
  16. data/lib/r10k/action/deploy/display.rb +1 -1
  17. data/lib/r10k/action/deploy/environment.rb +19 -9
  18. data/lib/r10k/action/deploy/module.rb +41 -11
  19. data/lib/r10k/action/puppetfile/check.rb +7 -5
  20. data/lib/r10k/action/puppetfile/install.rb +22 -16
  21. data/lib/r10k/action/puppetfile/purge.rb +12 -9
  22. data/lib/r10k/action/runner.rb +40 -4
  23. data/lib/r10k/action/visitor.rb +3 -0
  24. data/lib/r10k/cli/deploy.rb +5 -0
  25. data/lib/r10k/cli/puppetfile.rb +0 -1
  26. data/lib/r10k/content_synchronizer.rb +16 -4
  27. data/lib/r10k/environment/bare.rb +4 -7
  28. data/lib/r10k/environment/base.rb +64 -11
  29. data/lib/r10k/environment/plain.rb +16 -0
  30. data/lib/r10k/environment/with_modules.rb +6 -10
  31. data/lib/r10k/environment.rb +1 -0
  32. data/lib/r10k/errors.rb +5 -0
  33. data/lib/r10k/git/rugged/credentials.rb +77 -0
  34. data/lib/r10k/git/stateful_repository.rb +8 -0
  35. data/lib/r10k/git.rb +3 -0
  36. data/lib/r10k/initializers.rb +14 -7
  37. data/lib/r10k/logging.rb +78 -1
  38. data/lib/r10k/module/base.rb +42 -1
  39. data/lib/r10k/module/definition.rb +64 -0
  40. data/lib/r10k/module/forge.rb +11 -2
  41. data/lib/r10k/module/git.rb +23 -1
  42. data/lib/r10k/module/local.rb +6 -3
  43. data/lib/r10k/module/svn.rb +11 -0
  44. data/lib/r10k/module.rb +20 -2
  45. data/lib/r10k/module_loader/puppetfile/dsl.rb +8 -3
  46. data/lib/r10k/module_loader/puppetfile.rb +109 -28
  47. data/lib/r10k/puppetfile.rb +11 -13
  48. data/lib/r10k/settings/definition.rb +1 -1
  49. data/lib/r10k/settings.rb +89 -1
  50. data/lib/r10k/source/yaml.rb +1 -1
  51. data/lib/r10k/util/purgeable.rb +6 -2
  52. data/lib/r10k/util/setopts.rb +2 -0
  53. data/lib/r10k/util/subprocess.rb +1 -0
  54. data/lib/r10k/version.rb +1 -1
  55. data/locales/r10k.pot +168 -68
  56. data/r10k.gemspec +2 -0
  57. data/r10k.yaml.example +28 -0
  58. data/spec/fixtures/unit/action/r10k_logging.yaml +12 -0
  59. data/spec/fixtures/unit/puppetfile/forge-override/Puppetfile +8 -0
  60. data/spec/fixtures/unit/puppetfile/various-modules/Puppetfile +10 -0
  61. data/spec/fixtures/unit/puppetfile/various-modules/Puppetfile.new +10 -0
  62. data/spec/fixtures/unit/util/purgeable/managed_one/managed_subdir_1/managed_symlink_file +1 -0
  63. data/spec/fixtures/unit/util/purgeable/managed_one/managed_subdir_1/{managed_subdir_2 → subdir_allowlisted_2}/ignored_1 +0 -0
  64. data/spec/fixtures/unit/util/purgeable/managed_one/managed_subdir_1/unmanaged_symlink_dir +1 -0
  65. data/spec/fixtures/unit/util/purgeable/managed_one/managed_symlink_dir +1 -0
  66. data/spec/fixtures/unit/util/purgeable/managed_one/unmanaged_symlink_file +1 -0
  67. data/spec/integration/util/purageable_spec.rb +41 -0
  68. data/spec/r10k-mocks/mock_env.rb +3 -0
  69. data/spec/r10k-mocks/mock_source.rb +7 -3
  70. data/spec/unit/action/deploy/environment_spec.rb +96 -30
  71. data/spec/unit/action/deploy/module_spec.rb +217 -51
  72. data/spec/unit/action/puppetfile/check_spec.rb +17 -5
  73. data/spec/unit/action/puppetfile/install_spec.rb +42 -36
  74. data/spec/unit/action/puppetfile/purge_spec.rb +15 -17
  75. data/spec/unit/action/runner_spec.rb +132 -9
  76. data/spec/unit/environment/bare_spec.rb +13 -0
  77. data/spec/unit/environment/base_spec.rb +30 -17
  78. data/spec/unit/environment/git_spec.rb +2 -2
  79. data/spec/unit/environment/plain_spec.rb +8 -0
  80. data/spec/unit/environment/svn_spec.rb +4 -3
  81. data/spec/unit/environment/with_modules_spec.rb +3 -2
  82. data/spec/unit/git/rugged/credentials_spec.rb +29 -0
  83. data/spec/unit/git/stateful_repository_spec.rb +5 -0
  84. data/spec/unit/module/base_spec.rb +54 -8
  85. data/spec/unit/module/forge_spec.rb +51 -4
  86. data/spec/unit/module/git_spec.rb +67 -9
  87. data/spec/unit/module/svn_spec.rb +35 -5
  88. data/spec/unit/module_loader/puppetfile_spec.rb +108 -33
  89. data/spec/unit/module_spec.rb +12 -1
  90. data/spec/unit/puppetfile_spec.rb +33 -3
  91. data/spec/unit/settings_spec.rb +43 -2
  92. data/spec/unit/util/purgeable_spec.rb +22 -11
  93. metadata +31 -3
data/lib/r10k/module.rb CHANGED
@@ -22,17 +22,35 @@ module R10K::Module
22
22
  #
23
23
  # @return [Object < R10K::Module] A member of the implementing subclass
24
24
  def self.new(name, basedir, args, environment=nil)
25
+ with_implementation(name, args) do |implementation|
26
+ implementation.new(name, basedir, args, environment)
27
+ end
28
+ end
29
+
30
+ # Takes the same signature as Module.new but returns an metadata module
31
+ def self.from_metadata(name, basedir, args, environment=nil)
32
+ with_implementation(name, args) do |implementation|
33
+ R10K::Module::Definition.new(name,
34
+ dirname: basedir,
35
+ args: args,
36
+ implementation: implementation,
37
+ environment: environment)
38
+ end
39
+ end
40
+
41
+ def self.with_implementation(name, args, &block)
25
42
  if implementation = @klasses.find { |klass| klass.implement?(name, args) }
26
- obj = implementation.new(name, basedir, args, environment)
27
- obj
43
+ block.call(implementation)
28
44
  else
29
45
  raise _("Module %{name} with args %{args} doesn't have an implementation. (Are you using the right arguments?)") % {name: name, args: args.inspect}
30
46
  end
31
47
  end
32
48
 
49
+
33
50
  require 'r10k/module/base'
34
51
  require 'r10k/module/git'
35
52
  require 'r10k/module/svn'
36
53
  require 'r10k/module/local'
37
54
  require 'r10k/module/forge'
55
+ require 'r10k/module/definition'
38
56
  end
@@ -6,8 +6,9 @@ module R10K
6
6
  #
7
7
  # @api private
8
8
 
9
- def initialize(librarian)
10
- @librarian = librarian
9
+ def initialize(librarian, metadata_only: false)
10
+ @librarian = librarian
11
+ @metadata_only = metadata_only
11
12
  end
12
13
 
13
14
  def mod(name, args = nil)
@@ -17,7 +18,11 @@ module R10K
17
18
  opts = { version: args }
18
19
  end
19
20
 
20
- @librarian.add_module(name, opts)
21
+ if @metadata_only
22
+ @librarian.add_module_metadata(name, opts)
23
+ else
24
+ @librarian.add_module(name, opts)
25
+ end
21
26
  end
22
27
 
23
28
  def forge(location)
@@ -1,13 +1,21 @@
1
+ require 'r10k/errors'
2
+ require 'r10k/logging'
3
+ require 'r10k/module'
4
+ require 'r10k/module_loader/puppetfile/dsl'
5
+
6
+ require 'pathname'
7
+
1
8
  module R10K
2
9
  module ModuleLoader
3
10
  class Puppetfile
4
11
 
12
+ include R10K::Logging
13
+
5
14
  DEFAULT_MODULEDIR = 'modules'
6
15
  DEFAULT_PUPPETFILE_NAME = 'Puppetfile'
7
- DEFAULT_FORGE_API = 'forgeapi.puppetlabs.com'
8
16
 
9
17
  attr_accessor :default_branch_override, :environment
10
- attr_reader :modules, :moduledir,
18
+ attr_reader :modules, :moduledir, :puppetfile_path,
11
19
  :managed_directories, :desired_contents, :purge_exclusions
12
20
 
13
21
  # @param basedir [String] The path that contains the moduledir &
@@ -24,18 +32,19 @@ module R10K
24
32
  def initialize(basedir:,
25
33
  moduledir: DEFAULT_MODULEDIR,
26
34
  puppetfile: DEFAULT_PUPPETFILE_NAME,
27
- forge: DEFAULT_FORGE_API,
28
35
  overrides: {},
29
36
  environment: nil)
30
37
 
31
38
  @basedir = cleanpath(basedir)
32
39
  @moduledir = resolve_path(@basedir, moduledir)
33
- @puppetfile = resolve_path(@basedir, puppetfile)
34
- @forge = forge
40
+ @puppetfile_path = resolve_path(@basedir, puppetfile)
35
41
  @overrides = overrides
36
42
  @environment = environment
37
43
  @default_branch_override = @overrides.dig(:environments, :default_branch_override)
44
+ @allow_puppetfile_forge = @overrides.dig(:forge, :allow_puppetfile_override)
38
45
 
46
+ @existing_module_metadata = []
47
+ @existing_module_versions_by_name = {}
39
48
  @modules = []
40
49
 
41
50
  @managed_directories = []
@@ -44,11 +53,19 @@ module R10K
44
53
  end
45
54
 
46
55
  def load
56
+ with_readable_puppetfile(@puppetfile_path) do
57
+ self.load!
58
+ end
59
+ end
60
+
61
+ def load!
62
+ logger.info _("Using Puppetfile '%{puppetfile}'") % {puppetfile: @puppetfile_path}
63
+ logger.debug _("Using moduledir '%{moduledir}'") % {moduledir: @moduledir}
64
+
47
65
  dsl = R10K::ModuleLoader::Puppetfile::DSL.new(self)
48
- dsl.instance_eval(puppetfile_content(@puppetfile), @puppetfile)
66
+ dsl.instance_eval(puppetfile_content(@puppetfile_path), @puppetfile_path)
49
67
 
50
68
  validate_no_duplicate_names(@modules)
51
- @modules
52
69
 
53
70
  managed_content = @modules.group_by(&:dirname)
54
71
 
@@ -64,9 +81,33 @@ module R10K
64
81
  }
65
82
 
66
83
  rescue SyntaxError, LoadError, ArgumentError, NameError => e
67
- raise R10K::Error.wrap(e, _("Failed to evaluate %{path}") % {path: @puppetfile})
84
+ raise R10K::Error.wrap(e, _("Failed to evaluate %{path}") % {path: @puppetfile_path})
85
+ end
86
+
87
+ def load_metadata
88
+ with_readable_puppetfile(@puppetfile_path) do
89
+ self.load_metadata!
90
+ end
91
+ end
92
+
93
+ def load_metadata!
94
+ dsl = R10K::ModuleLoader::Puppetfile::DSL.new(self, metadata_only: true)
95
+ dsl.instance_eval(puppetfile_content(@puppetfile_path), @puppetfile_path)
96
+
97
+ @existing_module_versions_by_name = @existing_module_metadata.map {|mod| [ mod.name, mod.version ] }.to_h
98
+ empty_load_output.merge(modules: @existing_module_metadata)
99
+
100
+ rescue SyntaxError, LoadError, ArgumentError, NameError => e
101
+ logger.warn _("Unable to preload Puppetfile because of %{msg}" % { msg: e.message })
68
102
  end
69
103
 
104
+ def add_module_metadata(name, info)
105
+ install_path, metadata_info, _ = parse_module_definition(name, info)
106
+
107
+ mod = R10K::Module.from_metadata(name, install_path, metadata_info, @environment)
108
+
109
+ @existing_module_metadata << mod
110
+ end
70
111
 
71
112
  ##
72
113
  ## set_forge, set_moduledir, and add_module are used directly by the DSL class
@@ -74,7 +115,12 @@ module R10K
74
115
 
75
116
  # @param [String] forge
76
117
  def set_forge(forge)
77
- @forge = forge
118
+ if @allow_puppetfile_forge
119
+ logger.debug _("Using Forge from Puppetfile: %{forge}") % { forge: forge }
120
+ PuppetForge.host = forge
121
+ else
122
+ logger.debug _("Ignoring Forge declaration in Puppetfile, using value from settings: %{forge}.") % { forge: PuppetForge.host }
123
+ end
78
124
  end
79
125
 
80
126
  # @param [String] moduledir
@@ -83,7 +129,7 @@ module R10K
83
129
  end
84
130
 
85
131
  # @param [String] name
86
- # @param [Hash, String, Symbol, nil] module_info Calling with
132
+ # @param [Hash, String, Symbol, nil] info Calling with
87
133
  # anything but a Hash is deprecated. The DSL will now convert
88
134
  # String and Symbol versions to Hashes of the shape
89
135
  # { version: <String or Symbol> }
@@ -96,26 +142,12 @@ module R10K
96
142
  # DSL class, not the Puppetfile author) to do this conversion
97
143
  # itself.
98
144
  #
99
- def add_module(name, module_info)
100
- if !module_info.is_a?(Hash)
101
- module_info = { version: module_info }
102
- end
103
-
104
- module_info[:overrides] = @overrides
105
-
106
- if install_path = module_info.delete(:install_path)
107
- install_path = resolve_path(@basedir, install_path)
108
- validate_install_path(install_path, name)
109
- else
110
- install_path = @moduledir
111
- end
145
+ def add_module(name, info)
146
+ install_path, metadata_info, spec_deletable = parse_module_definition(name, info)
112
147
 
113
- if @default_branch_override
114
- module_info[:default_branch_override] = @default_branch_override
115
- end
116
-
117
- mod = R10K::Module.new(name, install_path, module_info, @environment)
148
+ mod = R10K::Module.from_metadata(name, install_path, metadata_info, @environment)
118
149
  mod.origin = :puppetfile
150
+ mod.spec_deletable = spec_deletable
119
151
 
120
152
  # Do not save modules if they would conflict with the attached
121
153
  # environment
@@ -123,11 +155,60 @@ module R10K
123
155
  return @modules
124
156
  end
125
157
 
158
+ # If this module's metadata has a static version and that version
159
+ # matches the existing module declaration use it, otherwise create
160
+ # a regular module to sync.
161
+ unless mod.version && (mod.version == @existing_module_versions_by_name[mod.name])
162
+ mod = mod.to_implementation
163
+ end
164
+
126
165
  @modules << mod
127
166
  end
128
167
 
129
168
  private
130
169
 
170
+ def empty_load_output
171
+ {
172
+ modules: [],
173
+ managed_directories: [],
174
+ desired_contents: [],
175
+ purge_exclusions: []
176
+ }
177
+ end
178
+
179
+ def with_readable_puppetfile(puppetfile_path, &block)
180
+ if File.readable?(puppetfile_path)
181
+ block.call
182
+ else
183
+ logger.debug _("Puppetfile %{path} missing or unreadable") % {path: puppetfile_path.inspect}
184
+
185
+ empty_load_output
186
+ end
187
+ end
188
+
189
+ def parse_module_definition(name, info)
190
+ if !info.is_a?(Hash)
191
+ info = { version: info }
192
+ end
193
+
194
+ info[:overrides] = @overrides
195
+
196
+ if @default_branch_override
197
+ info[:default_branch_override] = @default_branch_override
198
+ end
199
+
200
+ spec_deletable = false
201
+ if install_path = info.delete(:install_path)
202
+ install_path = resolve_path(@basedir, install_path)
203
+ validate_install_path(install_path, name)
204
+ else
205
+ install_path = @moduledir
206
+ spec_deletable = true
207
+ end
208
+
209
+ return [ install_path, info, spec_deletable ]
210
+ end
211
+
131
212
  # @param [Array<R10K::Module>] modules
132
213
  def validate_no_duplicate_names(modules)
133
214
  dupes = modules
@@ -30,10 +30,6 @@ class Puppetfile
30
30
  # @return [String] The base directory that contains the Puppetfile
31
31
  attr_reader :basedir
32
32
 
33
- # @!attrbute [r] puppetfile_path
34
- # @return [String] The path to the Puppetfile
35
- attr_reader :puppetfile_path
36
-
37
33
  # @!attribute [r] environment
38
34
  # @return [R10K::Environment] Optional R10K::Environment that this Puppetfile belongs to.
39
35
  attr_reader :environment
@@ -68,22 +64,20 @@ class Puppetfile
68
64
 
69
65
  @force = deprecated_force_arg || options.delete(:force) || false
70
66
  @moduledir = deprecated_moduledir_arg || options.delete(:moduledir) || File.join(basedir, 'modules')
71
- @puppetfile_name = deprecated_name_arg || options.delete(:puppetfile_name) || 'Puppetfile'
72
- @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
73
70
  @environment = options.delete(:environment)
74
71
 
75
72
  @overrides = options.delete(:overrides) || {}
76
73
  @default_branch_override = @overrides.dig(:environments, :default_branch_override)
77
74
 
78
- logger.info _("Using Puppetfile '%{puppetfile}'") % {puppetfile: @puppetfile_path}
79
-
80
75
  @forge = 'forgeapi.puppetlabs.com'
81
76
 
82
77
  @loader = ::R10K::ModuleLoader::Puppetfile.new(
83
78
  basedir: @basedir,
84
79
  moduledir: @moduledir,
85
- puppetfile: @puppetfile_path,
86
- forge: @forge,
80
+ puppetfile: @puppetfile,
87
81
  overrides: @overrides,
88
82
  environment: @environment
89
83
  )
@@ -106,8 +100,8 @@ class Puppetfile
106
100
  if self.loaded?
107
101
  return @loaded_content
108
102
  else
109
- if !File.readable?(@puppetfile_path)
110
- logger.debug _("Puppetfile %{path} missing or unreadable") % {path: @puppetfile_path.inspect}
103
+ if !File.readable?(puppetfile_path)
104
+ logger.debug _("Puppetfile %{path} missing or unreadable") % {path: puppetfile_path.inspect}
111
105
  else
112
106
  self.load!(default_branch_override)
113
107
  end
@@ -125,7 +119,7 @@ class Puppetfile
125
119
  @loader.default_branch_override = default_branch_override
126
120
  end
127
121
 
128
- @loaded_content = @loader.load
122
+ @loaded_content = @loader.load!
129
123
  @loaded = true
130
124
 
131
125
  @loaded_content
@@ -156,6 +150,10 @@ class Puppetfile
156
150
  @loader.moduledir
157
151
  end
158
152
 
153
+ def puppetfile_path
154
+ @loader.puppetfile_path
155
+ end
156
+
159
157
  def environment=(env)
160
158
  @loader.environment = env
161
159
  @environment = env
@@ -90,7 +90,7 @@ module R10K
90
90
  def resolve
91
91
  if !@value.nil?
92
92
  @value
93
- elsif @default
93
+ elsif !@default.nil?
94
94
  if @default == :inherit
95
95
  # walk all the way up to root, starting with grandparent
96
96
  ancestor = parent
data/lib/r10k/settings.rb CHANGED
@@ -42,6 +42,22 @@ module R10K
42
42
  Only used by the 'rugged' Git provider."
43
43
  }),
44
44
 
45
+ Definition.new(:github_app_id, {
46
+ :desc => "The Github App id for Git SSL remotes.
47
+ Only used by the 'rugged' Git provider."
48
+ }),
49
+
50
+ Definition.new(:github_app_key, {
51
+ :desc => "The Github App private key for Git SSL remotes.
52
+ Only used by the 'rugged' Git provider."
53
+ }),
54
+
55
+ Definition.new(:github_app_ttl, {
56
+ :desc => "The ttl expiration for SSL tokens.
57
+ Only used by the 'rugged' Git provider.",
58
+ :default => "120",
59
+ }),
60
+
45
61
  URIDefinition.new(:proxy, {
46
62
  :desc => "An optional proxy server to use when interacting with Git sources via HTTP(S).",
47
63
  :default => :inherit,
@@ -65,6 +81,24 @@ module R10K
65
81
  :default => :inherit
66
82
  }),
67
83
 
84
+ Definition.new(:github_app_id, {
85
+ :desc => "The Github App id for Git SSL remotes.
86
+ Only used by the 'rugged' Git provider.",
87
+ :default => :inherit
88
+ }),
89
+
90
+ Definition.new(:github_app_key, {
91
+ :desc => "The Github App private key for Git SSL remotes.
92
+ Only used by the 'rugged' Git provider.",
93
+ :default => :inherit
94
+ }),
95
+
96
+ Definition.new(:github_app_ttl, {
97
+ :desc => "The ttl expiration for Git SSL tokens.
98
+ Only used by the 'rugged' Git provider.",
99
+ :default => :inherit
100
+ }),
101
+
68
102
  URIDefinition.new(:proxy, {
69
103
  :desc => "An optional proxy server to use when interacting with Git sources via HTTP(S).",
70
104
  :default => :inherit,
@@ -92,8 +126,19 @@ module R10K
92
126
  URIDefinition.new(:baseurl, {
93
127
  :desc => "The URL to the Puppet Forge to use for downloading modules."
94
128
  }),
129
+
95
130
  Definition.new(:authorization_token, {
96
131
  :desc => "The token for Puppet Forge authorization. Leave blank for unauthorized or license-based connections."
132
+ }),
133
+
134
+ Definition.new(:allow_puppetfile_override, {
135
+ :desc => "Whether to use `forge` declarations in the Puppetfile as an override of `baseurl`.",
136
+ :default => false,
137
+ :validate => lambda do |value|
138
+ unless !!value == value
139
+ raise ArgumentError, "`allow_puppetfile_override` can only be a boolean value, not '#{value}'"
140
+ end
141
+ end
97
142
  })
98
143
  ])
99
144
  end
@@ -161,6 +206,47 @@ module R10K
161
206
  end
162
207
  end
163
208
  }),
209
+ Definition.new(:exclude_spec, {
210
+ :desc => "Whether or not to deploy the spec dir of a module. Defaults to false.",
211
+ :default => false,
212
+ :validate => lambda do |value|
213
+ unless !!value == value
214
+ raise ArgumentError, "`exclude_spec` can only be a boolean value, not '#{value}'"
215
+ end
216
+ end
217
+ })])
218
+ end
219
+
220
+ def self.logging_settings
221
+ R10K::Settings::Collection.new(:logging, [
222
+ Definition.new(:level, {
223
+ desc: 'What logging level should R10k run on if not specified at runtime.',
224
+ validate: lambda do |value|
225
+ if R10K::Logging.parse_level(value).nil?
226
+ raise ArgumentError, "`level` must be a valid log level.
227
+ Valid levels are #{R10K::Logging::LOG_LEVELS.map(&:downcase).inspect}"
228
+ end
229
+ end
230
+ }),
231
+
232
+ Definition.new(:outputs, {
233
+ desc: 'Additional log outputs to use.',
234
+ validate: lambda do |value|
235
+ unless value.is_a?(Array)
236
+ raise ArgumentError, "The `outputs` setting should be an array of outputs, not a #{value.class}"
237
+ end
238
+ end
239
+ }),
240
+
241
+ Definition.new(:disable_default_stderr, {
242
+ desc: 'Disable the default stderr logging output',
243
+ default: false,
244
+ validate: lambda do |value|
245
+ unless !!value == value
246
+ raise ArgumentError, "`disable_default_stderr` can only be a boolean value, not '#{value}'"
247
+ end
248
+ end
249
+ })
164
250
  ])
165
251
  end
166
252
 
@@ -180,7 +266,7 @@ module R10K
180
266
  }),
181
267
 
182
268
  Definition.new(:postrun, {
183
- :desc => "The command r10k should run after deploying environments.",
269
+ :desc => "The command r10k should run after deploying environments or modules.",
184
270
  :validate => lambda do |value|
185
271
  if !value.is_a?(Array)
186
272
  raise ArgumentError, "The postrun setting should be an array of strings, not a #{value.class}"
@@ -218,6 +304,8 @@ module R10K
218
304
  R10K::Settings.git_settings,
219
305
 
220
306
  R10K::Settings.deploy_settings,
307
+
308
+ R10K::Settings.logging_settings
221
309
  ])
222
310
  end
223
311
  end
@@ -7,7 +7,7 @@ class R10K::Source::Yaml < R10K::Source::Hash
7
7
  begin
8
8
  contents = ::YAML.load_file(config)
9
9
  rescue => e
10
- raise ConfigError, _("Couldn't open environments file %{file}: %{err}") % {file: config, err: e.message}
10
+ raise R10K::ConfigError, _("Couldn't open environments file %{file}: %{err}") % {file: config, err: e.message}
11
11
  end
12
12
 
13
13
  # Set the environments key for the parent class to consume
@@ -1,3 +1,5 @@
1
+ require 'r10k/logging'
2
+
1
3
  require 'fileutils'
2
4
 
3
5
  module R10K
@@ -9,6 +11,8 @@ module R10K
9
11
  # {#desired_contents}
10
12
  module Purgeable
11
13
 
14
+ include R10K::Logging
15
+
12
16
  HIDDEN_FILE = /\.[^.]+/
13
17
 
14
18
  FN_MATCH_OPTS = File::FNM_PATHNAME | File::FNM_DOTMATCH
@@ -95,8 +99,8 @@ module R10K
95
99
  end
96
100
 
97
101
  children.flat_map do |child|
98
- if File.directory?(child) && recurse
99
- potentially_purgeable(child, exclusion_globs, allowed_globs, desireds_not_to_recurse_into, recurse)
102
+ if File.directory?(child) && !File.symlink?(child) && recurse
103
+ potentially_purgeable(child, exclusion_globs, allowed_globs, desireds_not_to_recurse_into, recurse) << child.to_s
100
104
  else
101
105
  child.to_s
102
106
  end
@@ -1,3 +1,5 @@
1
+ require 'r10k/logging'
2
+
1
3
  module R10K
2
4
  module Util
3
5
 
@@ -1,3 +1,4 @@
1
+ require 'r10k/logging'
1
2
  require 'r10k/util/platform'
2
3
 
3
4
  module R10K
data/lib/r10k/version.rb CHANGED
@@ -2,5 +2,5 @@ module R10K
2
2
  # When updating to a new major (X) or minor (Y) version, include `#major` or
3
3
  # `#minor` (respectively) in your commit message to trigger the appropriate
4
4
  # release. Otherwise, a new patch (Z) version will be released.
5
- VERSION = '3.10.0'
5
+ VERSION = '3.13.0'
6
6
  end