lib/spoom/file_collector.rb in spoom-1.2.1 vs lib/spoom/file_collector.rb in spoom-1.2.2

- old
+ new

@@ -10,19 +10,25 @@ # Initialize a new file collector # # If `allow_extensions` is empty, all files are collected. # If `allow_extensions` is an array of extensions, only files with one of these extensions are collected. + # + # If `allow_mime_types` is empty, all files are collected. + # If `allow_mime_types` is an array of mimetypes, files without an extension are collected if their mimetype is in + # the list. sig do params( allow_extensions: T::Array[String], + allow_mime_types: T::Array[String], exclude_patterns: T::Array[String], ).void end - def initialize(allow_extensions: [], exclude_patterns: []) + def initialize(allow_extensions: [], allow_mime_types: [], exclude_patterns: []) @files = T.let([], T::Array[String]) @allow_extensions = allow_extensions + @allow_mime_types = allow_mime_types @exclude_patterns = exclude_patterns end sig { params(paths: T::Array[String]).void } def visit_paths(paths) @@ -66,14 +72,31 @@ sig { params(path: String).returns(T::Boolean) } def excluded_file?(path) return false if @allow_extensions.empty? extension = File.extname(path) - @allow_extensions.none? { |allowed| extension == allowed } + if extension.empty? + return true if @allow_mime_types.empty? + + mime = mime_type_for(path) + @allow_mime_types.none? { |allowed| mime == allowed } + else + @allow_extensions.none? { |allowed| extension == allowed } + end end sig { params(path: String).returns(T::Boolean) } def excluded_path?(path) - @exclude_patterns.any? { |pattern| File.fnmatch?(pattern, path) } + @exclude_patterns.any? do |pattern| + # Use `FNM_PATHNAME` so patterns do not match directory separators + # Use `FNM_EXTGLOB` to allow file globbing through `{a,b}` + File.fnmatch?(pattern, path, File::FNM_PATHNAME | File::FNM_EXTGLOB) + end + end + + sig { params(path: String).returns(T.nilable(String)) } + def mime_type_for(path) + # The `file` command appears to be hanging on MacOS for some files so we timeout after 1s. + %x{timeout 1s file --mime-type -b '#{path}'}.split("; ").first&.strip end end end