bashcov 4.0.0 → 4.0.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/CHANGELOG.md +13 -1
- data/Gemfile.nix.lock +16 -16
- data/README.md +2 -1
- data/flake.nix +1 -1
- data/gemset.nix +23 -23
- data/lib/bashcov/lexer.rb +61 -45
- data/lib/bashcov/version.rb +1 -1
- metadata +10 -10
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f0747d5303e019390aac25da832f145d0fe434ca0990ce68b11124423f6cf1f7
|
|
4
|
+
data.tar.gz: daed283089aa39da826552a98178c59916e215e30552113ebf094103388cae5b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8e04f898757e9fd035eac7f5da81e5de7a93a2d492f3039a6c97c2b88610fcce1f86af7c3ddc734ae941f6cfcebe05361dfe442826f7dcf792d0d6cb9a88b542
|
|
7
|
+
data.tar.gz: 9446b060debec76ebb08765cb7c16b8c16bb1d17b50d85da3543631ab2c5c9c32671033bdfd9bd811cda0d735c454a2a2e803f30ad812aebb7ea253e7e8cc2d2
|
data/CHANGELOG.md
CHANGED
|
@@ -1,7 +1,19 @@
|
|
|
1
|
-
## Unreleased ([changes](https://github.com/infertux/bashcov/compare/v4.0.
|
|
1
|
+
## Unreleased ([changes](https://github.com/infertux/bashcov/compare/v4.0.1...master))
|
|
2
2
|
|
|
3
3
|
* TBD
|
|
4
4
|
|
|
5
|
+
## v4.0.1, 2026-10-26 ([changes](https://github.com/infertux/bashcov/compare/v4.0.0...v4.0.1))
|
|
6
|
+
|
|
7
|
+
* [BUGFIX] Fix coverage of multiline strings on Bash < 5.3 (fixes #108)
|
|
8
|
+
* [BUGFIX] Fix coverage of multiline strings opened after a line continuation
|
|
9
|
+
* [BUGFIX] Handle escaped characters in multiline double-quoted strings
|
|
10
|
+
* [BUGFIX] Stop heredoc matches at the first closing delimiter
|
|
11
|
+
* [BUGFIX] Only allow tab-indented heredoc delimiters after `<<-`
|
|
12
|
+
* [BUGFIX] Recognize heredoc delimiters quoted with double quotes or a backslash
|
|
13
|
+
* [MISC] Speed up lexer on files with multiline constructs
|
|
14
|
+
* [MISC] Make sure we use compatible cucumber and aruba releases
|
|
15
|
+
* [MISC] Add link to Buy Me a Coffee
|
|
16
|
+
|
|
5
17
|
## v4.0.0, 2026-08-25 ([changes](https://github.com/infertux/bashcov/compare/v3.3.0...v4.0.0))
|
|
6
18
|
|
|
7
19
|
* [BUGFIX] Fix build for Nix
|
data/Gemfile.nix.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
bashcov (4.0.
|
|
4
|
+
bashcov (4.0.1)
|
|
5
5
|
simplecov (~> 1.1)
|
|
6
6
|
|
|
7
7
|
GEM
|
|
@@ -17,7 +17,7 @@ GEM
|
|
|
17
17
|
ast (2.4.3)
|
|
18
18
|
base64 (0.3.0)
|
|
19
19
|
benchmark (0.5.0)
|
|
20
|
-
bigdecimal (4.1.
|
|
20
|
+
bigdecimal (4.1.3)
|
|
21
21
|
builder (3.3.0)
|
|
22
22
|
bundler-audit (0.9.3)
|
|
23
23
|
bundler (>= 1.2.0)
|
|
@@ -51,26 +51,26 @@ GEM
|
|
|
51
51
|
diff-lcs (1.6.2)
|
|
52
52
|
erb (6.0.7)
|
|
53
53
|
ffi (1.16.3)
|
|
54
|
-
io-console (0.9.
|
|
54
|
+
io-console (0.9.4)
|
|
55
55
|
irb (1.18.0)
|
|
56
56
|
pp (>= 0.6.0)
|
|
57
57
|
prism (>= 1.3.0)
|
|
58
58
|
rdoc (>= 4.0.0)
|
|
59
59
|
reline (>= 0.4.2)
|
|
60
|
-
json (
|
|
60
|
+
json (3.1.0)
|
|
61
61
|
language_server-protocol (3.17.0.6)
|
|
62
62
|
lint_roller (1.1.0)
|
|
63
63
|
logger (1.7.0)
|
|
64
64
|
memoist3 (1.0.0)
|
|
65
65
|
mini_mime (1.1.5)
|
|
66
66
|
multi_test (1.1.0)
|
|
67
|
-
parallel (2.
|
|
67
|
+
parallel (2.3.0)
|
|
68
68
|
parser (3.3.12.0)
|
|
69
69
|
ast (~> 2.4.1)
|
|
70
70
|
racc
|
|
71
71
|
pp (0.6.4)
|
|
72
72
|
prettyprint
|
|
73
|
-
prettyprint (0.2.
|
|
73
|
+
prettyprint (0.2.1)
|
|
74
74
|
prism (1.9.0)
|
|
75
75
|
racc (1.8.1)
|
|
76
76
|
rainbow (3.1.1)
|
|
@@ -79,12 +79,12 @@ GEM
|
|
|
79
79
|
logger
|
|
80
80
|
prism (>= 1.6.0)
|
|
81
81
|
tsort
|
|
82
|
-
rdoc (8.
|
|
82
|
+
rdoc (8.1.0)
|
|
83
83
|
erb
|
|
84
84
|
prism (>= 1.6.0)
|
|
85
85
|
rbs (>= 4.0.0)
|
|
86
86
|
tsort
|
|
87
|
-
regexp_parser (2.
|
|
87
|
+
regexp_parser (2.13.1)
|
|
88
88
|
reline (0.7.0)
|
|
89
89
|
io-console (~> 0.5)
|
|
90
90
|
rspec (3.13.2)
|
|
@@ -100,14 +100,14 @@ GEM
|
|
|
100
100
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
101
101
|
rspec-support (~> 3.13.0)
|
|
102
102
|
rspec-support (3.13.7)
|
|
103
|
-
rubocop (1.
|
|
103
|
+
rubocop (1.92.0)
|
|
104
104
|
json (>= 2.3)
|
|
105
105
|
language_server-protocol (~> 3.17.0.2)
|
|
106
106
|
lint_roller (~> 1.1.0)
|
|
107
107
|
parallel (>= 1.10)
|
|
108
108
|
parser (>= 3.3.0.2)
|
|
109
109
|
rainbow (>= 2.2.2, < 4.0)
|
|
110
|
-
regexp_parser (>= 2.
|
|
110
|
+
regexp_parser (>= 2.11.3, < 3.0)
|
|
111
111
|
rubocop-ast (>= 1.49.0, < 2.0)
|
|
112
112
|
ruby-progressbar (~> 1.7)
|
|
113
113
|
unicode-display_width (>= 2.4.0, < 4.0)
|
|
@@ -122,15 +122,15 @@ GEM
|
|
|
122
122
|
regexp_parser (>= 2.0)
|
|
123
123
|
rubocop (~> 1.86, >= 1.86.2)
|
|
124
124
|
ruby-progressbar (1.13.0)
|
|
125
|
-
simplecov (1.
|
|
125
|
+
simplecov (1.3.2)
|
|
126
126
|
sys-uname (1.5.1)
|
|
127
127
|
ffi (~> 1.1)
|
|
128
128
|
memoist3 (~> 1.0.0)
|
|
129
129
|
thor (1.5.0)
|
|
130
130
|
tsort (0.2.0)
|
|
131
|
-
unicode-display_width (3.
|
|
132
|
-
unicode-emoji (~> 4.
|
|
133
|
-
unicode-emoji (4.
|
|
131
|
+
unicode-display_width (3.3.0)
|
|
132
|
+
unicode-emoji (~> 4.3)
|
|
133
|
+
unicode-emoji (4.3.0)
|
|
134
134
|
yard (0.9.45)
|
|
135
135
|
|
|
136
136
|
PLATFORMS
|
|
@@ -147,11 +147,11 @@ PLATFORMS
|
|
|
147
147
|
x86_64-linux-musl
|
|
148
148
|
|
|
149
149
|
DEPENDENCIES
|
|
150
|
-
aruba
|
|
150
|
+
aruba (~> 2.4.1)
|
|
151
151
|
bashcov!
|
|
152
152
|
benchmark
|
|
153
153
|
bundler-audit
|
|
154
|
-
cucumber
|
|
154
|
+
cucumber (~> 11.1.1)
|
|
155
155
|
ffi (~> 1.16.0)
|
|
156
156
|
irb
|
|
157
157
|
rake
|
data/README.md
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
# Bashcov
|
|
2
2
|
|
|
3
|
+
[](https://buymeacoffee.com/infertux)
|
|
3
4
|
[](https://liberapay.com/infertux/donate)
|
|
4
5
|
[](https://rubygems.org/gems/bashcov)
|
|
5
6
|
[](https://github.com/infertux/bashcov/actions/workflows/ci.yml)
|
|
@@ -59,7 +60,7 @@ For development tips, see [the hacking guide](./HACKING.md).
|
|
|
59
60
|
|
|
60
61
|
## Sponsorship
|
|
61
62
|
|
|
62
|
-
Bashcov was [created in 2012](https://github.com/infertux/bashcov/commit/f65e65e5aa3377beb334beee9924136a34a913e8) and it needs your help. I have been maintaining the project for over a decade and keeping it working with new releases of Bash and Ruby takes time. If you use Bashcov professionally, please consider supporting it on [Liberapay](https://liberapay.com/infertux) through your employer or directly. Thank you for supporting *Free and Open-Source Software*.
|
|
63
|
+
Bashcov was [created in 2012](https://github.com/infertux/bashcov/commit/f65e65e5aa3377beb334beee9924136a34a913e8) and it needs your help. I have been maintaining the project for over a decade and keeping it working with new releases of Bash and Ruby takes time. If you use Bashcov professionally, please consider supporting it on [Buy Me a Coffee](https://buymeacoffee.com/infertux) or [Liberapay](https://liberapay.com/infertux) through your employer or directly. Thank you for supporting *Free and Open-Source Software*.
|
|
63
64
|
|
|
64
65
|
## License
|
|
65
66
|
|
data/flake.nix
CHANGED
|
@@ -206,7 +206,7 @@
|
|
|
206
206
|
pname = "bashcov";
|
|
207
207
|
gemdir = self;
|
|
208
208
|
lockfile = ./Gemfile.nix.lock;
|
|
209
|
-
version = "4.0.
|
|
209
|
+
version = "4.0.1";
|
|
210
210
|
postBuild = ''
|
|
211
211
|
for gem in $out/${ruby.gemPath}/bundler/gems/*; do
|
|
212
212
|
ln -sfrT "$gem" $out/${ruby.gemPath}/gems/"''${gem##*/}"
|
data/gemset.nix
CHANGED
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
path = ./.;
|
|
39
39
|
type = "path";
|
|
40
40
|
};
|
|
41
|
-
version = "4.0.
|
|
41
|
+
version = "4.0.1";
|
|
42
42
|
};
|
|
43
43
|
benchmark = {
|
|
44
44
|
groups = ["development"];
|
|
@@ -55,10 +55,10 @@
|
|
|
55
55
|
platforms = [];
|
|
56
56
|
source = {
|
|
57
57
|
remotes = ["https://rubygems.org"];
|
|
58
|
-
sha256 = "
|
|
58
|
+
sha256 = "0rng45p4vc3f6nac44cnylwch7rj4zsff3icdz6c7garwpjy3sv1";
|
|
59
59
|
type = "gem";
|
|
60
60
|
};
|
|
61
|
-
version = "4.1.
|
|
61
|
+
version = "4.1.3";
|
|
62
62
|
};
|
|
63
63
|
builder = {
|
|
64
64
|
groups = ["default" "development"];
|
|
@@ -211,10 +211,10 @@
|
|
|
211
211
|
platforms = [];
|
|
212
212
|
source = {
|
|
213
213
|
remotes = ["https://rubygems.org"];
|
|
214
|
-
sha256 = "
|
|
214
|
+
sha256 = "1cgvhm0d4awr8j42b8v1nl1jfgx45ihv8mylargfi3lj697k00x4";
|
|
215
215
|
type = "gem";
|
|
216
216
|
};
|
|
217
|
-
version = "0.9.
|
|
217
|
+
version = "0.9.4";
|
|
218
218
|
};
|
|
219
219
|
irb = {
|
|
220
220
|
dependencies = ["pp" "prism" "rdoc" "reline"];
|
|
@@ -232,10 +232,10 @@
|
|
|
232
232
|
platforms = [];
|
|
233
233
|
source = {
|
|
234
234
|
remotes = ["https://rubygems.org"];
|
|
235
|
-
sha256 = "
|
|
235
|
+
sha256 = "1n1v9rhb19cnf1a89s6yvvhw394jy8qnqx9sg8bn12g5zpwcrrrw";
|
|
236
236
|
type = "gem";
|
|
237
237
|
};
|
|
238
|
-
version = "
|
|
238
|
+
version = "3.1.0";
|
|
239
239
|
};
|
|
240
240
|
language_server-protocol = {
|
|
241
241
|
groups = ["default" "development"];
|
|
@@ -302,10 +302,10 @@
|
|
|
302
302
|
platforms = [];
|
|
303
303
|
source = {
|
|
304
304
|
remotes = ["https://rubygems.org"];
|
|
305
|
-
sha256 = "
|
|
305
|
+
sha256 = "0vvs2sar7wnw70j1jc1kv1k23m5grc0ci3bbrcf6mkh18683wnpp";
|
|
306
306
|
type = "gem";
|
|
307
307
|
};
|
|
308
|
-
version = "2.
|
|
308
|
+
version = "2.3.0";
|
|
309
309
|
};
|
|
310
310
|
parser = {
|
|
311
311
|
dependencies = ["ast" "racc"];
|
|
@@ -334,10 +334,10 @@
|
|
|
334
334
|
platforms = [];
|
|
335
335
|
source = {
|
|
336
336
|
remotes = ["https://rubygems.org"];
|
|
337
|
-
sha256 = "
|
|
337
|
+
sha256 = "1m5pqkp8rdk0bkxxz3bp3vn8pn3bd9a97dkl8wfh1kyplrzdamfm";
|
|
338
338
|
type = "gem";
|
|
339
339
|
};
|
|
340
|
-
version = "0.2.
|
|
340
|
+
version = "0.2.1";
|
|
341
341
|
};
|
|
342
342
|
prism = {
|
|
343
343
|
groups = ["default" "development"];
|
|
@@ -396,20 +396,20 @@
|
|
|
396
396
|
platforms = [];
|
|
397
397
|
source = {
|
|
398
398
|
remotes = ["https://rubygems.org"];
|
|
399
|
-
sha256 = "
|
|
399
|
+
sha256 = "02pn63i2r5z44hcfhxbaag9rvqsyznsliivnn7f3dzaw1a43gz5y";
|
|
400
400
|
type = "gem";
|
|
401
401
|
};
|
|
402
|
-
version = "8.
|
|
402
|
+
version = "8.1.0";
|
|
403
403
|
};
|
|
404
404
|
regexp_parser = {
|
|
405
405
|
groups = ["default" "development"];
|
|
406
406
|
platforms = [];
|
|
407
407
|
source = {
|
|
408
408
|
remotes = ["https://rubygems.org"];
|
|
409
|
-
sha256 = "
|
|
409
|
+
sha256 = "0jxl6c5cagjz5i5n9jplhdy2izad6wapmwgfhqggb22nqfvvdvas";
|
|
410
410
|
type = "gem";
|
|
411
411
|
};
|
|
412
|
-
version = "2.
|
|
412
|
+
version = "2.13.1";
|
|
413
413
|
};
|
|
414
414
|
reline = {
|
|
415
415
|
dependencies = ["io-console"];
|
|
@@ -482,10 +482,10 @@
|
|
|
482
482
|
platforms = [];
|
|
483
483
|
source = {
|
|
484
484
|
remotes = ["https://rubygems.org"];
|
|
485
|
-
sha256 = "
|
|
485
|
+
sha256 = "1q2nih91fjbv6j1qqxfhlc480zyhz94rniyh469vsw1fzd0q1xia";
|
|
486
486
|
type = "gem";
|
|
487
487
|
};
|
|
488
|
-
version = "1.
|
|
488
|
+
version = "1.92.0";
|
|
489
489
|
};
|
|
490
490
|
rubocop-ast = {
|
|
491
491
|
dependencies = ["parser" "prism"];
|
|
@@ -535,10 +535,10 @@
|
|
|
535
535
|
platforms = [];
|
|
536
536
|
source = {
|
|
537
537
|
remotes = ["https://rubygems.org"];
|
|
538
|
-
sha256 = "
|
|
538
|
+
sha256 = "118fdpg7h1ny1fz6kmiyz6gccvwmb23h6bhsi1hdpf7ib4byq8ia";
|
|
539
539
|
type = "gem";
|
|
540
540
|
};
|
|
541
|
-
version = "1.
|
|
541
|
+
version = "1.3.2";
|
|
542
542
|
};
|
|
543
543
|
sys-uname = {
|
|
544
544
|
dependencies = ["ffi" "memoist3"];
|
|
@@ -577,20 +577,20 @@
|
|
|
577
577
|
platforms = [];
|
|
578
578
|
source = {
|
|
579
579
|
remotes = ["https://rubygems.org"];
|
|
580
|
-
sha256 = "
|
|
580
|
+
sha256 = "04xnl0zwpjjvxipd6rdnxkm11pfhbhhi3179yzv51nqi9dmacyjb";
|
|
581
581
|
type = "gem";
|
|
582
582
|
};
|
|
583
|
-
version = "3.
|
|
583
|
+
version = "3.3.0";
|
|
584
584
|
};
|
|
585
585
|
unicode-emoji = {
|
|
586
586
|
groups = ["default" "development"];
|
|
587
587
|
platforms = [];
|
|
588
588
|
source = {
|
|
589
589
|
remotes = ["https://rubygems.org"];
|
|
590
|
-
sha256 = "
|
|
590
|
+
sha256 = "1kp89lja8ii7l6f0bq5vdxq1p3kxr3a2qmmhdc38qdwh6akjzh0i";
|
|
591
591
|
type = "gem";
|
|
592
592
|
};
|
|
593
|
-
version = "4.
|
|
593
|
+
version = "4.3.0";
|
|
594
594
|
};
|
|
595
595
|
yard = {
|
|
596
596
|
groups = ["development"];
|
data/lib/bashcov/lexer.rb
CHANGED
|
@@ -15,6 +15,34 @@ module Bashcov
|
|
|
15
15
|
# Lines containing only one of these keywords are irrelevant for coverage
|
|
16
16
|
IGNORE_IS = %w[esac if then else elif fi while do done { } ;; ( )].freeze
|
|
17
17
|
|
|
18
|
+
# Constructs spanning multiple lines, as +[regexp, forward]+ pairs tried in
|
|
19
|
+
# order. Regexps are anchored with +\G+ to match from a given line offset.
|
|
20
|
+
MULTILINE_PATTERNS = [
|
|
21
|
+
# multi-line arrays
|
|
22
|
+
[/\G[^\n]*\b=\([^()]*\)/, false],
|
|
23
|
+
|
|
24
|
+
# heredoc, possibly with a quoted delimiter (e.g. 'EOF', "EOF" or \EOF) -
|
|
25
|
+
# ends at the first line holding only the delimiter, which `<<-` also
|
|
26
|
+
# allows to be indented with tabs
|
|
27
|
+
[/\G[^\n]+<<[ \t]*\\?['"]?(\w+)['"]?[^\n]*\n(?:[^\n]*\n)*?\1$/, true],
|
|
28
|
+
[/\G[^\n]+<<-[ \t]*\\?['"]?(\w+)['"]?[^\n]*\n(?:[^\n]*\n)*?\t*\1$/, true],
|
|
29
|
+
|
|
30
|
+
# multiline string concatenated with backslashes
|
|
31
|
+
[/\G[^\n]+\\$(\s*['"][^'"]*['"]\s*\\$){1,}\s*['"][^'"]*['"]\s*$/, true],
|
|
32
|
+
|
|
33
|
+
# multiline string concatenated with newlines, possibly opened after a
|
|
34
|
+
# line continuation (but never after an unescaped newline) - this must
|
|
35
|
+
# come before simple line continuations which would claim the opening
|
|
36
|
+
# line otherwise - unlike single quotes, double quotes may contain escaped
|
|
37
|
+
# characters such as \"
|
|
38
|
+
*[false, true].product([["'", /[^']*/], ['"', /(?:[^"\\]|\\.)*/m]]).map do |forward, (char, body)|
|
|
39
|
+
[/\G[^\n]+(?:[ \t=]|\\\n[ \t]*)+#{char}#{body}#{char}/m, forward]
|
|
40
|
+
end,
|
|
41
|
+
|
|
42
|
+
# simple line continuations with backslashes
|
|
43
|
+
[/\G([^\n&|;]*[^\\&|;](\\\\)*\\\n)+[^\n&|;]*[^\n\\&|;](\\\\)*$/, true],
|
|
44
|
+
].freeze
|
|
45
|
+
|
|
18
46
|
# @param [String] filename File to analyze
|
|
19
47
|
# @param [Hash] coverage Coverage with executed lines marked
|
|
20
48
|
# @raise [ArgumentError] if the given +filename+ is invalid.
|
|
@@ -28,60 +56,46 @@ module Bashcov
|
|
|
28
56
|
# Process and complete initial coverage.
|
|
29
57
|
# @return [void]
|
|
30
58
|
def complete_coverage
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
lines.
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
)
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
mark_multiline(
|
|
43
|
-
lines, lineno,
|
|
44
|
-
/\A[^\n]+<<-?\s*'?(\w+)'?.*$.*\1/m,
|
|
45
|
-
)
|
|
46
|
-
|
|
47
|
-
# multiline string concatenated with backslashes
|
|
48
|
-
mark_multiline(
|
|
49
|
-
lines, lineno,
|
|
50
|
-
/\A[^\n]+\\$(\s*['"][^'"]*['"]\s*\\$){1,}\s*['"][^'"]*['"]\s*$/,
|
|
51
|
-
)
|
|
52
|
-
|
|
53
|
-
# simple line continuations with backslashes
|
|
54
|
-
mark_multiline(
|
|
55
|
-
lines, lineno,
|
|
56
|
-
/\A([^\n&|;]*[^\\&|;](\\\\)*\\\n)+[^\n&|;]*[^\n\\&|;](\\\\)*$/,
|
|
57
|
-
)
|
|
58
|
-
|
|
59
|
-
# multiline string concatenated with newlines
|
|
60
|
-
[false, true].each do |direction|
|
|
61
|
-
%w[' "].each do |char|
|
|
62
|
-
mark_multiline(
|
|
63
|
-
lines, lineno,
|
|
64
|
-
/\A[^\n]+[\s=]+#{char}[^#{char}]*#{char}/m,
|
|
65
|
-
forward: direction,
|
|
66
|
-
)
|
|
67
|
-
end
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
mark_line(line, lineno)
|
|
59
|
+
content = File.read(@filename).encode("utf-8", invalid: :replace)
|
|
60
|
+
lines = content.lines
|
|
61
|
+
offsets = lines.each_with_object([0]) { |line, memo| memo << (memo.last + line.size) }
|
|
62
|
+
|
|
63
|
+
lineno = 0
|
|
64
|
+
while lineno < lines.size
|
|
65
|
+
# skip ahead past a multiline construct once its lines are marked, but
|
|
66
|
+
# recheck its last line as it may open another one, e.g. `a'; b='`
|
|
67
|
+
last = mark_multilines(content, offsets[lineno], lineno) || lineno
|
|
68
|
+
lineno.upto(last) { |sub_lineno| mark_line(lines[sub_lineno], sub_lineno) }
|
|
69
|
+
lineno = (last > lineno ? last : last + 1)
|
|
71
70
|
end
|
|
72
71
|
end
|
|
73
72
|
|
|
74
73
|
private
|
|
75
74
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
75
|
+
# @return [Integer, nil] last line of the multiline construct starting at
|
|
76
|
+
# +lineno+, if any
|
|
77
|
+
def mark_multilines(content, offset, lineno)
|
|
78
|
+
MULTILINE_PATTERNS.each do |regexp, forward|
|
|
79
|
+
last = mark_multiline(content, offset, lineno, regexp, forward: forward)
|
|
80
|
+
return last if last
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
nil
|
|
84
|
+
end
|
|
79
85
|
|
|
80
|
-
|
|
81
|
-
|
|
86
|
+
def mark_multiline(content, offset, lineno, regexp, forward: true)
|
|
87
|
+
# +regexp+ is anchored with \G so it only matches from +offset+
|
|
88
|
+
return unless (multiline_match = content.match(regexp, offset))
|
|
82
89
|
|
|
83
90
|
length = multiline_match.to_s.count($/)
|
|
84
91
|
first, last = lineno + 1, lineno + length
|
|
92
|
+
|
|
93
|
+
# skip if we are already inside marked multiline string - only inner
|
|
94
|
+
# lines are checked since Bash may report the hit on the last line
|
|
95
|
+
# (e.g. `readonly` before Bash 5.3), which is also the next line when
|
|
96
|
+
# the string spans only two lines
|
|
97
|
+
return unless first.upto(last - 1).all? { |i| @coverage[i].nil? }
|
|
98
|
+
|
|
85
99
|
range = (forward ? first.upto(last) : (last - 1).downto(first - 1))
|
|
86
100
|
reference_lineno = (forward ? first - 1 : last)
|
|
87
101
|
|
|
@@ -92,6 +106,8 @@ module Bashcov
|
|
|
92
106
|
# mark related lines with the same coverage as the reference line
|
|
93
107
|
@coverage[sub_lineno] ||= @coverage[reference_lineno]
|
|
94
108
|
end
|
|
109
|
+
|
|
110
|
+
last if length.positive?
|
|
95
111
|
end
|
|
96
112
|
|
|
97
113
|
def mark_line(line, lineno)
|
data/lib/bashcov/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: bashcov
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 4.0.
|
|
4
|
+
version: 4.0.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Cédric Félizard
|
|
@@ -27,16 +27,16 @@ dependencies:
|
|
|
27
27
|
name: aruba
|
|
28
28
|
requirement: !ruby/object:Gem::Requirement
|
|
29
29
|
requirements:
|
|
30
|
-
- - "
|
|
30
|
+
- - "~>"
|
|
31
31
|
- !ruby/object:Gem::Version
|
|
32
|
-
version:
|
|
32
|
+
version: 2.4.1
|
|
33
33
|
type: :development
|
|
34
34
|
prerelease: false
|
|
35
35
|
version_requirements: !ruby/object:Gem::Requirement
|
|
36
36
|
requirements:
|
|
37
|
-
- - "
|
|
37
|
+
- - "~>"
|
|
38
38
|
- !ruby/object:Gem::Version
|
|
39
|
-
version:
|
|
39
|
+
version: 2.4.1
|
|
40
40
|
- !ruby/object:Gem::Dependency
|
|
41
41
|
name: benchmark
|
|
42
42
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -69,16 +69,16 @@ dependencies:
|
|
|
69
69
|
name: cucumber
|
|
70
70
|
requirement: !ruby/object:Gem::Requirement
|
|
71
71
|
requirements:
|
|
72
|
-
- - "
|
|
72
|
+
- - "~>"
|
|
73
73
|
- !ruby/object:Gem::Version
|
|
74
|
-
version:
|
|
74
|
+
version: 11.1.1
|
|
75
75
|
type: :development
|
|
76
76
|
prerelease: false
|
|
77
77
|
version_requirements: !ruby/object:Gem::Requirement
|
|
78
78
|
requirements:
|
|
79
|
-
- - "
|
|
79
|
+
- - "~>"
|
|
80
80
|
- !ruby/object:Gem::Version
|
|
81
|
-
version:
|
|
81
|
+
version: 11.1.1
|
|
82
82
|
- !ruby/object:Gem::Dependency
|
|
83
83
|
name: ffi
|
|
84
84
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -268,7 +268,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
268
268
|
- !ruby/object:Gem::Version
|
|
269
269
|
version: '0'
|
|
270
270
|
requirements: []
|
|
271
|
-
rubygems_version: 4.0.
|
|
271
|
+
rubygems_version: 4.0.22
|
|
272
272
|
specification_version: 4
|
|
273
273
|
summary: Code coverage tool for Bash
|
|
274
274
|
test_files: []
|