bashcov 1.8.1 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -23,7 +23,7 @@ module Bashcov
23
23
  end
24
24
  end
25
25
 
26
- # Yields fields extracted from a input stream
26
+ # Yields fields extracted from an input stream
27
27
  # @param [String, nil] delimiter the field separator
28
28
  # @param [Integer] field_count the number of fields to extract
29
29
  # @param [Regexp] start_match a +Regexp+ that, when matched against the
@@ -33,39 +33,51 @@ module Bashcov
33
33
  # +start_match+ is matched with fewer than +field_count+ fields yielded
34
34
  # since the last match, yields empty strings until +field_count+ is
35
35
  # reached.
36
- def each(delimiter, field_count, start_match)
36
+ def each(delimiter, field_count, start_match, &block)
37
37
  return enum_for(__method__, delimiter, field_count, start_match) unless block_given?
38
38
 
39
- # The number of fields processed since passing the last start-of-fields
40
- # match
41
- seen_fields = 0
39
+ chunked = each_field(delimiter).chunk(&chunk_matches(start_match))
42
40
 
43
- fields = each_field(delimiter)
41
+ yield_fields = lambda do |(_, chunk)|
42
+ chunk.each(&block)
43
+ (field_count - chunk.size).times { yield "" }
44
+ end
45
+
46
+ # Skip junk that might appear before the first start-of-fields match
47
+ begin
48
+ n, chunk = chunked.next
49
+ yield_fields.call([n, chunk]) unless n.zero?
50
+ rescue StopIteration
51
+ return
52
+ end
44
53
 
45
- # Close over +field_count+ and +seen_fields+ to yield empty strings to
46
- # the caller when we've already hit the next start-of-fields match
47
- yield_remaining = -> { (field_count - seen_fields).times { yield "" } }
54
+ chunked.each(&yield_fields)
55
+ end
48
56
 
49
- # Advance until the first start-of-fields match
50
- loop { break if fields.next =~ start_match }
57
+ private
51
58
 
52
- fields.each do |field|
53
- # If the current field is the start-of-fields match...
54
- if field =~ start_match
55
- # Fill out any remaining (unparseable) fields with empty strings
56
- yield_remaining.call
59
+ # @param [Regexp] start_match a +Regexp+ that, when matched against the
60
+ # input stream, signifies the beginning of the next series of fields to
61
+ # yield
62
+ # @return [Proc] a unary +Proc+ that returns +nil+ if the argument mathes
63
+ # the +start_match+ +Regexp+, and otherwise returns the number of
64
+ # start-of-fields signifiers so far encountered.
65
+ # @example
66
+ # chunker = chunk_matches /<=>/
67
+ # chunked = %w[foo fighters <=> bar none <=> baz luhrmann].chunk(&chunker)
68
+ # chunked.to_a
69
+ # #=> [[0, ["foo", "fighters"]], [1, ["bar", "none"]], [2, ["baz", "luhrmann"]]]
70
+ def chunk_matches(start_match)
71
+ i = 0
57
72
 
58
- seen_fields = 0
59
- elsif seen_fields < field_count
60
- yield field
61
- seen_fields += 1
73
+ lambda do |e|
74
+ if e.match?(start_match)
75
+ i += 1
76
+ nil
77
+ else
78
+ i
62
79
  end
63
80
  end
64
-
65
- # One last filling-out of empty fields if we're at the end of the stream
66
- yield_remaining.call
67
-
68
- read.close unless read.closed?
69
81
  end
70
82
  end
71
83
  end
data/lib/bashcov/lexer.rb CHANGED
@@ -27,8 +27,8 @@ module Bashcov
27
27
 
28
28
  # Process and complete initial coverage.
29
29
  # @return [void]
30
- def complete_coverage # rubocop:disable Metrics/MethodLength
31
- lines = IO.read(@filename).encode("utf-8", invalid: :replace).lines
30
+ def complete_coverage
31
+ lines = File.read(@filename).encode("utf-8", invalid: :replace).lines
32
32
 
33
33
  lines.each_with_index do |line, lineno|
34
34
  # multi-line arrays
@@ -41,7 +41,7 @@ module Bashcov
41
41
  # heredoc
42
42
  mark_multiline(
43
43
  lines, lineno,
44
- /\A[^\n]+<<-?'?(\w+)'?\s*$.*\1/m
44
+ /\A[^\n]+<<-?'?(\w+)'?.*$.*\1/m
45
45
  )
46
46
 
47
47
  # multiline string concatenated with backslashes
@@ -72,7 +72,7 @@ module Bashcov
72
72
  private
73
73
 
74
74
  def mark_multiline(lines, lineno, regexp, forward: true)
75
- seek_forward = lines[lineno..-1].join
75
+ seek_forward = lines[lineno..].join
76
76
  return unless (multiline_match = seek_forward.match(regexp))
77
77
 
78
78
  length = multiline_match.to_s.count($/)
@@ -80,6 +80,9 @@ module Bashcov
80
80
  range = (forward ? first.upto(last) : (last - 1).downto(first - 1))
81
81
  reference_lineno = (forward ? first - 1 : last)
82
82
 
83
+ # don't seek backward if first line is already covered
84
+ return if !forward && @coverage[first - 1]
85
+
83
86
  range.each do |sub_lineno|
84
87
  # mark related lines with the same coverage as the reference line
85
88
  @coverage[sub_lineno] ||= @coverage[reference_lineno]
@@ -92,8 +95,8 @@ module Bashcov
92
95
  @coverage[lineno] = Bashcov::Line::UNCOVERED if relevant?(line)
93
96
  end
94
97
 
95
- def relevant?(line) # rubocop:disable Metrics/CyclomaticComplexity
96
- line.sub!(/ #.*\Z/, "") # remove comments
98
+ def relevant?(line)
99
+ line.sub!(/\s#.*\Z/, "") # remove comments
97
100
  line.strip!
98
101
 
99
102
  relevant = true
@@ -104,7 +107,7 @@ module Bashcov
104
107
  line.end_with?(*IGNORE_END_WITH)
105
108
 
106
109
  relevant &= false if line =~ /\A\w+\(\)/ # function declared without the `function` keyword
107
- relevant &= false if line =~ /\A[^\)]+\)\Z/ # case statement selector, e.g. `--help)`
110
+ relevant &= false if line =~ /\A[^)]+\)\Z/ # case statement selector, e.g. `--help)`
108
111
 
109
112
  relevant
110
113
  end
@@ -1,5 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "tempfile"
4
+
5
+ require "simplecov"
6
+
3
7
  require "bashcov/detective"
4
8
  require "bashcov/errors"
5
9
  require "bashcov/field_stream"
@@ -18,23 +22,40 @@ module Bashcov
18
22
  # Runs the command with appropriate xtrace settings.
19
23
  # @note Binds Bashcov +stdin+ to the program being executed.
20
24
  # @return [Process::Status] Status of the executed command
21
- def run # rubocop:disable Metrics/MethodLength
25
+ def run
22
26
  # Clear out previous run
23
27
  @result = nil
24
28
 
25
29
  field_stream = FieldStream.new
26
30
  @xtrace = Xtrace.new(field_stream)
27
-
28
31
  fd = @xtrace.file_descriptor
29
- env = { "PS4" => Xtrace.ps4 }
32
+
30
33
  options = { in: :in }
34
+ options[fd] = fd # bind FDs to the child process
31
35
 
32
36
  if Bashcov.options.mute
33
37
  options[:out] = "/dev/null"
34
38
  options[:err] = "/dev/null"
35
39
  end
36
40
 
37
- run_xtrace(fd, env, options) do
41
+ env =
42
+ if Process.uid.zero?
43
+ # if running as root, Bash 4.4+ does not inherit $PS4 from the environment
44
+ # https://github.com/infertux/bashcov/issues/43#issuecomment-450605839
45
+ write_warning "running as root is NOT recommended, Bashcov may not work properly."
46
+
47
+ temp_file = Tempfile.new("bashcov_bash_env")
48
+ temp_file.write("export PS4='#{Xtrace.ps4}'\n")
49
+ temp_file.close
50
+
51
+ { "BASH_ENV" => temp_file.path }
52
+ else
53
+ { "PS4" => Xtrace.ps4 }
54
+ end
55
+
56
+ env["BASH_XTRACEFD"] = fd.to_s
57
+
58
+ with_xtrace_flag do
38
59
  command_pid = Process.spawn env, *@command, options # spawn the command
39
60
 
40
61
  begin
@@ -58,6 +79,8 @@ module Bashcov
58
79
  end
59
80
  end
60
81
 
82
+ temp_file&.unlink
83
+
61
84
  $?
62
85
  end
63
86
 
@@ -83,39 +106,13 @@ module Bashcov
83
106
  ].join
84
107
  end
85
108
 
86
- def run_xtrace(fd, env, options)
87
- # Older versions of Bash (< 4.1) don't have the BASH_XTRACEFD variable
88
- if Bashcov.bash_xtracefd?
89
- options[fd] = fd # bind FDs to the child process
90
-
91
- env["BASH_XTRACEFD"] = fd.to_s
92
- else
93
- # Send subprocess standard error to @xtrace.file_descriptor
94
- options[:err] = fd
95
-
96
- # Don't bother issuing warning if we're silencing output anyway
97
- unless Bashcov.mute
98
- write_warning <<-WARNING
99
- you are using a version of Bash that does not support
100
- BASH_XTRACEFD. All xtrace output will print to standard error, and
101
- your script's output on standard error will not be printed to the
102
- console.
103
- WARNING
104
- end
105
- end
106
-
107
- with_xtrace_flag do
108
- yield
109
- end
110
- end
111
-
112
109
  # @note +SHELLOPTS+ must be exported so we use Ruby's {ENV} variable
113
110
  # @yield [void] adds "xtrace" to +SHELLOPTS+ and then runs the provided
114
111
  # block
115
112
  # @return [Object, ...] the value returned by the calling block
116
113
  def with_xtrace_flag
117
- existing_flags_s = ENV["SHELLOPTS"]
118
- existing_flags = (existing_flags_s || "").split(":")
114
+ existing_flags_s = ENV.fetch("SHELLOPTS", "")
115
+ existing_flags = existing_flags_s.split(":")
119
116
  ENV["SHELLOPTS"] = (existing_flags | ["xtrace"]).join(":")
120
117
 
121
118
  yield
@@ -126,25 +123,49 @@ module Bashcov
126
123
  # Add files which have not been executed at all (i.e. with no coverage)
127
124
  # @return [void]
128
125
  def find_bash_files!
129
- return if Bashcov.skip_uncovered
126
+ filtered_files.each do |filename|
127
+ @coverage[filename] = [] if !@coverage.include?(filename) && @detective.shellscript?(filename)
128
+ end
129
+ end
130
130
 
131
- Pathname.new(Bashcov.root_directory).find do |filename|
132
- if !@coverage.include?(filename) && @detective.shellscript?(filename)
133
- @coverage[filename] = []
134
- end
131
+ # @return [Array<Pathname>] the list of files that should be included in
132
+ # coverage results, unless filtered by one or more SimpleCov filters
133
+ def tracked_files
134
+ return @tracked_files if defined? @tracked_files
135
+
136
+ mandatory = SimpleCov.tracked_files ? Pathname.glob(SimpleCov.tracked_files) : []
137
+ under_root = Bashcov.skip_uncovered ? [] : Pathname.new(Bashcov.root_directory).find.to_a
138
+
139
+ @tracked_files = (mandatory + under_root).uniq
140
+ end
141
+
142
+ # @return [Array<Pathname>] the list of files that should be included in
143
+ # coverage results
144
+ def filtered_files
145
+ return @filtered_files if defined? @filtered_files
146
+
147
+ source_files = tracked_files.map do |file|
148
+ SimpleCov::SourceFile.new(file.to_s, @coverage.fetch(file, []))
149
+ end
150
+
151
+ source_file_to_tracked_file = source_files.zip(tracked_files).to_h
152
+
153
+ @filtered_files = SimpleCov.filtered(source_files).map do |source_file|
154
+ source_file_to_tracked_file[source_file]
135
155
  end
136
156
  end
137
157
 
138
158
  # @return [void]
139
159
  def expunge_invalid_files!
140
160
  @coverage.each_key do |filename|
141
- next if filename.file?
161
+ if !filename.file?
162
+ @coverage.delete filename
163
+ write_warning "#{filename} was executed but has been deleted since then - it won't be reported in coverage."
142
164
 
143
- @coverage.delete filename
144
- write_warning <<-WARNING
145
- #{filename} was executed but has been deleted since then - it won't
146
- be reported in coverage.
147
- WARNING
165
+ elsif !@detective.shellscript?(filename)
166
+ @coverage.delete filename
167
+ write_warning "#{filename} was partially executed but has invalid Bash syntax - it won't be reported in coverage."
168
+ end
148
169
  end
149
170
  end
150
171
 
@@ -158,7 +179,7 @@ module Bashcov
158
179
  end
159
180
 
160
181
  def convert_coverage
161
- Hash[@coverage.map { |filename, coverage| [filename.to_s, coverage] }]
182
+ @coverage.transform_keys(&:to_s)
162
183
  end
163
184
  end
164
185
  end
@@ -3,5 +3,5 @@
3
3
  # :nodoc:
4
4
  module Bashcov
5
5
  # Current Bashcov version
6
- VERSION = "1.8.1"
6
+ VERSION = "3.0.0"
7
7
  end
@@ -24,11 +24,10 @@ module Bashcov
24
24
  class << self
25
25
  attr_writer :delimiter, :ps4
26
26
 
27
- # [String] A randomly-generated UUID or the ASCII RS (record separator)
28
- # character, depending on whether the current Bash suffers from the
29
- # truncated +PS4+ bug. Used for delimiting the fields of the +PS4+.
27
+ # [String] A randomly-generated UUID used for delimiting the fields of
28
+ # the +PS4+.
30
29
  def delimiter
31
- @delimiter ||= Bashcov.truncated_ps4? ? "\x1E" : SecureRandom.uuid
30
+ @delimiter ||= SecureRandom.uuid
32
31
  end
33
32
 
34
33
  # @return [String] +PS4+ variable used for xtrace output. Expands to
@@ -93,9 +92,12 @@ module Bashcov
93
92
  # play nicely with +Enumerator+s backed by +IO+ objects.
94
93
  loop do
95
94
  break if (hit = (1..field_count).map { fields.next }).empty?
95
+
96
96
  parse_hit!(*hit)
97
97
  end
98
98
 
99
+ @read.close unless @read.closed?
100
+
99
101
  @files
100
102
  end
101
103
 
@@ -115,8 +117,11 @@ module Bashcov
115
117
  # If +LINENO+ isn't a series of digits, something has gone wrong. Add
116
118
  # +@files+ to the exception in order to propagate the existing coverage
117
119
  # data back to the {Bashcov::Runner} instance.
118
- if lineno =~ /\A\d+\z/
120
+ if /\A\d+\z/.match?(lineno)
119
121
  lineno = lineno.to_i
122
+ elsif lineno == "${LINENO-}"
123
+ # the variable doesn't expand on line misses so we can safely ignore it
124
+ return
120
125
  else
121
126
  raise XtraceError.new(
122
127
  "expected integer for LINENO, got #{lineno.inspect}", @files
data/lib/bashcov.rb CHANGED
@@ -3,15 +3,12 @@
3
3
  require "optparse"
4
4
  require "pathname"
5
5
 
6
- require "bashcov/bash_info"
7
6
  require "bashcov/runner"
8
7
  require "bashcov/version"
9
8
 
10
9
  # Bashcov default module
11
10
  # @note Keep it short!
12
11
  module Bashcov
13
- extend Bashcov::BashInfo
14
-
15
12
  # A +Struct+ to store Bashcov configuration
16
13
  Options = Struct.new(
17
14
  *%i[skip_uncovered mute bash_path root_directory command command_name]
@@ -55,8 +52,9 @@ module Bashcov
55
52
  VERSION,
56
53
  "with Bash #{BASH_VERSION},",
57
54
  "Ruby #{RUBY_VERSION},",
58
- "and SimpleCov #{SimpleCov::VERSION}.",
59
- ].join(" ")
55
+ "and SimpleCov #{SimpleCov::VERSION}",
56
+ (Process.uid.zero? ? " as root user (NOT recommended)" : nil),
57
+ ].compact.join(" ")
60
58
  end
61
59
 
62
60
  # @return [String] The value to use as +SimpleCov.command_name+. Uses the
@@ -65,17 +63,35 @@ module Bashcov
65
63
  # representation of {Bashcov#command}.
66
64
  def command_name
67
65
  return @options.command_name if @options.command_name
68
- return ENV["BASHCOV_COMMAND_NAME"] unless ENV.fetch("BASHCOV_COMMAND_NAME", "").empty?
66
+ return ENV.fetch("BASHCOV_COMMAND_NAME", nil) unless ENV.fetch("BASHCOV_COMMAND_NAME", "").empty?
67
+
69
68
  command.compact.join(" ")
70
69
  end
71
70
 
71
+ def bash_path
72
+ # First attempt to use the value from `options`, but ignore all exceptions.
73
+ # This is used early for the `BASH_VERSION` definition, so first use will likely error.
74
+ begin
75
+ return @options.bash_path if @options.bash_path
76
+ rescue NoMethodError; end # rubocop:disable Lint/SuppressedException
77
+
78
+ # Support the same `BASHCOV_BASH_PATH` environment variable used in the spec tests.
79
+ return ENV.fetch("BASHCOV_BASH_PATH", nil) unless ENV.fetch("BASHCOV_BASH_PATH", "").empty?
80
+
81
+ # Fall back to standard Bash location.
82
+ "/bin/bash"
83
+ end
84
+
85
+ def bash_version
86
+ `#{bash_path} -c 'echo -n ${BASH_VERSINFO[0]}.${BASH_VERSINFO[1]}'`
87
+ end
88
+
72
89
  # Wipe the current options and reset default values
73
90
  def set_default_options!
74
91
  @options = Options.new
75
92
 
76
93
  @options.skip_uncovered = false
77
94
  @options.mute = false
78
- @options.bash_path = "/bin/bash"
79
95
  @options.root_directory = Dir.getwd
80
96
  end
81
97
 
@@ -103,8 +119,8 @@ module Bashcov
103
119
  HELP
104
120
  end
105
121
 
106
- def option_parser # rubocop:disable Metrics/MethodLength
107
- OptionParser.new do |opts| # rubocop:disable Metrics/BlockLength
122
+ def option_parser
123
+ OptionParser.new do |opts|
108
124
  opts.program_name = program_name
109
125
  opts.version = Bashcov::VERSION
110
126
  opts.banner = help
@@ -119,10 +135,17 @@ module Bashcov
119
135
  end
120
136
  opts.on("--bash-path PATH", "Path to Bash executable") do |p|
121
137
  raise Errno::ENOENT, p unless File.file? p
138
+
122
139
  options.bash_path = p
140
+
141
+ # Redefine `BASH_VERSION` constant with upated `bash_path`.
142
+ # This is hacky, but a lot of code references that constant and this should only have to be done once.
143
+ send(:remove_const, "BASH_VERSION")
144
+ const_set("BASH_VERSION", bash_version.freeze)
123
145
  end
124
146
  opts.on("--root PATH", "Project root directory") do |d|
125
147
  raise Errno::ENOENT, d unless File.directory? d
148
+
126
149
  options.root_directory = d
127
150
  end
128
151
  opts.on("--command-name NAME", "Value to use as SimpleCov.command_name") do |c|
@@ -143,5 +166,5 @@ module Bashcov
143
166
  end
144
167
 
145
168
  # Current Bash version (e.g. 4.2)
146
- BASH_VERSION = `#{bash_path} -c 'echo -n ${BASH_VERSINFO[0]}.${BASH_VERSINFO[1]}'`.freeze
169
+ BASH_VERSION = bash_version.freeze
147
170
  end
data/test.sh ADDED
@@ -0,0 +1,10 @@
1
+ #!/bin/bash
2
+
3
+ set -euo pipefail
4
+
5
+ jobs=$(grep -o '^[a-z].*:$' .gitlab-ci.yml | tr -d ':' | grep -Ev '^(before_script)$')
6
+
7
+ for job in $jobs; do
8
+ echo "Running ${job}..."
9
+ gitlab-runner exec docker "$job"
10
+ done
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bashcov
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.8.1
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cédric Félizard
8
- autorequire:
9
- bindir: bin
8
+ autorequire:
9
+ bindir: exe
10
10
  cert_chain: []
11
- date: 2018-03-01 00:00:00.000000000 Z
11
+ date: 2023-04-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: simplecov
@@ -16,30 +16,30 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '0.15'
19
+ version: 0.21.2
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '0.15'
26
+ version: 0.21.2
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: aruba
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: 0.14.3
33
+ version: '0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "~>"
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: 0.14.3
40
+ version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: coveralls
42
+ name: bundler-audit
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - ">="
@@ -67,7 +67,7 @@ dependencies:
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
- name: mutant-rspec
70
+ name: rake
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - ">="
@@ -81,7 +81,7 @@ dependencies:
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
83
  - !ruby/object:Gem::Dependency
84
- name: rake
84
+ name: rspec
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - ">="
@@ -95,7 +95,7 @@ dependencies:
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
97
  - !ruby/object:Gem::Dependency
98
- name: rspec
98
+ name: rubocop
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
101
  - - ">="
@@ -109,7 +109,21 @@ dependencies:
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0'
111
111
  - !ruby/object:Gem::Dependency
112
- name: rubocop
112
+ name: rubocop-rake
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: rubocop-rspec
113
127
  requirement: !ruby/object:Gem::Requirement
114
128
  requirements:
115
129
  - - ">="
@@ -139,11 +153,17 @@ dependencies:
139
153
  description: Code coverage tool for Bash
140
154
  email:
141
155
  - cedric@felizard.fr
142
- executables:
143
- - bashcov
156
+ executables: []
144
157
  extensions: []
145
158
  extra_rdoc_files: []
146
159
  files:
160
+ - ".build.yml"
161
+ - ".github/FUNDING.yml"
162
+ - ".gitignore"
163
+ - ".gitlab-ci.yml"
164
+ - ".rspec"
165
+ - ".rubocop.yml"
166
+ - ".simplecov"
147
167
  - CHANGELOG.md
148
168
  - CONTRIBUTING.md
149
169
  - Gemfile
@@ -151,10 +171,11 @@ files:
151
171
  - LICENSE.txt
152
172
  - README.md
153
173
  - Rakefile
174
+ - TESTING.md
175
+ - USAGE.md
154
176
  - bashcov.gemspec
155
177
  - bin/bashcov
156
178
  - lib/bashcov.rb
157
- - lib/bashcov/bash_info.rb
158
179
  - lib/bashcov/detective.rb
159
180
  - lib/bashcov/errors.rb
160
181
  - lib/bashcov/field_stream.rb
@@ -163,11 +184,16 @@ files:
163
184
  - lib/bashcov/runner.rb
164
185
  - lib/bashcov/version.rb
165
186
  - lib/bashcov/xtrace.rb
187
+ - test.sh
166
188
  homepage: https://github.com/infertux/bashcov
167
189
  licenses:
168
190
  - MIT
169
- metadata: {}
170
- post_install_message:
191
+ metadata:
192
+ homepage_uri: https://github.com/infertux/bashcov
193
+ source_code_uri: https://github.com/infertux/bashcov
194
+ changelog_uri: https://github.com/infertux/bashcov/blob/master/CHANGELOG.md
195
+ rubygems_mfa_required: 'true'
196
+ post_install_message:
171
197
  rdoc_options: []
172
198
  require_paths:
173
199
  - lib
@@ -175,16 +201,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
175
201
  requirements:
176
202
  - - ">="
177
203
  - !ruby/object:Gem::Version
178
- version: 2.3.0
204
+ version: 3.0.0
179
205
  required_rubygems_version: !ruby/object:Gem::Requirement
180
206
  requirements:
181
207
  - - ">="
182
208
  - !ruby/object:Gem::Version
183
209
  version: '0'
184
210
  requirements: []
185
- rubyforge_project:
186
- rubygems_version: 2.7.4
187
- signing_key:
211
+ rubygems_version: 3.4.10
212
+ signing_key:
188
213
  specification_version: 4
189
- summary: Code coverage tool for Bash
214
+ summary: ''
190
215
  test_files: []
@@ -1,26 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Bashcov
4
- # Module exposing information concerning the installed Bash version
5
- # @note methods do not cache results because +bash_path+ can change at
6
- # runtime
7
- # @note receiver is expected to implement +bash_path+
8
- module BashInfo
9
- # @return [Boolean] Whether Bash supports +BASH_XTRACEFD+
10
- def bash_xtracefd?
11
- BASH_VERSION >= "4.1"
12
- end
13
-
14
- # @param [Integer] length the number of bytes to test; default 128
15
- # @return [Boolean] whether Bash supports a +PS4+ of at least a given
16
- # number of bytes
17
- # @see https://tiswww.case.edu/php/chet/bash/CHANGES
18
- # @note Item +i.+ under the +bash-4.2-release+ to +bash-4.3-alpha+ change
19
- # list notes that version 4.2 truncates +PS4+ if it is greater than 128
20
- # bytes.
21
- def truncated_ps4?(length = 128)
22
- ps4 = SecureRandom.base64(length)
23
- !`PS4=#{ps4} #{bash_path} 2>&1 1>&- -xc 'echo hello'`.start_with?(ps4)
24
- end
25
- end
26
- end