puppetlabs_spec_helper 5.0.1 → 5.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dd628239ec2911772d37af4b47553d83c1ebebbc7a5fa0dc61d89d170fb513e4
4
- data.tar.gz: 66bd38e002986eb1921889db2934971936eba7936d0056bf6f6ac88c8745b901
3
+ metadata.gz: 50d161a5158e33840d6ce49a9135ff7929f210f03fdbc9def2f1b9dfb1f9eecd
4
+ data.tar.gz: bcef9675b43f702105c6fae5c4494198454bccc37466eb329f10830742f242c3
5
5
  SHA512:
6
- metadata.gz: fe79780dbf5b0d270c5426222b136989c1c6af14d934fc4449a7be573e986a73e42d3c5799f522afaa976c27d0397646f2517e520d72de83ed22eed84ceb962e
7
- data.tar.gz: 57ee6e2ec746a210265fa7162eda41dfff212f055b47b9728caf38b651ecf959759d9f178d348e8f73e52ac75e705dc3aeb0a3edbb8edf7ab8f5609c28541938
6
+ metadata.gz: a834921021d78348d7a3f25f36282e58b2650dd6c8382db65e20a7f45e81fae0ee9b3e39eacb9e9d79f241c2a76d1461e0acbc8a7d996d44dc18061857ab36df
7
+ data.tar.gz: 3f3fb17e7db1bcf81f4d33c7cb723f88f5f5d0c29c6cb43c610232366f5a2c2346e95dbafc975d692f6419ccc20684bbf38bc6f35a8749c2c73d6e79dd4cc784
data/.rubocop.yml CHANGED
@@ -36,9 +36,6 @@ Style/BlockDelimiters:
36
36
  Description: Prefer braces for chaining. Mostly an aesthetical choice. Better to
37
37
  be consistent then.
38
38
  EnforcedStyle: braces_for_chaining
39
- Style/ClassAndModuleChildren:
40
- Description: Compact style reduces the required amount of indentation.
41
- EnforcedStyle: compact
42
39
  Style/EmptyElse:
43
40
  Description: Enforce against empty else clauses, but allow `nil` for clarity.
44
41
  EnforcedStyle: empty
@@ -6,56 +6,58 @@ require 'fileutils'
6
6
  require 'tempfile'
7
7
  require 'pathname'
8
8
 
9
- # A support module for testing files.
10
- module PuppetlabsSpec::Files
11
- # This code exists only to support tests that run as root, pretty much.
12
- # Once they have finally been eliminated this can all go... --daniel 2011-04-08
13
- def self.in_tmp(path)
14
- tempdir = Dir.tmpdir
15
-
16
- Pathname.new(path).ascend do |dir|
17
- return true if File.identical?(tempdir, dir)
18
- end
9
+ module PuppetlabsSpec
10
+ # A support module for testing files.
11
+ module Files
12
+ # This code exists only to support tests that run as root, pretty much.
13
+ # Once they have finally been eliminated this can all go... --daniel 2011-04-08
14
+ def self.in_tmp(path)
15
+ tempdir = Dir.tmpdir
16
+
17
+ Pathname.new(path).ascend do |dir|
18
+ return true if File.identical?(tempdir, dir)
19
+ end
19
20
 
20
- false
21
- end
21
+ false
22
+ end
22
23
 
23
- def self.cleanup
24
- $global_tempfiles ||= []
25
- while (path = $global_tempfiles.pop)
26
- raise "Not deleting tmpfile #{path} outside regular tmpdir" unless in_tmp(path)
24
+ def self.cleanup
25
+ $global_tempfiles ||= []
26
+ while (path = $global_tempfiles.pop)
27
+ raise "Not deleting tmpfile #{path} outside regular tmpdir" unless in_tmp(path)
27
28
 
28
- begin
29
- FileUtils.rm_r path, secure: true
30
- rescue Errno::ENOENT
31
- # nothing to do
29
+ begin
30
+ FileUtils.rm_r path, secure: true
31
+ rescue Errno::ENOENT
32
+ # nothing to do
33
+ end
32
34
  end
33
35
  end
34
- end
35
36
 
36
- def make_absolute(path)
37
- path = File.expand_path(path)
38
- path[0] = 'c' if Puppet.features.microsoft_windows?
39
- path
40
- end
37
+ def make_absolute(path)
38
+ path = File.expand_path(path)
39
+ path[0] = 'c' if Puppet.features.microsoft_windows?
40
+ path
41
+ end
41
42
 
42
- def tmpfilename(name)
43
- # Generate a temporary file, just for the name...
44
- source = Tempfile.new(name)
45
- path = source.path
46
- source.close!
43
+ def tmpfilename(name)
44
+ # Generate a temporary file, just for the name...
45
+ source = Tempfile.new(name)
46
+ path = source.path
47
+ source.close!
47
48
 
48
- # ...record it for cleanup,
49
- $global_tempfiles ||= []
50
- $global_tempfiles << File.expand_path(path)
49
+ # ...record it for cleanup,
50
+ $global_tempfiles ||= []
51
+ $global_tempfiles << File.expand_path(path)
51
52
 
52
- # ...and bam.
53
- path
54
- end
53
+ # ...and bam.
54
+ path
55
+ end
55
56
 
56
- def tmpdir(name)
57
- path = tmpfilename(name)
58
- FileUtils.mkdir_p(path)
59
- path
57
+ def tmpdir(name)
58
+ path = tmpfilename(name)
59
+ FileUtils.mkdir_p(path)
60
+ path
61
+ end
60
62
  end
61
63
  end
@@ -1,53 +1,55 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # This module provides some helper methods to assist with fixtures. It's
4
- # methods are designed to help when you have a conforming fixture layout so we
5
- # get project consistency.
6
- module PuppetlabsSpec::Fixtures
7
- # Returns the joined path of the global FIXTURE_DIR plus any path given to it
8
- def fixtures(*rest)
9
- File.join(PuppetlabsSpec::FIXTURE_DIR, *rest)
10
- end
11
-
12
- # Returns the path to your relative fixture dir. So if your spec test is
13
- # <project>/spec/unit/facter/foo_spec.rb then your relative dir will be
14
- # <project>/spec/fixture/unit/facter/foo
15
- def my_fixture_dir
16
- callers = caller
17
- while (line = callers.shift)
18
- next unless (found = line.match(%r{/spec/(.*)_spec\.rb:}))
19
-
20
- return fixtures(found[1])
3
+ module PuppetlabsSpec
4
+ # This module provides some helper methods to assist with fixtures. It's
5
+ # methods are designed to help when you have a conforming fixture layout so we
6
+ # get project consistency.
7
+ module Fixtures
8
+ # Returns the joined path of the global FIXTURE_DIR plus any path given to it
9
+ def fixtures(*rest)
10
+ File.join(PuppetlabsSpec::FIXTURE_DIR, *rest)
21
11
  end
22
- raise "sorry, I couldn't work out your path from the caller stack!"
23
- end
24
12
 
25
- # Given a name, returns the full path of a file from your relative fixture
26
- # dir as returned by my_fixture_dir.
27
- def my_fixture(name)
28
- file = File.join(my_fixture_dir, name)
29
- unless File.readable? file
30
- raise "fixture '#{name}' for #{my_fixture_dir} is not readable"
13
+ # Returns the path to your relative fixture dir. So if your spec test is
14
+ # <project>/spec/unit/facter/foo_spec.rb then your relative dir will be
15
+ # <project>/spec/fixture/unit/facter/foo
16
+ def my_fixture_dir
17
+ callers = caller
18
+ while (line = callers.shift)
19
+ next unless (found = line.match(%r{/spec/(.*)_spec\.rb:}))
20
+
21
+ return fixtures(found[1])
22
+ end
23
+ raise "sorry, I couldn't work out your path from the caller stack!"
31
24
  end
32
25
 
33
- file
34
- end
26
+ # Given a name, returns the full path of a file from your relative fixture
27
+ # dir as returned by my_fixture_dir.
28
+ def my_fixture(name)
29
+ file = File.join(my_fixture_dir, name)
30
+ unless File.readable? file
31
+ raise "fixture '#{name}' for #{my_fixture_dir} is not readable"
32
+ end
35
33
 
36
- # Return the contents of the file using read when given a name. Uses
37
- # my_fixture to work out the relative path.
38
- def my_fixture_read(name)
39
- File.read(my_fixture(name))
40
- end
34
+ file
35
+ end
41
36
 
42
- # Provides a block mechanism for iterating across the files in your fixture
43
- # area.
44
- def my_fixtures(glob = '*', flags = 0, &block)
45
- files = Dir.glob(File.join(my_fixture_dir, glob), flags)
46
- if files.empty?
47
- raise "fixture '#{glob}' for #{my_fixture_dir} had no files!"
37
+ # Return the contents of the file using read when given a name. Uses
38
+ # my_fixture to work out the relative path.
39
+ def my_fixture_read(name)
40
+ File.read(my_fixture(name))
48
41
  end
49
42
 
50
- block && files.each(&block)
51
- files
43
+ # Provides a block mechanism for iterating across the files in your fixture
44
+ # area.
45
+ def my_fixtures(glob = '*', flags = 0, &block)
46
+ files = Dir.glob(File.join(my_fixture_dir, glob), flags)
47
+ if files.empty?
48
+ raise "fixture '#{glob}' for #{my_fixture_dir} had no files!"
49
+ end
50
+
51
+ block && files.each(&block)
52
+ files
53
+ end
52
54
  end
53
55
  end
@@ -4,41 +4,43 @@
4
4
  # 'puppetlabs_spec_helper/puppet_spec_helper' library
5
5
  require 'puppetlabs_spec_helper/puppet_spec_helper'
6
6
 
7
- # PuppetInternals provides a set of methods that interface
8
- # with internal puppet implementations.
9
- module PuppetlabsSpec::PuppetInternals
10
- def resource(parts = {})
11
- resource_type = parts[:type] || :hostclass
12
- resource_name = parts[:name] || 'testing'
13
- Puppet::Resource::Type.new(resource_type, resource_name)
14
- end
15
- module_function :resource
7
+ module PuppetlabsSpec
8
+ # PuppetInternals provides a set of methods that interface
9
+ # with internal puppet implementations.
10
+ module PuppetInternals
11
+ def resource(parts = {})
12
+ resource_type = parts[:type] || :hostclass
13
+ resource_name = parts[:name] || 'testing'
14
+ Puppet::Resource::Type.new(resource_type, resource_name)
15
+ end
16
+ module_function :resource
16
17
 
17
- def compiler(parts = {})
18
- compiler_node = parts[:node] || node
19
- Puppet::Parser::Compiler.new(compiler_node)
20
- end
21
- module_function :compiler
18
+ def compiler(parts = {})
19
+ compiler_node = parts[:node] || node
20
+ Puppet::Parser::Compiler.new(compiler_node)
21
+ end
22
+ module_function :compiler
22
23
 
23
- def node(parts = {})
24
- node_name = parts[:name] || 'testinghost'
25
- options = parts[:options] || {}
26
- node_environment = Puppet::Node::Environment.create(parts[:environment] || 'test', [])
27
- options[:environment] = node_environment
28
- Puppet::Node.new(node_name, options)
29
- end
30
- module_function :node
24
+ def node(parts = {})
25
+ node_name = parts[:name] || 'testinghost'
26
+ options = parts[:options] || {}
27
+ node_environment = Puppet::Node::Environment.create(parts[:environment] || 'test', [])
28
+ options[:environment] = node_environment
29
+ Puppet::Node.new(node_name, options)
30
+ end
31
+ module_function :node
31
32
 
32
- # Return a method instance for a given function. This is primarily useful
33
- # for rspec-puppet
34
- def function_method(name, parts = {})
35
- scope = parts[:scope] || scope()
36
- # Ensure the method instance is defined by side-effect of checking if it
37
- # exists. This is a hack, but at least it's a hidden hack and not an
38
- # exposed hack.
39
- return nil unless Puppet::Parser::Functions.function(name)
33
+ # Return a method instance for a given function. This is primarily useful
34
+ # for rspec-puppet
35
+ def function_method(name, parts = {})
36
+ scope = parts[:scope] || scope()
37
+ # Ensure the method instance is defined by side-effect of checking if it
38
+ # exists. This is a hack, but at least it's a hidden hack and not an
39
+ # exposed hack.
40
+ return nil unless Puppet::Parser::Functions.function(name)
40
41
 
41
- scope.method("function_#{name}".to_sym)
42
+ scope.method("function_#{name}".to_sym)
43
+ end
44
+ module_function :function_method
42
45
  end
43
- module_function :function_method
44
46
  end
@@ -2,48 +2,52 @@
2
2
 
3
3
  require 'pathspec'
4
4
 
5
- # Helpers for validating symlinks.
6
- class PuppetlabsSpecHelper::Tasks::CheckSymlinks
7
- DEFAULT_IGNORED = [
8
- '/.git/',
9
- '/.bundle/',
10
- '/vendor/',
11
- ].freeze
12
-
13
- IGNORE_LIST_FILES = [
14
- '.pdkignore',
15
- '.gitignore',
16
- ].freeze
17
-
18
- def check(dir = Dir.pwd)
19
- dir = Pathname.new(dir) unless dir.is_a?(Pathname)
20
- results = []
21
-
22
- dir.each_child(true) do |child|
23
- next if ignored?(child.to_s)
24
-
25
- if child.symlink?
26
- results << child
27
- elsif child.directory? && child.basename.to_s !~ %r{^(\.git|\.?bundle)$}
28
- results.concat(check(child))
5
+ module PuppetlabsSpecHelper
6
+ module Tasks
7
+ # Helpers for validating symlinks.
8
+ class CheckSymlinks
9
+ DEFAULT_IGNORED = [
10
+ '/.git/',
11
+ '/.bundle/',
12
+ '/vendor/',
13
+ ].freeze
14
+
15
+ IGNORE_LIST_FILES = [
16
+ '.pdkignore',
17
+ '.gitignore',
18
+ ].freeze
19
+
20
+ def check(dir = Dir.pwd)
21
+ dir = Pathname.new(dir) unless dir.is_a?(Pathname)
22
+ results = []
23
+
24
+ dir.each_child(true) do |child|
25
+ next if ignored?(child.to_s)
26
+
27
+ if child.symlink?
28
+ results << child
29
+ elsif child.directory? && child.basename.to_s !~ %r{^(\.git|\.?bundle)$}
30
+ results.concat(check(child))
31
+ end
32
+ end
33
+
34
+ results
29
35
  end
30
- end
31
-
32
- results
33
- end
34
36
 
35
- def ignored?(path)
36
- path = "#{path}/" if File.directory?(path)
37
+ def ignored?(path)
38
+ path = "#{path}/" if File.directory?(path)
37
39
 
38
- !ignore_pathspec.match_paths([path], Dir.pwd).empty?
39
- end
40
+ !ignore_pathspec.match_paths([path], Dir.pwd).empty?
41
+ end
40
42
 
41
- def ignore_pathspec
42
- @ignore_pathspec ||= PathSpec.new(DEFAULT_IGNORED).tap do |pathspec|
43
- IGNORE_LIST_FILES.each do |f|
44
- next unless File.file?(f) && File.readable?(f)
43
+ def ignore_pathspec
44
+ @ignore_pathspec ||= PathSpec.new(DEFAULT_IGNORED).tap do |pathspec|
45
+ IGNORE_LIST_FILES.each do |f|
46
+ next unless File.file?(f) && File.readable?(f)
45
47
 
46
- File.open(f, 'r') { |fd| pathspec.add(fd) }
48
+ File.open(f, 'r') { |fd| pathspec.add(fd) }
49
+ end
50
+ end
47
51
  end
48
52
  end
49
53
  end
@@ -4,406 +4,407 @@ require 'yaml'
4
4
  require 'open3'
5
5
  require 'json'
6
6
 
7
- # Top level namespace for spec helper tasks.
8
- module PuppetlabsSpecHelper::Tasks end
9
-
10
- # Helpers for workfing with fixtures.
11
- module PuppetlabsSpecHelper::Tasks::FixtureHelpers
12
- # This is a helper for the self-symlink entry of fixtures.yml
13
- def source_dir
14
- Dir.pwd
15
- end
16
-
17
- # @return [String] - the name of current module
18
- def module_name
19
- raise ArgumentError unless File.file?('metadata.json') && File.readable?('metadata.json')
20
-
21
- metadata = JSON.parse(File.read('metadata.json'))
22
- metadata_name = metadata.fetch('name', nil) || ''
23
-
24
- raise ArgumentError if metadata_name.empty?
7
+ module PuppetlabsSpecHelper
8
+ module Tasks
9
+ # Helpers for working with fixtures.
10
+ module FixtureHelpers
11
+ # This is a helper for the self-symlink entry of fixtures.yml
12
+ def source_dir
13
+ Dir.pwd
14
+ end
25
15
 
26
- metadata_name.split('-').last
27
- rescue JSON::ParserError, ArgumentError
28
- File.basename(Dir.pwd).split('-').last
29
- end
16
+ # @return [String] - the name of current module
17
+ def module_name
18
+ raise ArgumentError unless File.file?('metadata.json') && File.readable?('metadata.json')
30
19
 
31
- def module_version(path)
32
- metadata_path = File.join(path, 'metadata.json')
33
- raise ArgumentError unless File.file?(metadata_path) && File.readable?(metadata_path)
20
+ metadata = JSON.parse(File.read('metadata.json'))
21
+ metadata_name = metadata.fetch('name', nil) || ''
34
22
 
35
- metadata = JSON.parse(File.read(metadata_path))
36
- metadata.fetch('version', nil) || '0.0.1'
37
- rescue JSON::ParserError, ArgumentError
38
- logger.warn "Failed to find module version at path #{path}"
39
- '0.0.1'
40
- end
23
+ raise ArgumentError if metadata_name.empty?
41
24
 
42
- # @return [Hash] - returns a hash of all the fixture repositories
43
- # @example
44
- # {"puppetlabs-stdlib"=>{"target"=>"https://gitlab.com/puppetlabs/puppet-stdlib.git",
45
- # "ref"=>nil, "branch"=>"main", "scm"=>nil,
46
- # }}
47
- def repositories
48
- @repositories ||= fixtures('repositories') || {}
49
- end
25
+ metadata_name.split('-').last
26
+ rescue JSON::ParserError, ArgumentError
27
+ File.basename(Dir.pwd).split('-').last
28
+ end
50
29
 
51
- # @return [Hash] - returns a hash of all the fixture forge modules
52
- # @example
53
- # {"puppetlabs-stdlib"=>{"target"=>"spec/fixtures/modules/stdlib",
54
- # "ref"=>nil, "branch"=>nil, "scm"=>nil,
55
- # "flags"=>"--module_repository=https://myforge.example.com/", "subdir"=>nil}}
56
- def forge_modules
57
- @forge_modules ||= fixtures('forge_modules') || {}
58
- end
30
+ def module_version(path)
31
+ metadata_path = File.join(path, 'metadata.json')
32
+ raise ArgumentError unless File.file?(metadata_path) && File.readable?(metadata_path)
59
33
 
60
- # @return [Hash] - a hash of symlinks specified in the fixtures file
61
- def symlinks
62
- @symlinks ||= fixtures('symlinks') || {}
63
- end
34
+ metadata = JSON.parse(File.read(metadata_path))
35
+ metadata.fetch('version', nil) || '0.0.1'
36
+ rescue JSON::ParserError, ArgumentError
37
+ logger.warn "Failed to find module version at path #{path}"
38
+ '0.0.1'
39
+ end
64
40
 
65
- # @return [Hash] - returns a hash with the module name and the source directory
66
- def auto_symlink
67
- { module_name => "\#{source_dir}" }
68
- end
41
+ # @return [Hash] - returns a hash of all the fixture repositories
42
+ # @example
43
+ # {"puppetlabs-stdlib"=>{"target"=>"https://gitlab.com/puppetlabs/puppet-stdlib.git",
44
+ # "ref"=>nil, "branch"=>"main", "scm"=>nil,
45
+ # }}
46
+ def repositories
47
+ @repositories ||= fixtures('repositories') || {}
48
+ end
69
49
 
70
- # @return [Boolean] - true if the os is a windows system
71
- def windows?
72
- !!File::ALT_SEPARATOR
73
- end
50
+ # @return [Hash] - returns a hash of all the fixture forge modules
51
+ # @example
52
+ # {"puppetlabs-stdlib"=>{"target"=>"spec/fixtures/modules/stdlib",
53
+ # "ref"=>nil, "branch"=>nil, "scm"=>nil,
54
+ # "flags"=>"--module_repository=https://myforge.example.com/", "subdir"=>nil}}
55
+ def forge_modules
56
+ @forge_modules ||= fixtures('forge_modules') || {}
57
+ end
74
58
 
75
- def fixtures(category)
76
- fixtures_yaml = if ENV['FIXTURES_YML']
77
- ENV['FIXTURES_YML']
78
- elsif File.exist?('.fixtures.yml')
79
- '.fixtures.yml'
80
- elsif File.exist?('.fixtures.yaml')
81
- '.fixtures.yaml'
82
- else
83
- false
84
- end
59
+ # @return [Hash] - a hash of symlinks specified in the fixtures file
60
+ def symlinks
61
+ @symlinks ||= fixtures('symlinks') || {}
62
+ end
85
63
 
86
- begin
87
- fixtures = if fixtures_yaml
88
- YAML.load_file(fixtures_yaml) || { 'fixtures' => {} }
89
- else
90
- { 'fixtures' => {} }
91
- end
92
- rescue Errno::ENOENT
93
- raise("Fixtures file not found: '#{fixtures_yaml}'")
94
- rescue Psych::SyntaxError => e
95
- raise("Found malformed YAML in '#{fixtures_yaml}' on line #{e.line} column #{e.column}: #{e.problem}")
96
- end
64
+ # @return [Hash] - returns a hash with the module name and the source directory
65
+ def auto_symlink
66
+ { module_name => "\#{source_dir}" }
67
+ end
97
68
 
98
- unless fixtures.include?('fixtures')
99
- # File is non-empty, but does not specify fixtures
100
- raise("No 'fixtures' entries found in '#{fixtures_yaml}'; required")
101
- end
69
+ # @return [Boolean] - true if the os is a windows system
70
+ def windows?
71
+ !!File::ALT_SEPARATOR
72
+ end
102
73
 
103
- fixture_defaults = if fixtures.include? 'defaults'
104
- fixtures['defaults']
105
- else
106
- {}
107
- end
74
+ def fixtures(category)
75
+ fixtures_yaml = if ENV['FIXTURES_YML']
76
+ ENV['FIXTURES_YML']
77
+ elsif File.exist?('.fixtures.yml')
78
+ '.fixtures.yml'
79
+ elsif File.exist?('.fixtures.yaml')
80
+ '.fixtures.yaml'
81
+ else
82
+ false
83
+ end
84
+
85
+ begin
86
+ fixtures = if fixtures_yaml
87
+ YAML.load_file(fixtures_yaml) || { 'fixtures' => {} }
88
+ else
89
+ { 'fixtures' => {} }
90
+ end
91
+ rescue Errno::ENOENT
92
+ raise("Fixtures file not found: '#{fixtures_yaml}'")
93
+ rescue Psych::SyntaxError => e
94
+ raise("Found malformed YAML in '#{fixtures_yaml}' on line #{e.line} column #{e.column}: #{e.problem}")
95
+ end
108
96
 
109
- fixtures = fixtures['fixtures']
97
+ unless fixtures.include?('fixtures')
98
+ # File is non-empty, but does not specify fixtures
99
+ raise("No 'fixtures' entries found in '#{fixtures_yaml}'; required")
100
+ end
110
101
 
111
- if fixtures['symlinks'].nil?
112
- fixtures['symlinks'] = auto_symlink
113
- end
102
+ fixture_defaults = if fixtures.include? 'defaults'
103
+ fixtures['defaults']
104
+ else
105
+ {}
106
+ end
114
107
 
115
- result = {}
116
- if fixtures.include?(category) && !fixtures[category].nil?
117
- defaults = { 'target' => 'spec/fixtures/modules' }
108
+ fixtures = fixtures['fixtures']
118
109
 
119
- # load defaults from the `.fixtures.yml` `defaults` section
120
- # for the requested category and merge them into my defaults
121
- if fixture_defaults.include? category
122
- defaults = defaults.merge(fixture_defaults[category])
123
- end
110
+ if fixtures['symlinks'].nil?
111
+ fixtures['symlinks'] = auto_symlink
112
+ end
124
113
 
125
- fixtures[category].each do |fixture, opts|
126
- # convert a simple string fixture to a hash, by
127
- # using the string fixture as the `repo` option of the hash.
128
- if opts.instance_of?(String)
129
- opts = { 'repo' => opts }
114
+ result = {}
115
+ if fixtures.include?(category) && !fixtures[category].nil?
116
+ defaults = { 'target' => 'spec/fixtures/modules' }
117
+
118
+ # load defaults from the `.fixtures.yml` `defaults` section
119
+ # for the requested category and merge them into my defaults
120
+ if fixture_defaults.include? category
121
+ defaults = defaults.merge(fixture_defaults[category])
122
+ end
123
+
124
+ fixtures[category].each do |fixture, opts|
125
+ # convert a simple string fixture to a hash, by
126
+ # using the string fixture as the `repo` option of the hash.
127
+ if opts.instance_of?(String)
128
+ opts = { 'repo' => opts }
129
+ end
130
+ # there should be a warning or something if it's not a hash...
131
+ next unless opts.instance_of?(Hash)
132
+
133
+ # merge our options into the defaults to get the
134
+ # final option list
135
+ opts = defaults.merge(opts)
136
+
137
+ next unless include_repo?(opts['puppet_version'])
138
+
139
+ # rubocop:disable Security/Eval
140
+ # TODO: Remove eval
141
+ real_target = eval("\"#{opts['target']}\"", binding, __FILE__, __LINE__) # evaluating target reference in this context (see auto_symlink)
142
+ real_source = eval("\"#{opts['repo']}\"", binding, __FILE__, __LINE__) # evaluating repo reference in this context (see auto_symlink)
143
+
144
+ result[real_source] = validate_fixture_hash!(
145
+ 'target' => File.join(real_target, fixture),
146
+ 'ref' => opts['ref'] || opts['tag'],
147
+ 'branch' => opts['branch'],
148
+ 'scm' => opts['scm'],
149
+ 'flags' => opts['flags'],
150
+ 'subdir' => opts['subdir'],
151
+ )
152
+ end
130
153
  end
131
- # there should be a warning or something if it's not a hash...
132
- next unless opts.instance_of?(Hash)
133
-
134
- # merge our options into the defaults to get the
135
- # final option list
136
- opts = defaults.merge(opts)
137
-
138
- next unless include_repo?(opts['puppet_version'])
139
-
140
- # rubocop:disable Security/Eval
141
- # TODO: Remove eval
142
- real_target = eval("\"#{opts['target']}\"", binding, __FILE__, __LINE__) # evaluating target reference in this context (see auto_symlink)
143
- real_source = eval("\"#{opts['repo']}\"", binding, __FILE__, __LINE__) # evaluating repo reference in this context (see auto_symlink)
144
-
145
- result[real_source] = validate_fixture_hash!(
146
- 'target' => File.join(real_target, fixture),
147
- 'ref' => opts['ref'] || opts['tag'],
148
- 'branch' => opts['branch'],
149
- 'scm' => opts['scm'],
150
- 'flags' => opts['flags'],
151
- 'subdir' => opts['subdir'],
152
- )
154
+ result
153
155
  end
154
- end
155
- result
156
- end
157
156
 
158
- def validate_fixture_hash!(hash)
159
- # Can only validate git based scm
160
- return hash unless hash['scm'] == 'git'
157
+ def validate_fixture_hash!(hash)
158
+ # Can only validate git based scm
159
+ return hash unless hash['scm'] == 'git'
161
160
 
162
- # Forward slashes in the ref aren't allowed. And is probably a branch name.
163
- raise ArgumentError, "The ref for #{hash['target']} is invalid (Contains a forward slash). If this is a branch name, please use the 'branch' setting instead." if hash['ref'].include?('/')
161
+ # Forward slashes in the ref aren't allowed. And is probably a branch name.
162
+ raise ArgumentError, "The ref for #{hash['target']} is invalid (Contains a forward slash). If this is a branch name, please use the 'branch' setting instead." if hash['ref'].include?('/')
164
163
 
165
- hash
166
- end
164
+ hash
165
+ end
167
166
 
168
- def include_repo?(version_range)
169
- if version_range && defined?(SemanticPuppet)
170
- puppet_spec = Gem::Specification.find_by_name('puppet')
171
- puppet_version = SemanticPuppet::Version.parse(puppet_spec.version.to_s)
167
+ def include_repo?(version_range)
168
+ if version_range && defined?(SemanticPuppet)
169
+ puppet_spec = Gem::Specification.find_by_name('puppet')
170
+ puppet_version = SemanticPuppet::Version.parse(puppet_spec.version.to_s)
172
171
 
173
- constraint = SemanticPuppet::VersionRange.parse(version_range)
174
- constraint.include?(puppet_version)
175
- else
176
- true
177
- end
178
- end
172
+ constraint = SemanticPuppet::VersionRange.parse(version_range)
173
+ constraint.include?(puppet_version)
174
+ else
175
+ true
176
+ end
177
+ end
179
178
 
180
- def clone_repo(scm, remote, target, _subdir = nil, ref = nil, branch = nil, flags = nil)
181
- args = []
182
- case scm
183
- when 'hg'
184
- args.push('clone')
185
- args.push('-b', branch) if branch
186
- args.push(flags) if flags
187
- args.push(remote, target)
188
- when 'git'
189
- args.push('clone')
190
- args.push('--depth 1') unless ref
191
- args.push('-b', branch) if branch
192
- args.push(flags) if flags
193
- args.push(remote, target)
194
- else
195
- raise "Unfortunately #{scm} is not supported yet"
196
- end
197
- result = system("#{scm} #{args.flatten.join ' '}")
198
- unless File.exist?(target)
199
- raise "Failed to clone #{scm} repository #{remote} into #{target}"
200
- end
179
+ def clone_repo(scm, remote, target, _subdir = nil, ref = nil, branch = nil, flags = nil)
180
+ args = []
181
+ case scm
182
+ when 'hg'
183
+ args.push('clone')
184
+ args.push('-b', branch) if branch
185
+ args.push(flags) if flags
186
+ args.push(remote, target)
187
+ when 'git'
188
+ args.push('clone')
189
+ args.push('--depth 1') unless ref
190
+ args.push('-b', branch) if branch
191
+ args.push(flags) if flags
192
+ args.push(remote, target)
193
+ else
194
+ raise "Unfortunately #{scm} is not supported yet"
195
+ end
196
+ result = system("#{scm} #{args.flatten.join ' '}")
197
+ unless File.exist?(target)
198
+ raise "Failed to clone #{scm} repository #{remote} into #{target}"
199
+ end
201
200
 
202
- result
203
- end
201
+ result
202
+ end
204
203
 
205
- def update_repo(scm, target)
206
- args = case scm
207
- when 'hg'
208
- ['pull']
209
- when 'git'
210
- ['fetch'].tap do |git_args|
211
- git_args << '--unshallow' if shallow_git_repo?
212
- end
213
- else
214
- raise "Unfortunately #{scm} is not supported yet"
215
- end
216
- system("#{scm} #{args.flatten.join(' ')}", chdir: target)
217
- end
204
+ def update_repo(scm, target)
205
+ args = case scm
206
+ when 'hg'
207
+ ['pull']
208
+ when 'git'
209
+ ['fetch'].tap do |git_args|
210
+ git_args << '--unshallow' if shallow_git_repo?
211
+ end
212
+ else
213
+ raise "Unfortunately #{scm} is not supported yet"
214
+ end
215
+ system("#{scm} #{args.flatten.join(' ')}", chdir: target)
216
+ end
218
217
 
219
- def shallow_git_repo?
220
- File.file?(File.join('.git', 'shallow'))
221
- end
218
+ def shallow_git_repo?
219
+ File.file?(File.join('.git', 'shallow'))
220
+ end
222
221
 
223
- def revision(scm, target, ref)
224
- args = []
225
- case scm
226
- when 'hg'
227
- args.push('update', '--clean', '-r', ref)
228
- when 'git'
229
- args.push('reset', '--hard', ref)
230
- else
231
- raise "Unfortunately #{scm} is not supported yet"
232
- end
233
- result = system("#{scm} #{args.flatten.join ' '}", chdir: target)
234
- raise "Invalid ref #{ref} for #{target}" unless result
235
- end
222
+ def revision(scm, target, ref)
223
+ args = []
224
+ case scm
225
+ when 'hg'
226
+ args.push('update', '--clean', '-r', ref)
227
+ when 'git'
228
+ args.push('reset', '--hard', ref)
229
+ else
230
+ raise "Unfortunately #{scm} is not supported yet"
231
+ end
232
+ result = system("#{scm} #{args.flatten.join ' '}", chdir: target)
233
+ raise "Invalid ref #{ref} for #{target}" unless result
234
+ end
236
235
 
237
- def valid_repo?(scm, target, remote)
238
- return false unless File.directory?(target)
239
- return true if scm == 'hg'
236
+ def valid_repo?(scm, target, remote)
237
+ return false unless File.directory?(target)
238
+ return true if scm == 'hg'
240
239
 
241
- return true if git_remote_url(target) == remote
240
+ return true if git_remote_url(target) == remote
242
241
 
243
- warn "Git remote for #{target} has changed, recloning repository"
244
- FileUtils.rm_rf(target)
245
- false
246
- end
242
+ warn "Git remote for #{target} has changed, recloning repository"
243
+ FileUtils.rm_rf(target)
244
+ false
245
+ end
247
246
 
248
- def git_remote_url(target)
249
- output, status = Open3.capture2e('git', '--git-dir', File.join(target, '.git'), 'ls-remote', '--get-url', 'origin')
250
- status.success? ? output.strip : nil
251
- end
247
+ def git_remote_url(target)
248
+ output, status = Open3.capture2e('git', '--git-dir', File.join(target, '.git'), 'ls-remote', '--get-url', 'origin')
249
+ status.success? ? output.strip : nil
250
+ end
252
251
 
253
- def remove_subdirectory(target, subdir)
254
- return if subdir.nil?
255
- Dir.mktmpdir do |tmpdir|
256
- FileUtils.mv(Dir.glob("#{target}/#{subdir}/{.[^\.]*,*}"), tmpdir)
257
- FileUtils.rm_rf("#{target}/#{subdir}")
258
- FileUtils.mv(Dir.glob("#{tmpdir}/{.[^\.]*,*}"), target.to_s)
259
- end
260
- end
252
+ def remove_subdirectory(target, subdir)
253
+ return if subdir.nil?
254
+ Dir.mktmpdir do |tmpdir|
255
+ FileUtils.mv(Dir.glob("#{target}/#{subdir}/{.[^\.]*,*}"), tmpdir)
256
+ FileUtils.rm_rf("#{target}/#{subdir}")
257
+ FileUtils.mv(Dir.glob("#{tmpdir}/{.[^\.]*,*}"), target.to_s)
258
+ end
259
+ end
261
260
 
262
- # creates a logger so we can log events with certain levels
263
- def logger
264
- unless @logger
265
- require 'logger'
266
- level = if ENV['ENABLE_LOGGER']
267
- Logger::DEBUG
268
- else
269
- Logger::INFO
270
- end
271
- @logger = Logger.new($stderr)
272
- @logger.level = level
273
- end
274
- @logger
275
- end
261
+ # creates a logger so we can log events with certain levels
262
+ def logger
263
+ unless @logger
264
+ require 'logger'
265
+ level = if ENV['ENABLE_LOGGER']
266
+ Logger::DEBUG
267
+ else
268
+ Logger::INFO
269
+ end
270
+ @logger = Logger.new($stderr)
271
+ @logger.level = level
272
+ end
273
+ @logger
274
+ end
276
275
 
277
- def module_working_directory
278
- # The problem with the relative path is that PMT doesn't expand the path properly and so passing in a relative path here
279
- # becomes something like C:\somewhere\backslashes/spec/fixtures/work-dir on Windows, and then PMT barfs itself.
280
- # This has been reported as https://tickets.puppetlabs.com/browse/PUP-4884
281
- File.expand_path(ENV['MODULE_WORKING_DIR'] || 'spec/fixtures/work-dir')
282
- end
276
+ def module_working_directory
277
+ # The problem with the relative path is that PMT doesn't expand the path properly and so passing in a relative path here
278
+ # becomes something like C:\somewhere\backslashes/spec/fixtures/work-dir on Windows, and then PMT barfs itself.
279
+ # This has been reported as https://tickets.puppetlabs.com/browse/PUP-4884
280
+ File.expand_path(ENV['MODULE_WORKING_DIR'] || 'spec/fixtures/work-dir')
281
+ end
283
282
 
284
- # returns the current thread count that is currently active
285
- # a status of false or nil means the thread completed
286
- # so when anything else we count that as a active thread
287
- # @return [Integer] - current thread count
288
- def current_thread_count(items)
289
- active_threads = items.select do |_item, opts|
290
- if opts[:thread]
291
- opts[:thread].status
292
- else
293
- false
283
+ # returns the current thread count that is currently active
284
+ # a status of false or nil means the thread completed
285
+ # so when anything else we count that as a active thread
286
+ # @return [Integer] - current thread count
287
+ def current_thread_count(items)
288
+ active_threads = items.select do |_item, opts|
289
+ if opts[:thread]
290
+ opts[:thread].status
291
+ else
292
+ false
293
+ end
294
+ end
295
+ logger.debug "Current thread count #{active_threads.count}"
296
+ active_threads.count
294
297
  end
295
- end
296
- logger.debug "Current thread count #{active_threads.count}"
297
- active_threads.count
298
- end
299
298
 
300
- # @summary Set a limit on the amount threads used, defaults to 10
301
- # MAX_FIXTURE_THREAD_COUNT can be used to set this limit
302
- # @return [Integer] - returns the max_thread_count
303
- def max_thread_limit
304
- @max_thread_limit ||= (ENV['MAX_FIXTURE_THREAD_COUNT'] || 10).to_i
305
- end
299
+ # @summary Set a limit on the amount threads used, defaults to 10
300
+ # MAX_FIXTURE_THREAD_COUNT can be used to set this limit
301
+ # @return [Integer] - returns the max_thread_count
302
+ def max_thread_limit
303
+ @max_thread_limit ||= (ENV['MAX_FIXTURE_THREAD_COUNT'] || 10).to_i
304
+ end
306
305
 
307
- # @param items [Hash] - a hash of either repositories or forge modules
308
- # @param [Block] - the method you wish to use to download the item
309
- def download_items(items)
310
- items.each do |remote, opts|
311
- # get the current active threads that are alive
312
- count = current_thread_count(items)
313
- if count < max_thread_limit
314
- logger.debug "New Thread started for #{remote}"
315
- # start up a new thread and store it in the opts hash
316
- opts[:thread] = Thread.new do
317
- yield(remote, opts)
306
+ # @param items [Hash] - a hash of either repositories or forge modules
307
+ # @param [Block] - the method you wish to use to download the item
308
+ def download_items(items)
309
+ items.each do |remote, opts|
310
+ # get the current active threads that are alive
311
+ count = current_thread_count(items)
312
+ if count < max_thread_limit
313
+ logger.debug "New Thread started for #{remote}"
314
+ # start up a new thread and store it in the opts hash
315
+ opts[:thread] = Thread.new do
316
+ yield(remote, opts)
317
+ end
318
+ else
319
+ # the last thread started should be the longest wait
320
+ item, item_opts = items.reverse.find { |_i, o| o.key?(:thread) }
321
+ logger.debug "Waiting on #{item}"
322
+ item_opts[:thread].join # wait for the thread to finish
323
+ # now that we waited lets try again
324
+ redo
325
+ end
318
326
  end
319
- else
320
- # the last thread started should be the longest wait
321
- item, item_opts = items.reverse.find { |_i, o| o.key?(:thread) }
322
- logger.debug "Waiting on #{item}"
323
- item_opts[:thread].join # wait for the thread to finish
324
- # now that we waited lets try again
325
- redo
327
+ # wait for all the threads to finish
328
+ items.each { |_remote, opts| opts[:thread].join }
326
329
  end
327
- end
328
- # wait for all the threads to finish
329
- items.each { |_remote, opts| opts[:thread].join }
330
- end
331
330
 
332
- # @param target [String] - the target directory
333
- # @param link [String] - the name of the link you wish to create
334
- # works on windows and linux
335
- def setup_symlink(target, link)
336
- link = link['target']
337
- return if File.symlink?(link)
338
-
339
- logger.info("Creating symlink from #{link} to #{target}")
340
- if windows?
341
- target = File.join(File.dirname(link), target) unless Pathname.new(target).absolute?
342
- if Dir.respond_to?(:create_junction)
343
- Dir.create_junction(link, target)
344
- else
345
- system("call mklink /J \"#{link.tr('/', '\\')}\" \"#{target.tr('/', '\\')}\"")
331
+ # @param target [String] - the target directory
332
+ # @param link [String] - the name of the link you wish to create
333
+ # works on windows and linux
334
+ def setup_symlink(target, link)
335
+ link = link['target']
336
+ return if File.symlink?(link)
337
+
338
+ logger.info("Creating symlink from #{link} to #{target}")
339
+ if windows?
340
+ target = File.join(File.dirname(link), target) unless Pathname.new(target).absolute?
341
+ if Dir.respond_to?(:create_junction)
342
+ Dir.create_junction(link, target)
343
+ else
344
+ system("call mklink /J \"#{link.tr('/', '\\')}\" \"#{target.tr('/', '\\')}\"")
345
+ end
346
+ else
347
+ FileUtils.ln_sf(target, link)
348
+ end
346
349
  end
347
- else
348
- FileUtils.ln_sf(target, link)
349
- end
350
- end
351
350
 
352
- # @return [Boolean] - returns true if the module was downloaded successfully, false otherwise
353
- # @param [String] - the remote url or namespace/name of the module to download
354
- # @param [Hash] - list of options such as version, branch, ref
355
- def download_repository(remote, opts)
356
- scm = 'git'
357
- target = opts['target']
358
- subdir = opts['subdir']
359
- ref = opts['ref']
360
- scm = opts['scm'] if opts['scm']
361
- branch = opts['branch'] if opts['branch']
362
- flags = opts['flags']
363
- if valid_repo?(scm, target, remote)
364
- update_repo(scm, target)
365
- else
366
- clone_repo(scm, remote, target, subdir, ref, branch, flags)
367
- end
368
- revision(scm, target, ref) if ref
369
- remove_subdirectory(target, subdir) if subdir
370
- end
351
+ # @return [Boolean] - returns true if the module was downloaded successfully, false otherwise
352
+ # @param [String] - the remote url or namespace/name of the module to download
353
+ # @param [Hash] - list of options such as version, branch, ref
354
+ def download_repository(remote, opts)
355
+ scm = 'git'
356
+ target = opts['target']
357
+ subdir = opts['subdir']
358
+ ref = opts['ref']
359
+ scm = opts['scm'] if opts['scm']
360
+ branch = opts['branch'] if opts['branch']
361
+ flags = opts['flags']
362
+ if valid_repo?(scm, target, remote)
363
+ update_repo(scm, target)
364
+ else
365
+ clone_repo(scm, remote, target, subdir, ref, branch, flags)
366
+ end
367
+ revision(scm, target, ref) if ref
368
+ remove_subdirectory(target, subdir) if subdir
369
+ end
371
370
 
372
- # @return [String] - the spec/fixtures/modules directory in the module root folder
373
- def module_target_dir
374
- @module_target_dir ||= File.expand_path('spec/fixtures/modules')
375
- end
371
+ # @return [String] - the spec/fixtures/modules directory in the module root folder
372
+ def module_target_dir
373
+ @module_target_dir ||= File.expand_path('spec/fixtures/modules')
374
+ end
376
375
 
377
- # @return [Boolean] - returns true if the module was downloaded successfully, false otherwise
378
- # @param [String] - the remote url or namespace/name of the module to download
379
- # @param [Hash] - list of options such as version
380
- def download_module(remote, opts)
381
- ref = ''
382
- flags = ''
383
- if opts.instance_of?(String)
384
- target = opts
385
- elsif opts.instance_of?(Hash)
386
- target = opts['target']
387
- ref = " --version #{opts['ref']}" unless opts['ref'].nil?
388
- flags = " #{opts['flags']}" if opts['flags']
389
- end
376
+ # @return [Boolean] - returns true if the module was downloaded successfully, false otherwise
377
+ # @param [String] - the remote url or namespace/name of the module to download
378
+ # @param [Hash] - list of options such as version
379
+ def download_module(remote, opts)
380
+ ref = ''
381
+ flags = ''
382
+ if opts.instance_of?(String)
383
+ target = opts
384
+ elsif opts.instance_of?(Hash)
385
+ target = opts['target']
386
+ ref = " --version #{opts['ref']}" unless opts['ref'].nil?
387
+ flags = " #{opts['flags']}" if opts['flags']
388
+ end
390
389
 
391
- return false if File.directory?(target) && (ref.empty? || opts['ref'] == module_version(target))
390
+ return false if File.directory?(target) && (ref.empty? || opts['ref'] == module_version(target))
392
391
 
393
- # The PMT cannot handle multi threaded runs due to cache directory collisons
394
- # so we randomize the directory instead.
395
- # Does working_dir even need to be passed?
396
- Dir.mktmpdir do |working_dir|
397
- command = "puppet module install#{ref}#{flags} --ignore-dependencies" \
398
- ' --force' \
399
- " --module_working_dir \"#{working_dir}\"" \
400
- " --target-dir \"#{module_target_dir}\" \"#{remote}\""
392
+ # The PMT cannot handle multi threaded runs due to cache directory collisons
393
+ # so we randomize the directory instead.
394
+ # Does working_dir even need to be passed?
395
+ Dir.mktmpdir do |working_dir|
396
+ command = "puppet module install#{ref}#{flags} --ignore-dependencies" \
397
+ ' --force' \
398
+ " --module_working_dir \"#{working_dir}\"" \
399
+ " --target-dir \"#{module_target_dir}\" \"#{remote}\""
401
400
 
402
- unless system(command)
403
- raise "Failed to install module #{remote} to #{module_target_dir}"
401
+ unless system(command)
402
+ raise "Failed to install module #{remote} to #{module_target_dir}"
403
+ end
404
+ end
405
+ $CHILD_STATUS.success?
404
406
  end
405
407
  end
406
- $CHILD_STATUS.success?
407
408
  end
408
409
  end
409
410
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PuppetlabsSpecHelper
4
- VERSION = '5.0.1'
4
+ VERSION = '5.0.2'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: puppetlabs_spec_helper
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.0.1
4
+ version: 5.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Puppet, Inc.
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2023-01-23 00:00:00.000000000 Z
12
+ date: 2023-01-25 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: mocha
@@ -29,30 +29,42 @@ dependencies:
29
29
  name: pathspec
30
30
  requirement: !ruby/object:Gem::Requirement
31
31
  requirements:
32
- - - "~>"
32
+ - - ">="
33
33
  - !ruby/object:Gem::Version
34
34
  version: '0.2'
35
+ - - "<"
36
+ - !ruby/object:Gem::Version
37
+ version: 2.0.0
35
38
  type: :runtime
36
39
  prerelease: false
37
40
  version_requirements: !ruby/object:Gem::Requirement
38
41
  requirements:
39
- - - "~>"
42
+ - - ">="
40
43
  - !ruby/object:Gem::Version
41
44
  version: '0.2'
45
+ - - "<"
46
+ - !ruby/object:Gem::Version
47
+ version: 2.0.0
42
48
  - !ruby/object:Gem::Dependency
43
49
  name: puppet-lint
44
50
  requirement: !ruby/object:Gem::Requirement
45
51
  requirements:
46
- - - "~>"
52
+ - - ">="
47
53
  - !ruby/object:Gem::Version
48
54
  version: 2.5.2
55
+ - - "<"
56
+ - !ruby/object:Gem::Version
57
+ version: 4.0.0
49
58
  type: :runtime
50
59
  prerelease: false
51
60
  version_requirements: !ruby/object:Gem::Requirement
52
61
  requirements:
53
- - - "~>"
62
+ - - ">="
54
63
  - !ruby/object:Gem::Version
55
64
  version: 2.5.2
65
+ - - "<"
66
+ - !ruby/object:Gem::Version
67
+ version: 4.0.0
56
68
  - !ruby/object:Gem::Dependency
57
69
  name: puppet-syntax
58
70
  requirement: !ruby/object:Gem::Requirement