#!/usr/bin/env bundle exec ruby # frozen_string_literal: true # encoding=utf-8 # version 2024-01-15 # Finds files matching a given pattern within specified directory paths. # # The function takes a pattern (filename or pattern with wildcards) and an array of paths. # It searches for files matching the pattern within each of the specified paths. Hidden files # are also included in the search. The search can include subdirectories depending on the # path specification (e.g., 'dir/**' for recursive search). # # Args: # pattern (String): A filename or a pattern string with wildcards. # paths (Array): An array of directory paths where the search will be performed. # Paths can include wildcards for recursive search. # # Returns: # Array: A unique list of file paths that match the given pattern in the specified paths. # # Example: # find_files('version.rb', ['lib/**', 'spec']) # # This might return file paths like ['lib/markdown_exec/version.rb', 'spec/version_spec.rb']. def find_files(pattern, paths = ['', Dir.pwd]) matched_files = [] paths.each do |path_with_wildcard| # Combine the path with the wildcard and the pattern search_pattern = File.join(path_with_wildcard, pattern) # Use Dir.glob with the File::FNM_DOTMATCH flag to include hidden files matched_files += Dir.glob(search_pattern, File::FNM_DOTMATCH) end matched_files.uniq end return if $PROGRAM_NAME != __FILE__ # example CLI # ruby lib/find_files.rb import1.md 'spec:fixtures/**:examples/**' ':' if ARGV.length.positive? pattern, path_list, sep = ARGV puts find_files(pattern, path_list.split(sep || ':')) return end require 'bundler/setup' Bundler.require(:default) require 'minitest/autorun' class TestFindFiles < Minitest::Test def test_find_files_no_recursion # Test with no recursive directories result = find_files('cli.rb', ['lib']) assert_includes result, 'lib/cli.rb' end def test_find_files_with_recursion # Test with recursive directories expected_files = [ 'lib/cli.rb', 'lib/colorize.rb', 'lib/dev/watchfile.sh', 'lib/markdown_exec.rb', 'lib/markdown_exec/version.rb' ] result = find_files('*', ['lib/**']) expected_files.each do |file| assert_includes result, file end end def test_find_files_in_multiple_paths # Test with multiple paths expected_files = [ 'lib/markdown_exec/version.rb', 'spec/cli_spec.rb', 'spec/env_spec.rb', 'spec/markdown_exec_spec.rb', 'spec/tap_spec.rb' ] result = find_files('*', ['lib/**', 'spec']) expected_files.each do |file| assert_includes result, file end end def test_find_files_with_hidden_files # Test to ensure hidden files are also found result = find_files('.gitignore', ['.']) assert_includes result, './.gitignore' end end