From 9d09cd4ea4a7ef8a3a4dbe4dd1347406f4ffc825 Mon Sep 17 00:00:00 2001 From: Kevin Newton Date: Mon, 19 Sep 2022 10:49:06 -0400 Subject: [PATCH] Support ignoring certain filepaths in CLI/rake --- README.md | 25 +++++++-- lib/syntax_tree/cli.rb | 19 ++++++- lib/syntax_tree/rake/check_task.rb | 71 +++---------------------- lib/syntax_tree/rake/task.rb | 85 ++++++++++++++++++++++++++++++ lib/syntax_tree/rake/write_task.rb | 73 +++---------------------- test/cli_test.rb | 6 +++ 6 files changed, 144 insertions(+), 135 deletions(-) create mode 100644 lib/syntax_tree/rake/task.rb diff --git a/README.md b/README.md index 47545502..afb65843 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ It is built with only standard library dependencies. It additionally ships with - [textDocument/inlayHint](#textdocumentinlayhint) - [syntaxTree/visualizing](#syntaxtreevisualizing) - [Plugins](#plugins) - - [Configuration](#configuration) + - [Customization](#customization) - [Languages](#languages) - [Integration](#integration) - [Rake](#rake) @@ -235,6 +235,12 @@ To change the print width that you are writing with, specify the `--print-width` stree write --print-width=100 path/to/file.rb ``` +To ignore certain files from a glob (in order to make it easier to specify the filepaths), you can pass the `--ignore-files` option as an additional glob, as in: + +```sh +stree write --ignore-files='db/**/*.rb' '**/*.rb' +``` + ### Configuration Any of the above CLI commands can also read configuration options from a `.streerc` file in the directory where the commands are executed. @@ -475,11 +481,11 @@ The language server additionally includes this custom request to return a textua ## Plugins -You can register additional configuration and additional languages that can flow through the same CLI with Syntax Tree's plugin system. When invoking the CLI, you pass through the list of plugins with the `--plugins` options to the commands that accept them. They should be a comma-delimited list. When the CLI first starts, it will require the files corresponding to those names. +You can register additional customization and additional languages that can flow through the same CLI with Syntax Tree's plugin system. When invoking the CLI, you pass through the list of plugins with the `--plugins` options to the commands that accept them. They should be a comma-delimited list. When the CLI first starts, it will require the files corresponding to those names. -### Configuration +### Customization -To register additional configuration, define a file somewhere in your load path named `syntax_tree/my_plugin`. Then when invoking the CLI, you will pass `--plugins=my_plugin`. To require multiple, separate them by a comma. In this way, you can modify Syntax Tree however you would like. Some plugins ship with Syntax Tree itself. They are: +To register additional customization, define a file somewhere in your load path named `syntax_tree/my_plugin`. Then when invoking the CLI, you will pass `--plugins=my_plugin`. To require multiple, separate them by a comma. In this way, you can modify Syntax Tree however you would like. Some plugins ship with Syntax Tree itself. They are: * `plugin/single_quotes` - This will change all of your string literals to use single quotes instead of the default double quotes. * `plugin/trailing_comma` - This will put trailing commas into multiline array literals, hash literals, and method calls that can support trailing commas. @@ -543,6 +549,17 @@ SyntaxTree::Rake::WriteTask.new do |t| end ``` +#### `ignore_files` + +If you want to ignore certain file patterns when running the command, you can pass the `ignore_files` option. This will be checked with `File.fnmatch?` against each filepath that the command would be run against. For example: + +```ruby +SyntaxTree::Rake::WriteTask.new do |t| + t.source_files = "**/*.rb" + t.ignore_files = "db/**/*.rb" +end +``` + #### `print_width` If you want to use a different print width from the default (80), you can pass that to the `print_width` field, as in: diff --git a/lib/syntax_tree/cli.rb b/lib/syntax_tree/cli.rb index ca3647f5..a364cd34 100644 --- a/lib/syntax_tree/cli.rb +++ b/lib/syntax_tree/cli.rb @@ -283,9 +283,14 @@ def run(item) # responsible for parsing the list and then returning the file paths at the # end. class Options - attr_reader :plugins, :print_width, :scripts, :target_ruby_version + attr_reader :ignore_files, + :plugins, + :print_width, + :scripts, + :target_ruby_version def initialize(print_width: DEFAULT_PRINT_WIDTH) + @ignore_files = "" @plugins = [] @print_width = print_width @scripts = [] @@ -304,6 +309,13 @@ def parse(arguments) def parser OptionParser.new do |opts| + # If there is a glob specified to ignore, then we'll track that here. + # Any of the CLI commands that operate on filenames will then ignore + # this set of files. + opts.on("--ignore-files=GLOB") do |glob| + @ignore_files = glob.match(/\A'(.*)'\z/) ? $1 : glob + end + # If there are any plugins specified on the command line, then load # them by requiring them here. We do this by transforming something # like @@ -428,7 +440,10 @@ def run(argv) Dir .glob(pattern) .each do |filepath| - queue << FileItem.new(filepath) if File.readable?(filepath) + if File.readable?(filepath) && + !File.fnmatch?(options.ignore_files, filepath) + queue << FileItem.new(filepath) + end end end diff --git a/lib/syntax_tree/rake/check_task.rb b/lib/syntax_tree/rake/check_task.rb index 48247718..5b441a5b 100644 --- a/lib/syntax_tree/rake/check_task.rb +++ b/lib/syntax_tree/rake/check_task.rb @@ -1,10 +1,6 @@ # frozen_string_literal: true -require "rake" -require "rake/tasklib" - -require "syntax_tree" -require "syntax_tree/cli" +require_relative "task" module SyntaxTree module Rake @@ -12,74 +8,21 @@ module Rake # # Example: # - # require 'syntax_tree/rake/check_task' + # require "syntax_tree/rake/check_task" # # SyntaxTree::Rake::CheckTask.new do |t| - # t.source_files = '{app,config,lib}/**/*.rb' + # t.source_files = "{app,config,lib}/**/*.rb" # end # # This will create task that can be run with: # - # rake stree_check + # rake stree:check # - class CheckTask < ::Rake::TaskLib - # Name of the task. - # Defaults to :"stree:check". - attr_accessor :name - - # Glob pattern to match source files. - # Defaults to 'lib/**/*.rb'. - attr_accessor :source_files - - # The set of plugins to require. - # Defaults to []. - attr_accessor :plugins - - # Max line length. - # Defaults to 80. - attr_accessor :print_width - - # The target Ruby version to use for formatting. - # Defaults to Gem::Version.new(RUBY_VERSION). - attr_accessor :target_ruby_version - - def initialize( - name = :"stree:check", - source_files = ::Rake::FileList["lib/**/*.rb"], - plugins = [], - print_width = DEFAULT_PRINT_WIDTH, - target_ruby_version = Gem::Version.new(RUBY_VERSION) - ) - @name = name - @source_files = source_files - @plugins = plugins - @print_width = print_width - @target_ruby_version = target_ruby_version - - yield self if block_given? - define_task - end - + class CheckTask < Task private - def define_task - desc "Runs `stree check` over source files" - task(name) { run_task } - end - - def run_task - arguments = ["check"] - arguments << "--plugins=#{plugins.join(",")}" if plugins.any? - - if print_width != DEFAULT_PRINT_WIDTH - arguments << "--print-width=#{print_width}" - end - - if target_ruby_version != Gem::Version.new(RUBY_VERSION) - arguments << "--target-ruby-version=#{target_ruby_version}" - end - - SyntaxTree::CLI.run(arguments + Array(source_files)) + def command + "check" end end end diff --git a/lib/syntax_tree/rake/task.rb b/lib/syntax_tree/rake/task.rb new file mode 100644 index 00000000..ea228e8f --- /dev/null +++ b/lib/syntax_tree/rake/task.rb @@ -0,0 +1,85 @@ +# frozen_string_literal: true + +require "rake" +require "rake/tasklib" + +require "syntax_tree" +require "syntax_tree/cli" + +module SyntaxTree + module Rake + # A parent Rake task that runs a command on a set of source files. + class Task < ::Rake::TaskLib + # Name of the task. + attr_accessor :name + + # Glob pattern to match source files. + # Defaults to 'lib/**/*.rb'. + attr_accessor :source_files + + # The set of plugins to require. + # Defaults to []. + attr_accessor :plugins + + # Max line length. + # Defaults to 80. + attr_accessor :print_width + + # The target Ruby version to use for formatting. + # Defaults to Gem::Version.new(RUBY_VERSION). + attr_accessor :target_ruby_version + + # Glob pattern to ignore source files. + # Defaults to ''. + attr_accessor :ignore_files + + def initialize( + name = :"stree:#{command}", + source_files = ::Rake::FileList["lib/**/*.rb"], + plugins = [], + print_width = DEFAULT_PRINT_WIDTH, + target_ruby_version = Gem::Version.new(RUBY_VERSION), + ignore_files = "" + ) + @name = name + @source_files = source_files + @plugins = plugins + @print_width = print_width + @target_ruby_version = target_ruby_version + @ignore_files = ignore_files + + yield self if block_given? + define_task + end + + private + + # This method needs to be overridden in the child tasks. + def command + raise NotImplementedError + end + + def define_task + desc "Runs `stree #{command}` over source files" + task(name) { run_task } + end + + def run_task + arguments = [command] + arguments << "--plugins=#{plugins.join(",")}" if plugins.any? + + if print_width != DEFAULT_PRINT_WIDTH + arguments << "--print-width=#{print_width}" + end + + if target_ruby_version != Gem::Version.new(RUBY_VERSION) + arguments << "--target-ruby-version=#{target_ruby_version}" + end + + arguments << "--ignore-files=#{ignore_files}" if ignore_files != "" + + SyntaxTree::CLI.run(arguments + Array(source_files)) + end + end + end +end diff --git a/lib/syntax_tree/rake/write_task.rb b/lib/syntax_tree/rake/write_task.rb index 69ce97e7..8037792e 100644 --- a/lib/syntax_tree/rake/write_task.rb +++ b/lib/syntax_tree/rake/write_task.rb @@ -1,85 +1,28 @@ # frozen_string_literal: true -require "rake" -require "rake/tasklib" - -require "syntax_tree" -require "syntax_tree/cli" +require_relative "task" module SyntaxTree module Rake - # A Rake task that runs format on a set of source files. + # A Rake task that runs write on a set of source files. # # Example: # - # require 'syntax_tree/rake/write_task' + # require "syntax_tree/rake/write_task" # # SyntaxTree::Rake::WriteTask.new do |t| - # t.source_files = '{app,config,lib}/**/*.rb' + # t.source_files = "{app,config,lib}/**/*.rb" # end # # This will create task that can be run with: # - # rake stree_write + # rake stree:write # - class WriteTask < ::Rake::TaskLib - # Name of the task. - # Defaults to :"stree:write". - attr_accessor :name - - # Glob pattern to match source files. - # Defaults to 'lib/**/*.rb'. - attr_accessor :source_files - - # The set of plugins to require. - # Defaults to []. - attr_accessor :plugins - - # Max line length. - # Defaults to 80. - attr_accessor :print_width - - # The target Ruby version to use for formatting. - # Defaults to Gem::Version.new(RUBY_VERSION). - attr_accessor :target_ruby_version - - def initialize( - name = :"stree:write", - source_files = ::Rake::FileList["lib/**/*.rb"], - plugins = [], - print_width = DEFAULT_PRINT_WIDTH, - target_ruby_version = Gem::Version.new(RUBY_VERSION) - ) - @name = name - @source_files = source_files - @plugins = plugins - @print_width = print_width - @target_ruby_version = target_ruby_version - - yield self if block_given? - define_task - end - + class WriteTask < Task private - def define_task - desc "Runs `stree write` over source files" - task(name) { run_task } - end - - def run_task - arguments = ["write"] - arguments << "--plugins=#{plugins.join(",")}" if plugins.any? - - if print_width != DEFAULT_PRINT_WIDTH - arguments << "--print-width=#{print_width}" - end - - if target_ruby_version != Gem::Version.new(RUBY_VERSION) - arguments << "--target-ruby-version=#{target_ruby_version}" - end - - SyntaxTree::CLI.run(arguments + Array(source_files)) + def command + "write" end end end diff --git a/test/cli_test.rb b/test/cli_test.rb index 6743f759..de09b093 100644 --- a/test/cli_test.rb +++ b/test/cli_test.rb @@ -32,6 +32,12 @@ def test_ast assert_includes(result.stdio, "ident \"test\"") end + def test_ast_ignore + result = run_cli("ast", "--ignore-files='*/test*'") + assert_equal(0, result.status) + assert_empty(result.stdio) + end + def test_ast_syntax_error result = run_cli("ast", contents: "foo\n<>\nbar\n") assert_includes(result.stderr, "syntax error")