markdown_exec 1.7 → 1.8
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/.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
|