bashcov 1.6.0 → 1.7.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 69ae560709ca922d5768a2755b4c9f9fa0de60d9
4
- data.tar.gz: c0ccca240348b0736dca3357af5412c98159466a
3
+ metadata.gz: 4f9c5cde335ec3f77c2e8671870587c91c0b7921
4
+ data.tar.gz: 3aa49b58a3030285aa9dbdbd6852d1090f9770b0
5
5
  SHA512:
6
- metadata.gz: 7032cb66094fa7f79ae7916eb93dc58e814d5e46cac8fce6a0006ec8370c9f18a8aba2de2a9f642e5c984e3a992e28e98cd59664a8d5828afa45bf33c5f6f5bf
7
- data.tar.gz: 2ed6423accb917c077797224efe9644668349be5adb05ccd32b37413b8904bc1a560b566c871cde50331017bcd557ffdb6e75309822bd0cd58481ae0a6666f91
6
+ metadata.gz: fe850cf7e3ff9c56889b853bbb128aeaf4cf4da97702308b2df1ba67f24ec4161c1d96f9dd0ca14d308dc0b8ae374850bd295891e55c94cf25bd7ff8e01bb87f
7
+ data.tar.gz: ccf1e25f9be556328f8f6abf311ff95a2161af389f387aa1a2c611fa3f8b8683d954fcd4b710ad337bb5ba6e85d84206cf1dbf2d09ef6c5c2345cdbf215429ab
data/CHANGELOG.md CHANGED
@@ -1,7 +1,15 @@
1
- ## Unreleased ([changes](https://github.com/infertux/bashcov/compare/v1.6.0...master))
1
+ ## Unreleased ([changes](https://github.com/infertux/bashcov/compare/v1.7.0...master))
2
2
 
3
3
  * TBD
4
4
 
5
+ ## v1.7.0, 2017-12-28 ([changes](https://github.com/infertux/bashcov/compare/v1.6.0...v1.7.0))
6
+
7
+ * [MISC] Add support for Ruby 2.5 and drop 2.2
8
+ * [BUGFIX] Fix issue where coverage would be run twice and overwritten (#33)
9
+ * [FEATURE] Enhance shell script detection by parsing shebangs, checking
10
+ filename extensions, and running syntax checks with `bash -n`
11
+ (classes `Detective` & `Runner`) (#30)
12
+
5
13
  ## v1.6.0, 2017-10-24 ([changes](https://github.com/infertux/bashcov/compare/v1.5.1...v1.6.0))
6
14
 
7
15
  * [BUGFIX] Don't crash when files contain invalid UTF-8 characters (#27)
data/README.md CHANGED
@@ -1,10 +1,10 @@
1
1
  # Bashcov
2
2
 
3
+ [![Gem Version](https://img.shields.io/gem/v/bashcov.svg)](https://rubygems.org/gems/bashcov)
3
4
  [![Build Status](https://secure.travis-ci.org/infertux/bashcov.png?branch=master)](https://travis-ci.org/infertux/bashcov)
4
- [![Dependency Status](https://gemnasium.com/infertux/bashcov.png)](https://gemnasium.com/infertux/bashcov)
5
- [![Code Climate](https://codeclimate.com/github/infertux/bashcov.png)](https://codeclimate.com/github/infertux/bashcov)
6
5
  [![Coverage Status](https://coveralls.io/repos/infertux/bashcov/badge.png?branch=master)](https://coveralls.io/r/infertux/bashcov)
7
- [![Gem Version](https://img.shields.io/gem/v/bashcov.svg)](https://rubygems.org/gems/bashcov)
6
+ [![Dependency Status](https://gemnasium.com/infertux/bashcov.png)](https://gemnasium.com/infertux/bashcov)
7
+ [![Maintainability](https://api.codeclimate.com/v1/badges/083fdbba795049cd5f06/maintainability)](https://codeclimate.com/github/infertux/bashcov/maintainability)
8
8
 
9
9
  **Code coverage for Bash**
10
10
 
data/bashcov.gemspec CHANGED
@@ -21,7 +21,7 @@ Gem::Specification.new do |gem|
21
21
  gem.executables = gem.files.grep(%r{\Abin/}).map { |f| File.basename(f) }
22
22
  gem.require_paths = ["lib"]
23
23
 
24
- gem.required_ruby_version = ">= 2.2.7"
24
+ gem.required_ruby_version = ">= 2.3.0"
25
25
 
26
26
  gem.add_dependency "simplecov", "~> 0.15"
27
27
 
data/bin/bashcov CHANGED
@@ -16,6 +16,6 @@ require "simplecov"
16
16
 
17
17
  SimpleCov.command_name Bashcov.fullname
18
18
  SimpleCov.root Bashcov.root_directory
19
- SimpleCov::Result.new(coverage).format!
19
+ SimpleCov.at_exit { SimpleCov::Result.new(coverage).format! }
20
20
 
21
21
  exit status.exitstatus
data/lib/bashcov.rb CHANGED
@@ -59,7 +59,13 @@ module Bashcov
59
59
  # @return [String] Program name including version for easy consistent output
60
60
  # @note +fullname+ instead of name to avoid clashing with +Module.name+
61
61
  def fullname
62
- "#{program_name} #{VERSION} (bash #{BASH_VERSION})"
62
+ [
63
+ program_name,
64
+ VERSION,
65
+ "(with Bash #{BASH_VERSION},",
66
+ "Ruby #{RUBY_VERSION},",
67
+ "and SimpleCov #{SimpleCov::VERSION})",
68
+ ].join(" ")
63
69
  end
64
70
 
65
71
  # Wipe the current options and reset default values
@@ -0,0 +1,79 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "set"
4
+
5
+ module Bashcov
6
+ # Detect shell scripts
7
+ class Detective
8
+ # [Set<String>] Basenames of shell executables
9
+ SHELL_BASENAMES = Set.new(%w[bash sh ash dash]).freeze
10
+
11
+ # [Set<String>] Basenames of executables commonly used to +exec+ other
12
+ # processes, including shells
13
+ OTHER_BASENAMES = Set.new(%w[env]).freeze
14
+
15
+ # [Set<String>] Filename extensions commonly used for shell scripts
16
+ SHELLSCRIPT_EXTENSIONS = Set.new(%w[.bash .sh]).freeze
17
+
18
+ # Create an object that can be used for inferring whether a file is or is
19
+ # not a shell script.
20
+ # @param [String] bash_path path to a Bash interpreter
21
+ def initialize(bash_path)
22
+ @bash_path = bash_path
23
+ end
24
+
25
+ # Checks whether the provided file refers to a shell script by
26
+ # determining whether the first line is a shebang that refers to a shell
27
+ # executable, or whether the file has a shellscript extension and contains
28
+ # valid shell syntax.
29
+ # @param [String,Pathname] filename the name of the file to be checked
30
+ # @return [Boolean] whether +filename+ refers to a shell script
31
+ # @note returns +false+ when +filename+ is not readable, even if +filename+
32
+ # indeed refers to a shell script.
33
+ def shellscript?(filename)
34
+ return false unless File.exist?(filename) && File.readable?(filename) \
35
+ && File.file?(File.realpath(filename))
36
+
37
+ shellscript_shebang?(filename) || \
38
+ (shellscript_extension?(filename) && shellscript_syntax?(filename))
39
+ end
40
+
41
+ private
42
+
43
+ # @param [String,Pathname] filename the name of the file to be checked
44
+ # @return [Boolean] whether +filename+'s first line is a valid shell
45
+ # shebang
46
+ # @note assumes that +filename+ is readable and refers to a regular file
47
+ def shellscript_shebang?(filename)
48
+ # Handle empty files that cause an immediate EOFError
49
+ begin
50
+ shebang = File.open(filename) { |f| f.readline.chomp }
51
+ rescue EOFError
52
+ return false
53
+ end
54
+
55
+ return false unless shebang[0..1] == "#!"
56
+
57
+ shell, arg = shebang[2..-1].split(/\s+/, 2)
58
+ shell_basename = File.basename(shell)
59
+
60
+ SHELL_BASENAMES.include?(shell_basename) || \
61
+ (OTHER_BASENAMES.include?(shell_basename) && SHELL_BASENAMES.include?(arg))
62
+ end
63
+
64
+ # @param [String,Pathname] filename the name of the file to be checked
65
+ # @return [Boolean] whether +filename+'s extension is a valid shellscript
66
+ # extension
67
+ def shellscript_extension?(filename)
68
+ SHELLSCRIPT_EXTENSIONS.include? File.extname(filename)
69
+ end
70
+
71
+ # @param [String,Pathname] filename the name of the file to be checked
72
+ # @return [Boolean] whether +filename+'s text matches valid shell syntax
73
+ # @note assumes that +filename+ is readable and refers to a regular file
74
+ def shellscript_syntax?(filename)
75
+ system(@bash_path, "-n", filename.to_s, in: :close, out: :close, err: :close)
76
+ $?.success?
77
+ end
78
+ end
79
+ end
@@ -34,9 +34,7 @@ module Bashcov
34
34
  # since the last match, yields empty strings until +field_count+ is
35
35
  # reached.
36
36
  def each(delimiter, field_count, start_match)
37
- unless block_given?
38
- return enum_for(__method__, delimiter, field_count, start_match)
39
- end
37
+ return enum_for(__method__, delimiter, field_count, start_match) unless block_given?
40
38
 
41
39
  # Whether the current field is the start-of-fields match
42
40
  matched_start = nil
data/lib/bashcov/lexer.rb CHANGED
@@ -22,9 +22,7 @@ module Bashcov
22
22
  @filename = filename
23
23
  @coverage = coverage
24
24
 
25
- unless File.file?(@filename) # rubocop:disable Style/GuardClause
26
- raise ArgumentError, "#{@filename} is not a file"
27
- end
25
+ raise ArgumentError, "#{@filename} is not a file" unless File.file?(@filename)
28
26
  end
29
27
 
30
28
  # Process and complete initial coverage.
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "bashcov/detective"
3
4
  require "bashcov/errors"
4
5
  require "bashcov/field_stream"
5
6
  require "bashcov/lexer"
@@ -11,6 +12,7 @@ module Bashcov
11
12
  # @param [String] command Command to run
12
13
  def initialize(command)
13
14
  @command = command
15
+ @detective = Detective.new(Bashcov.bash_path)
14
16
  end
15
17
 
16
18
  # Runs the command with appropriate xtrace settings.
@@ -74,8 +76,11 @@ module Bashcov
74
76
  private
75
77
 
76
78
  def write_warning(message)
77
- warn format "%s: warning: %s", Bashcov.program_name,
78
- message.gsub(/^\s+/, "").lines.map(&:chomp).join(" ")
79
+ warn [
80
+ Bashcov.program_name,
81
+ ": warning: ",
82
+ message.gsub(/^\s+/, "").lines.map(&:chomp).join(" "),
83
+ ].join
79
84
  end
80
85
 
81
86
  def run_xtrace(fd, env, options)
@@ -123,8 +128,10 @@ module Bashcov
123
128
  def find_bash_files!
124
129
  return if Bashcov.skip_uncovered
125
130
 
126
- Pathname.glob("#{Bashcov.root_directory}/**/*.sh").each do |filename|
127
- @coverage[filename] = [] unless @coverage.include?(filename)
131
+ Pathname.new(Bashcov.root_directory).find do |filename|
132
+ if !@coverage.include?(filename) && @detective.shellscript?(filename)
133
+ @coverage[filename] = []
134
+ end
128
135
  end
129
136
  end
130
137
 
@@ -3,5 +3,5 @@
3
3
  # :nodoc:
4
4
  module Bashcov
5
5
  # Current Bashcov version
6
- VERSION = "1.6.0".freeze
6
+ VERSION = "1.7.0"
7
7
  end
@@ -12,10 +12,10 @@ module Bashcov
12
12
  class Xtrace
13
13
  # [String] Character that will be used to indicate the nesting level of
14
14
  # +xtrace+d instructions
15
- DEPTH_CHAR = "+".freeze
15
+ DEPTH_CHAR = "+"
16
16
 
17
17
  # [String] Prefix used in +PS4+ to identify relevant output
18
- PREFIX = "BASHCOV>".freeze
18
+ PREFIX = "BASHCOV>"
19
19
 
20
20
  # [Array<String>] A collection of Bash internal variables to expand in the
21
21
  # {PS4}
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.6.0
4
+ version: 1.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cédric Félizard
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-10-24 00:00:00.000000000 Z
11
+ date: 2017-12-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: simplecov
@@ -127,6 +127,7 @@ files:
127
127
  - bin/bashcov
128
128
  - lib/bashcov.rb
129
129
  - lib/bashcov/bash_info.rb
130
+ - lib/bashcov/detective.rb
130
131
  - lib/bashcov/errors.rb
131
132
  - lib/bashcov/field_stream.rb
132
133
  - lib/bashcov/lexer.rb
@@ -146,7 +147,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
146
147
  requirements:
147
148
  - - ">="
148
149
  - !ruby/object:Gem::Version
149
- version: 2.2.7
150
+ version: 2.3.0
150
151
  required_rubygems_version: !ruby/object:Gem::Requirement
151
152
  requirements:
152
153
  - - ">="
@@ -154,7 +155,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
154
155
  version: '0'
155
156
  requirements: []
156
157
  rubyforge_project:
157
- rubygems_version: 2.6.13
158
+ rubygems_version: 2.6.14
158
159
  signing_key:
159
160
  specification_version: 4
160
161
  summary: Code coverage tool for Bash