diff --git a/CHANGELOG.md b/CHANGELOG.md index d5f9ba82..ee7261ea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,12 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a ## [Unreleased] +## [3.0.1] - 2022-07-15 + +### Changed + +- [#112](https://github.com/ruby-syntax-tree/syntax_tree/pull/112) - Fix parallel CLI execution by not short-circuiting with the `||` operator. + ## [3.0.0] - 2022-07-04 ### Changed @@ -288,7 +294,9 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a - 🎉 Initial release! 🎉 -[unreleased]: https://github.com/ruby-syntax-tree/syntax_tree/compare/v2.9.0...HEAD +[unreleased]: https://github.com/ruby-syntax-tree/syntax_tree/compare/v3.0.1...HEAD +[3.0.1]: https://github.com/ruby-syntax-tree/syntax_tree/compare/v3.0.0...v3.0.1 +[3.0.0]: https://github.com/ruby-syntax-tree/syntax_tree/compare/v2.9.0...v3.0.0 [2.9.0]: https://github.com/ruby-syntax-tree/syntax_tree/compare/v2.8.0...v2.9.0 [2.8.0]: https://github.com/ruby-syntax-tree/syntax_tree/compare/v2.7.1...v2.8.0 [2.7.1]: https://github.com/ruby-syntax-tree/syntax_tree/compare/v2.7.0...v2.7.1 diff --git a/Gemfile.lock b/Gemfile.lock index 62415795..ac7403ba 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - syntax_tree (3.0.0) + syntax_tree (3.0.1) prettier_print GEM @@ -19,7 +19,7 @@ GEM rake (13.0.6) regexp_parser (2.5.0) rexml (3.2.5) - rubocop (1.31.1) + rubocop (1.31.2) json (~> 2.3) parallel (~> 1.10) parser (>= 3.1.0.0) diff --git a/lib/syntax_tree/cli.rb b/lib/syntax_tree/cli.rb index a7c6a684..c8e42831 100644 --- a/lib/syntax_tree/cli.rb +++ b/lib/syntax_tree/cli.rb @@ -315,23 +315,7 @@ def run(argv) # At the end, we're going to return whether or not this worker ever # encountered an error. - errored = - with_workers(queue) do |item| - action.run(item) - false - rescue Parser::ParseError => error - warn("Error: #{error.message}") - highlight_error(error, item.source) - true - rescue Check::UnformattedError, Debug::NonIdempotentFormatError - true - rescue StandardError => error - warn(error.message) - warn(error.backtrace) - true - end - - if errored + if process_queue(queue, action) action.failure 1 else @@ -342,13 +326,11 @@ def run(argv) private - def with_workers(queue) - # If the queue is just 1 item, then we're not going to bother going - # through the whole ceremony of parallelizing the work. - return yield queue.shift if queue.size == 1 - + # Processes each item in the queue with the given action. Returns whether + # or not any errors were encountered. + def process_queue(queue, action) workers = - Etc.nprocessors.times.map do + [Etc.nprocessors, queue.size].min.times.map do Thread.new do # Propagate errors in the worker threads up to the parent thread. Thread.current.abort_on_exception = true @@ -360,7 +342,25 @@ def with_workers(queue) # While there is still work left to do, shift off the queue and # process the item. - (errored ||= yield queue.shift) until queue.empty? + until queue.empty? + item = queue.shift + errored |= + begin + action.run(item) + false + rescue Parser::ParseError => error + warn("Error: #{error.message}") + highlight_error(error, item.source) + true + rescue Check::UnformattedError, + Debug::NonIdempotentFormatError + true + rescue StandardError => error + warn(error.message) + warn(error.backtrace) + true + end + end # At the end, we're going to return whether or not this worker # ever encountered an error. @@ -368,7 +368,7 @@ def with_workers(queue) end end - workers.inject(false) { |accum, thread| accum || thread.value } + workers.map(&:value).inject(:|) end # Highlights a snippet from a source and parse error. diff --git a/lib/syntax_tree/version.rb b/lib/syntax_tree/version.rb index d3f929e6..3a740b84 100644 --- a/lib/syntax_tree/version.rb +++ b/lib/syntax_tree/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module SyntaxTree - VERSION = "3.0.0" + VERSION = "3.0.1" end