markdown_exec 2.0.4 → 2.0.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +12 -5
- data/CHANGELOG.md +27 -0
- data/Gemfile.lock +1 -1
- data/bin/tab_completion.sh +15 -31
- data/examples/block_names.md +23 -0
- data/examples/linked.md +8 -0
- data/examples/linked_show.md +7 -0
- data/examples/load_code.md +10 -0
- data/examples/search.md +21 -0
- data/lib/color_scheme.rb +65 -0
- data/lib/constants.rb +18 -19
- data/lib/directory_searcher.rb +4 -2
- data/lib/find_files.rb +36 -42
- data/lib/hash_delegator.rb +842 -571
- data/lib/input_sequencer.rb +16 -9
- data/lib/markdown_exec/version.rb +1 -1
- data/lib/markdown_exec.rb +146 -31
- data/lib/menu.src.yml +76 -19
- data/lib/menu.yml +68 -12
- data/lib/std_out_err_logger.rb +12 -14
- metadata +7 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d1b2a98d8279b5a5705ba3dc3221d46f55387c0d834ec4283e93ac54f5929835
|
4
|
+
data.tar.gz: 440070d30a4650c0bb8b9a8b472d91d0bcb4357d18f5330194b10d1c5d6a764d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 32702e459d5eeac152583bd7dd8c5de3f6049b0fa8b2c389441f45afadc132678dabbb6898336297d09fa5411ae44963cd0b2353a69f9dc319eb9b302d4ec2db
|
7
|
+
data.tar.gz: a2ea933810ec3e90ed1cc62eccc9a2e8c94ee5dee1ed8c267b8750a97c67fb4a44bbcf8eb471137a65618b991966692d05684b3f69a97e5911dad3a777a15c60
|
data/.rubocop.yml
CHANGED
@@ -13,10 +13,8 @@ Layout/LeadingCommentSpace:
|
|
13
13
|
Layout/LineContinuationLeadingSpace:
|
14
14
|
Enabled: false
|
15
15
|
|
16
|
-
Layout/LineLength:
|
17
|
-
Enabled: false
|
16
|
+
Layout/LineLength:
|
18
17
|
Max: 96
|
19
|
-
Max: 120
|
20
18
|
|
21
19
|
Lint/Debugger:
|
22
20
|
Enabled: false
|
@@ -24,6 +22,9 @@ Lint/Debugger:
|
|
24
22
|
Lint/SafeNavigationChain:
|
25
23
|
Enabled: false
|
26
24
|
|
25
|
+
Lint/UnusedMethodArgument:
|
26
|
+
Enabled: false
|
27
|
+
|
27
28
|
Metrics/AbcSize:
|
28
29
|
Enabled: false
|
29
30
|
|
@@ -54,13 +55,16 @@ Minitest/MultipleAssertions:
|
|
54
55
|
Naming/RescuedExceptionsVariableName:
|
55
56
|
PreferredName: err
|
56
57
|
|
58
|
+
Security/Eval:
|
59
|
+
Enabled: false
|
60
|
+
|
57
61
|
Security/YAMLLoad:
|
58
62
|
Enabled: false
|
59
63
|
|
60
|
-
Style/
|
64
|
+
Style/ClassVars:
|
61
65
|
Enabled: false
|
62
66
|
|
63
|
-
Style/
|
67
|
+
Style/CommentedKeyword:
|
64
68
|
Enabled: false
|
65
69
|
|
66
70
|
Style/DoubleNegation:
|
@@ -87,6 +91,9 @@ Style/MultilineBlockChain:
|
|
87
91
|
Style/OpenStructUse:
|
88
92
|
Enabled: false
|
89
93
|
|
94
|
+
Style/OptionalBooleanParameter:
|
95
|
+
Enabled: false
|
96
|
+
|
90
97
|
Style/PerlBackrefs: # Prefer ::Regexp.last_match.post_match over $'.
|
91
98
|
Enabled: false
|
92
99
|
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,32 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## [2.0.6] - 2024-05-28
|
4
|
+
|
5
|
+
### Added
|
6
|
+
|
7
|
+
- Color-coding to folder names in the menu following a keyword search.
|
8
|
+
Implement color-coding for folder names. Each folder name is assigned a color based on the folder name to highlight repetitive folder structures.
|
9
|
+
|
10
|
+
- Load-code option to read one or more files into inherited lines.
|
11
|
+
|
12
|
+
- Automatic Load, Edit, Save, and View menu entries to manage inherited lines.
|
13
|
+
The value of `document_saved_lines_glob` is displayed above the menu items, if any.
|
14
|
+
The Load menu item appears when one or more files match the glob.
|
15
|
+
The Edit menu item appears when one or more lines have been inherited.
|
16
|
+
The Save menu item appears when one or more lines have been inherited.
|
17
|
+
The View menu item appears when one or more lines have been inherited.
|
18
|
+
|
19
|
+
### Changed
|
20
|
+
|
21
|
+
- Fix block name processing for blocks with no name.
|
22
|
+
Demo in examples/block_names.md loads content of examples/load1.sh.
|
23
|
+
|
24
|
+
## [2.0.5] - 2024-04-24
|
25
|
+
|
26
|
+
### Changed
|
27
|
+
|
28
|
+
- Open option: Search for keyword in block names instead of entire document.
|
29
|
+
|
3
30
|
## [2.0.4] - 2024-04-22
|
4
31
|
|
5
32
|
### Added
|
data/Gemfile.lock
CHANGED
data/bin/tab_completion.sh
CHANGED
@@ -13,7 +13,7 @@ __filedirs_all()
|
|
13
13
|
}
|
14
14
|
|
15
15
|
_mde_echo_version() {
|
16
|
-
echo "2.0.
|
16
|
+
echo "2.0.6"
|
17
17
|
}
|
18
18
|
|
19
19
|
_mde() {
|
@@ -36,15 +36,15 @@ _mde() {
|
|
36
36
|
|
37
37
|
-d) COMPREPLY="0"; return 0 ;;
|
38
38
|
|
39
|
-
--dump-
|
39
|
+
--dump-delegate-object) COMPREPLY="0"; return 0 ;;
|
40
40
|
|
41
41
|
--dump-blocks-in-file) COMPREPLY="0"; return 0 ;;
|
42
42
|
|
43
|
-
--dump-
|
43
|
+
--dump-inherited-block_names) COMPREPLY="0"; return 0 ;;
|
44
44
|
|
45
|
-
--dump-
|
45
|
+
--dump-inherited-dependencies) COMPREPLY="0"; return 0 ;;
|
46
46
|
|
47
|
-
--dump-
|
47
|
+
--dump-inherited-lines) COMPREPLY="0"; return 0 ;;
|
48
48
|
|
49
49
|
--dump-menu-blocks) COMPREPLY="0"; return 0 ;;
|
50
50
|
|
@@ -66,12 +66,12 @@ _mde() {
|
|
66
66
|
|
67
67
|
--list-count) COMPREPLY="32"; return 0 ;;
|
68
68
|
|
69
|
+
--load-code) COMPREPLY="''"; return 0 ;;
|
70
|
+
|
69
71
|
--open) COMPREPLY="''"; return 0 ;;
|
70
72
|
|
71
73
|
-o) COMPREPLY="''"; return 0 ;;
|
72
74
|
|
73
|
-
--output-execution-summary) COMPREPLY="0"; return 0 ;;
|
74
|
-
|
75
75
|
--output-script) COMPREPLY="0"; return 0 ;;
|
76
76
|
|
77
77
|
--output-stdout) COMPREPLY="1"; return 0 ;;
|
@@ -80,14 +80,6 @@ _mde() {
|
|
80
80
|
|
81
81
|
-p) COMPREPLY="."; return 0 ;;
|
82
82
|
|
83
|
-
--save-executed-script) COMPREPLY="0"; return 0 ;;
|
84
|
-
|
85
|
-
--save-execution-output) COMPREPLY="0"; return 0 ;;
|
86
|
-
|
87
|
-
--saved-script-folder) COMPREPLY="logs"; return 0 ;;
|
88
|
-
|
89
|
-
--saved-stdout-folder) COMPREPLY="logs"; return 0 ;;
|
90
|
-
|
91
83
|
--user-must-approve) COMPREPLY="0"; return 0 ;;
|
92
84
|
|
93
85
|
-q) COMPREPLY="0"; return 0 ;;
|
@@ -102,7 +94,7 @@ _mde() {
|
|
102
94
|
# present matching option names
|
103
95
|
#
|
104
96
|
if [[ ${cur} == -* ]] ; then
|
105
|
-
opts=("--block-name" "--config" "--debug" "--dump-
|
97
|
+
opts=("--block-name" "--config" "--debug" "--dump-delegate-object" "--dump-blocks-in-file" "--dump-inherited-block_names" "--dump-inherited-dependencies" "--dump-inherited-lines" "--dump-menu-blocks" "--dump-selected-block" "--exit" "--filename" "--find" "--find-path" "--help" "--how" "--list-blocks" "--list-count" "--list-default-env" "--list-default-yaml" "--list-docs" "--list-recent-output" "--list-recent-scripts" "--load-code" "--open" "--output-script" "--output-stdout" "--path" "--pwd" "--run-last-script" "--select-recent-output" "--select-recent-script" "--tab-completions" "--user-must-approve" "--version" "--display-level")
|
106
98
|
COMPREPLY=( $(compgen -W "$(printf "'%s' " "${opts[@]}")" -- "${cur}") )
|
107
99
|
|
108
100
|
return 0
|
@@ -125,15 +117,15 @@ _mde() {
|
|
125
117
|
|
126
118
|
-d) COMPREPLY=".BOOL."; return 0 ;;
|
127
119
|
|
128
|
-
--dump-
|
120
|
+
--dump-delegate-object) COMPREPLY=".BOOL."; return 0 ;;
|
129
121
|
|
130
122
|
--dump-blocks-in-file) COMPREPLY=".BOOL."; return 0 ;;
|
131
123
|
|
132
|
-
--dump-
|
124
|
+
--dump-inherited-block_names) COMPREPLY=".BOOL."; return 0 ;;
|
133
125
|
|
134
|
-
--dump-
|
126
|
+
--dump-inherited-dependencies) COMPREPLY=".BOOL."; return 0 ;;
|
135
127
|
|
136
|
-
--dump-
|
128
|
+
--dump-inherited-lines) COMPREPLY=".BOOL."; return 0 ;;
|
137
129
|
|
138
130
|
--dump-menu-blocks) COMPREPLY=".BOOL."; return 0 ;;
|
139
131
|
|
@@ -155,12 +147,12 @@ _mde() {
|
|
155
147
|
|
156
148
|
--list-count) COMPREPLY=".INT.1-."; return 0 ;;
|
157
149
|
|
150
|
+
--load-code) COMPREPLY=".PATH."; return 0 ;;
|
151
|
+
|
158
152
|
--open) COMPREPLY=".OPEN."; return 0 ;;
|
159
153
|
|
160
154
|
-o) COMPREPLY=".OPEN."; return 0 ;;
|
161
155
|
|
162
|
-
--output-execution-summary) COMPREPLY=".BOOL."; return 0 ;;
|
163
|
-
|
164
156
|
--output-script) COMPREPLY=".BOOL."; return 0 ;;
|
165
157
|
|
166
158
|
--output-stdout) COMPREPLY=".BOOL."; return 0 ;;
|
@@ -169,14 +161,6 @@ _mde() {
|
|
169
161
|
|
170
162
|
-p) COMPREPLY=".RELATIVE_PATH."; return 0 ;;
|
171
163
|
|
172
|
-
--save-executed-script) COMPREPLY=".BOOL."; return 0 ;;
|
173
|
-
|
174
|
-
--save-execution-output) COMPREPLY=".BOOL."; return 0 ;;
|
175
|
-
|
176
|
-
--saved-script-folder) COMPREPLY=".RELATIVE_PATH."; return 0 ;;
|
177
|
-
|
178
|
-
--saved-stdout-folder) COMPREPLY=".RELATIVE_PATH."; return 0 ;;
|
179
|
-
|
180
164
|
--user-must-approve) COMPREPLY=".BOOL."; return 0 ;;
|
181
165
|
|
182
166
|
-q) COMPREPLY=".BOOL."; return 0 ;;
|
@@ -194,4 +178,4 @@ _mde() {
|
|
194
178
|
|
195
179
|
complete -o filenames -o nospace -F _mde mde
|
196
180
|
# _mde_echo_version
|
197
|
-
# echo "Updated: 2024-
|
181
|
+
# echo "Updated: 2024-05-31 07:22:55 UTC"
|
@@ -0,0 +1,23 @@
|
|
1
|
+
Demonstrate display of block names and requiring blocks.
|
2
|
+
|
3
|
+
This block is listed by its name `A`.
|
4
|
+
It requires block `[C]`.
|
5
|
+
Executing it outputs `1`, `3`.
|
6
|
+
```bash :A +[C]
|
7
|
+
echo "1"
|
8
|
+
```
|
9
|
+
|
10
|
+
This block is listed according to its content `echo "2"`.
|
11
|
+
It requires blocks `A`, `[C]`.
|
12
|
+
Executing it outputs `1`, `2`, `3`.
|
13
|
+
It cannot be addressed/required.
|
14
|
+
```bash +A
|
15
|
+
echo "2"
|
16
|
+
```
|
17
|
+
|
18
|
+
This block is listed according to its content `echo "3"` and addressed by its nick name `[C]`.
|
19
|
+
It requires no blocks.
|
20
|
+
Executing it outputs `3`.
|
21
|
+
```bash :[C]
|
22
|
+
echo "3"
|
23
|
+
```
|
data/examples/linked.md
CHANGED
@@ -92,6 +92,14 @@ load: examples/load2.sh
|
|
92
92
|
eval: true
|
93
93
|
```
|
94
94
|
|
95
|
+
::: Load file into inherited lines and switch document
|
96
|
+
Load (do not evaluate) and append to inherited lines and switch document.
|
97
|
+
```link :load_from_file_link_and_show
|
98
|
+
block: show_vars
|
99
|
+
file: examples/linked_show.md
|
100
|
+
load: examples/load1.sh
|
101
|
+
```
|
102
|
+
|
95
103
|
::: Save and Load
|
96
104
|
Save inherited lines to a file.
|
97
105
|
```link :save1
|
@@ -0,0 +1,10 @@
|
|
1
|
+
Demonstrate loading inherited code via the command line.
|
2
|
+
|
3
|
+
Run this command to display the inherited code.
|
4
|
+
`mde --load-code examples/load1.sh examples/load_code.md display_variables`
|
5
|
+
|
6
|
+
```bash :display_variables
|
7
|
+
source bin/colorize_env_vars.sh
|
8
|
+
echo The current value of environment variables:
|
9
|
+
colorize_env_vars '' var1 var2
|
10
|
+
```
|
data/examples/search.md
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
Demonstrate keyword search in documents.
|
2
|
+
Keywords in body: monkey secret
|
3
|
+
|
4
|
+
Keyword in untyped block name.
|
5
|
+
``` :monkey1
|
6
|
+
```
|
7
|
+
|
8
|
+
Keyword in Bash block name.
|
9
|
+
```bash :monkey2
|
10
|
+
```
|
11
|
+
|
12
|
+
Keyword in block body.
|
13
|
+
```
|
14
|
+
monkey3
|
15
|
+
```
|
16
|
+
|
17
|
+
Keyword in Link block body.
|
18
|
+
```link
|
19
|
+
vars:
|
20
|
+
monkey4: 4
|
21
|
+
```
|
data/lib/color_scheme.rb
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# encoding=utf-8
|
4
|
+
|
5
|
+
# A class that represents a color scheme based on configurable parameters
|
6
|
+
# that determine how the RGB values are calculated for a given string segment.
|
7
|
+
class ColorScheme
|
8
|
+
attr_accessor :base_red, :multiplier_red, :modulus_red,
|
9
|
+
:base_green, :multiplier_green, :modulus_green,
|
10
|
+
:base_blue, :multiplier_blue, :modulus_blue
|
11
|
+
|
12
|
+
# Initializes a new ColorScheme object with base values, multipliers, and moduli
|
13
|
+
# for the red, green, and blue components of an RGB color.
|
14
|
+
# @param [Integer] base_red Base red component value.
|
15
|
+
# @param [Integer] multiplier_red Multiplier for red component based on string hash.
|
16
|
+
# @param [Integer] modulus_red Modulus for calculating red component.
|
17
|
+
# @param [Integer] base_green Base green component value.
|
18
|
+
# @param [Integer] multiplier_green Multiplier for green component based on string hash.
|
19
|
+
# @param [Integer] modulus_green Modulus for calculating green component.
|
20
|
+
# @param [Integer] base_blue Base blue component value.
|
21
|
+
# @param [Integer] multiplier_blue Multiplier for blue component based on string hash.
|
22
|
+
# @param [Integer] modulus_blue Modulus for calculating blue component.
|
23
|
+
def initialize(base_red, multiplier_red, modulus_red,
|
24
|
+
base_green, multiplier_green, modulus_green,
|
25
|
+
base_blue, multiplier_blue, modulus_blue)
|
26
|
+
@base_red = base_red
|
27
|
+
@multiplier_red = multiplier_red
|
28
|
+
@modulus_red = modulus_red
|
29
|
+
@base_green = base_green
|
30
|
+
@multiplier_green = multiplier_green
|
31
|
+
@modulus_green = modulus_green
|
32
|
+
@base_blue = base_blue
|
33
|
+
@multiplier_blue = multiplier_blue
|
34
|
+
@modulus_blue = modulus_blue
|
35
|
+
end
|
36
|
+
|
37
|
+
# Calculates and returns the ANSI escape code for coloring a string segment
|
38
|
+
# based on its hash value.
|
39
|
+
# @param [String] segment The string segment to color.
|
40
|
+
# @return [String] ANSI escape code string with RGB color formatting.
|
41
|
+
def color_for(segment)
|
42
|
+
hash_value = segment.each_byte.reduce(0, :+)
|
43
|
+
red = @base_red + (@multiplier_red * (hash_value % @modulus_red))
|
44
|
+
green = @base_green + (@multiplier_green * (hash_value % @modulus_green))
|
45
|
+
blue = @base_blue + (@multiplier_blue * (hash_value % @modulus_blue))
|
46
|
+
"\e[38;2;#{red};#{green};#{blue}m#{segment}\e[0m"
|
47
|
+
end
|
48
|
+
|
49
|
+
# Applies color codes to each segment of a filesystem path, differentiating the
|
50
|
+
# final segment from others using a distinct color scheme.
|
51
|
+
# @param [String] path The filesystem path to colorize.
|
52
|
+
# @return [String] The colorized path.
|
53
|
+
def self.colorize_path(path)
|
54
|
+
segments = path.split('/')
|
55
|
+
segments.map.with_index do |segment, index|
|
56
|
+
color_scheme = if index == segments.size - 1
|
57
|
+
ColorScheme.new(192, 0, 1, 192, 0, 1, 192, 0, 1)
|
58
|
+
else
|
59
|
+
ColorScheme.new(32, 1, 192, 32, 1, 192, 255, 0, 1)
|
60
|
+
end
|
61
|
+
|
62
|
+
color_scheme.color_for(segment)
|
63
|
+
end.join('/')
|
64
|
+
end
|
65
|
+
end
|
data/lib/constants.rb
CHANGED
@@ -6,9 +6,9 @@
|
|
6
6
|
require_relative 'block_types'
|
7
7
|
|
8
8
|
class ExecutionStreams
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
STD_ERR = :stderr
|
10
|
+
STD_IN = :stdin
|
11
|
+
STD_OUT = :stdout
|
12
12
|
end
|
13
13
|
|
14
14
|
IndexedLine = Struct.new(:index, :line) do
|
@@ -18,29 +18,24 @@ IndexedLine = Struct.new(:index, :line) do
|
|
18
18
|
end
|
19
19
|
|
20
20
|
class LinkKeys
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
21
|
+
BLOCK = 'block'
|
22
|
+
EVAL = 'eval'
|
23
|
+
EXEC = 'exec'
|
24
|
+
FILE = 'file'
|
25
|
+
LOAD = 'load'
|
26
|
+
NEXT_BLOCK = 'next_block'
|
27
|
+
RETURN = 'return'
|
28
|
+
SAVE = 'save'
|
29
|
+
VARS = 'vars'
|
30
30
|
end
|
31
31
|
|
32
32
|
class LoadFile
|
33
|
-
|
34
|
-
|
33
|
+
LOAD = true
|
34
|
+
REUSE = false
|
35
35
|
end
|
36
36
|
|
37
37
|
LoadFileLinkState = Struct.new(:load_file, :link_state)
|
38
38
|
|
39
|
-
class MenuControl
|
40
|
-
Fresh = false
|
41
|
-
Repeat = true
|
42
|
-
end
|
43
|
-
|
44
39
|
class MenuOptions
|
45
40
|
YES = 1
|
46
41
|
NO = 2
|
@@ -51,7 +46,11 @@ end
|
|
51
46
|
class MenuState
|
52
47
|
BACK = :back
|
53
48
|
CONTINUE = :continue
|
49
|
+
EDIT = :edit
|
54
50
|
EXIT = :exit
|
51
|
+
LOAD = :load
|
52
|
+
SAVE = :save
|
53
|
+
VIEW = :view
|
55
54
|
end
|
56
55
|
|
57
56
|
# a struct to hold the data for a single line
|
data/lib/directory_searcher.rb
CHANGED
@@ -160,9 +160,11 @@ class DirectorySearcher
|
|
160
160
|
begin
|
161
161
|
File.foreach(p).with_index(1) do |line, line_num| # Index starts from 1 for line numbers
|
162
162
|
line_utf8 = line.encode('UTF-8', invalid: :replace, undef: :replace, replace: '')
|
163
|
-
|
163
|
+
|
164
|
+
line_utf8 = yield(line_utf8) if block_given?
|
165
|
+
|
166
|
+
if line_utf8&.match?(@pattern)
|
164
167
|
match_details[p] ||= []
|
165
|
-
# match_details[p] << { number: line_num, line: line_utf8.chomp }
|
166
168
|
match_details[p] << IndexedLine.new(line_num, line_utf8.chomp)
|
167
169
|
end
|
168
170
|
end
|
data/lib/find_files.rb
CHANGED
@@ -2,13 +2,13 @@
|
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
# encoding=utf-8
|
5
|
-
# version 2024-
|
5
|
+
# version 2024-05-24
|
6
6
|
|
7
7
|
# Finds files matching a given pattern within specified directory paths while optionally excluding
|
8
8
|
# "." and ".." entries and directory names from the results.
|
9
9
|
#
|
10
|
-
# The function takes a pattern (filename or pattern with wildcards), an array of paths, and
|
11
|
-
#
|
10
|
+
# The function takes a pattern (filename or pattern with wildcards), an array of paths, and options
|
11
|
+
# to exclude directory entries and special entries "." and "..", and to use relative paths.
|
12
12
|
# It searches for files matching the pattern within each of the specified paths. Hidden files
|
13
13
|
# are included in the search. The search can include subdirectories depending on the
|
14
14
|
# path specification (e.g., 'dir/**' for recursive search).
|
@@ -18,15 +18,17 @@
|
|
18
18
|
# paths (Array<String>): An array of directory paths where the search will be performed.
|
19
19
|
# Paths can include wildcards for recursive search.
|
20
20
|
# exclude_dirs (Boolean): If true, excludes "." and ".." and directory names from the results.
|
21
|
+
# use_relative_paths (Boolean): If true, removes the app's base directory from the file names
|
22
|
+
# if present.
|
21
23
|
#
|
22
24
|
# Returns:
|
23
25
|
# Array<String>: A unique list of file paths that match the given pattern in the specified paths,
|
24
|
-
# excluding directories if exclude_dirs is true.
|
26
|
+
# excluding directories if exclude_dirs is true. Paths are relative if use_relative_paths is true.
|
25
27
|
#
|
26
28
|
# Example:
|
27
|
-
# find_files('version.rb', ['lib/**', 'spec'], true)
|
28
|
-
# # This might return file paths like ['
|
29
|
-
def find_files(pattern, paths = ['', Dir.pwd], exclude_dirs: false)
|
29
|
+
# find_files('version.rb', ['lib/**', 'spec'], true, true)
|
30
|
+
# # This might return file paths like ['markdown_exec/version.rb', 'spec/version_spec.rb'].
|
31
|
+
def find_files(pattern, paths = ['', Dir.pwd], base_dir: Dir.pwd, exclude_dirs: false, use_relative_paths: true)
|
30
32
|
matched_files = []
|
31
33
|
|
32
34
|
paths.each do |path_with_wildcard|
|
@@ -37,9 +39,10 @@ def find_files(pattern, paths = ['', Dir.pwd], exclude_dirs: false)
|
|
37
39
|
files = Dir.glob(search_pattern, File::FNM_DOTMATCH)
|
38
40
|
|
39
41
|
# Optionally exclude "." and ".." and directory names
|
40
|
-
if exclude_dirs
|
41
|
-
|
42
|
-
|
42
|
+
files.reject! { |file| file.end_with?('/.', '/..') || File.directory?(file) } if exclude_dirs
|
43
|
+
|
44
|
+
# Optionally use relative paths
|
45
|
+
files.map! { |file| file.sub(/^#{Regexp.escape(base_dir)}\//, '') } if use_relative_paths
|
43
46
|
|
44
47
|
matched_files += files
|
45
48
|
end
|
@@ -47,38 +50,6 @@ def find_files(pattern, paths = ['', Dir.pwd], exclude_dirs: false)
|
|
47
50
|
matched_files.uniq
|
48
51
|
end
|
49
52
|
|
50
|
-
# # Finds files matching a given pattern within specified directory paths.
|
51
|
-
# #
|
52
|
-
# # The function takes a pattern (filename or pattern with wildcards) and an array of paths.
|
53
|
-
# # It searches for files matching the pattern within each of the specified paths. Hidden files
|
54
|
-
# # are also included in the search. The search can include subdirectories depending on the
|
55
|
-
# # path specification (e.g., 'dir/**' for recursive search).
|
56
|
-
# #
|
57
|
-
# # Args:
|
58
|
-
# # pattern (String): A filename or a pattern string with wildcards.
|
59
|
-
# # paths (Array<String>): An array of directory paths where the search will be performed.
|
60
|
-
# # Paths can include wildcards for recursive search.
|
61
|
-
# #
|
62
|
-
# # Returns:
|
63
|
-
# # Array<String>: A unique list of file paths that match the given pattern in the specified paths.
|
64
|
-
# #
|
65
|
-
# # Example:
|
66
|
-
# # find_files('version.rb', ['lib/**', 'spec'])
|
67
|
-
# # # This might return file paths like ['lib/markdown_exec/version.rb', 'spec/version_spec.rb'].
|
68
|
-
# def find_files(pattern, paths = ['', Dir.pwd])
|
69
|
-
# matched_files = []
|
70
|
-
|
71
|
-
# paths.each do |path_with_wildcard|
|
72
|
-
# # Combine the path with the wildcard and the pattern
|
73
|
-
# search_pattern = File.join(path_with_wildcard, pattern)
|
74
|
-
|
75
|
-
# # Use Dir.glob with the File::FNM_DOTMATCH flag to include hidden files
|
76
|
-
# matched_files += Dir.glob(search_pattern, File::FNM_DOTMATCH)
|
77
|
-
# end
|
78
|
-
|
79
|
-
# matched_files.uniq
|
80
|
-
# end
|
81
|
-
|
82
53
|
return if $PROGRAM_NAME != __FILE__
|
83
54
|
|
84
55
|
# example CLI
|
@@ -138,4 +109,27 @@ class TestFindFiles < Minitest::Test
|
|
138
109
|
result = find_files('.gitignore', ['.'])
|
139
110
|
assert_includes result, './.gitignore'
|
140
111
|
end
|
112
|
+
|
113
|
+
def test_find_files_with_non_existent_paths
|
114
|
+
# Test with non-existent paths
|
115
|
+
result = find_files('*.rb', %w[non_existent_dir another_fake_dir])
|
116
|
+
assert_empty result
|
117
|
+
end
|
118
|
+
|
119
|
+
def test_find_files_with_mixed_existent_and_non_existent_paths
|
120
|
+
# Test with a mix of existing and non-existing paths
|
121
|
+
result = find_files('*.rb', %w[lib non_existent_dir])
|
122
|
+
assert_includes result, 'lib/cli.rb'
|
123
|
+
assert_includes result, 'lib/colorize.rb'
|
124
|
+
# Ensure that non-existent paths do not cause failure and do not include files
|
125
|
+
assert_equal result.length, Dir.glob('lib/*.rb').length
|
126
|
+
end
|
127
|
+
|
128
|
+
def test_find_files_with_relative_paths
|
129
|
+
# Test with relative paths
|
130
|
+
base_dir = Dir.pwd
|
131
|
+
result = find_files('cli.rb', ['lib'], use_relative_paths: true)
|
132
|
+
assert_includes result, 'lib/cli.rb'
|
133
|
+
refute_includes result, "#{base_dir}/lib/cli.rb"
|
134
|
+
end
|
141
135
|
end
|