diff --git a/src/compiler/crystal/command.cr b/src/compiler/crystal/command.cr index 462653c77f0b..b0e117ea49d0 100644 --- a/src/compiler/crystal/command.cr +++ b/src/compiler/crystal/command.cr @@ -341,7 +341,9 @@ class Crystal::Command hierarchy_exp : String?, cursor_location : String?, output_format : String?, - combine_rpath : Bool do + combine_rpath : Bool, + includes : Array(String), + excludes : Array(String) do def compile(output_filename = self.output_filename) compiler.emit_base_filename = emit_base_filename || output_filename.rchop(File.extname(output_filename)) compiler.compile sources, output_filename, combine_rpath: combine_rpath @@ -367,6 +369,8 @@ class Crystal::Command hierarchy_exp = nil cursor_location = nil output_format = nil + excludes = [] of String + includes = [] of String option_parser = parse_with_crystal_opts do |opts| opts.banner = "Usage: crystal #{command} [options] [programfile] [--] [arguments]\n\nOptions:" @@ -414,6 +418,14 @@ class Crystal::Command opts.on("-f tree|flat", "--format tree|flat", "Output format tree (default) or flat") do |f| output_format = f end + + opts.on("-i ", "--include ", "Include path") do |f| + includes << f + end + + opts.on("-e ", "--exclude ", "Exclude path (default: lib)") do |f| + excludes << f + end else opts.on("-f text|json", "--format text|json", "Output format text (default) or json") do |f| output_format = f @@ -576,7 +588,7 @@ class Crystal::Command end combine_rpath = run && !no_codegen - @config = CompilerConfig.new compiler, sources, output_filename, emit_base_filename, arguments, specified_output, hierarchy_exp, cursor_location, output_format, combine_rpath + @config = CompilerConfig.new compiler, sources, output_filename, emit_base_filename, arguments, specified_output, hierarchy_exp, cursor_location, output_format, combine_rpath, includes, excludes end private def gather_sources(filenames) diff --git a/src/compiler/crystal/tools/dependencies.cr b/src/compiler/crystal/tools/dependencies.cr index 76ab6d98bed4..cf2f30f6290a 100644 --- a/src/compiler/crystal/tools/dependencies.cr +++ b/src/compiler/crystal/tools/dependencies.cr @@ -6,7 +6,11 @@ class Crystal::Command private def dependencies config = create_compiler "tool dependencies", no_codegen: true, dependencies: true - config.compiler.dependency_printer = DependencyPrinter.new(STDOUT, flat: config.output_format == "flat") + dependency_printer = DependencyPrinter.new(STDOUT, flat: config.output_format == "flat") + dependency_printer.includes.concat config.includes.map { |path| ::Path[path].expand.to_s } + dependency_printer.excludes.concat config.excludes.map { |path| ::Path[path].expand.to_s } + config.compiler.dependency_printer = dependency_printer + config.compiler.top_level_semantic config.sources end end @@ -14,17 +18,34 @@ end module Crystal class DependencyPrinter @depth = 0 + @filter_depth = Int32::MAX + + property includes = [] of String + property excludes = [] of String + + getter default_paths : Array(::Path) = CrystalPath.default_paths.map { |path| ::Path[path].expand } def initialize(@io : IO, @flat : Bool = false) end def enter_file(filename : String, unseen : Bool) - print_indent - print_file(filename) - unless unseen - @io.print " (duplicate skipped)" + if @depth <= @filter_depth + filter = filter?(filename) + if filter + @filter_depth = @depth + else + @filter_depth = Int32::MAX + end + + print_indent + print_file(filename) + if unseen + @io.print " (filtered)" if filter + else + @io.print " (duplicate skipped)" + end + @io.puts end - @io.puts @depth += 1 end @@ -41,5 +62,20 @@ module Crystal private def print_file(filename) @io.print ::Path[filename].relative_to?(Dir.current) || filename end + + private def filter?(filename) + paths = ::Path[filename].parents + paths << ::Path[filename] + + return false if match_patterns?(includes, paths) + + return true if default_paths.any? { |path| paths.includes?(path) } + + match_patterns?(excludes, paths) + end + + private def match_patterns?(patterns, paths) + patterns.any? { |pattern| paths.any? { |path| File.match?(pattern, path) } } + end end end