diff --git a/CHANGELOG.md b/CHANGELOG.md index 7f4ddb9..8d7ddb8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ ## HEAD (unreleased) +## 1.0.0 + +- Gem name changed from `syntax_search` to `dead_end` (https://github.com/zombocom/syntax_search/pull/30) +- Moved `syntax_search/auto` behavior to top level require (https://github.com/zombocom/syntax_search/pull/30) - Error banner now indicates when missing a `|` or `}` in addition to `end` (https://github.com/zombocom/syntax_search/pull/29) - Trailing slashes are now handled (joined) before the code search (https://github.com/zombocom/syntax_search/pull/28) diff --git a/Gemfile b/Gemfile index f046253..89e7644 100644 --- a/Gemfile +++ b/Gemfile @@ -2,7 +2,7 @@ source "https://rubygems.org" -# Specify your gem's dependencies in syntax_search.gemspec +# Specify your gem's dependencies in dead_end.gemspec gemspec gem "rake", "~> 12.0" diff --git a/Gemfile.lock b/Gemfile.lock index a50d062..ac1075a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - syntax_search (0.2.0) + dead_end (1.0.0) GEM remote: https://rubygems.org/ @@ -27,10 +27,10 @@ PLATFORMS ruby DEPENDENCIES + dead_end! rake (~> 12.0) rspec (~> 3.0) stackprof - syntax_search! BUNDLED WITH 2.1.4 diff --git a/README.md b/README.md index 677a6cd..f2c225c 100644 --- a/README.md +++ b/README.md @@ -1,43 +1,27 @@ -# SyntaxSearch +# DeadEnd -Imagine you're programming, everything is awesome. You write code, it runs. Still awesome. You write more code, you save it, you run it and then: +An AI powered library to find syntax errors in your source code: -``` -file.rb:333: syntax error, unexpected `end', expecting end-of-input -``` - -What happened? Likely you forgot a `def`, `do`, or maybe you deleted some code and missed an `end`. Either way it's an extremely unhelpful error and a very time consuming mistake to track down. - -What if I told you, that there was a library that helped find your missing `def`s and missing `do`s. What if instead of searching through hundreds of lines of source for the cause of your syntax error, there was a way to highlight just code in the file that contained syntax errors. - - $ syntax_search path/to/file.rb - - SyntaxSearch: Unmatched `end` detected + DeadEnd: Unmatched `end` detected This code has an unmatched `end`. Ensure that all `end` lines in your code have a matching syntax keyword (`def`, `do`, etc.) and that you don't have any extra `end` lines. - file: path/to/file.rb + file: path/to/dog.rb simplified: - 1 require 'zoo' - 2 - 3 class Animal - 4 - ❯ 5 defdog + 3 class Dog + ❯ 5 defbark ❯ 7 end - 8 12 end -How much would you pay for such a library? A million, a billion, a trillion? Well friends, today is your lucky day because you can use this library today for free! - ## Installation in your codebase To automatically search syntax errors when they happen, add this to your Gemfile: ```ruby -gem 'syntax_search', require: "syntax_search/auto" +gem 'dead_end' ``` And then execute: @@ -47,13 +31,13 @@ And then execute: If your application is not calling `Bundler.require` then you must manually add a require: ```ruby -require "syntax_search/auto" +require "dead_end" ``` If you're using rspec add this to your `.rspec` file: ``` ---require syntax_search/auto +--require dead_end ``` > This is needed because people can execute a single test file via `bundle exec rspec path/to/file_spec.rb` and if that file has a syntax error, it won't load `spec_helper.rb` to trigger any requires. @@ -62,13 +46,40 @@ If you're using rspec add this to your `.rspec` file: To get the CLI and manually search for syntax errors, install the gem: - $ gem install syntax_search + $ gem install dead_end + +This gives you the CLI command `$ dead_end` for more info run `$ dead_end --help`. + +## What syntax errors does it handle? + +- Missing `end`: + +``` +class Dog + def bark + puts "bark" + + def woof + puts "woof" + end +end +# => scratch.rb:8: syntax error, unexpected end-of-input, expecting `end' +``` -This gives you the CLI command `$ syntax_search` for more info run `$ syntax_search --help`. +- Unexpected `end` -## What does it do? +``` +class Dog + def speak + @sounds.each |sound| # Note the missing `do` here + puts sound + end + end +end +# => scratch.rb:7: syntax error, unexpected `end', expecting end-of-input +``` -When your code triggers a SyntaxError due to an "unexpected `end'" in a file, this library fires to narrow down your search to the most likely offending locations. +As well as unmatched `|` and unmatched `}`. These errors can be time consuming to debug because Ruby often only tells you the last line in the file. The command `ruby -wc path/to/file.rb` can narrow it down a little bit, but this library does a better job. ## Sounds cool, but why isn't this baked into Ruby directly? @@ -77,6 +88,10 @@ I would love to get something like this directly in Ruby, but I first need to pr 1. Get real world useage and feedback. If we gave you an awful suggestion, let us know! We try to handle lots of cases well, but maybe we could be better. 2. Prove out demand. If you like this idea, then vote for it by putting it in your Gemfile. +## Artificial Inteligence? + +This library uses a goal-seeking algorithm similar to that of a path-finding search. For more information [read the blog post about how it works under the hood](https://schneems.com/2020/12/01/squash-unexpectedend-errors-with-syntaxsearch/). + ## How does it detect syntax error locations? We know that source code that does not contain a syntax error can be parsed. We also know that code with a syntax error contains both valid code and invalid code. If you remove the invalid code, then we can programatically determine that the code we removed contained a syntax error. We can do this detection by generating small code blocks and searching for which blocks need to be removed to generate valid source code. @@ -87,16 +102,6 @@ Here's an example: ![](assets/syntax_search.gif) -## How is source code broken up into smaller blocks? - -By definition source code with a syntax error in it cannot be parsed, so we have to guess how to chunk up the file into smaller pieces. Once we've split up the file we can safely rule out or zoom into a specific piece of code to determine the location of the syntax error. This libary uses indentation and empty lines to make guesses about what might be a "block" of code. Once we've got a chunk of code, we can test it. - -At the end of the day we can't say where the syntax error is FOR SURE, but we can get pretty close. It sounds simple when spelled out like this, but it's a very complicated problem. Even when code is not correctly indented/formatted we can still likely tell you where to start searching even if we can't point at the exact problem line or location. - -## How does this gem know when a syntax error occured in my code? - -Right now the search isn't performed automatically when you get a syntax error. Instead we append a warning message letting you know how to test the file. Eventually we'll enable the seach by default instead of printing a warning message. To do both of these we have to monkeypatch `require` in the same way that bootsnap does. - ## Development After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment. @@ -105,7 +110,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To ## Contributing -Bug reports and pull requests are welcome on GitHub at https://github.com/zombocom/syntax_search. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/[USERNAME]/syntax_search/blob/master/CODE_OF_CONDUCT.md). +Bug reports and pull requests are welcome on GitHub at https://github.com/zombocom/dead_end. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/zombocom/dead_end/blob/master/CODE_OF_CONDUCT.md). ## License @@ -114,4 +119,4 @@ The gem is available as open source under the terms of the [MIT License](https:/ ## Code of Conduct -Everyone interacting in the SyntaxErrorSearch project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/zombocom/syntax_search/blob/master/CODE_OF_CONDUCT.md). +Everyone interacting in the DeadEnd project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/zombocom/dead_end/blob/master/CODE_OF_CONDUCT.md). diff --git a/bin/console b/bin/console index 5b9e60d..b3c0995 100755 --- a/bin/console +++ b/bin/console @@ -1,7 +1,7 @@ #!/usr/bin/env ruby require "bundler/setup" -require "syntax_search" +require "dead_end" # You can add fixtures and/or initialization code here to make experimenting # with your gem easier. You can also use a different console, if you like. diff --git a/syntax_search.gemspec b/dead_end.gemspec similarity index 81% rename from syntax_search.gemspec rename to dead_end.gemspec index 4a705ad..3576f93 100644 --- a/syntax_search.gemspec +++ b/dead_end.gemspec @@ -1,21 +1,21 @@ # frozen_string_literal: true -require_relative 'lib/syntax_search/version' +require_relative 'lib/dead_end/version' Gem::Specification.new do |spec| - spec.name = "syntax_search" - spec.version = SyntaxErrorSearch::VERSION + spec.name = "dead_end" + spec.version = DeadEnd::VERSION spec.authors = ["schneems"] spec.email = ["richard.schneeman+foo@gmail.com"] spec.summary = %q{Find syntax errors in your source in a snap} spec.description = %q{When you get an "unexpected end" in your syntax this gem helps you find it} - spec.homepage = "https://github.com/zombocom/syntax_search.git" + spec.homepage = "https://github.com/zombocom/dead_end.git" spec.license = "MIT" spec.required_ruby_version = Gem::Requirement.new(">= 2.5.0") spec.metadata["homepage_uri"] = spec.homepage - spec.metadata["source_code_uri"] = "https://github.com/zombocom/syntax_search.git" + spec.metadata["source_code_uri"] = "https://github.com/zombocom/dead_end.git" # Specify which files should be added to the gem when it is released. # The `git ls-files -z` loads the files in the RubyGem that have been added into git. diff --git a/exe/syntax_search b/exe/dead_end similarity index 66% rename from exe/syntax_search rename to exe/dead_end index 5102f9d..bccb636 100755 --- a/exe/syntax_search +++ b/exe/dead_end @@ -2,39 +2,35 @@ require 'pathname' require "optparse" -require_relative "../lib/syntax_search.rb" +require_relative "../lib/dead_end.rb" options = {} options[:terminal] = true -options[:record_dir] = ENV["SYNTAX_SEARCH_RECORD_DIR"] +options[:record_dir] = ENV["DEAD_END_RECORD_DIR"] parser = OptionParser.new do |opts| opts.banner = <<~EOM - Usage: syntax_search [options] + Usage: dead_end [options] - Parses a ruby source file and searches for syntax error(s) unexpected `end', expecting end-of-input. + Parses a ruby source file and searches for syntax error(s) such as + unexpected `end', expecting end-of-input. Example: - $ syntax_search dog.rb + $ dead_end dog.rb # ... - ``` - 1 require 'animals' - 2 - ❯ 10 defdog - ❯ 15 end - ❯ 16 - 20 def cat - 22 end - ``` + ❯ 10 defdog + ❯ 15 end + ❯ 16 Env options: - SYNTAX_SEARCH_RECORD_DIR= + DEAD_END_RECORD_DIR= - When enabled, records the steps used to search for a syntax error to the given directory + When enabled, records the steps used to search for a syntax error to the + given directory Options: EOM @@ -66,7 +62,7 @@ options[:record_dir] = "tmp" if ENV["DEBUG"] $stderr.puts "Record dir: #{options[:record_dir]}" if options[:record_dir] -SyntaxErrorSearch.call( +DeadEnd.call( source: file.read, filename: file.expand_path, terminal: options[:terminal], diff --git a/lib/dead_end.rb b/lib/dead_end.rb new file mode 100644 index 0000000..cd55c53 --- /dev/null +++ b/lib/dead_end.rb @@ -0,0 +1,4 @@ +# frozen_string_literal: true + +require_relative "dead_end/internals" +require_relative "dead_end/auto" diff --git a/lib/syntax_search/around_block_scan.rb b/lib/dead_end/around_block_scan.rb similarity index 99% rename from lib/syntax_search/around_block_scan.rb rename to lib/dead_end/around_block_scan.rb index cc7af16..8aea9df 100644 --- a/lib/syntax_search/around_block_scan.rb +++ b/lib/dead_end/around_block_scan.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true # -module SyntaxErrorSearch +module DeadEnd # This class is useful for exploring contents before and after # a block # diff --git a/lib/syntax_search/auto.rb b/lib/dead_end/auto.rb similarity index 82% rename from lib/syntax_search/auto.rb rename to lib/dead_end/auto.rb index ad47389..3ee1905 100644 --- a/lib/syntax_search/auto.rb +++ b/lib/dead_end/auto.rb @@ -1,4 +1,4 @@ -require_relative "../syntax_search" +require_relative "../dead_end/internals" # Monkey patch kernel to ensure that all `require` calls call the same # method @@ -10,13 +10,13 @@ module Kernel def load(file, wrap = false) original_load(file) rescue SyntaxError => e - SyntaxErrorSearch.handle_error(e) + DeadEnd.handle_error(e) end def require(file) original_require(file) rescue SyntaxError => e - SyntaxErrorSearch.handle_error(e) + DeadEnd.handle_error(e) end def require_relative(file) @@ -26,7 +26,7 @@ def require_relative(file) original_require File.expand_path("../#{file}", caller_locations(1, 1)[0].absolute_path) end rescue SyntaxError => e - SyntaxErrorSearch.handle_error(e) + DeadEnd.handle_error(e) end end @@ -39,13 +39,13 @@ class Object def load(path, wrap = false) Kernel.load(path, wrap) rescue SyntaxError => e - SyntaxErrorSearch.handle_error(e) + DeadEnd.handle_error(e) end def require(path) Kernel.require(path) rescue SyntaxError => e - SyntaxErrorSearch.handle_error(e) + DeadEnd.handle_error(e) end end diff --git a/lib/syntax_search/block_expand.rb b/lib/dead_end/block_expand.rb similarity index 98% rename from lib/syntax_search/block_expand.rb rename to lib/dead_end/block_expand.rb index 947b039..b48c80a 100644 --- a/lib/syntax_search/block_expand.rb +++ b/lib/dead_end/block_expand.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true -module SyntaxErrorSearch +module DeadEnd # This class is responsible for taking a code block that exists # at a far indentaion and then iteratively increasing the block # so that it captures everything within the same indentation block. diff --git a/lib/syntax_search/capture_code_context.rb b/lib/dead_end/capture_code_context.rb similarity index 98% rename from lib/syntax_search/capture_code_context.rb rename to lib/dead_end/capture_code_context.rb index 94d5ac6..0518344 100644 --- a/lib/syntax_search/capture_code_context.rb +++ b/lib/dead_end/capture_code_context.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -module SyntaxErrorSearch +module DeadEnd # Given a block, this method will capture surrounding # code to give the user more context for the location of diff --git a/lib/syntax_search/code_block.rb b/lib/dead_end/code_block.rb similarity index 95% rename from lib/syntax_search/code_block.rb rename to lib/dead_end/code_block.rb index 754e952..786fb9f 100644 --- a/lib/syntax_search/code_block.rb +++ b/lib/dead_end/code_block.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -module SyntaxErrorSearch +module DeadEnd # Multiple lines form a singular CodeBlock # # Source code is made of multiple CodeBlocks. @@ -68,7 +68,7 @@ def invalid? end def valid? - SyntaxErrorSearch.valid?(self.to_s) + DeadEnd.valid?(self.to_s) end def to_s diff --git a/lib/syntax_search/code_frontier.rb b/lib/dead_end/code_frontier.rb similarity index 98% rename from lib/syntax_search/code_frontier.rb rename to lib/dead_end/code_frontier.rb index f8b87f4..e5659d6 100644 --- a/lib/syntax_search/code_frontier.rb +++ b/lib/dead_end/code_frontier.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -module SyntaxErrorSearch +module DeadEnd # The main function of the frontier is to hold the edges of our search and to # evaluate when we can stop searching. # @@ -64,7 +64,7 @@ def holds_all_syntax_errors?(block_array = @frontier) block.lines end - SyntaxErrorSearch.valid_without?( + DeadEnd.valid_without?( without_lines: without_lines, code_lines: @code_lines ) diff --git a/lib/syntax_search/code_line.rb b/lib/dead_end/code_line.rb similarity index 99% rename from lib/syntax_search/code_line.rb rename to lib/dead_end/code_line.rb index b5f7ea1..5c874b7 100644 --- a/lib/syntax_search/code_line.rb +++ b/lib/dead_end/code_line.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -module SyntaxErrorSearch +module DeadEnd # Represents a single line of code of a given source file # # This object contains metadata about the line such as diff --git a/lib/syntax_search/code_search.rb b/lib/dead_end/code_search.rb similarity index 97% rename from lib/syntax_search/code_search.rb rename to lib/dead_end/code_search.rb index 485e887..7fc97e1 100644 --- a/lib/syntax_search/code_search.rb +++ b/lib/dead_end/code_search.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -module SyntaxErrorSearch +module DeadEnd # Searches code for a syntax error # # The bulk of the heavy lifting is done in: @@ -28,7 +28,7 @@ class CodeSearch private; attr_reader :frontier; public public; attr_reader :invalid_blocks, :record_dir, :code_lines - def initialize(source, record_dir: ENV["SYNTAX_SEARCH_RECORD_DIR"] || ENV["DEBUG"] ? "tmp" : nil) + def initialize(source, record_dir: ENV["DEAD_END_RECORD_DIR"] || ENV["DEBUG"] ? "tmp" : nil) @source = source if record_dir @time = Time.now.strftime('%Y-%m-%d-%H-%M-%s-%N') diff --git a/lib/syntax_search/display_code_with_line_numbers.rb b/lib/dead_end/display_code_with_line_numbers.rb similarity index 98% rename from lib/syntax_search/display_code_with_line_numbers.rb rename to lib/dead_end/display_code_with_line_numbers.rb index ca3015a..dbe3147 100644 --- a/lib/syntax_search/display_code_with_line_numbers.rb +++ b/lib/dead_end/display_code_with_line_numbers.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -module SyntaxErrorSearch +module DeadEnd # Outputs code with highlighted lines # # Whatever is passed to this class will be rendered diff --git a/lib/syntax_search/display_invalid_blocks.rb b/lib/dead_end/display_invalid_blocks.rb similarity index 89% rename from lib/syntax_search/display_invalid_blocks.rb rename to lib/dead_end/display_invalid_blocks.rb index 7ddf2e5..11b5c4d 100644 --- a/lib/syntax_search/display_invalid_blocks.rb +++ b/lib/dead_end/display_invalid_blocks.rb @@ -3,7 +3,7 @@ require_relative "capture_code_context" require_relative "display_code_with_line_numbers" -module SyntaxErrorSearch +module DeadEnd # Used for formatting invalid blocks class DisplayInvalidBlocks attr_reader :filename @@ -51,7 +51,7 @@ def banner case @invalid_obj.error_symbol when :missing_end <<~EOM - SyntaxSearch: Missing `end` detected + DeadEnd: Missing `end` detected This code has a missing `end`. Ensure that all syntax keywords (`def`, `do`, etc.) have a matching `end`. @@ -60,7 +60,7 @@ def banner case @invalid_obj.unmatched_symbol when :end <<~EOM - SyntaxSearch: Unmatched `end` detected + DeadEnd: Unmatched `end` detected This code has an unmatched `end`. Ensure that all `end` lines in your code have a matching syntax keyword (`def`, `do`, etc.) @@ -68,7 +68,7 @@ def banner EOM when :| <<~EOM - SyntaxSearch: Unmatched `|` character detected + DeadEnd: Unmatched `|` character detected Example: @@ -76,13 +76,13 @@ def banner EOM when :"}" <<~EOM - SyntaxSearch: Unmatched `}` character detected + DeadEnd: Unmatched `}` character detected This code has an unmatched `}`. Ensure that opening curl braces are closed: `{ }`. EOM else - "SyntaxSearch: Unmatched #{@invalid_obj.unmatched_symbol}` detected" + "DeadEnd: Unmatched #{@invalid_obj.unmatched_symbol}` detected" end end diff --git a/lib/dead_end/fyi.rb b/lib/dead_end/fyi.rb new file mode 100644 index 0000000..6e37c2a --- /dev/null +++ b/lib/dead_end/fyi.rb @@ -0,0 +1,7 @@ +require_relative "../dead_end/internals" + +require_relative "auto.rb" + +DeadEnd.send(:remove_const, :SEARCH_SOURCE_ON_ERROR_DEFAULT) +DeadEnd::SEARCH_SOURCE_ON_ERROR_DEFAULT = false + diff --git a/lib/syntax_search/heredoc_block_parse.rb b/lib/dead_end/heredoc_block_parse.rb similarity index 96% rename from lib/syntax_search/heredoc_block_parse.rb rename to lib/dead_end/heredoc_block_parse.rb index 9617530..5d48ba3 100644 --- a/lib/syntax_search/heredoc_block_parse.rb +++ b/lib/dead_end/heredoc_block_parse.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -module SyntaxErrorSearch +module DeadEnd # Takes in a source, and returns blocks containing each heredoc class HeredocBlockParse private; attr_reader :code_lines, :lex; public diff --git a/lib/syntax_search.rb b/lib/dead_end/internals.rb similarity index 71% rename from lib/syntax_search.rb rename to lib/dead_end/internals.rb index ed89e23..c4bb39f 100644 --- a/lib/syntax_search.rb +++ b/lib/dead_end/internals.rb @@ -1,6 +1,9 @@ # frozen_string_literal: true +# +# This is the top level file, but is moved to `internals` +# so the top level file can instead enable the "automatic" behavior -require_relative "syntax_search/version" +require_relative "version" require 'tmpdir' require 'stringio' @@ -8,10 +11,10 @@ require 'ripper' require 'timeout' -module SyntaxErrorSearch +module DeadEnd class Error < StandardError; end SEARCH_SOURCE_ON_ERROR_DEFAULT = true - TIMEOUT_DEFAULT = ENV.fetch("SYNTAX_SEARCH_TIMEOUT", 5).to_i + TIMEOUT_DEFAULT = ENV.fetch("DEAD_END_TIMEOUT", 5).to_i def self.handle_error(e, search_source_on_error: SEARCH_SOURCE_ON_ERROR_DEFAULT) raise e if !e.message.include?("end-of-input") @@ -19,7 +22,7 @@ def self.handle_error(e, search_source_on_error: SEARCH_SOURCE_ON_ERROR_DEFAULT) filename = e.message.split(":").first $stderr.sync = true - $stderr.puts "Run `$ syntax_search #{filename}` for more options\n" + $stderr.puts "Run `$ dead_end #{filename}` for more options\n" if search_source_on_error self.call( @@ -50,7 +53,7 @@ def self.call(source: , filename: , terminal: false, record_dir: nil, timeout: T io: $stderr ).call rescue Timeout::Error - $stderr.puts "Syntax search timed out SYNTAX_SEARCH_TIMEOUT=#{timeout}, run with DEBUG=1 for more info" + $stderr.puts "Search timed out DEAD_END_TIMEOUT=#{timeout}, run with DEBUG=1 for more info" end # Used for counting spaces @@ -71,12 +74,12 @@ def self.indent(string) # CodeLine.new(line: "end\n", index: 2) # ] # - # SyntaxErrorSearch.valid_without?( + # DeadEnd.valid_without?( # without_lines: code_lines[1], # code_lines: code_lines # ) # => true # - # SyntaxErrorSearch.valid?(code_lines) # => false + # DeadEnd.valid?(code_lines) # => false def self.valid_without?(without_lines: , code_lines:) lines = code_lines - Array(without_lines).flatten @@ -96,12 +99,12 @@ def self.invalid?(source) # Returns truthy if a given input source is valid syntax # - # SyntaxErrorSearch.valid?(<<~EOM) # => true + # DeadEnd.valid?(<<~EOM) # => true # def foo # end # EOM # - # SyntaxErrorSearch.valid?(<<~EOM) # => false + # DeadEnd.valid?(<<~EOM) # => false # def foo # def bar # Syntax error here # end @@ -110,14 +113,14 @@ def self.invalid?(source) # You can also pass in an array of lines and they'll be # joined before evaluating # - # SyntaxErrorSearch.valid?( + # DeadEnd.valid?( # [ # "def foo\n", # "end\n" # ] # ) # => true # - # SyntaxErrorSearch.valid?( + # DeadEnd.valid?( # [ # "def foo\n", # " def bar\n", # Syntax error here @@ -138,16 +141,16 @@ def self.invalid_type(source) end end -require_relative "syntax_search/code_line" -require_relative "syntax_search/code_block" -require_relative "syntax_search/code_frontier" -require_relative "syntax_search/display_invalid_blocks" -require_relative "syntax_search/around_block_scan" -require_relative "syntax_search/block_expand" -require_relative "syntax_search/parse_blocks_from_indent_line" - -require_relative "syntax_search/code_search" -require_relative "syntax_search/who_dis_syntax_error" -require_relative "syntax_search/heredoc_block_parse" -require_relative "syntax_search/lex_all" -require_relative "syntax_search/trailing_slash_join" +require_relative "code_line" +require_relative "code_block" +require_relative "code_frontier" +require_relative "display_invalid_blocks" +require_relative "around_block_scan" +require_relative "block_expand" +require_relative "parse_blocks_from_indent_line" + +require_relative "code_search" +require_relative "who_dis_syntax_error" +require_relative "heredoc_block_parse" +require_relative "lex_all" +require_relative "trailing_slash_join" diff --git a/lib/syntax_search/lex_all.rb b/lib/dead_end/lex_all.rb similarity index 98% rename from lib/syntax_search/lex_all.rb rename to lib/dead_end/lex_all.rb index 11a4305..5a6a128 100644 --- a/lib/syntax_search/lex_all.rb +++ b/lib/dead_end/lex_all.rb @@ -1,4 +1,4 @@ -module SyntaxErrorSearch +module DeadEnd # Ripper.lex is not guaranteed to lex the entire source document # # lex = LexAll.new(source: source) diff --git a/lib/syntax_search/parse_blocks_from_indent_line.rb b/lib/dead_end/parse_blocks_from_indent_line.rb similarity index 98% rename from lib/syntax_search/parse_blocks_from_indent_line.rb rename to lib/dead_end/parse_blocks_from_indent_line.rb index 53cb8b4..b2cb436 100644 --- a/lib/syntax_search/parse_blocks_from_indent_line.rb +++ b/lib/dead_end/parse_blocks_from_indent_line.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -module SyntaxErrorSearch +module DeadEnd # This class is responsible for generating initial code blocks # that will then later be expanded. # diff --git a/lib/syntax_search/trailing_slash_join.rb b/lib/dead_end/trailing_slash_join.rb similarity index 98% rename from lib/syntax_search/trailing_slash_join.rb rename to lib/dead_end/trailing_slash_join.rb index abe7820..76c54a8 100644 --- a/lib/syntax_search/trailing_slash_join.rb +++ b/lib/dead_end/trailing_slash_join.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -module SyntaxErrorSearch +module DeadEnd # Handles code that contains trailing slashes # by turning multiple lines with trailing slash(es) into # a single code line diff --git a/lib/dead_end/version.rb b/lib/dead_end/version.rb new file mode 100644 index 0000000..d404adb --- /dev/null +++ b/lib/dead_end/version.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +module DeadEnd + VERSION = "1.0.0" +end diff --git a/lib/syntax_search/who_dis_syntax_error.rb b/lib/dead_end/who_dis_syntax_error.rb similarity index 98% rename from lib/syntax_search/who_dis_syntax_error.rb rename to lib/dead_end/who_dis_syntax_error.rb index c5eb227..4f5e360 100644 --- a/lib/syntax_search/who_dis_syntax_error.rb +++ b/lib/dead_end/who_dis_syntax_error.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -module SyntaxErrorSearch +module DeadEnd # Determines what type of syntax error is in the source # # Example: diff --git a/lib/syntax_search/fyi.rb b/lib/syntax_search/fyi.rb deleted file mode 100644 index 0bfc17c..0000000 --- a/lib/syntax_search/fyi.rb +++ /dev/null @@ -1,7 +0,0 @@ -require_relative "../syntax_search" - -require_relative "auto.rb" - -SyntaxErrorSearch.send(:remove_const, :SEARCH_SOURCE_ON_ERROR_DEFAULT) -SyntaxErrorSearch::SEARCH_SOURCE_ON_ERROR_DEFAULT = false - diff --git a/lib/syntax_search/version.rb b/lib/syntax_search/version.rb deleted file mode 100644 index f54b1e7..0000000 --- a/lib/syntax_search/version.rb +++ /dev/null @@ -1,5 +0,0 @@ -# frozen_string_literal: true - -module SyntaxErrorSearch - VERSION = "0.2.0" -end diff --git a/spec/fixtures/rexe.rb b/spec/fixtures/rexe.rb.txt similarity index 100% rename from spec/fixtures/rexe.rb rename to spec/fixtures/rexe.rb.txt diff --git a/spec/fixtures/this_project_extra_def.rb.txt b/spec/fixtures/this_project_extra_def.rb.txt index 1ad29ad..23369f7 100644 --- a/spec/fixtures/this_project_extra_def.rb.txt +++ b/spec/fixtures/this_project_extra_def.rb.txt @@ -17,7 +17,7 @@ module SyntaxErrorSearch def call @io.puts <<~EOM - SyntaxErrorSearch: A syntax error was detected + DeadEnd: A syntax error was detected This code has an unmatched `end` this is caused by either missing a syntax keyword (`def`, `do`, etc.) or inclusion diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index b6394ba..7cd194e 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true require "bundler/setup" -require "syntax_search" +require "dead_end/internals" # Don't auto load code to require 'tempfile' @@ -36,7 +36,7 @@ def fixtures_dir def code_line_array(string) code_lines = [] string.lines.each_with_index do |line, index| - code_lines << SyntaxErrorSearch::CodeLine.new(line: line, index: index) + code_lines << DeadEnd::CodeLine.new(line: line, index: index) end code_lines end diff --git a/spec/unit/around_block_scan_spec.rb b/spec/unit/around_block_scan_spec.rb index 93401e9..a9e6b73 100644 --- a/spec/unit/around_block_scan_spec.rb +++ b/spec/unit/around_block_scan_spec.rb @@ -2,7 +2,7 @@ require_relative "../spec_helper.rb" -module SyntaxErrorSearch +module DeadEnd RSpec.describe AroundBlockScan do it "expands indentation" do source_string = <<~EOM diff --git a/spec/unit/block_expand_spec.rb b/spec/unit/block_expand_spec.rb index 500c61d..57e5fb6 100644 --- a/spec/unit/block_expand_spec.rb +++ b/spec/unit/block_expand_spec.rb @@ -3,7 +3,7 @@ require_relative "../spec_helper.rb" -module SyntaxErrorSearch +module DeadEnd RSpec.describe BlockExpand do it "captures multiple empty and hidden lines" do diff --git a/spec/unit/code_block_spec.rb b/spec/unit/code_block_spec.rb index d160af4..086a2df 100644 --- a/spec/unit/code_block_spec.rb +++ b/spec/unit/code_block_spec.rb @@ -2,7 +2,7 @@ require_relative "../spec_helper.rb" -module SyntaxErrorSearch +module DeadEnd RSpec.describe CodeBlock do it "can detect if it's valid or not" do code_lines = code_line_array(<<~EOM) diff --git a/spec/unit/code_frontier_spec.rb b/spec/unit/code_frontier_spec.rb index 3b621fc..33358af 100644 --- a/spec/unit/code_frontier_spec.rb +++ b/spec/unit/code_frontier_spec.rb @@ -2,7 +2,7 @@ require_relative "../spec_helper.rb" -module SyntaxErrorSearch +module DeadEnd RSpec.describe CodeFrontier do it "detect_bad_blocks" do code_lines = code_line_array(<<~EOM) diff --git a/spec/unit/code_line_spec.rb b/spec/unit/code_line_spec.rb index 63c449a..1ba22f3 100644 --- a/spec/unit/code_line_spec.rb +++ b/spec/unit/code_line_spec.rb @@ -2,7 +2,7 @@ require_relative "../spec_helper.rb" -module SyntaxErrorSearch +module DeadEnd RSpec.describe CodeLine do it "trailing slash" do code_lines = code_line_array(<<~'EOM') @@ -63,7 +63,7 @@ def foo end EOM - expect(SyntaxErrorSearch.valid?(code_lines)).to be_falsey + expect(DeadEnd.valid?(code_lines)).to be_falsey expect(code_lines.join).to eq(<<~EOM) def foo Array(value) |x| @@ -84,7 +84,7 @@ def foo Array(value) |x| end EOM - expect(SyntaxErrorSearch.valid?(code_lines)).to be_falsey + expect(DeadEnd.valid?(code_lines)).to be_falsey end it "knows empty lines" do @@ -96,7 +96,7 @@ def foo expect(code_lines.map(&:empty?)).to eq([false, true, false]) expect(code_lines.map(&:not_empty?)).to eq([true, false, true]) - expect(code_lines.map {|l| SyntaxErrorSearch.valid?(l) }).to eq([true, true, true]) + expect(code_lines.map {|l| DeadEnd.valid?(l) }).to eq([true, true, true]) end it "counts indentations" do diff --git a/spec/unit/code_search_spec.rb b/spec/unit/code_search_spec.rb index a5cf0f0..c6c69a8 100644 --- a/spec/unit/code_search_spec.rb +++ b/spec/unit/code_search_spec.rb @@ -2,7 +2,7 @@ require_relative "../spec_helper.rb" -module SyntaxErrorSearch +module DeadEnd RSpec.describe CodeSearch do it "handles mismatched |" do source = <<~EOM diff --git a/spec/unit/syntax_search_spec.rb b/spec/unit/dead_end_spec.rb similarity index 72% rename from spec/unit/syntax_search_spec.rb rename to spec/unit/dead_end_spec.rb index 5bb01ee..7786214 100644 --- a/spec/unit/syntax_search_spec.rb +++ b/spec/unit/dead_end_spec.rb @@ -2,10 +2,10 @@ require_relative "../spec_helper.rb" -module SyntaxErrorSearch - RSpec.describe SyntaxErrorSearch do +module DeadEnd + RSpec.describe DeadEnd do it "has a version number" do - expect(SyntaxErrorSearch::VERSION).not_to be nil + expect(DeadEnd::VERSION).not_to be nil end it "detects require error and adds a message with auto mode" do @@ -30,10 +30,16 @@ module SyntaxErrorSearch require_relative "./script.rb" EOM - out = `ruby -I#{lib_dir} -rsyntax_search/auto #{require_rb} 2>&1` + out = `ruby -I#{lib_dir} -rdead_end/auto #{require_rb} 2>&1` expect(out).to include("Unmatched `end` detected") - expect(out).to include("Run `$ syntax_search") + expect(out).to include("Run `$ dead_end") + expect($?.success?).to be_falsey + + out = `ruby -I#{lib_dir} -rdead_end #{require_rb} 2>&1` + + expect(out).to include("Unmatched `end` detected") + expect(out).to include("Run `$ dead_end") expect($?.success?).to be_falsey end end @@ -60,10 +66,10 @@ module SyntaxErrorSearch require_relative "./script.rb" EOM - out = `ruby -I#{lib_dir} -rsyntax_search/fyi #{require_rb} 2>&1` + out = `ruby -I#{lib_dir} -rdead_end/fyi #{require_rb} 2>&1` expect(out).to_not include("This code has an unmatched") - expect(out).to include("Run `$ syntax_search") + expect(out).to include("Run `$ dead_end") expect($?.success?).to be_falsey end end diff --git a/spec/unit/display_invalid_blocks_spec.rb b/spec/unit/display_invalid_blocks_spec.rb index 82cad0e..9f9f3c4 100644 --- a/spec/unit/display_invalid_blocks_spec.rb +++ b/spec/unit/display_invalid_blocks_spec.rb @@ -2,7 +2,7 @@ require_relative "../spec_helper.rb" -module SyntaxErrorSearch +module DeadEnd RSpec.describe DisplayInvalidBlocks do it "Unmatched | banner" do source = <<~EOM @@ -48,7 +48,7 @@ class Cat blocks: CodeBlock.new(lines: code_lines), invalid_obj: WhoDisSyntaxError.new(source), ) - expect(display.banner).to include("SyntaxSearch: Unmatched `end` detected") + expect(display.banner).to include("DeadEnd: Unmatched `end` detected") end it "missing end banner" do @@ -64,7 +64,7 @@ def meow blocks: CodeBlock.new(lines: code_lines), invalid_obj: WhoDisSyntaxError.new(source), ) - expect(display.banner).to include("SyntaxSearch: Missing `end` detected") + expect(display.banner).to include("DeadEnd: Missing `end` detected") end it "captures surrounding context on same indent" do @@ -199,7 +199,7 @@ def hai ) display.call expect(io.string).to include("❯ 2 def hello") - expect(io.string).to include("SyntaxSearch") + expect(io.string).to include("DeadEnd") end it " wraps code with github style codeblocks" do diff --git a/spec/unit/exe_spec.rb b/spec/unit/exe_spec.rb index e3b9f3c..120d015 100644 --- a/spec/unit/exe_spec.rb +++ b/spec/unit/exe_spec.rb @@ -2,10 +2,10 @@ require_relative "../spec_helper.rb" -module SyntaxErrorSearch +module DeadEnd RSpec.describe "exe" do def exe_path - root_dir.join("exe").join("syntax_search") + root_dir.join("exe").join("dead_end") end def exe(cmd) @@ -30,7 +30,7 @@ def exe(cmd) it "handles heredocs" do Tempfile.create do |file| - lines = fixtures_dir.join("rexe.rb").read.lines + lines = fixtures_dir.join("rexe.rb.txt").read.lines lines.delete_at(85 - 1) Pathname(file.path).write(lines.join) diff --git a/spec/unit/heredoc_block_parse_spec.rb b/spec/unit/heredoc_block_parse_spec.rb index e32fc59..9c82f98 100644 --- a/spec/unit/heredoc_block_parse_spec.rb +++ b/spec/unit/heredoc_block_parse_spec.rb @@ -2,7 +2,7 @@ require_relative "../spec_helper.rb" -module SyntaxErrorSearch +module DeadEnd RSpec.describe "HeredocBlockParse" do it "works" do @@ -12,7 +12,7 @@ module SyntaxErrorSearch expect(blocks[0].to_s).to eq(<<-'EOL') @io.puts <<~EOM - SyntaxErrorSearch: A syntax error was detected + DeadEnd: A syntax error was detected This code has an unmatched `end` this is caused by either missing a syntax keyword (`def`, `do`, etc.) or inclusion diff --git a/spec/unit/lex_all_spec.rb b/spec/unit/lex_all_spec.rb index 10c69f2..d1f872f 100644 --- a/spec/unit/lex_all_spec.rb +++ b/spec/unit/lex_all_spec.rb @@ -2,7 +2,7 @@ require_relative "../spec_helper.rb" -module SyntaxErrorSearch +module DeadEnd RSpec.describe "EndBlockParse" do it "finds blocks based on `end` keyword" do source = <<~EOM diff --git a/spec/unit/trailing_slash_join_spec.rb b/spec/unit/trailing_slash_join_spec.rb index bbb4e51..5eb6942 100644 --- a/spec/unit/trailing_slash_join_spec.rb +++ b/spec/unit/trailing_slash_join_spec.rb @@ -2,7 +2,7 @@ require_relative "../spec_helper.rb" -module SyntaxErrorSearch +module DeadEnd RSpec.describe TrailingSlashJoin do it "formats output" do diff --git a/spec/unit/who_dis_syntax_error_spec.rb b/spec/unit/who_dis_syntax_error_spec.rb index 0280f05..b23d55f 100644 --- a/spec/unit/who_dis_syntax_error_spec.rb +++ b/spec/unit/who_dis_syntax_error_spec.rb @@ -2,7 +2,7 @@ require_relative "../spec_helper.rb" -module SyntaxErrorSearch +module DeadEnd RSpec.describe WhoDisSyntaxError do it "determines the type of syntax error" do expect( @@ -31,11 +31,11 @@ class Foo EOM expect( - SyntaxErrorSearch.invalid_type(source).error_symbol + DeadEnd.invalid_type(source).error_symbol ).to eq(:unmatched_syntax) expect( - SyntaxErrorSearch.invalid_type(source).unmatched_symbol + DeadEnd.invalid_type(source).unmatched_symbol ).to eq(:|) end end