diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..8947ad2 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,20 @@ +name: Test + +on: + pull_request: + push: + branches: + - '*' + +jobs: + unit: + name: Unit tests + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: ruby/setup-ruby@v1 + with: + ruby-version: '3.3' + bundler-cache: true + - name: Run tests + run: bundle exec rake diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 70c84bf..0000000 --- a/.travis.yml +++ /dev/null @@ -1,8 +0,0 @@ -sudo: false -language: ruby -script: bundle exec rspec - -matrix: - include: - - rvm: 2.5.5 - - rvm: 2.6.2 diff --git a/CHANGELOG.md b/CHANGELOG.md index 4690dcf..2e182dc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +# 2.2.0 +A number of bug fixes and improvements, namely: + +1. Fix handling of anonymous kwargs. +2. Fix formatting for nested classes when the parent class has methods. +3. Upgrade to v3.0 of the parser gem. +4. For certain types, the class name cannot be used as a type (eg. anonymous classes). Use `T.untyped` in these cases. +5. Add better support for Minitest via `require 'gelauto/minitest'`. This allows you to add Gelauto directly to your test setup, which works better than using the CLI for some projects. + # 2.1.0 * Do not add duplicate signatures to methods (@wpride, #15). diff --git a/README.md b/README.md index b500b88..5cc915d 100644 --- a/README.md +++ b/README.md @@ -137,6 +137,16 @@ GELAUTO_FILES=$(find . -name *.rb) GELAUTO_ANNOTATE=true bundle exec rspec Finally, set `GELAUTO_RBI=/path/to/output.rbi` to have Gelauto emit an RBI file when the test suite finishes. +#### Minitest Helper + +Gelauto also comes with a handy Minitest helper. Simply add + +```ruby +require 'gelauto/minitest' +``` + +to your test_helper.rb (or wherever Minitest is `require`d and configured). The same environment variables described above for RSpec, eg. `GELAUTO_FILES`, `GELAUTO_ANNOTATE`, and `GELAUTO_RBI`, can be used in a Minitest setup. + ## How does it Work? Gelauto makes use of Ruby's [TracePoint API](https://ruby-doc.org/core-2.6/TracePoint.html). TracePoint effectively allows Gelauto to receive a notification whenever a Ruby method is called and whenever a method returns. That info combined with method location information gathered from parsing your Ruby files ahead of time allows Gelauto to know a) where methods are located, 2) what arguments they take, 3) the types of those arguments, and 4) the type of the return value. diff --git a/gelauto.gemspec b/gelauto.gemspec index cea8ea7..4c4b79f 100644 --- a/gelauto.gemspec +++ b/gelauto.gemspec @@ -11,7 +11,7 @@ Gem::Specification.new do |s| s.description = s.summary = 'Automatically annotate your code with Sorbet type definitions.' s.platform = Gem::Platform::RUBY - s.add_dependency 'parser', '~> 2.6' + s.add_dependency 'parser', '~> 3.0' s.add_dependency 'gli', '~> 2.0' s.executables << 'gelauto' diff --git a/lib/gelauto.rb b/lib/gelauto.rb index d356398..e63a6fe 100644 --- a/lib/gelauto.rb +++ b/lib/gelauto.rb @@ -92,7 +92,7 @@ def index_methods ) Gelauto::Logger.info("Indexed #{idx + 1}/#{paths.size} paths") - rescue Parser::SyntaxError => e + rescue Parser::SyntaxError Gelauto::Logger.error("Syntax error in #{path}, skipping") end end diff --git a/lib/gelauto/method_index.rb b/lib/gelauto/method_index.rb index 496d27d..75c5e8e 100644 --- a/lib/gelauto/method_index.rb +++ b/lib/gelauto/method_index.rb @@ -17,10 +17,16 @@ def index_methods_in(path, ast, nesting = []) if ast.type == :def name = ast.children[0] - args = ast.children[1].children.map { |c| c.children.first } + args = ast.children[1].children.each_with_object([]) do |c, memo| + # ignore anonymous args like **, etc + memo << c.children.first if c.children.first + end else name = ast.children[1] - args = ast.children[2].children.map { |c| c.children.first } + args = ast.children[2].children.each_with_object([]) do |c, memo| + # ignore anonymous args like **, etc + memo << c.children.first if c.children.first + end end md = MethodDef.new(name, args, nesting) @@ -48,6 +54,8 @@ def find(path, lineno) # md is actually an index pointing to another line index[path][md] end + + nil end def each diff --git a/lib/gelauto/minitest.rb b/lib/gelauto/minitest.rb new file mode 100644 index 0000000..6c9597e --- /dev/null +++ b/lib/gelauto/minitest.rb @@ -0,0 +1,25 @@ +require 'gelauto' + +Gelauto.paths += ENV.fetch('GELAUTO_FILES', '').split(/[\s\n,]/).map(&:strip) +Gelauto.setup + +Minitest.after_run do + Gelauto.teardown + + if ENV['GELAUTO_ANNOTATE'] == 'true' + Gelauto.each_absolute_path do |path| + Gelauto.annotate_file(path) + Gelauto::Logger.info("Annotated #{path}") + end + end + + if ENV['GELAUTO_RBI'] + rbi_str = Gelauto::Rbi.new(Gelauto.method_index).to_s + + if ENV['GELAUTO_RBI'] == '-' + puts rbi_str + else + File.write(ENV['GELAUTO_RBI'], rbi_str) + end + end +end diff --git a/lib/gelauto/rbi.rb b/lib/gelauto/rbi.rb index 33ba50b..d2e9ea7 100644 --- a/lib/gelauto/rbi.rb +++ b/lib/gelauto/rbi.rb @@ -31,7 +31,7 @@ def compose(h, io, indent_level = 0) io.write(indent(h[:methods].map { |md| md.to_rbi }.join("\n\n"), indent_level)) h[:children].each_with_index do |((namespace, type), next_level), idx| - io.write("\n\n") if idx > 0 + io.write("\n\n") if idx > 0 || h[:methods].size > 0 io.write(indent("#{type} #{namespace}", indent_level)) io.write("\n") compose(next_level, io, indent_level + 1) diff --git a/lib/gelauto/type_set.rb b/lib/gelauto/type_set.rb index f11ef6c..4c17664 100644 --- a/lib/gelauto/type_set.rb +++ b/lib/gelauto/type_set.rb @@ -43,7 +43,9 @@ def to_sig if rt == ::NilClass nilable = true else - ret << t.to_sig + t.to_sig.tap do |s| + ret << s if s + end end end diff --git a/lib/gelauto/version.rb b/lib/gelauto/version.rb index a25736e..f81b3b1 100644 --- a/lib/gelauto/version.rb +++ b/lib/gelauto/version.rb @@ -1,3 +1,3 @@ module Gelauto - VERSION = '2.1.0' + VERSION = '2.2.0' end