markdown_exec 2.0.4 → 2.0.6

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: eadeecd7019d53202aabe57d9486ee616826e6b5f42fce0fa24f8e377c1b50e5
4
- data.tar.gz: cde007bddd4821263045eeba415cc1e2f42591d03294fc678c4093384373146b
3
+ metadata.gz: d1b2a98d8279b5a5705ba3dc3221d46f55387c0d834ec4283e93ac54f5929835
4
+ data.tar.gz: 440070d30a4650c0bb8b9a8b472d91d0bcb4357d18f5330194b10d1c5d6a764d
5
5
  SHA512:
6
- metadata.gz: 5a4a3a36d420c41403be33dbc7ac8e53f446dac53ba3ce8e9cd2fafb1ff0c1026aa1df633f6d79e1742ea11a07f71bd3f64df95f772798ff4624b8c36a8f93b2
7
- data.tar.gz: 1acc6cb2bf716b30a1ab8037ad0e43ff3646b23b991cd1bd9d31b1aad37ccf6ae97bd01eaeecc57e644ceb580a9aa9bf61742075777a528ffc180a43a955ccb1
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: # 2024-01-21 temp disable
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/CommentedKeyword:
64
+ Style/ClassVars:
61
65
  Enabled: false
62
66
 
63
- Style/Documentation: # 2024-01-21 temp disable
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
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- markdown_exec (2.0.4)
4
+ markdown_exec (2.0.6)
5
5
  clipboard (~> 1.3.6)
6
6
  open3 (~> 0.1.1)
7
7
  optparse (~> 0.1.1)
@@ -13,7 +13,7 @@ __filedirs_all()
13
13
  }
14
14
 
15
15
  _mde_echo_version() {
16
- echo "2.0.4"
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-dump-delegate-object) COMPREPLY="0"; return 0 ;;
39
+ --dump-delegate-object) COMPREPLY="0"; return 0 ;;
40
40
 
41
41
  --dump-blocks-in-file) COMPREPLY="0"; return 0 ;;
42
42
 
43
- --dump-dump-inherited-block_names) COMPREPLY="0"; return 0 ;;
43
+ --dump-inherited-block_names) COMPREPLY="0"; return 0 ;;
44
44
 
45
- --dump-dump-inherited-dependencies) COMPREPLY="0"; return 0 ;;
45
+ --dump-inherited-dependencies) COMPREPLY="0"; return 0 ;;
46
46
 
47
- --dump-dump-inherited-lines) COMPREPLY="0"; return 0 ;;
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-dump-delegate-object" "--dump-blocks-in-file" "--dump-dump-inherited-block_names" "--dump-dump-inherited-dependencies" "--dump-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" "--open" "--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")
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-dump-delegate-object) COMPREPLY=".BOOL."; return 0 ;;
120
+ --dump-delegate-object) COMPREPLY=".BOOL."; return 0 ;;
129
121
 
130
122
  --dump-blocks-in-file) COMPREPLY=".BOOL."; return 0 ;;
131
123
 
132
- --dump-dump-inherited-block_names) COMPREPLY=".BOOL."; return 0 ;;
124
+ --dump-inherited-block_names) COMPREPLY=".BOOL."; return 0 ;;
133
125
 
134
- --dump-dump-inherited-dependencies) COMPREPLY=".BOOL."; return 0 ;;
126
+ --dump-inherited-dependencies) COMPREPLY=".BOOL."; return 0 ;;
135
127
 
136
- --dump-dump-inherited-lines) COMPREPLY=".BOOL."; return 0 ;;
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-04-23 01:25:22 UTC"
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,7 @@
1
+ # Demo document linking
2
+
3
+ ::: Display variables set in the calling document
4
+ ```bash :show_vars
5
+ source bin/colorize_env_vars.sh
6
+ colorize_env_vars 'from linked.md load1.sh' var1 var2
7
+ ```
@@ -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
+ ```
@@ -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
+ ```
@@ -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
- StdErr = :stderr
10
- StdIn = :stdin
11
- StdOut = :stdout
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
- Block = 'block'
22
- Eval = 'eval'
23
- Exec = 'exec'
24
- File = 'file'
25
- Load = 'load'
26
- NextBlock = 'next_block'
27
- Return = 'return'
28
- Save = 'save'
29
- Vars = 'vars'
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
- Load = true
34
- Reuse = false
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
@@ -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
- if line_utf8.match?(@pattern)
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-01-15
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 an
11
- # option to exclude directory entries and special entries "." and "..".
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 ['lib/markdown_exec/version.rb', 'spec/version_spec.rb'].
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
- files.reject! { |file| file.end_with?('/.', '/..') || File.directory?(file) }
42
- end
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