puppet 8.6.0 → 8.8.1
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 +4 -4
- data/Gemfile +7 -2
- data/Gemfile.lock +63 -53
- data/Rakefile +45 -22
- data/examples/hiera/README.md +68 -57
- data/examples/hiera/data/common.yaml +12 -0
- data/examples/hiera/data/dc1.yaml +6 -0
- data/examples/hiera/hiera.yaml +15 -0
- data/examples/hiera/modules/ntp/data/common.yaml +4 -0
- data/examples/hiera/modules/ntp/hiera.yaml +9 -0
- data/examples/hiera/modules/ntp/manifests/config.pp +16 -4
- data/examples/hiera/modules/ntp/templates/ntp.conf.epp +3 -0
- data/examples/hiera/modules/users/manifests/common.pp +7 -2
- data/examples/hiera/modules/users/manifests/dc1.pp +7 -2
- data/examples/hiera/site.pp +1 -1
- data/ext/project_data.yaml +0 -45
- data/ext/windows/service/daemon.rb +9 -2
- data/lib/puppet/application/doc.rb +1 -5
- data/lib/puppet/application/lookup.rb +2 -0
- data/lib/puppet/defaults.rb +5 -19
- data/lib/puppet/file_serving/http_metadata.rb +2 -0
- data/lib/puppet/functions/regsubst.rb +11 -14
- data/lib/puppet/indirector/catalog/compiler.rb +2 -35
- data/lib/puppet/module_tool/tar/gnu.rb +10 -8
- data/lib/puppet/node/server_facts.rb +43 -0
- data/lib/puppet/parser/functions/generate.rb +2 -1
- data/lib/puppet/pops/evaluator/deferred_resolver.rb +41 -6
- data/lib/puppet/pops/evaluator/runtime3_resource_support.rb +2 -1
- data/lib/puppet/pops/evaluator/runtime3_support.rb +0 -6
- data/lib/puppet/pops/loader/static_loader.rb +2 -2
- data/lib/puppet/pops/lookup/module_data_provider.rb +9 -9
- data/lib/puppet/provider/aix_object.rb +1 -1
- data/lib/puppet/provider/file/posix.rb +16 -2
- data/lib/puppet/provider/group/groupadd.rb +30 -9
- data/lib/puppet/provider/package/gem.rb +1 -0
- data/lib/puppet/provider/package/pkgutil.rb +6 -5
- data/lib/puppet/provider/package/puppet_gem.rb +4 -15
- data/lib/puppet/provider/package/xbps.rb +127 -0
- data/lib/puppet/type/exec.rb +8 -0
- data/lib/puppet/type/file/selcontext.rb +7 -6
- data/lib/puppet/type/file/target.rb +9 -11
- data/lib/puppet/util/command_line/trollop.rb +20 -2
- data/lib/puppet/util/execution.rb +1 -1
- data/lib/puppet/util/reference.rb +1 -30
- data/lib/puppet/util/rpm_compare.rb +1 -1
- data/lib/puppet/util/run_mode.rb +40 -0
- data/lib/puppet/util/selinux.rb +14 -4
- data/lib/puppet/util/windows/com.rb +2 -2
- data/lib/puppet/util/windows/daemon.rb +15 -32
- data/lib/puppet/version.rb +1 -1
- data/locales/puppet.pot +648 -648
- data/man/man5/puppet.conf.5 +2 -2
- data/man/man8/puppet-agent.8 +1 -1
- data/man/man8/puppet-apply.8 +1 -1
- data/man/man8/puppet-catalog.8 +1 -1
- data/man/man8/puppet-config.8 +1 -1
- data/man/man8/puppet-describe.8 +1 -1
- data/man/man8/puppet-device.8 +1 -1
- data/man/man8/puppet-doc.8 +1 -1
- data/man/man8/puppet-epp.8 +1 -1
- data/man/man8/puppet-facts.8 +1 -1
- data/man/man8/puppet-filebucket.8 +1 -1
- data/man/man8/puppet-generate.8 +1 -1
- data/man/man8/puppet-help.8 +1 -1
- data/man/man8/puppet-lookup.8 +1 -1
- data/man/man8/puppet-module.8 +1 -1
- data/man/man8/puppet-node.8 +1 -1
- data/man/man8/puppet-parser.8 +1 -1
- data/man/man8/puppet-plugin.8 +1 -1
- data/man/man8/puppet-report.8 +1 -1
- data/man/man8/puppet-resource.8 +1 -1
- data/man/man8/puppet-script.8 +1 -1
- data/man/man8/puppet-ssl.8 +1 -1
- data/man/man8/puppet.8 +2 -2
- metadata +56 -51
- data/examples/hiera/etc/hiera.yaml +0 -15
- data/examples/hiera/etc/hieradb/common.yaml +0 -3
- data/examples/hiera/etc/hieradb/dc1.yaml +0 -6
- data/examples/hiera/etc/hieradb/development.yaml +0 -2
- data/examples/hiera/etc/puppet.conf +0 -3
- data/examples/hiera/modules/data/manifests/common.pp +0 -4
- data/examples/hiera/modules/ntp/manifests/data.pp +0 -4
- data/examples/hiera/modules/ntp/templates/ntp.conf.erb +0 -3
- data/examples/hiera/modules/users/manifests/development.pp +0 -4
- data/tasks/benchmark.rake +0 -180
- data/tasks/cfpropertylist.rake +0 -15
- data/tasks/ci.rake +0 -24
- data/tasks/generate_ast_model.rake +0 -90
- data/tasks/generate_cert_fixtures.rake +0 -199
- data/tasks/manpages.rake +0 -67
- data/tasks/memwalk.rake +0 -195
- data/tasks/parallel.rake +0 -410
- data/tasks/parser.rake +0 -22
- data/tasks/yard.rake +0 -59
data/tasks/memwalk.rake
DELETED
@@ -1,195 +0,0 @@
|
|
1
|
-
# Walks the memory dumped into heap.json, and produces a graph of the memory dumped in diff.json
|
2
|
-
# If a single argument (a hex address to one object) is given, the graph is limited to this object and what references it
|
3
|
-
# The heap dumps should be in the format produced by Ruby ObjectSpace in Ruby version 2.1.0 or later.
|
4
|
-
#
|
5
|
-
# The command produces a .dot file that can be rendered with graphwiz dot into SVG. If a memwalk is performed for all
|
6
|
-
# objects in the diff.json, the output file name is memwalk.dot. If it is produced for a single address, the name of the
|
7
|
-
# output file is memwalk-<address>.dot
|
8
|
-
#
|
9
|
-
# The dot file can be rendered with something like: dot -Tsvg -omemwalk.svg memwalk.dot
|
10
|
-
#
|
11
|
-
desc "Process a diff.json of object ids, and a heap.json of a Ruby 2.1.0 ObjectSpace dump and produce a graph"
|
12
|
-
task :memwalk, [:id] do |t, args|
|
13
|
-
puts "Memwalk"
|
14
|
-
puts "Computing for #{args[:id] ? args[:id] : 'all'}"
|
15
|
-
@single_id = args[:id] ? args[:id].to_i(16) : nil
|
16
|
-
|
17
|
-
require 'json'
|
18
|
-
#require 'debug'
|
19
|
-
|
20
|
-
TYPE = "type".freeze
|
21
|
-
ROOT = "root".freeze
|
22
|
-
ROOT_UC = "ROOT".freeze
|
23
|
-
ADDR = "address".freeze
|
24
|
-
NODE = "NODE".freeze
|
25
|
-
STRING = "STRING".freeze
|
26
|
-
DATA = "DATA".freeze
|
27
|
-
HASH = "HASH".freeze
|
28
|
-
ARRAY = "ARRAY".freeze
|
29
|
-
OBJECT = "OBJECT".freeze
|
30
|
-
CLASS = "CLASS".freeze
|
31
|
-
|
32
|
-
allocations = {}
|
33
|
-
# An array of integer addresses of the objects to trace bindings for
|
34
|
-
diff_index = {}
|
35
|
-
puts "Reading data"
|
36
|
-
begin
|
37
|
-
puts "Reading diff"
|
38
|
-
lines = 0;
|
39
|
-
File.readlines("diff.json").each do | line |
|
40
|
-
lines += 1
|
41
|
-
diff = JSON.parse(line)
|
42
|
-
case diff[ TYPE ]
|
43
|
-
when STRING, DATA, HASH, ARRAY
|
44
|
-
# skip the strings
|
45
|
-
else
|
46
|
-
diff_index[ diff[ ADDR ].to_i(16) ] = diff
|
47
|
-
end
|
48
|
-
end
|
49
|
-
puts "Read #{lines} number of diffs"
|
50
|
-
rescue => e
|
51
|
-
raise "ERROR READING DIFF at line #{lines} #{e.message[0, 200]}"
|
52
|
-
end
|
53
|
-
|
54
|
-
begin
|
55
|
-
puts "Reading heap"
|
56
|
-
lines = 0
|
57
|
-
allocation = nil
|
58
|
-
File.readlines("heap.json").each do | line |
|
59
|
-
lines += 1
|
60
|
-
allocation = JSON.parse(line)
|
61
|
-
case allocation[ TYPE ]
|
62
|
-
when ROOT_UC
|
63
|
-
# Graph for single id must include roots, as it may be a root that holds on to the reference
|
64
|
-
# a global variable, thread, etc.
|
65
|
-
#
|
66
|
-
if @single_id
|
67
|
-
allocations[ allocation[ ROOT ] ] = allocation
|
68
|
-
end
|
69
|
-
when NODE
|
70
|
-
# skip the NODE objects - they represent the loaded ruby code
|
71
|
-
when STRING
|
72
|
-
# skip all strings - they are everywhere
|
73
|
-
else
|
74
|
-
allocations[ allocation[ ADDR ].to_i(16) ] = allocation
|
75
|
-
end
|
76
|
-
end
|
77
|
-
puts "Read #{lines} number of entries"
|
78
|
-
rescue => e
|
79
|
-
require 'debug'
|
80
|
-
puts "ERROR READING HEAP #{e.message[0, 200]}"
|
81
|
-
raise e
|
82
|
-
end
|
83
|
-
@heap = allocations
|
84
|
-
|
85
|
-
puts "Building reference index"
|
86
|
-
# References is an index from a referenced object to an array with addresses to the objects that references it
|
87
|
-
@references = Hash.new { |h, k| h[k] = [] }
|
88
|
-
REFERENCES = "references".freeze
|
89
|
-
allocations.each do |k,v|
|
90
|
-
refs = v[ REFERENCES ]
|
91
|
-
if refs.is_a?(Array)
|
92
|
-
refs.each {|addr| @references[ addr.to_i(16) ] << k }
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
@printed = Set.new()
|
97
|
-
|
98
|
-
def print_object(addr, entry)
|
99
|
-
# only print each node once
|
100
|
-
return unless @printed.add?(addr)
|
101
|
-
begin
|
102
|
-
if addr.is_a?(String)
|
103
|
-
@output.write( "x#{node_name(addr)} [label=\"#{node_label(addr, entry)}\\n#{addr}\"];\n")
|
104
|
-
else
|
105
|
-
@output.write( "x#{node_name(addr)} [label=\"#{node_label(addr, entry)}\\n#{addr.to_s(16)}\"];\n")
|
106
|
-
end
|
107
|
-
rescue => e
|
108
|
-
require 'debug'
|
109
|
-
raise e
|
110
|
-
end
|
111
|
-
end
|
112
|
-
|
113
|
-
def node_label(addr, entry)
|
114
|
-
if entry[ TYPE ] == OBJECT
|
115
|
-
class_ref = entry[ "class" ].to_i(16)
|
116
|
-
@heap[ class_ref ][ "name" ]
|
117
|
-
elsif entry[ TYPE ] == CLASS
|
118
|
-
"CLASS #{entry[ "name"]}"
|
119
|
-
else
|
120
|
-
entry[TYPE]
|
121
|
-
end
|
122
|
-
end
|
123
|
-
|
124
|
-
def node_name(addr)
|
125
|
-
return addr if addr.is_a? String
|
126
|
-
addr.to_s(16)
|
127
|
-
end
|
128
|
-
|
129
|
-
def print_edge(from_addr, to_addr)
|
130
|
-
@output.write("x#{node_name(from_addr)}->x#{node_name(to_addr)};\n")
|
131
|
-
end
|
132
|
-
|
133
|
-
def closure_and_edges(diff)
|
134
|
-
edges = Set.new()
|
135
|
-
walked = Set.new()
|
136
|
-
puts "Number of diffs referenced = #{diff.count {|k,_| @references[k].is_a?(Array) && @references[k].size() > 0 }}"
|
137
|
-
diff.each {|k,_| walk(k, edges, walked) }
|
138
|
-
edges.each {|e| print_edge(*e) }
|
139
|
-
end
|
140
|
-
|
141
|
-
def walk(addr, edges, walked)
|
142
|
-
if !@heap[ addr ].nil?
|
143
|
-
print_object(addr, @heap[addr])
|
144
|
-
|
145
|
-
@references [ addr ].each do |r|
|
146
|
-
walk_to_object(addr, r, edges, walked)
|
147
|
-
end
|
148
|
-
end
|
149
|
-
end
|
150
|
-
|
151
|
-
def walk_to_object(to_addr, cursor, edges, walked)
|
152
|
-
return unless walked
|
153
|
-
# if walked to an object, or everything if a single_id is the target
|
154
|
-
if @heap[ cursor ][ TYPE ] == OBJECT || (@single_id && @heap[ cursor ][ TYPE ] == ROOT_UC || @heap[ cursor ][ TYPE ] == CLASS )
|
155
|
-
# and the edge is unique
|
156
|
-
if edges.add?( [ cursor, to_addr ] )
|
157
|
-
# then we may not have visited objects this objects is being referred from
|
158
|
-
print_object(cursor, @heap[ cursor ])
|
159
|
-
# Do not follow what binds a class
|
160
|
-
if @heap[ cursor ][ TYPE ] != CLASS
|
161
|
-
@references[ cursor ].each do |r|
|
162
|
-
walk_to_object(cursor, r, edges, walked.add?(r))
|
163
|
-
walked.delete(r)
|
164
|
-
end
|
165
|
-
end
|
166
|
-
end
|
167
|
-
else
|
168
|
-
# continue search until Object
|
169
|
-
@references[cursor].each do |r|
|
170
|
-
walk_to_object(to_addr, r, edges, walked.add?(r))
|
171
|
-
end
|
172
|
-
end
|
173
|
-
end
|
174
|
-
|
175
|
-
def single_closure_and_edges(the_target)
|
176
|
-
edges = Set.new()
|
177
|
-
walked = Set.new()
|
178
|
-
walk(the_target, edges, walked)
|
179
|
-
edges.each {|e| print_edge(*e) }
|
180
|
-
end
|
181
|
-
|
182
|
-
puts "creating graph"
|
183
|
-
if @single_id
|
184
|
-
@output = File.open("memwalk-#{@single_id.to_s(16)}.dot", "w")
|
185
|
-
@output.write("digraph root {\n")
|
186
|
-
single_closure_and_edges(@single_id)
|
187
|
-
else
|
188
|
-
@output = File.open("memwalk.dot", "w")
|
189
|
-
@output.write("digraph root {\n")
|
190
|
-
closure_and_edges(diff_index)
|
191
|
-
end
|
192
|
-
@output.write("}\n")
|
193
|
-
@output.close
|
194
|
-
puts "done"
|
195
|
-
end
|
data/tasks/parallel.rake
DELETED
@@ -1,410 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
require 'rubygems'
|
4
|
-
require 'thread'
|
5
|
-
begin
|
6
|
-
require 'rspec'
|
7
|
-
require 'rspec/core/formatters/helpers'
|
8
|
-
require 'etc'
|
9
|
-
rescue LoadError
|
10
|
-
# Don't define the task if we don't have rspec present
|
11
|
-
else
|
12
|
-
module Parallel
|
13
|
-
module RSpec
|
14
|
-
#
|
15
|
-
# Responsible for buffering the output of RSpec's progress formatter.
|
16
|
-
#
|
17
|
-
class ProgressFormatBuffer
|
18
|
-
attr_reader :pending_lines
|
19
|
-
attr_reader :failure_lines
|
20
|
-
attr_reader :examples
|
21
|
-
attr_reader :failures
|
22
|
-
attr_reader :pending
|
23
|
-
attr_reader :failed_example_lines
|
24
|
-
attr_reader :state
|
25
|
-
|
26
|
-
module OutputState
|
27
|
-
HEADER = 1
|
28
|
-
PROGRESS = 2
|
29
|
-
SUMMARY = 3
|
30
|
-
PENDING = 4
|
31
|
-
FAILURES = 5
|
32
|
-
DURATION = 6
|
33
|
-
COUNTS = 7
|
34
|
-
FAILED_EXAMPLES = 8
|
35
|
-
end
|
36
|
-
|
37
|
-
def initialize(io, color)
|
38
|
-
@io = io
|
39
|
-
@color = color
|
40
|
-
@state = OutputState::HEADER
|
41
|
-
@pending_lines = []
|
42
|
-
@failure_lines = []
|
43
|
-
@examples = 0
|
44
|
-
@failures = 0
|
45
|
-
@pending = 0
|
46
|
-
@failed_example_lines = []
|
47
|
-
end
|
48
|
-
|
49
|
-
def color?
|
50
|
-
@color
|
51
|
-
end
|
52
|
-
|
53
|
-
def read
|
54
|
-
# Parse and ignore the one line header
|
55
|
-
if @state == OutputState::HEADER
|
56
|
-
begin
|
57
|
-
@io.readline
|
58
|
-
rescue EOFError
|
59
|
-
return nil
|
60
|
-
end
|
61
|
-
@state = OutputState::PROGRESS
|
62
|
-
return ''
|
63
|
-
end
|
64
|
-
|
65
|
-
# If the progress has been read, parse the summary
|
66
|
-
if @state == OutputState::SUMMARY
|
67
|
-
parse_summary
|
68
|
-
return nil
|
69
|
-
end
|
70
|
-
|
71
|
-
# Read the progress output up to 128 bytes at a time
|
72
|
-
# 128 is a small enough number to show some progress, but not too small that
|
73
|
-
# we're constantly writing synchronized output
|
74
|
-
data = @io.read(128)
|
75
|
-
return nil unless data
|
76
|
-
|
77
|
-
data = @remainder + data if @remainder
|
78
|
-
|
79
|
-
# Check for the end of the progress line
|
80
|
-
if (index = data.index "\n")
|
81
|
-
@state = OutputState::SUMMARY
|
82
|
-
@remainder = data[(index+1)..-1]
|
83
|
-
data = data[0...index]
|
84
|
-
# Check for partial ANSI escape codes in colorized output
|
85
|
-
elsif @color && !data.end_with?("\e[0m") && (index = data.rindex("\e[", -6))
|
86
|
-
@remainder = data[index..-1]
|
87
|
-
data = data[0...index]
|
88
|
-
else
|
89
|
-
@remainder = nil
|
90
|
-
end
|
91
|
-
|
92
|
-
data
|
93
|
-
end
|
94
|
-
|
95
|
-
private
|
96
|
-
|
97
|
-
def parse_summary
|
98
|
-
# If there is a remainder, concat it with the next line and handle each line
|
99
|
-
unless @remainder.empty?
|
100
|
-
lines = @remainder
|
101
|
-
eof = false
|
102
|
-
begin
|
103
|
-
lines += @io.readline
|
104
|
-
rescue EOFError
|
105
|
-
eof = true
|
106
|
-
end
|
107
|
-
lines.each_line do |line|
|
108
|
-
parse_summary_line line
|
109
|
-
end
|
110
|
-
return if eof
|
111
|
-
end
|
112
|
-
|
113
|
-
# Process the rest of the lines
|
114
|
-
begin
|
115
|
-
@io.each_line do |line|
|
116
|
-
parse_summary_line line
|
117
|
-
end
|
118
|
-
rescue EOFError
|
119
|
-
end
|
120
|
-
end
|
121
|
-
|
122
|
-
def parse_summary_line(line)
|
123
|
-
line.chomp!
|
124
|
-
return if line.empty?
|
125
|
-
|
126
|
-
if line == 'Pending:'
|
127
|
-
@status = OutputState::PENDING
|
128
|
-
return
|
129
|
-
elsif line == 'Failures:'
|
130
|
-
@status = OutputState::FAILURES
|
131
|
-
return
|
132
|
-
elsif line == 'Failed examples:'
|
133
|
-
@status = OutputState::FAILED_EXAMPLES
|
134
|
-
return
|
135
|
-
elsif (line.match /^Finished in ((\d+\.?\d*) minutes?)? ?(\d+\.?\d*) seconds?$/)
|
136
|
-
@status = OutputState::DURATION
|
137
|
-
return
|
138
|
-
elsif (match = line.gsub(/\e\[\d+m/, '').match /^(\d+) examples?, (\d+) failures?(, (\d+) pending)?$/)
|
139
|
-
@status = OutputState::COUNTS
|
140
|
-
@examples = match[1].to_i
|
141
|
-
@failures = match[2].to_i
|
142
|
-
@pending = (match[4] || 0).to_i
|
143
|
-
return
|
144
|
-
end
|
145
|
-
|
146
|
-
case @status
|
147
|
-
when OutputState::PENDING
|
148
|
-
@pending_lines << line
|
149
|
-
when OutputState::FAILURES
|
150
|
-
@failure_lines << line
|
151
|
-
when OutputState::FAILED_EXAMPLES
|
152
|
-
@failed_example_lines << line
|
153
|
-
end
|
154
|
-
end
|
155
|
-
end
|
156
|
-
|
157
|
-
#
|
158
|
-
# Responsible for parallelizing spec testing.
|
159
|
-
# Optional options list will be passed to rspec.
|
160
|
-
#
|
161
|
-
class Parallelizer
|
162
|
-
# Number of processes to use
|
163
|
-
attr_reader :process_count
|
164
|
-
# Approximate size of each group of tests
|
165
|
-
attr_reader :group_size
|
166
|
-
# Options list for rspec
|
167
|
-
attr_reader :options
|
168
|
-
|
169
|
-
def initialize(process_count, group_size, color, options = [])
|
170
|
-
@process_count = process_count
|
171
|
-
@group_size = group_size
|
172
|
-
@color = color
|
173
|
-
@options = options
|
174
|
-
end
|
175
|
-
|
176
|
-
def color?
|
177
|
-
@color
|
178
|
-
end
|
179
|
-
|
180
|
-
def run
|
181
|
-
@start_time = Time.now
|
182
|
-
|
183
|
-
groups = group_specs
|
184
|
-
fail red('error: no specs were found') if groups.length == 0
|
185
|
-
|
186
|
-
begin
|
187
|
-
run_specs(groups, options)
|
188
|
-
ensure
|
189
|
-
groups.each do |file|
|
190
|
-
File.unlink(file)
|
191
|
-
end
|
192
|
-
end
|
193
|
-
end
|
194
|
-
|
195
|
-
private
|
196
|
-
|
197
|
-
def group_specs
|
198
|
-
# Spawn the rspec_grouper utility to perform the test grouping
|
199
|
-
# We do this in a separate process to limit this processes' long-running footprint
|
200
|
-
io = IO.popen("ruby util/rspec_grouper #{@group_size}")
|
201
|
-
|
202
|
-
header = true
|
203
|
-
spec_group_files = []
|
204
|
-
io.each_line do |line|
|
205
|
-
line.chomp!
|
206
|
-
header = false if line.empty?
|
207
|
-
next if header || line.empty?
|
208
|
-
spec_group_files << line
|
209
|
-
end
|
210
|
-
|
211
|
-
_, status = Process.waitpid2(io.pid)
|
212
|
-
io.close
|
213
|
-
|
214
|
-
fail red('error: no specs were found.') unless status.success?
|
215
|
-
spec_group_files
|
216
|
-
end
|
217
|
-
|
218
|
-
def run_specs(groups, options)
|
219
|
-
puts "Processing #{groups.length} spec group(s) with #{@process_count} worker(s)"
|
220
|
-
|
221
|
-
interrupted = false
|
222
|
-
success = true
|
223
|
-
worker_threads = []
|
224
|
-
group_index = -1
|
225
|
-
pids = Array.new(@process_count)
|
226
|
-
mutex = Mutex.new
|
227
|
-
|
228
|
-
# Handle SIGINT by killing child processes
|
229
|
-
original_handler = Signal.trap :SIGINT do
|
230
|
-
break if interrupted
|
231
|
-
interrupted = true
|
232
|
-
|
233
|
-
# Can't synchronize in a trap context, so read dirty
|
234
|
-
pids.each do |pid|
|
235
|
-
begin
|
236
|
-
Process.kill(:SIGKILL, pid) if pid
|
237
|
-
rescue Errno::ESRCH
|
238
|
-
end
|
239
|
-
end
|
240
|
-
puts yellow("\nshutting down...")
|
241
|
-
end
|
242
|
-
|
243
|
-
buffers = []
|
244
|
-
|
245
|
-
process_count.times do |thread_id|
|
246
|
-
worker_threads << Thread.new do
|
247
|
-
while !interrupted do
|
248
|
-
# Get the spec file for this rspec run
|
249
|
-
group = mutex.synchronize { if group_index < groups.length then groups[group_index += 1] else nil end }
|
250
|
-
break unless group && !interrupted
|
251
|
-
|
252
|
-
# Spawn the worker process with redirected output
|
253
|
-
options_string = options ? options.join(' ') : ''
|
254
|
-
io = IO.popen("ruby util/rspec_runner #{group} #{options_string}")
|
255
|
-
pids[thread_id] = io.pid
|
256
|
-
|
257
|
-
# TODO: make the buffer pluggable to handle other output formats like documentation
|
258
|
-
buffer = ProgressFormatBuffer.new(io, @color)
|
259
|
-
|
260
|
-
# Process the output
|
261
|
-
while !interrupted
|
262
|
-
output = buffer.read
|
263
|
-
break unless output && !interrupted
|
264
|
-
next if output.empty?
|
265
|
-
mutex.synchronize { print output }
|
266
|
-
end
|
267
|
-
|
268
|
-
# Kill the process if we were interrupted, just to be sure
|
269
|
-
if interrupted
|
270
|
-
begin
|
271
|
-
Process.kill(:SIGKILL, pids[thread_id])
|
272
|
-
rescue Errno::ESRCH
|
273
|
-
end
|
274
|
-
end
|
275
|
-
|
276
|
-
# Reap the process
|
277
|
-
result = Process.waitpid2(pids[thread_id])[1].success?
|
278
|
-
io.close
|
279
|
-
pids[thread_id] = nil
|
280
|
-
mutex.synchronize do
|
281
|
-
buffers << buffer
|
282
|
-
success &= result
|
283
|
-
end
|
284
|
-
end
|
285
|
-
end
|
286
|
-
end
|
287
|
-
|
288
|
-
# Join all worker threads
|
289
|
-
worker_threads.each do |thread|
|
290
|
-
thread.join
|
291
|
-
end
|
292
|
-
|
293
|
-
Signal.trap :SIGINT, original_handler
|
294
|
-
fail yellow('execution was interrupted') if interrupted
|
295
|
-
|
296
|
-
dump_summary buffers
|
297
|
-
success
|
298
|
-
end
|
299
|
-
|
300
|
-
def colorize(text, color_code)
|
301
|
-
if @color
|
302
|
-
"#{color_code}#{text}\e[0m"
|
303
|
-
else
|
304
|
-
text
|
305
|
-
end
|
306
|
-
end
|
307
|
-
|
308
|
-
def red(text)
|
309
|
-
colorize(text, "\e[31m")
|
310
|
-
end
|
311
|
-
|
312
|
-
def green(text)
|
313
|
-
colorize(text, "\e[32m")
|
314
|
-
end
|
315
|
-
|
316
|
-
def yellow(text)
|
317
|
-
colorize(text, "\e[33m")
|
318
|
-
end
|
319
|
-
|
320
|
-
def dump_summary(buffers)
|
321
|
-
puts
|
322
|
-
|
323
|
-
# Print out the pending tests
|
324
|
-
print_header = true
|
325
|
-
buffers.each do |buffer|
|
326
|
-
next if buffer.pending_lines.empty?
|
327
|
-
if print_header
|
328
|
-
puts "\nPending:"
|
329
|
-
print_header = false
|
330
|
-
end
|
331
|
-
puts buffer.pending_lines
|
332
|
-
end
|
333
|
-
|
334
|
-
# Print out the failures
|
335
|
-
print_header = true
|
336
|
-
buffers.each do |buffer|
|
337
|
-
next if buffer.failure_lines.empty?
|
338
|
-
if print_header
|
339
|
-
puts "\nFailures:"
|
340
|
-
print_header = false
|
341
|
-
end
|
342
|
-
puts
|
343
|
-
puts buffer.failure_lines
|
344
|
-
end
|
345
|
-
|
346
|
-
# Print out the run time
|
347
|
-
puts "\nFinished in #{::RSpec::Core::Formatters::Helpers.format_duration(Time.now - @start_time)}"
|
348
|
-
|
349
|
-
# Count all of the examples
|
350
|
-
examples = 0
|
351
|
-
failures = 0
|
352
|
-
pending = 0
|
353
|
-
buffers.each do |buffer|
|
354
|
-
examples += buffer.examples
|
355
|
-
failures += buffer.failures
|
356
|
-
pending += buffer.pending
|
357
|
-
end
|
358
|
-
if failures > 0
|
359
|
-
puts red(summary_count_line(examples, failures, pending))
|
360
|
-
elsif pending > 0
|
361
|
-
puts yellow(summary_count_line(examples, failures, pending))
|
362
|
-
else
|
363
|
-
puts green(summary_count_line(examples, failures, pending))
|
364
|
-
end
|
365
|
-
|
366
|
-
# Print out the failed examples
|
367
|
-
print_header = true
|
368
|
-
buffers.each do |buffer|
|
369
|
-
next if buffer.failed_example_lines.empty?
|
370
|
-
if print_header
|
371
|
-
puts "\nFailed examples:"
|
372
|
-
print_header = false
|
373
|
-
end
|
374
|
-
puts buffer.failed_example_lines
|
375
|
-
end
|
376
|
-
end
|
377
|
-
|
378
|
-
def summary_count_line(examples, failures, pending)
|
379
|
-
summary = ::RSpec::Core::Formatters::Helpers.pluralize(examples, "example")
|
380
|
-
summary << ", " << ::RSpec::Core::Formatters::Helpers.pluralize(failures, "failure")
|
381
|
-
summary << ", #{pending} pending" if pending > 0
|
382
|
-
summary
|
383
|
-
end
|
384
|
-
end
|
385
|
-
end
|
386
|
-
end
|
387
|
-
|
388
|
-
namespace 'parallel' do
|
389
|
-
def color_output?
|
390
|
-
# Check with RSpec to see if color is enabled
|
391
|
-
config = ::RSpec::Core::Configuration.new
|
392
|
-
config.error_stream = $stderr
|
393
|
-
config.output_stream = $stdout
|
394
|
-
options = ::RSpec::Core::ConfigurationOptions.new []
|
395
|
-
options.configure config
|
396
|
-
config.color
|
397
|
-
end
|
398
|
-
|
399
|
-
desc 'Runs specs in parallel. Extra args are passed to rspec.'
|
400
|
-
task 'spec', [:process_count, :group_size] do |_, args|
|
401
|
-
# Default group size in rspec examples
|
402
|
-
DEFAULT_GROUP_SIZE = 1000
|
403
|
-
|
404
|
-
process_count = [(args[:process_count] || Etc.nprocessors).to_i, 1].max
|
405
|
-
group_size = [(args[:group_size] || DEFAULT_GROUP_SIZE).to_i, 1].max
|
406
|
-
|
407
|
-
abort unless Parallel::RSpec::Parallelizer.new(process_count, group_size, color_output?, args.extras).run
|
408
|
-
end
|
409
|
-
end
|
410
|
-
end
|
data/tasks/parser.rake
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
desc "Generate the 4.x 'future' parser"
|
2
|
-
task :gen_eparser => :require_racc do
|
3
|
-
%x{racc -olib/puppet/pops/parser/eparser.rb lib/puppet/pops/parser/egrammar.ra}
|
4
|
-
end
|
5
|
-
|
6
|
-
desc "Generate the 4.x 'future' parser with egrammar.output"
|
7
|
-
task :gen_eparser_output => :require_racc do
|
8
|
-
%x{racc -v -olib/puppet/pops/parser/eparser.rb lib/puppet/pops/parser/egrammar.ra}
|
9
|
-
end
|
10
|
-
|
11
|
-
desc "Generate the 4.x 'future' parser with debugging output"
|
12
|
-
task :gen_eparser_debug => :require_racc do
|
13
|
-
%x{racc -t -olib/puppet/pops/parser/eparser.rb lib/puppet/pops/parser/egrammar.ra}
|
14
|
-
end
|
15
|
-
|
16
|
-
task :require_racc do
|
17
|
-
begin
|
18
|
-
require 'racc'
|
19
|
-
rescue LoadError
|
20
|
-
abort("Run `bundle install --with development` to install the `racc` gem.")
|
21
|
-
end
|
22
|
-
end
|
data/tasks/yard.rake
DELETED
@@ -1,59 +0,0 @@
|
|
1
|
-
begin
|
2
|
-
require 'yard'
|
3
|
-
|
4
|
-
namespace :doc do
|
5
|
-
desc "Clean up generated documentation"
|
6
|
-
task :clean do
|
7
|
-
rm_rf "doc"
|
8
|
-
end
|
9
|
-
|
10
|
-
desc "Generate public documentation pages for the API"
|
11
|
-
YARD::Rake::YardocTask.new(:api) do |t|
|
12
|
-
t.files = ['lib/**/*.rb']
|
13
|
-
t.options = %w{
|
14
|
-
--protected
|
15
|
-
--private
|
16
|
-
--verbose
|
17
|
-
--markup markdown
|
18
|
-
--readme README.md
|
19
|
-
--tag status
|
20
|
-
--transitive-tag status
|
21
|
-
--tag comment
|
22
|
-
--hide-tag comment
|
23
|
-
--tag dsl:"DSL"
|
24
|
-
--no-transitive-tag api
|
25
|
-
--template-path yardoc/templates
|
26
|
-
--files README_DEVELOPER.md,CO*.md,api/**/*.md
|
27
|
-
--api public
|
28
|
-
--api private
|
29
|
-
--hide-void-return
|
30
|
-
}
|
31
|
-
end
|
32
|
-
|
33
|
-
desc "Generate documentation pages for all of the code"
|
34
|
-
YARD::Rake::YardocTask.new(:all) do |t|
|
35
|
-
t.files = ['lib/**/*.rb']
|
36
|
-
t.options = %w{
|
37
|
-
--verbose
|
38
|
-
--markup markdown
|
39
|
-
--readme README.md
|
40
|
-
--tag status
|
41
|
-
--transitive-tag status
|
42
|
-
--tag comment
|
43
|
-
--hide-tag comment
|
44
|
-
--tag dsl:"DSL"
|
45
|
-
--no-transitive-tag api
|
46
|
-
--template-path yardoc/templates
|
47
|
-
--files README_DEVELOPER.md,CO*.md,api/**/*.md
|
48
|
-
--api public
|
49
|
-
--api private
|
50
|
-
--no-api
|
51
|
-
--hide-void-return
|
52
|
-
}
|
53
|
-
end
|
54
|
-
end
|
55
|
-
rescue LoadError => e
|
56
|
-
if verbose
|
57
|
-
STDERR.puts "Document generation not available without yard. #{e.message}"
|
58
|
-
end
|
59
|
-
end
|