markdown_exec 1.7 → 1.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +5 -2
- data/Gemfile.lock +1 -1
- data/Rakefile +1 -0
- data/bin/tab_completion.sh +19 -3
- data/examples/colors.md +48 -0
- data/examples/include.md +11 -4
- data/examples/opts.md +7 -0
- data/lib/ansi_formatter.rb +161 -0
- data/lib/directory_searcher.rb +239 -0
- data/lib/env.rb +1 -2
- data/lib/hash_delegator.rb +138 -51
- data/lib/markdown_exec/version.rb +1 -1
- data/lib/markdown_exec.rb +66 -29
- data/lib/mdoc.rb +148 -33
- data/lib/menu.src.yml +94 -17
- data/lib/menu.yml +86 -18
- data/lib/option_value.rb +2 -4
- data/lib/regexp.rb +1 -2
- data/lib/saved_assets.rb +2 -4
- data/lib/saved_files_matcher.rb +3 -7
- data/lib/tap.rb +2 -5
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c4fdb41b414911d16030ffbfb8c4b07ca8c09e3684f21e123d0d99cd738dba3d
|
4
|
+
data.tar.gz: 70c1ec9fb9b795d0cbdcc87ceb03809a57af5901a70dc2b1d319c9451592d687
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: abea63db83a4d785bce7c2ec1c9babebe6d78637872a068c4d6b2169832de8ea707a2c3ae426f6cd5ea548269194a797d95abdd7fceb286c4efa49da9d591bfe
|
7
|
+
data.tar.gz: 1b102cb3e898789d6ddf2a401f90cfee04403ea135a14a5067673b250855aef569ca3b39a171570930ef5946d52874d022fb19fd9cf7c1561737144aefc5ef3c
|
data/.rubocop.yml
CHANGED
@@ -14,9 +14,9 @@ Layout/LineContinuationLeadingSpace:
|
|
14
14
|
Enabled: false
|
15
15
|
|
16
16
|
Layout/LineLength:
|
17
|
-
Max: 78
|
17
|
+
# Max: 78
|
18
18
|
# Max: 80
|
19
|
-
|
19
|
+
Max: 96
|
20
20
|
|
21
21
|
Lint/Debugger:
|
22
22
|
Enabled: false
|
@@ -72,6 +72,9 @@ Style/FormatStringToken:
|
|
72
72
|
Style/GlobalVars:
|
73
73
|
Enabled: false
|
74
74
|
|
75
|
+
Style/Lambda:
|
76
|
+
Enabled: false
|
77
|
+
|
75
78
|
Style/MixinUsage:
|
76
79
|
Enabled: false
|
77
80
|
|
data/Gemfile.lock
CHANGED
data/Rakefile
CHANGED
data/bin/tab_completion.sh
CHANGED
@@ -13,7 +13,7 @@ __filedirs_all()
|
|
13
13
|
}
|
14
14
|
|
15
15
|
_mde_echo_version() {
|
16
|
-
echo "1.
|
16
|
+
echo "1.8"
|
17
17
|
}
|
18
18
|
|
19
19
|
_mde() {
|
@@ -40,6 +40,14 @@ _mde() {
|
|
40
40
|
|
41
41
|
-f) COMPREPLY="."; return 0 ;;
|
42
42
|
|
43
|
+
--find) COMPREPLY="''"; return 0 ;;
|
44
|
+
|
45
|
+
-?) COMPREPLY="''"; return 0 ;;
|
46
|
+
|
47
|
+
--how) COMPREPLY="''"; return 0 ;;
|
48
|
+
|
49
|
+
-?) COMPREPLY="''"; return 0 ;;
|
50
|
+
|
43
51
|
--list-count) COMPREPLY="32"; return 0 ;;
|
44
52
|
|
45
53
|
--output-execution-summary) COMPREPLY="0"; return 0 ;;
|
@@ -74,7 +82,7 @@ _mde() {
|
|
74
82
|
# present matching option names
|
75
83
|
#
|
76
84
|
if [[ ${cur} == -* ]] ; then
|
77
|
-
opts=("--block-name" "--config" "--debug" "--exit" "--filename" "--help" "--list-blocks" "--list-count" "--list-default-env" "--list-default-yaml" "--list-docs" "--list-recent-output" "--list-recent-scripts" "--output-execution-summary" "--output-script" "--output-stdout" "--path" "--pwd" "--run-last-script" "--save-executed-script" "--save-execution-output" "--saved-script-folder" "--saved-stdout-folder" "--select-recent-output" "--select-recent-script" "--tab-completions" "--user-must-approve" "--version" "--display-level")
|
85
|
+
opts=("--block-name" "--config" "--debug" "--exit" "--filename" "--find" "--help" "--how" "--list-blocks" "--list-count" "--list-default-env" "--list-default-yaml" "--list-docs" "--list-recent-output" "--list-recent-scripts" "--output-execution-summary" "--output-script" "--output-stdout" "--path" "--pwd" "--run-last-script" "--save-executed-script" "--save-execution-output" "--saved-script-folder" "--saved-stdout-folder" "--select-recent-output" "--select-recent-script" "--tab-completions" "--user-must-approve" "--version" "--display-level")
|
78
86
|
COMPREPLY=( $(compgen -W "$(printf "'%s' " "${opts[@]}")" -- "${cur}") )
|
79
87
|
|
80
88
|
return 0
|
@@ -101,6 +109,14 @@ _mde() {
|
|
101
109
|
|
102
110
|
-f) COMPREPLY=".RELATIVE_PATH."; return 0 ;;
|
103
111
|
|
112
|
+
--find) COMPREPLY=".FIND."; return 0 ;;
|
113
|
+
|
114
|
+
-?) COMPREPLY=".FIND."; return 0 ;;
|
115
|
+
|
116
|
+
--how) COMPREPLY=".HOW."; return 0 ;;
|
117
|
+
|
118
|
+
-?) COMPREPLY=".HOW."; return 0 ;;
|
119
|
+
|
104
120
|
--list-count) COMPREPLY=".INT.1-."; return 0 ;;
|
105
121
|
|
106
122
|
--output-execution-summary) COMPREPLY=".BOOL."; return 0 ;;
|
@@ -138,4 +154,4 @@ _mde() {
|
|
138
154
|
|
139
155
|
complete -o filenames -o nospace -F _mde mde
|
140
156
|
# _mde_echo_version
|
141
|
-
# echo "Updated: 2023-12-
|
157
|
+
# echo "Updated: 2023-12-11 19:58:50 UTC"
|
data/examples/colors.md
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
# Demo configuring options
|
2
|
+
|
3
|
+
::: These Opts blocks set the color for all elements.
|
4
|
+
|
5
|
+
```opts :(document_options)
|
6
|
+
```
|
7
|
+
```opts :(default)
|
8
|
+
exception_color_detail: fg_rgbh_E0_E0_20 # Color of exception detail
|
9
|
+
exception_color_name: fg_rgbh_E0_20_20 # Color of exception name
|
10
|
+
execution_report_preview_frame_color: fg_rgbh_20_80_80 # execution_report_preview_frame_color
|
11
|
+
menu_bash_color: fg_rgbh_40_C0_F0 # Color of menu bash
|
12
|
+
menu_chrome_color: fg_rgbh_80_80_20 # Color of menu chrome
|
13
|
+
menu_divider_color: fg_rgbh_20_98_80 # Color of menu divider
|
14
|
+
menu_link_color: fg_rgbh_20_E0_20 # Color of menu link
|
15
|
+
menu_note_color: fg_rgbh_40_A0_A0 # Color of menu note
|
16
|
+
menu_opts_color: fg_rgbh_E0_60_E0 # Color of menu opts
|
17
|
+
menu_opts_set_color: fg_rgbh_E0_20_20 # Color of menu opts
|
18
|
+
menu_task_color: fg_rgbh_A0_20_D0 # Color of menu task
|
19
|
+
menu_vars_color: fg_rgbh_E0_80_20 # Color of menu vars
|
20
|
+
menu_vars_set_color: fg_rgbh_E0_80_20 # Color of menu vars
|
21
|
+
output_execution_label_name_color: fg_rgbh_20_D8_80 # Color of output_execution_label_name
|
22
|
+
output_execution_label_value_color: fg_rgbh_20_E0_80 # Color of output_execution_label_value
|
23
|
+
prompt_color_after_script_execution: fg_rgbh_20_E8_80 # Color of prompt after script execution
|
24
|
+
script_execution_frame_color: fg_rgbh_20_80_80 # script_execution_frame_color
|
25
|
+
script_preview_frame_color: fg_rgbh_20_80_80 # Color of output divider
|
26
|
+
warning_color: fg_rgbh_E0_E0_20 # Color of warning message
|
27
|
+
```
|
28
|
+
|
29
|
+
::: Example blocks
|
30
|
+
|
31
|
+
```bash :Bash1
|
32
|
+
```
|
33
|
+
```link :Link1
|
34
|
+
```
|
35
|
+
```opts :Opts1
|
36
|
+
```
|
37
|
+
```port :Port1
|
38
|
+
```
|
39
|
+
```vars :Vars1
|
40
|
+
```
|
41
|
+
[ ] Task1
|
42
|
+
blue; fg_rgbh_00_00_FF
|
43
|
+
green; fg_rgbh_00_FF_00
|
44
|
+
indigo; fg_rgbh_4B_00_82
|
45
|
+
orange; fg_rgbh_FF_7F_00
|
46
|
+
red; fg_rgbh_FF_00_00
|
47
|
+
violet; fg_rgbh_94_00_D3
|
48
|
+
yellow; fg_rgbh_FF_FF_00
|
data/examples/include.md
CHANGED
@@ -1,12 +1,19 @@
|
|
1
1
|
```bash :(one)
|
2
|
-
|
2
|
+
echo block "one"
|
3
3
|
```
|
4
|
+
|
4
5
|
```bash :two +(one)
|
5
|
-
|
6
|
+
echo block "two" requires one
|
6
7
|
```
|
8
|
+
|
7
9
|
```bash :(three) +two +(one)
|
8
|
-
|
10
|
+
echo block "three" requires two and one
|
9
11
|
```
|
12
|
+
|
10
13
|
```bash :four +(three)
|
11
|
-
|
14
|
+
echo block "four" requires three
|
15
|
+
```
|
16
|
+
|
17
|
+
```bash :trigger_unmet_dependency +(unmet)
|
18
|
+
echo block "five" requires an unmet dependency
|
12
19
|
```
|
data/examples/opts.md
CHANGED
@@ -19,4 +19,11 @@ menu_task_color: fg_rgb_127_127_255
|
|
19
19
|
menu_divider_color: green
|
20
20
|
menu_link_color: fg_rgbh_88_cc_66
|
21
21
|
menu_note_color: yellow
|
22
|
+
|
23
|
+
menu_note_match: "^\\s*(?<line>[^\\s/].*)\\s*$" # Pattern for notes in block selection menu; start with any char except '/'
|
22
24
|
```
|
25
|
+
|
26
|
+
note 1
|
27
|
+
note 2 ends with /
|
28
|
+
/ note 3 starts with /
|
29
|
+
note 4
|
@@ -0,0 +1,161 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# encoding=utf-8
|
5
|
+
|
6
|
+
class AnsiFormatter
|
7
|
+
def initialize(options = {})
|
8
|
+
@options = options
|
9
|
+
end
|
10
|
+
|
11
|
+
def format_and_highlight_array(
|
12
|
+
data,
|
13
|
+
highlight_color_sym: :exception_color_detail,
|
14
|
+
plain_color_sym: :menu_chrome_color,
|
15
|
+
label: 'Data:',
|
16
|
+
highlight: [],
|
17
|
+
line_prefix: ' ',
|
18
|
+
line_postfix: '',
|
19
|
+
detail_sep: ''
|
20
|
+
)
|
21
|
+
(data&.map do |item|
|
22
|
+
scan_and_process_multiple_substrings(item, highlight, plain_color_sym,
|
23
|
+
highlight_color_sym).join
|
24
|
+
# color_sym = highlight.include?(item) ? highlight_color_sym : c
|
25
|
+
# string_send_color(item, color_sym)
|
26
|
+
end || []) #.join
|
27
|
+
# formatted_deps
|
28
|
+
# "#{line_prefix}#{string_send_color(label, highlight_color_sym)}#{line_postfix}\n" + formatted_deps.join("\n")
|
29
|
+
end
|
30
|
+
|
31
|
+
# Formats and highlights a list of data. data are presented with indentation,
|
32
|
+
# and specific items can be highlighted in a specified color, while others are shown in a plain color.
|
33
|
+
#
|
34
|
+
# @param data [Hash] A hash of data, where each key is a dependency name,
|
35
|
+
# and its value is an array of sub-items.
|
36
|
+
# @param highlight_color_sym [Symbol] The color method to apply to highlighted items.
|
37
|
+
# Default is :exception_color_detail.
|
38
|
+
# @param plain_color_sym [Symbol] The color method for non-highlighted items.
|
39
|
+
# Default is :menu_chrome_color.
|
40
|
+
# @param label [String] The label to prefix the list of data with.
|
41
|
+
# Default is 'data:'.
|
42
|
+
# @param highlight [Array] An array of items to highlight. Each item in this array will be
|
43
|
+
# formatted with the specified highlight color.
|
44
|
+
# @param line_prefix [String] Prefix for each line. Default is ' '.
|
45
|
+
# @param line_postfix [String] Postfix for each line. Default is ''.
|
46
|
+
# @param detail_sep [String] Separator for items in the sub-list. Default is ' '.
|
47
|
+
# @return [String] A formatted string representation of the data with highlighted items.
|
48
|
+
def format_and_highlight_hash(
|
49
|
+
data,
|
50
|
+
highlight_color_sym: :exception_color_detail,
|
51
|
+
plain_color_sym: :menu_chrome_color,
|
52
|
+
label: 'Data:',
|
53
|
+
highlight: [],
|
54
|
+
line_prefix: ' ',
|
55
|
+
line_postfix: '',
|
56
|
+
detail_sep: ' '
|
57
|
+
)
|
58
|
+
formatted_deps = data&.map do |dep_name, sub_items|
|
59
|
+
formatted_sub_items = sub_items.map do |item|
|
60
|
+
color_sym = highlight.include?(item) ? highlight_color_sym : plain_color_sym
|
61
|
+
string_send_color(item, color_sym)
|
62
|
+
end.join(detail_sep)
|
63
|
+
|
64
|
+
"#{line_prefix}- #{string_send_color(dep_name,
|
65
|
+
highlight.include?(dep_name) ? highlight_color_sym : plain_color_sym)}: #{formatted_sub_items}#{line_postfix}"
|
66
|
+
end || []
|
67
|
+
|
68
|
+
"#{line_prefix}#{string_send_color(label,
|
69
|
+
highlight_color_sym)}#{line_postfix}\n" + formatted_deps.join("\n")
|
70
|
+
end
|
71
|
+
|
72
|
+
# Function to scan a string and process its segments based on multiple substrings
|
73
|
+
# @param str [String] The string to scan.
|
74
|
+
# @param substrings [Array<String>] The substrings to match in the string.
|
75
|
+
# @param plain_sym [Symbol] The symbol for non-matching segments.
|
76
|
+
# @param color_sym [Symbol] The symbol for matching segments.
|
77
|
+
# @return [Array<String>] The processed segments.
|
78
|
+
def scan_and_process_multiple_substrings(str, substrings, plain_sym, color_sym)
|
79
|
+
return string_send_color(str, plain_sym) if substrings.empty? || substrings.any?(&:empty?)
|
80
|
+
|
81
|
+
results = []
|
82
|
+
remaining_str = str.dup
|
83
|
+
|
84
|
+
while remaining_str.length.positive?
|
85
|
+
match_indices = substrings.map { |substring| remaining_str.index(substring) }.compact
|
86
|
+
earliest_match = match_indices.min
|
87
|
+
|
88
|
+
if earliest_match
|
89
|
+
# Process non-matching segment before the earliest match, if any
|
90
|
+
unless earliest_match.zero?
|
91
|
+
non_matching_segment = remaining_str.slice!(0...earliest_match)
|
92
|
+
results << string_send_color(non_matching_segment, plain_sym)
|
93
|
+
end
|
94
|
+
|
95
|
+
# Find which substring has this earliest match
|
96
|
+
matching_substring = substrings.find do |substring|
|
97
|
+
remaining_str.index(substring) == earliest_match
|
98
|
+
end
|
99
|
+
|
100
|
+
if matching_substring
|
101
|
+
matching_segment = remaining_str.slice!(0...matching_substring.length)
|
102
|
+
results << string_send_color(matching_segment, color_sym)
|
103
|
+
end
|
104
|
+
else
|
105
|
+
# Process the remaining non-matching segment
|
106
|
+
results << string_send_color(remaining_str, plain_sym)
|
107
|
+
break
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
results
|
112
|
+
end
|
113
|
+
|
114
|
+
# Function to scan a string and process its segments
|
115
|
+
# @param str [String] The string to scan.
|
116
|
+
# @param substring [String] The substring to match in the string.
|
117
|
+
# @param plain_sym [Symbol] The symbol for non-matching segments.
|
118
|
+
# @param color_sym [Symbol] The symbol for matching segments.
|
119
|
+
# @return [Array<String>] The processed segments.
|
120
|
+
def scan_and_process_string(str, substring, plain_sym, color_sym)
|
121
|
+
return string_send_color(str, plain_sym) unless substring.present?
|
122
|
+
|
123
|
+
results = []
|
124
|
+
remaining_str = str.dup
|
125
|
+
|
126
|
+
while remaining_str.length.positive?
|
127
|
+
match_index = remaining_str.index(substring)
|
128
|
+
if match_index
|
129
|
+
# Process non-matching segment before the match, if any
|
130
|
+
unless match_index.zero?
|
131
|
+
non_matching_segment = remaining_str.slice!(0...match_index)
|
132
|
+
results << string_send_color(non_matching_segment, plain_sym)
|
133
|
+
end
|
134
|
+
|
135
|
+
# Process the matching segment
|
136
|
+
matching_segment = remaining_str.slice!(0...substring.length)
|
137
|
+
results << string_send_color(matching_segment, color_sym)
|
138
|
+
else
|
139
|
+
# Process the remaining non-matching segment
|
140
|
+
results << string_send_color(remaining_str, plain_sym)
|
141
|
+
break
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
results
|
146
|
+
end
|
147
|
+
|
148
|
+
# # Example usage
|
149
|
+
# scan_and_process_string("Hello world, hello universe", "hello", :plain, :color)
|
150
|
+
|
151
|
+
# Applies a color method to a string based on the provided color symbol.
|
152
|
+
# The color method is fetched from @options and applied to the string.
|
153
|
+
# @param string [String] The string to which the color will be applied.
|
154
|
+
# @param color_sym [Symbol] The symbol representing the color method.
|
155
|
+
# @param default [String] Default color method to use if color_sym is not found in @options.
|
156
|
+
# @return [String] The string with the applied color method.
|
157
|
+
def string_send_color(string, color_sym, default: 'plain')
|
158
|
+
color_method = @options.fetch(color_sym, default).to_sym
|
159
|
+
string.to_s.send(color_method)
|
160
|
+
end
|
161
|
+
end
|
@@ -0,0 +1,239 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# encoding=utf-8
|
5
|
+
|
6
|
+
require 'find'
|
7
|
+
|
8
|
+
# Formats and highlights a list of dependencies. Dependencies are presented with indentation,
|
9
|
+
# and specific items can be highlighted in a specified color, while others are shown in a plain color.
|
10
|
+
#
|
11
|
+
# @param dependencies [Hash] A hash of dependencies, where each key is a dependency name,
|
12
|
+
# and its value is an array of sub-items.
|
13
|
+
# @param highlight_color_sym [Symbol] The color method to apply to highlighted items.
|
14
|
+
# Default is :exception_color_detail.
|
15
|
+
# @param plain_color_sym [Symbol] The color method for non-highlighted items.
|
16
|
+
# Default is :menu_chrome_color.
|
17
|
+
# @param label [String] The label to prefix the list of dependencies with.
|
18
|
+
# Default is 'Dependencies:'.
|
19
|
+
# @param highlight [Array] An array of items to highlight. Each item in this array will be
|
20
|
+
# formatted with the specified highlight color.
|
21
|
+
# @param line_prefix [String] Prefix for each line. Default is ' '.
|
22
|
+
# @param line_postfix [String] Postfix for each line. Default is ''.
|
23
|
+
# @param detail_sep [String] Separator for items in the sub-list. Default is ' '.
|
24
|
+
# @return [String] A formatted string representation of the dependencies with highlighted items.
|
25
|
+
def format_and_highlight_dependencies(
|
26
|
+
dependencies,
|
27
|
+
highlight_color_sym: :exception_color_detail,
|
28
|
+
plain_color_sym: :menu_chrome_color,
|
29
|
+
label: 'Dependencies:',
|
30
|
+
highlight: [],
|
31
|
+
line_prefix: ' ',
|
32
|
+
line_postfix: '',
|
33
|
+
detail_sep: ' '
|
34
|
+
)
|
35
|
+
formatted_deps = dependencies&.map do |dep_name, sub_items|
|
36
|
+
formatted_sub_items = sub_items.map do |item|
|
37
|
+
color_sym = highlight.include?(item) ? highlight_color_sym : plain_color_sym
|
38
|
+
string_send_color(item, color_sym)
|
39
|
+
end.join(detail_sep)
|
40
|
+
|
41
|
+
"#{line_prefix}- #{string_send_color(dep_name,
|
42
|
+
highlight.include?(dep_name) ? highlight_color_sym : plain_color_sym)}: #{formatted_sub_items}#{line_postfix}"
|
43
|
+
end || []
|
44
|
+
|
45
|
+
"#{line_prefix}#{string_send_color(label,
|
46
|
+
highlight_color_sym)}#{line_postfix}\n" + formatted_deps.join("\n")
|
47
|
+
end
|
48
|
+
# warn menu_blocks.to_yaml.sub(/^(?:---\n)?/, "MenuBlocks:\n")
|
49
|
+
|
50
|
+
IndexedLine = Struct.new(:index, :line) do
|
51
|
+
def to_s
|
52
|
+
line
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# Class DirectorySearcher
|
57
|
+
# This class provides methods to search for a specified pattern
|
58
|
+
# in directory names, file names, and contents of files within given paths.
|
59
|
+
class DirectorySearcher
|
60
|
+
attr_reader :pattern, :paths, :include_subdirectories, :filename_glob
|
61
|
+
|
62
|
+
# Constructor
|
63
|
+
# @param pattern [Regexp] The regular expression pattern to search for.
|
64
|
+
# @param paths [Array<String>] List of directories to search in.
|
65
|
+
# @param include_subdirectories [Boolean] Whether to search in subdirectories.
|
66
|
+
# @param filename_glob [String, nil] Glob pattern for file names.
|
67
|
+
def initialize(pattern, paths, include_subdirectories: true, filename_glob: '*.[Mm][Dd]') #'*.md'
|
68
|
+
@pattern = pattern
|
69
|
+
@paths = paths
|
70
|
+
@include_subdirectories = include_subdirectories
|
71
|
+
@filename_glob = filename_glob
|
72
|
+
end
|
73
|
+
|
74
|
+
# Searches for the pattern in directory names.
|
75
|
+
# @return [Array<String>] List of matching directory names.
|
76
|
+
def search_in_directory_names
|
77
|
+
match_dirs = []
|
78
|
+
@paths.each do |path|
|
79
|
+
Find.find(path) do |p|
|
80
|
+
# p 'search_in_directory_names', p
|
81
|
+
# Find.prune unless @include_subdirectories || path == p
|
82
|
+
match_dirs << p if File.directory?(p) && p.match?(@pattern)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
match_dirs
|
86
|
+
end
|
87
|
+
|
88
|
+
# Searches for the pattern in file names.
|
89
|
+
# @return [Array<String>] List of matching file names.
|
90
|
+
def search_in_file_names
|
91
|
+
match_files = []
|
92
|
+
@paths.each do |path|
|
93
|
+
Find.find(path) do |p|
|
94
|
+
# Find.prune unless @include_subdirectories || path == p
|
95
|
+
next unless File.file?(p)
|
96
|
+
|
97
|
+
file_name = File.basename(p)
|
98
|
+
next if @filename_glob && !File.fnmatch(@filename_glob, file_name)
|
99
|
+
|
100
|
+
begin
|
101
|
+
match_files << p if file_name.encode('UTF-8', invalid: :replace, undef: :replace,
|
102
|
+
replace: '').match?(@pattern)
|
103
|
+
rescue EncodingError
|
104
|
+
# Optionally log the file with encoding issues
|
105
|
+
# puts "Encoding error in file: #{p}"
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
match_files
|
110
|
+
end
|
111
|
+
|
112
|
+
# Searches for the pattern in the contents of the files and returns matches along with their file paths and line numbers.
|
113
|
+
# @return [Hash] A hash where each key is a file path and each value is an array of hashes with :line_number and :line keys.
|
114
|
+
def search_in_file_contents
|
115
|
+
match_details = {}
|
116
|
+
|
117
|
+
@paths.each do |path|
|
118
|
+
Find.find(path) do |p|
|
119
|
+
Find.prune unless @include_subdirectories || path == p
|
120
|
+
next unless File.file?(p)
|
121
|
+
|
122
|
+
next if @filename_glob && !File.fnmatch(@filename_glob, File.basename(p))
|
123
|
+
|
124
|
+
begin
|
125
|
+
File.foreach(p).with_index(1) do |line, line_num| # Index starts from 1 for line numbers
|
126
|
+
line_utf8 = line.encode('UTF-8', invalid: :replace, undef: :replace, replace: '')
|
127
|
+
if line_utf8.match?(@pattern)
|
128
|
+
match_details[p] ||= []
|
129
|
+
# match_details[p] << { number: line_num, line: line_utf8.chomp }
|
130
|
+
match_details[p] << IndexedLine.new(line_num, line_utf8.chomp)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
rescue EncodingError
|
134
|
+
# Optionally log the file with encoding issues
|
135
|
+
# puts "Encoding error in file: #{p}"
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
match_details
|
141
|
+
end
|
142
|
+
|
143
|
+
# # Searches for the pattern in the contents of the files.
|
144
|
+
# # @return [Array<String>] List of matching lines from files.
|
145
|
+
# def search_in_file_contents
|
146
|
+
# match_lines = []
|
147
|
+
# @paths.each do |path|
|
148
|
+
# Find.find(path) do |p|
|
149
|
+
# Find.prune unless @include_subdirectories || path == p
|
150
|
+
# next unless File.file?(p)
|
151
|
+
|
152
|
+
# next if @filename_glob && !File.fnmatch(@filename_glob, File.basename(p))
|
153
|
+
|
154
|
+
# begin
|
155
|
+
# File.foreach(p).with_index do |line, _line_num|
|
156
|
+
# line_utf8 = line.encode('UTF-8', invalid: :replace, undef: :replace, replace: '')
|
157
|
+
# match_lines << line_utf8.chomp if line_utf8.match?(@pattern)
|
158
|
+
# end
|
159
|
+
# rescue EncodingError
|
160
|
+
# # Optionally log the file with encoding issues
|
161
|
+
# # puts "Encoding error in file: #{p}"
|
162
|
+
# end
|
163
|
+
# end
|
164
|
+
# end
|
165
|
+
# match_lines
|
166
|
+
# end
|
167
|
+
end
|
168
|
+
|
169
|
+
if $PROGRAM_NAME == __FILE__
|
170
|
+
require 'bundler/setup'
|
171
|
+
Bundler.require(:default)
|
172
|
+
|
173
|
+
require 'minitest/autorun'
|
174
|
+
# require 'mocha/minitest'
|
175
|
+
# require_relative 'directory_searcher'
|
176
|
+
|
177
|
+
# Test class for DirectorySearcher
|
178
|
+
class DirectorySearcherTest < Minitest::Test
|
179
|
+
# Setup method to initialize common test data
|
180
|
+
def setup
|
181
|
+
@pattern = /test_pattern/
|
182
|
+
@paths = ['./spec']
|
183
|
+
@searcher = DirectorySearcher.new(@pattern, @paths)
|
184
|
+
end
|
185
|
+
|
186
|
+
# Test search_in_directory_names method
|
187
|
+
def test_search_in_directory_names
|
188
|
+
# Add assertions based on your test directory structure and expected results
|
189
|
+
assert_equal [], @searcher.search_in_directory_names
|
190
|
+
end
|
191
|
+
|
192
|
+
# Test search_in_file_names method
|
193
|
+
def test_search_in_file_names
|
194
|
+
# Add assertions based on your test directory structure and expected results
|
195
|
+
assert_equal [], @searcher.search_in_file_names
|
196
|
+
end
|
197
|
+
|
198
|
+
# Test search_in_file_contents method
|
199
|
+
def test_search_in_file_contents
|
200
|
+
# Add assertions based on your test directory structure and expected results
|
201
|
+
assert_equal ({}), @searcher.search_in_file_contents
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
# Test class for DirectorySearcher
|
206
|
+
class DirectorySearcherTest2 < Minitest::Test
|
207
|
+
# Setup method to initialize common test data
|
208
|
+
def setup
|
209
|
+
@pattern_spec = /spec/
|
210
|
+
@paths = ['./spec']
|
211
|
+
@filename_glob = nil
|
212
|
+
@searcher_spec = DirectorySearcher.new(@pattern_spec, @paths,
|
213
|
+
filename_glob: @filename_glob)
|
214
|
+
end
|
215
|
+
|
216
|
+
# Test search_in_directory_names method for 'spec'
|
217
|
+
def test_search_in_directory_names_for_spec
|
218
|
+
# Replace with actual expected directory names containing 'spec'
|
219
|
+
expected_dirs = ['./spec']
|
220
|
+
assert_equal expected_dirs, @searcher_spec.search_in_directory_names
|
221
|
+
end
|
222
|
+
|
223
|
+
# Test search_in_file_names method for 'spec'
|
224
|
+
def test_search_in_file_names_for_spec
|
225
|
+
# Replace with actual expected file names containing 'spec'
|
226
|
+
expected_files = ['./spec/cli_spec.rb', './spec/env_spec.rb',
|
227
|
+
'./spec/markdown_exec_spec.rb', './spec/tap_spec.rb']
|
228
|
+
assert_equal expected_files, @searcher_spec.search_in_file_names
|
229
|
+
end
|
230
|
+
|
231
|
+
# # Test search_in_file_contents method for 'spec'
|
232
|
+
# def test_search_in_file_contents_for_spec
|
233
|
+
# # Replace with actual expected lines containing 'spec'
|
234
|
+
# expected_lines = {['Line with spec 1', 'Line with spec 2']}
|
235
|
+
# assert_equal expected_lines, @searcher_spec.search_in_file_contents
|
236
|
+
# end
|
237
|
+
end
|
238
|
+
|
239
|
+
end
|
data/lib/env.rb
CHANGED
@@ -18,8 +18,7 @@ module Env
|
|
18
18
|
|
19
19
|
# :reek:UtilityFunction
|
20
20
|
def env_bool_false(name)
|
21
|
-
!(val = (name && ENV.fetch(name,
|
22
|
-
nil))).nil? && !(val.empty? || val == '0')
|
21
|
+
!(val = (name && ENV.fetch(name, nil))).nil? && !(val.empty? || val == '0')
|
23
22
|
end
|
24
23
|
|
25
24
|
# skip :reek:DataClump
|