syntax_search 0.1.2 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9efb5d44fe2c979f66237173d1bf7b215a1bcc8003b4a96cb595eabbcac606c6
4
- data.tar.gz: 5757f68cdf7dace8980bb31b49a756b858fba8f7260156640621832374b4e635
3
+ metadata.gz: 739770be9259abf88e8ea3c7dc1223e279cc79ab35d907312b0cc268d00363ed
4
+ data.tar.gz: ca7fbab5999100db76c5758f3f920fc7f91872d678b028157761cd6b72e348d5
5
5
  SHA512:
6
- metadata.gz: b9fb23706395a520d52af51ea2a441d972115d6cd85a9e4048d17424d0e7077e679cd23d6ec1a9f43f4fde1e6d29ab8670906dc27451b730f2dab4c5c753789f
7
- data.tar.gz: 13209882976145efe8087a5c5d52e1980d5295c4b7ab51628dc92007f6b83900933fb2e08046bac7ccf118056289bba04f3f5597b70400c74c32969468e31409
6
+ metadata.gz: 60c1aea7c3f075f0486d85e72bc4761879efd09d5805c6581efa21765c78edd335f172094dcc961f77e00f1bf4e0867f8382b32e7d13e2de248085679e3728e6
7
+ data.tar.gz: adf40fe0011de00194eef22b5f4caa86196f0b8bf1439c8d48a7f3fbe465521ab04bf856f9cd20407dace52ab154cf1c27d0a519c00d15e862e6100322f2c4f2
data/.gitignore CHANGED
@@ -6,6 +6,7 @@
6
6
  /pkg/
7
7
  /spec/reports/
8
8
  /tmp/
9
+ scratch.rb
9
10
 
10
11
  # rspec failure tracking
11
12
  .rspec_status
@@ -1,14 +1,5 @@
1
1
  ## HEAD (unreleased)
2
2
 
3
- ## 0.1.2
3
+ ## 0.2.1
4
4
 
5
- - Codeblocks in output are now indented with 4 spaces and "code fences" are removed (https://github.com/zombocom/syntax_search/pull/11)
6
- - "Unmatched end" and "missing end" not generate different error text instructions (https://github.com/zombocom/syntax_search/pull/10)
7
-
8
- ## 0.1.1
9
-
10
- - Fire search on both unexpected end-of-input and unexected end (https://github.com/zombocom/syntax_search/pull/8)
11
-
12
- ## 0.1.0
13
-
14
- - Initial release
5
+ This gem is moved to the `dead_end` gem. Please use that instead
data/Gemfile CHANGED
@@ -7,3 +7,4 @@ gemspec
7
7
 
8
8
  gem "rake", "~> 12.0"
9
9
  gem "rspec", "~> 3.0"
10
+ gem "stackprof"
@@ -1,16 +1,14 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- syntax_search (0.1.2)
5
- parser
4
+ syntax_search (0.2.1)
5
+ dead_end (> 0)
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
9
9
  specs:
10
- ast (2.4.1)
10
+ dead_end (1.0.0)
11
11
  diff-lcs (1.4.4)
12
- parser (2.7.2.0)
13
- ast (~> 2.4.1)
14
12
  rake (12.3.3)
15
13
  rspec (3.10.0)
16
14
  rspec-core (~> 3.10.0)
@@ -25,6 +23,7 @@ GEM
25
23
  diff-lcs (>= 1.2.0, < 2.0)
26
24
  rspec-support (~> 3.10.0)
27
25
  rspec-support (3.10.0)
26
+ stackprof (0.2.16)
28
27
 
29
28
  PLATFORMS
30
29
  ruby
@@ -32,6 +31,7 @@ PLATFORMS
32
31
  DEPENDENCIES
33
32
  rake (~> 12.0)
34
33
  rspec (~> 3.0)
34
+ stackprof
35
35
  syntax_search!
36
36
 
37
37
  BUNDLED WITH
data/README.md CHANGED
@@ -10,30 +10,29 @@ What happened? Likely you forgot a `def`, `do`, or maybe you deleted some code a
10
10
 
11
11
  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.
12
12
 
13
- $ syntax_search <path/to/file.rb>
13
+ $ syntax_search path/to/file.rb
14
14
 
15
- SyntaxErrorSearch: A syntax error was detected
15
+ SyntaxSearch: Unmatched `end` detected
16
16
 
17
- This code has an unmatched `end` this is caused by either
18
- missing a syntax keyword (`def`, `do`, etc.) or inclusion
19
- of an extra `end` line
17
+ This code has an unmatched `end`. Ensure that all `end` lines
18
+ in your code have a matching syntax keyword (`def`, `do`, etc.)
19
+ and that you don't have any extra `end` lines.
20
20
 
21
21
  file: path/to/file.rb
22
22
  simplified:
23
23
 
24
- ```
25
- 1 require 'animals'
26
- 2
27
- ❯ 10 defdog
28
- 15 end
29
- 16
30
- 20 def cat
31
- 22 end
32
- ```
24
+ 1 require 'zoo'
25
+ 2
26
+ 3 class Animal
27
+ 4
28
+ 5 defdog
29
+ 7 end
30
+ 8
31
+ 12 end
33
32
 
34
33
  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!
35
34
 
36
- ## Installation
35
+ ## Installation in your codebase
37
36
 
38
37
  To automatically search syntax errors when they happen, add this to your Gemfile:
39
38
 
@@ -51,6 +50,16 @@ If your application is not calling `Bundler.require` then you must manually add
51
50
  require "syntax_search/auto"
52
51
  ```
53
52
 
53
+ If you're using rspec add this to your `.rspec` file:
54
+
55
+ ```
56
+ --require syntax_search/auto
57
+ ```
58
+
59
+ > 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.
60
+
61
+ ## Install the CLI
62
+
54
63
  To get the CLI and manually search for syntax errors, install the gem:
55
64
 
56
65
  $ gem install syntax_search
@@ -74,6 +83,10 @@ We know that source code that does not contain a syntax error can be parsed. We
74
83
 
75
84
  Since there can be multiple syntax errors in a document it's not good enough to check individual code blocks, we've got to check multiple at the same time. We will keep creating and adding new blocks to our search until we detect that our "frontier" (which contains all of our blocks) contains the syntax error. After this, we can stop our search and instead focus on filtering to find the smallest subset of blocks that contain the syntax error.
76
85
 
86
+ Here's an example:
87
+
88
+ ![](assets/syntax_search.gif)
89
+
77
90
  ## How is source code broken up into smaller blocks?
78
91
 
79
92
  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.
Binary file
@@ -1,73 +1,8 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require 'pathname'
4
- require "optparse"
5
- require_relative "../lib/syntax_search.rb"
3
+ warn "syntax_search gem is deprecated please use `dead_end` instead"
4
+ warn
5
+ warn " $ gem install dead_end`"
6
+ warn
6
7
 
7
- options = {}
8
- options[:terminal] = true
9
- options[:record_dir] = ENV["SYNTAX_SEARCH_RECORD_DIR"]
10
-
11
- parser = OptionParser.new do |opts|
12
- opts.banner = <<~EOM
13
- Usage: syntax_search <file> [options]
14
-
15
- Parses a ruby source file and searches for syntax error(s) unexpected `end', expecting end-of-input.
16
-
17
- Example:
18
-
19
- $ syntax_search dog.rb
20
-
21
- # ...
22
-
23
- ```
24
- 1 require 'animals'
25
- 2
26
- ❯ 10 defdog
27
- ❯ 15 end
28
- ❯ 16
29
- 20 def cat
30
- 22 end
31
- ```
32
-
33
- Env options:
34
-
35
- SYNTAX_SEARCH_RECORD_DIR=<dir>
36
-
37
- When enabled, records the steps used to search for a syntax error to the given directory
38
-
39
- Options:
40
- EOM
41
-
42
- opts.on("--help", "Help - displays this message") do |v|
43
- puts opts
44
- exit
45
- end
46
-
47
- opts.on("--record <dir>", "When enabled, records the steps used to search for a syntax error to the given directory") do |v|
48
- options[:record_dir] = v
49
- end
50
-
51
- opts.on("--no-terminal", "Disable terminal highlighting") do |v|
52
- options[:terminal] = false
53
- end
54
- end
55
- parser.parse!
56
-
57
- file = ARGV[0]
58
-
59
- if file.nil? || file.empty?
60
- # Display help if raw command
61
- parser.parse! %w[--help]
62
- end
63
-
64
- file = Pathname(file)
65
-
66
- $stderr.puts "Record dir: #{options[:record_dir]}" if options[:record_dir]
67
-
68
- SyntaxErrorSearch.call(
69
- source: file.read,
70
- filename: file.expand_path,
71
- terminal: options[:terminal],
72
- record_dir: options[:record_dir]
73
- )
8
+ exit 1
@@ -1,51 +1,7 @@
1
- require_relative "../syntax_search"
1
+ warn "syntax_search gem is deprecated please use `dead_end` instead"
2
+ warn
3
+ warn " $ gem install dead_end`"
4
+ warn
2
5
 
3
- # Monkey patch kernel to ensure that all `require` calls call the same
4
- # method
5
- module Kernel
6
- alias_method :original_require, :require
7
- alias_method :original_require_relative, :require_relative
8
- alias_method :original_load, :load
9
-
10
- def load(file, wrap = false)
11
- original_load(file)
12
- rescue SyntaxError => e
13
- SyntaxErrorSearch.handle_error(e)
14
- end
15
-
16
- def require(file)
17
- original_require(file)
18
- rescue SyntaxError => e
19
- SyntaxErrorSearch.handle_error(e)
20
- end
21
-
22
- def require_relative(file)
23
- if Pathname.new(file).absolute?
24
- original_require file
25
- else
26
- original_require File.expand_path("../#{file}", caller_locations(1, 1)[0].absolute_path)
27
- end
28
- rescue SyntaxError => e
29
- SyntaxErrorSearch.handle_error(e)
30
- end
31
- end
32
-
33
- # I honestly have no idea why this Object delegation is needed
34
- # I keep staring at bootsnap and it doesn't have to do this
35
- # is there a bug in their implementation they haven't caught or
36
- # am I doing something different?
37
- class Object
38
- private
39
- def load(path, wrap = false)
40
- Kernel.load(path, wrap)
41
- rescue SyntaxError => e
42
- SyntaxErrorSearch.handle_error(e)
43
- end
44
-
45
- def require(path)
46
- Kernel.require(path)
47
- rescue SyntaxError => e
48
- SyntaxErrorSearch.handle_error(e)
49
- end
50
- end
6
+ require "dead_end"
51
7
 
@@ -1,10 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'lib/syntax_search/version'
4
-
5
3
  Gem::Specification.new do |spec|
6
4
  spec.name = "syntax_search"
7
- spec.version = SyntaxErrorSearch::VERSION
5
+ spec.version = "0.2.1"
8
6
  spec.authors = ["schneems"]
9
7
  spec.email = ["richard.schneeman+foo@gmail.com"]
10
8
 
@@ -26,5 +24,5 @@ Gem::Specification.new do |spec|
26
24
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
27
25
  spec.require_paths = ["lib"]
28
26
 
29
- spec.add_dependency "parser"
27
+ spec.add_dependency "dead_end", "> 0"
30
28
  end
metadata CHANGED
@@ -1,27 +1,27 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: syntax_search
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - schneems
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-11-12 00:00:00.000000000 Z
11
+ date: 2020-12-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: parser
14
+ name: dead_end
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
17
+ - - ">"
18
18
  - !ruby/object:Gem::Version
19
19
  version: '0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ">="
24
+ - - ">"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  description: When you get an "unexpected end" in your syntax this gem helps you find
@@ -45,18 +45,11 @@ files:
45
45
  - LICENSE.txt
46
46
  - README.md
47
47
  - Rakefile
48
+ - assets/syntax_search.gif
48
49
  - bin/console
49
50
  - bin/setup
50
51
  - exe/syntax_search
51
- - lib/syntax_search.rb
52
52
  - lib/syntax_search/auto.rb
53
- - lib/syntax_search/code_block.rb
54
- - lib/syntax_search/code_frontier.rb
55
- - lib/syntax_search/code_line.rb
56
- - lib/syntax_search/code_search.rb
57
- - lib/syntax_search/display_invalid_blocks.rb
58
- - lib/syntax_search/fyi.rb
59
- - lib/syntax_search/version.rb
60
53
  - syntax_search.gemspec
61
54
  homepage: https://github.com/zombocom/syntax_search.git
62
55
  licenses:
@@ -1,156 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "syntax_search/version"
4
-
5
- require 'parser/current'
6
- require 'tmpdir'
7
- require 'stringio'
8
- require 'pathname'
9
-
10
- module SyntaxErrorSearch
11
- class Error < StandardError; end
12
- SEARCH_SOURCE_ON_ERROR_DEFAULT = true
13
-
14
- def self.handle_error(e, search_source_on_error: SEARCH_SOURCE_ON_ERROR_DEFAULT)
15
- raise e if !e.message.include?("end-of-input")
16
-
17
- filename = e.message.split(":").first
18
-
19
- $stderr.sync = true
20
- $stderr.puts "Run `$ syntax_search #{filename}` for more options\n"
21
-
22
- if search_source_on_error
23
- self.call(
24
- source: Pathname(filename).read,
25
- filename: filename,
26
- terminal: true,
27
- )
28
- end
29
-
30
- $stderr.puts ""
31
- $stderr.puts ""
32
- raise e
33
- end
34
-
35
- def self.call(source: , filename: , terminal: false, record_dir: nil)
36
- search = CodeSearch.new(source, record_dir: record_dir).call
37
-
38
- blocks = search.invalid_blocks
39
- DisplayInvalidBlocks.new(
40
- blocks: blocks,
41
- filename: filename,
42
- terminal: terminal,
43
- invalid_type: invalid_type(source),
44
- io: $stderr
45
- ).call
46
- end
47
-
48
- # Used for counting spaces
49
- module SpaceCount
50
- def self.indent(string)
51
- string.split(/\S/).first&.length || 0
52
- end
53
- end
54
-
55
- # This will tell you if the `code_lines` would be valid
56
- # if you removed the `without_lines`. In short it's a
57
- # way to detect if we've found the lines with syntax errors
58
- # in our document yet.
59
- #
60
- # code_lines = [
61
- # CodeLine.new(line: "def foo\n", index: 0)
62
- # CodeLine.new(line: " def bar\n", index: 1)
63
- # CodeLine.new(line: "end\n", index: 2)
64
- # ]
65
- #
66
- # SyntaxErrorSearch.valid_without?(
67
- # without_lines: code_lines[1],
68
- # code_lines: code_lines
69
- # ) # => true
70
- #
71
- # SyntaxErrorSearch.valid?(code_lines) # => false
72
- def self.valid_without?(without_lines: , code_lines:)
73
- lines = code_lines - Array(without_lines).flatten
74
-
75
- if lines.empty?
76
- return true
77
- else
78
- return valid?(lines)
79
- end
80
- end
81
-
82
- # Returns truthy if a given input source is valid syntax
83
- #
84
- # SyntaxErrorSearch.valid?(<<~EOM) # => true
85
- # def foo
86
- # end
87
- # EOM
88
- #
89
- # SyntaxErrorSearch.valid?(<<~EOM) # => false
90
- # def foo
91
- # def bar # Syntax error here
92
- # end
93
- # EOM
94
- #
95
- # You can also pass in an array of lines and they'll be
96
- # joined before evaluating
97
- #
98
- # SyntaxErrorSearch.valid?(
99
- # [
100
- # "def foo\n",
101
- # "end\n"
102
- # ]
103
- # ) # => true
104
- #
105
- # SyntaxErrorSearch.valid?(
106
- # [
107
- # "def foo\n",
108
- # " def bar\n", # Syntax error here
109
- # "end\n"
110
- # ]
111
- # ) # => false
112
- #
113
- # As an FYI the CodeLine class instances respond to `to_s`
114
- # so passing a CodeLine in as an object or as an array
115
- # will convert it to it's code representation.
116
- def self.valid?(source)
117
- source = source.join if source.is_a?(Array)
118
- source = source.to_s
119
-
120
- # Parser writes to stderr even if you catch the error
121
- stderr = $stderr
122
- $stderr = StringIO.new
123
-
124
- Parser::CurrentRuby.parse(source)
125
- true
126
- rescue Parser::SyntaxError => e
127
- yield e if block_given?
128
- false
129
- ensure
130
- $stderr = stderr if stderr
131
- end
132
-
133
- def self.invalid_type(source)
134
- message = nil
135
- self.valid?(source) do |error|
136
- message = error.message
137
- end
138
-
139
- case message
140
- when nil
141
- :none
142
- when /token kEND/
143
- :unmatched_end
144
- when /token \$end/ #
145
- :missing_end
146
- else
147
- raise "Unexpected message #{message}"
148
- end
149
- end
150
- end
151
-
152
- require_relative "syntax_search/code_line"
153
- require_relative "syntax_search/code_block"
154
- require_relative "syntax_search/code_frontier"
155
- require_relative "syntax_search/code_search"
156
- require_relative "syntax_search/display_invalid_blocks"