rufo 0.7.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.circleci/config.yml +23 -8
- data/.gitignore +1 -0
- data/CHANGELOG.md +18 -0
- data/bin/verify-sample-code +60 -0
- data/docs/settings.md +59 -0
- data/lib/rufo/command.rb +21 -16
- data/lib/rufo/dot_file.rb +2 -0
- data/lib/rufo/erb_formatter.rb +120 -0
- data/lib/rufo/file_finder.rb +31 -22
- data/lib/rufo/formatter.rb +16 -15
- data/lib/rufo/parser.rb +13 -0
- data/lib/rufo/settings.rb +4 -2
- data/lib/rufo/version.rb +1 -1
- data/lib/rufo.rb +10 -1
- metadata +6 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3bbc374be047a3b1a07b7f73dd004aa0629b07bdf70de0342041dabbebd16166
|
4
|
+
data.tar.gz: ac54fb2d1e593baa3207109d9cb40d4bef40ab9eb64db13be344fcfd64bdcfe2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0bf1ada9dcd91f5565c519a90693f7b2e35b46b4075f7cb92e57a120539df196286fce17ab42427fd3b9937f97585093487309624b59415ee42dbd87259d3178
|
7
|
+
data.tar.gz: 40b9de53720d9ad2c1b09c44f4b5a88cd3bb69ad4ceef8034d78abdb940052f504fff1995df5eaada6d936ae418d96ba1a1c5c3d82745761f9a8f8cf45a8a4f0
|
data/.circleci/config.yml
CHANGED
@@ -15,18 +15,12 @@
|
|
15
15
|
# Restore bundle cache
|
16
16
|
- restore_cache:
|
17
17
|
keys:
|
18
|
-
- bundler-packages-{{ checksum "ruby-version-for-ci.txt" }}-{{ checksum "rufo.gemspec" }}
|
18
|
+
- bundler-packages-v2-{{ checksum "ruby-version-for-ci.txt" }}-{{ checksum "rufo.gemspec" }}-{{ checksum "bin/verify-sample-code" }}
|
19
19
|
|
20
20
|
- run:
|
21
21
|
name: Bundle Install
|
22
22
|
command: bundle check || bundle install
|
23
23
|
|
24
|
-
# Store bundle cache
|
25
|
-
- save_cache:
|
26
|
-
key: bundler-packages-{{ checksum "ruby-version-for-ci.txt" }}-{{ checksum "rufo.gemspec" }}
|
27
|
-
paths:
|
28
|
-
- vendor/bundle
|
29
|
-
- Gemfile.lock
|
30
24
|
- run:
|
31
25
|
name: Run rspec
|
32
26
|
command: |
|
@@ -43,6 +37,18 @@
|
|
43
37
|
command: |
|
44
38
|
bundle exec rake rufo:run
|
45
39
|
|
40
|
+
- run:
|
41
|
+
name: Verify rufo works against sample codebases
|
42
|
+
command: |
|
43
|
+
bin/verify-sample-code
|
44
|
+
|
45
|
+
# Store bundle cache
|
46
|
+
- save_cache:
|
47
|
+
key: bundler-packages-v2-{{ checksum "ruby-version-for-ci.txt" }}-{{ checksum "rufo.gemspec" }}-{{ checksum "bin/verify-sample-code" }}
|
48
|
+
paths:
|
49
|
+
- vendor/bundle
|
50
|
+
- Gemfile.lock
|
51
|
+
|
46
52
|
# Save test results for timing analysis
|
47
53
|
- store_test_results:
|
48
54
|
path: test_results
|
@@ -50,6 +56,14 @@
|
|
50
56
|
|
51
57
|
version: 2
|
52
58
|
jobs:
|
59
|
+
build-2-7-0:
|
60
|
+
<<: *dockerbuild
|
61
|
+
docker:
|
62
|
+
- image: circleci/ruby:2.7.0
|
63
|
+
environment:
|
64
|
+
BUNDLE_JOBS: "3"
|
65
|
+
BUNDLE_RETRY: "3"
|
66
|
+
BUNDLE_PATH: /home/circleci/project/vendor/bundle
|
53
67
|
build-2-6-3:
|
54
68
|
<<: *dockerbuild
|
55
69
|
docker:
|
@@ -57,7 +71,7 @@ jobs:
|
|
57
71
|
environment:
|
58
72
|
BUNDLE_JOBS: "3"
|
59
73
|
BUNDLE_RETRY: "3"
|
60
|
-
BUNDLE_PATH: vendor/bundle
|
74
|
+
BUNDLE_PATH: /home/circleci/project/vendor/bundle
|
61
75
|
build-2-6-1:
|
62
76
|
<<: *dockerbuild
|
63
77
|
docker:
|
@@ -86,6 +100,7 @@ workflows:
|
|
86
100
|
version: 2
|
87
101
|
test:
|
88
102
|
jobs:
|
103
|
+
- build-2-7-0
|
89
104
|
- build-2-6-3
|
90
105
|
- build-2-6-1
|
91
106
|
- build-2-5-3
|
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
@@ -12,6 +12,24 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|
12
12
|
|
13
13
|
### Added
|
14
14
|
|
15
|
+
## [0.8.0] - 2020-01-02
|
16
|
+
|
17
|
+
### Fixed
|
18
|
+
- Handle endless ranges in ruby 2.6
|
19
|
+
- Handle empty string hash keys
|
20
|
+
|
21
|
+
### Changed
|
22
|
+
- Output detailed description of Syntax Error to log
|
23
|
+
- Removed newlines from start of files.
|
24
|
+
|
25
|
+
### Added
|
26
|
+
|
27
|
+
- Support for rackup files
|
28
|
+
- Settings for 'quote_style' to settings.md
|
29
|
+
- Add support for ERB files
|
30
|
+
- Add Ruby 2.7.0 to test runs on CI
|
31
|
+
- `includes` and `excludes` configuration options
|
32
|
+
|
15
33
|
## [0.7.0] - 2019-04-28
|
16
34
|
|
17
35
|
### Fixed
|
@@ -0,0 +1,60 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
repos = {
|
4
|
+
"rspec/rspec-core" => {
|
5
|
+
"--exclude-pattern" => [
|
6
|
+
"spec/rspec/core/world_spec.rb",
|
7
|
+
"spec/rspec/core/formatters/exception_presenter_spec.rb",
|
8
|
+
"spec/rspec/core/formatters/snippet_extractor_spec.rb",
|
9
|
+
"spec/rspec/core/metadata_spec.rb",
|
10
|
+
"spec/rspec/core/formatters/html_formatter_spec.rb",
|
11
|
+
].join(","),
|
12
|
+
},
|
13
|
+
}
|
14
|
+
|
15
|
+
def run_command(cmd, allowed_statuses: [0])
|
16
|
+
puts "Running: #{cmd.inspect}"
|
17
|
+
system(cmd)
|
18
|
+
unless allowed_statuses.include?($?.exitstatus)
|
19
|
+
$stderr.puts "Command failed, aborting!"
|
20
|
+
exit 1
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def clone_repo(repo)
|
25
|
+
run_command(
|
26
|
+
"git clone --depth=1 'https://github.com/#{repo}' sample_code/#{repo}"
|
27
|
+
)
|
28
|
+
end
|
29
|
+
|
30
|
+
def setup_repo(repo)
|
31
|
+
run_command("cd sample_code/#{repo} && bundle")
|
32
|
+
end
|
33
|
+
|
34
|
+
def run_rspec(repo, flags)
|
35
|
+
str_flags = flags.to_a.join(" ")
|
36
|
+
run_command("cd sample_code/#{repo} && bundle exec rspec #{str_flags}")
|
37
|
+
end
|
38
|
+
|
39
|
+
def pre_format_checks(repo, rspec_flags)
|
40
|
+
run_rspec(repo, rspec_flags)
|
41
|
+
end
|
42
|
+
|
43
|
+
def format_repo(repo)
|
44
|
+
run_command(
|
45
|
+
"bundle exec rake rufo:run sample_code/#{repo}",
|
46
|
+
allowed_statuses: [0, 1, 3],
|
47
|
+
)
|
48
|
+
end
|
49
|
+
|
50
|
+
def post_format_checks(repo, rspec_flags)
|
51
|
+
run_rspec(repo, rspec_flags)
|
52
|
+
end
|
53
|
+
|
54
|
+
repos.each do |repo, rspec_flags|
|
55
|
+
clone_repo(repo)
|
56
|
+
setup_repo(repo)
|
57
|
+
pre_format_checks(repo, rspec_flags)
|
58
|
+
format_repo(repo)
|
59
|
+
post_format_checks(repo, rspec_flags)
|
60
|
+
end
|
data/docs/settings.md
CHANGED
@@ -22,6 +22,7 @@ See https://github.com/ruby-formatter/rufo/issues/2 for more context!
|
|
22
22
|
- [align_chained_calls](#align_chained_calls)
|
23
23
|
- [parens_in_def](#parens_in_def)
|
24
24
|
- [trailing_commas](#trailing_commas)
|
25
|
+
- [quote_style](#quote_style)
|
25
26
|
|
26
27
|
### align_case_when
|
27
28
|
|
@@ -184,6 +185,7 @@ foo(
|
|
184
185
|
y: 2,
|
185
186
|
)
|
186
187
|
```
|
188
|
+
|
187
189
|
With `:never`, the formatter will change it to:
|
188
190
|
|
189
191
|
```ruby
|
@@ -217,3 +219,60 @@ foo(
|
|
217
219
|
y: 2
|
218
220
|
)
|
219
221
|
```
|
222
|
+
|
223
|
+
### quote_style
|
224
|
+
|
225
|
+
Use the specified quotation marks.
|
226
|
+
|
227
|
+
- `:double`: (default) use doublequotations unless one or more escaped double-quotations are included
|
228
|
+
- `:single`: use single quotations unless one or more interpolations `#{}` or escaped single quotations are included
|
229
|
+
|
230
|
+
This does not affect `%q()` (single), `%Q()` (double), or quotation marks within heredocs.
|
231
|
+
|
232
|
+
Given this code:
|
233
|
+
|
234
|
+
```ruby
|
235
|
+
'a great string'
|
236
|
+
|
237
|
+
'import \"quotes\"'
|
238
|
+
"import \'quotes\'"
|
239
|
+
"#{interpolation}"
|
240
|
+
%q(single quoted)
|
241
|
+
%Q(double quoted)
|
242
|
+
code = <<CODE
|
243
|
+
"double"
|
244
|
+
'single'
|
245
|
+
CODE
|
246
|
+
```
|
247
|
+
|
248
|
+
With `:double`, the formatter will change the first line to:
|
249
|
+
|
250
|
+
```ruby
|
251
|
+
"a great string"
|
252
|
+
|
253
|
+
'import \"quotes\"'
|
254
|
+
"import \'quotes\'"
|
255
|
+
"#{interpolation}"
|
256
|
+
%q(single quoted)
|
257
|
+
%Q(double quoted)
|
258
|
+
code = <<CODE
|
259
|
+
"double"
|
260
|
+
'single'
|
261
|
+
CODE
|
262
|
+
```
|
263
|
+
|
264
|
+
With `:single`, the formatter will change the first line just above to:
|
265
|
+
|
266
|
+
```ruby
|
267
|
+
'a great string'
|
268
|
+
|
269
|
+
'import \"quotes\"'
|
270
|
+
"import \'quotes\'"
|
271
|
+
"#{interpolation}"
|
272
|
+
%q(single quoted)
|
273
|
+
%Q(double quoted)
|
274
|
+
code = <<CODE
|
275
|
+
"double"
|
276
|
+
'single'
|
277
|
+
CODE
|
278
|
+
```
|
data/lib/rufo/command.rb
CHANGED
@@ -17,7 +17,6 @@ class Rufo::Command
|
|
17
17
|
@exit_code = exit_code
|
18
18
|
@filename_for_dot_rufo = filename_for_dot_rufo
|
19
19
|
@dot_file = Rufo::DotFile.new
|
20
|
-
@squiggly_warning_files = []
|
21
20
|
@logger = Rufo::Logger.new(loglevel)
|
22
21
|
end
|
23
22
|
|
@@ -51,8 +50,8 @@ class Rufo::Command
|
|
51
50
|
print(result) if !@want_check
|
52
51
|
|
53
52
|
code == result ? CODE_OK : CODE_CHANGE
|
54
|
-
rescue Rufo::SyntaxError
|
55
|
-
logger.error("
|
53
|
+
rescue Rufo::SyntaxError => e
|
54
|
+
logger.error("STDIN is invalid code. Error on line:#{e.lineno} #{e.message}")
|
56
55
|
CODE_ERROR
|
57
56
|
rescue => ex
|
58
57
|
logger.error("You've found a bug!")
|
@@ -61,7 +60,11 @@ class Rufo::Command
|
|
61
60
|
end
|
62
61
|
|
63
62
|
def format_args(args)
|
64
|
-
|
63
|
+
top_level_dot_file = @filename_for_dot_rufo || Dir.getwd
|
64
|
+
options = @dot_file.get_config_in(top_level_dot_file) || {}
|
65
|
+
file_finder = Rufo::FileFinder.new(
|
66
|
+
args, includes: options[:includes], excludes: options[:excludes],
|
67
|
+
)
|
65
68
|
files = file_finder.to_a
|
66
69
|
|
67
70
|
changed = false
|
@@ -95,11 +98,13 @@ class Rufo::Command
|
|
95
98
|
code = File.read(filename)
|
96
99
|
|
97
100
|
begin
|
98
|
-
|
99
|
-
|
101
|
+
location = @filename_for_dot_rufo || File.dirname(filename)
|
102
|
+
erb = filename.end_with?(".erb")
|
103
|
+
result = format(code, location, erb: erb)
|
104
|
+
rescue Rufo::SyntaxError => e
|
100
105
|
# We ignore syntax errors as these might be template files
|
101
106
|
# with .rb extension
|
102
|
-
logger.warn("
|
107
|
+
logger.warn("#{filename}:#{e.lineno} #{e.message}")
|
103
108
|
return CODE_ERROR
|
104
109
|
end
|
105
110
|
|
@@ -113,8 +118,8 @@ class Rufo::Command
|
|
113
118
|
|
114
119
|
return CODE_CHANGE
|
115
120
|
end
|
116
|
-
rescue Rufo::SyntaxError
|
117
|
-
logger.error("
|
121
|
+
rescue Rufo::SyntaxError => e
|
122
|
+
logger.error("#{filename}:#{e.lineno} #{e.message}")
|
118
123
|
CODE_ERROR
|
119
124
|
rescue => ex
|
120
125
|
logger.error("You've found a bug!")
|
@@ -123,14 +128,14 @@ class Rufo::Command
|
|
123
128
|
raise ex
|
124
129
|
end
|
125
130
|
|
126
|
-
def format(code, dir)
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
formatter.init_settings(options)
|
131
|
+
def format(code, dir, erb: false)
|
132
|
+
options = @dot_file.get_config_in(dir) || {}
|
133
|
+
if erb
|
134
|
+
formatter = Rufo::ErbFormatter.new(code, **options)
|
135
|
+
else
|
136
|
+
formatter = Rufo::Formatter.new(code, **options)
|
133
137
|
end
|
138
|
+
|
134
139
|
formatter.format
|
135
140
|
result = formatter.result
|
136
141
|
result
|
data/lib/rufo/dot_file.rb
CHANGED
@@ -0,0 +1,120 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require "erb"
|
3
|
+
|
4
|
+
class Rufo::ErbFormatter
|
5
|
+
def self.format(code, **options)
|
6
|
+
new(code, **options).format
|
7
|
+
end
|
8
|
+
|
9
|
+
attr_reader :result
|
10
|
+
|
11
|
+
def initialize(code, **options)
|
12
|
+
compiler = ERB::Compiler.new("<>")
|
13
|
+
@options = options
|
14
|
+
@scanner = compiler.make_scanner(code)
|
15
|
+
@code_mode = false
|
16
|
+
@current_lineno = 0
|
17
|
+
@current_column = 0
|
18
|
+
end
|
19
|
+
|
20
|
+
def format
|
21
|
+
out = []
|
22
|
+
process_erb do |(type, content)|
|
23
|
+
if type == :code
|
24
|
+
formatted_code = process_code(content)
|
25
|
+
indented_code = formatted_code.lines.join(" " * current_column)
|
26
|
+
out << " #{indented_code} "
|
27
|
+
else
|
28
|
+
out << content
|
29
|
+
end
|
30
|
+
|
31
|
+
update_lineno(out.last)
|
32
|
+
update_column(out.last)
|
33
|
+
end
|
34
|
+
@result = out.join("")
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
attr_reader :scanner, :code_mode
|
40
|
+
attr_accessor :current_lineno, :current_column
|
41
|
+
|
42
|
+
def update_lineno(token)
|
43
|
+
lines = token.count("\n")
|
44
|
+
if lines > 0
|
45
|
+
self.current_lineno = current_lineno + lines
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def update_column(token)
|
50
|
+
last_newline_index = token.rindex("\n")
|
51
|
+
if last_newline_index == nil
|
52
|
+
self.current_column = current_column + token.length
|
53
|
+
else
|
54
|
+
self.current_column = token[last_newline_index..-1].length
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def process_erb
|
59
|
+
code = []
|
60
|
+
scanner.scan do |token|
|
61
|
+
if token.is_a?(String) && token.end_with?("%>")
|
62
|
+
disable_code_mode
|
63
|
+
yield [:code, code.join("")]
|
64
|
+
yield [:text, token]
|
65
|
+
code = []
|
66
|
+
elsif code_mode
|
67
|
+
code << token
|
68
|
+
elsif token == :cr
|
69
|
+
yield [:text, "\n"]
|
70
|
+
else
|
71
|
+
yield [:text, token]
|
72
|
+
end
|
73
|
+
|
74
|
+
enable_code_mode if token.is_a?(String) && token.start_with?("<%")
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def process_code(code_str)
|
79
|
+
sexps = Ripper.sexp(code_str)
|
80
|
+
if sexps.nil?
|
81
|
+
prefix, suffix = determine_code_wrappers(code_str)
|
82
|
+
end
|
83
|
+
result = format_code("#{prefix} " + code_str + " #{suffix}")
|
84
|
+
unless suffix.nil?
|
85
|
+
result = result.chomp(suffix)
|
86
|
+
end
|
87
|
+
unless prefix.nil?
|
88
|
+
result = result.sub(prefix, "")
|
89
|
+
end
|
90
|
+
result.strip
|
91
|
+
end
|
92
|
+
|
93
|
+
def determine_code_wrappers(code_str)
|
94
|
+
return nil, "\nend" if Ripper.sexp("#{code_str}\nend")
|
95
|
+
return nil, "}" if Ripper.sexp("#{code_str} }")
|
96
|
+
return "{", nil if Ripper.sexp("{ #{code_str}")
|
97
|
+
return "begin", nil if Ripper.sexp("begin #{code_str}")
|
98
|
+
return "begin\n", "\nend" if Ripper.sexp("begin\n#{code_str}\nend")
|
99
|
+
return "if a\n", "\nend" if Ripper.sexp("if a\n#{code_str}\nend")
|
100
|
+
raise_syntax_error!(code_str)
|
101
|
+
end
|
102
|
+
|
103
|
+
def raise_syntax_error!(code_str)
|
104
|
+
format_code(code_str)
|
105
|
+
rescue Rufo::SyntaxError => e
|
106
|
+
raise Rufo::SyntaxError.new(e.message, current_lineno + e.lineno)
|
107
|
+
end
|
108
|
+
|
109
|
+
def format_code(str)
|
110
|
+
Rufo::Formatter.format(str).chomp
|
111
|
+
end
|
112
|
+
|
113
|
+
def enable_code_mode
|
114
|
+
@code_mode = true
|
115
|
+
end
|
116
|
+
|
117
|
+
def disable_code_mode
|
118
|
+
@code_mode = false
|
119
|
+
end
|
120
|
+
end
|
data/lib/rufo/file_finder.rb
CHANGED
@@ -1,34 +1,48 @@
|
|
1
1
|
require "find"
|
2
|
+
require "rake/file_list"
|
2
3
|
|
3
4
|
class Rufo::FileFinder
|
4
5
|
include Enumerable
|
5
6
|
|
6
7
|
# Taken from https://github.com/ruby/rake/blob/f0a897e3fb557f64f5da59785b1a4464826f77b2/lib/rake/application.rb#L41
|
7
8
|
RAKEFILES = [
|
8
|
-
"rakefile",
|
9
|
-
"Rakefile",
|
10
|
-
"rakefile.rb",
|
11
|
-
"Rakefile.rb",
|
9
|
+
"**/rakefile",
|
10
|
+
"**/Rakefile",
|
11
|
+
"**/rakefile.rb",
|
12
|
+
"**/Rakefile.rb",
|
12
13
|
]
|
13
14
|
|
14
15
|
FILENAMES = [
|
15
|
-
"Gemfile",
|
16
|
+
"**/Gemfile",
|
16
17
|
*RAKEFILES,
|
17
18
|
]
|
18
19
|
|
19
20
|
EXTENSIONS = [
|
20
|
-
"
|
21
|
-
"
|
22
|
-
"
|
23
|
-
"
|
21
|
+
"**/*.rb",
|
22
|
+
"**/*.gemspec",
|
23
|
+
"**/*.rake",
|
24
|
+
"**/*.ru",
|
25
|
+
"**/*.jbuilder",
|
26
|
+
"**/*.erb",
|
27
|
+
]
|
28
|
+
|
29
|
+
DEFAULT_PATTERNS = [
|
30
|
+
*FILENAMES,
|
31
|
+
*EXTENSIONS,
|
24
32
|
]
|
25
33
|
|
26
34
|
EXCLUDED_DIRS = [
|
27
35
|
"vendor",
|
28
36
|
]
|
29
37
|
|
30
|
-
|
38
|
+
EXCLUDE_PATTERNS = [
|
39
|
+
"vendor/**/*",
|
40
|
+
]
|
41
|
+
|
42
|
+
def initialize(files_or_dirs, includes: [], excludes: [])
|
31
43
|
@files_or_dirs = files_or_dirs
|
44
|
+
@includes = includes
|
45
|
+
@excludes = excludes
|
32
46
|
end
|
33
47
|
|
34
48
|
def each
|
@@ -43,20 +57,15 @@ class Rufo::FileFinder
|
|
43
57
|
|
44
58
|
private
|
45
59
|
|
46
|
-
attr_reader :files_or_dirs
|
60
|
+
attr_reader :files_or_dirs, :includes, :excludes
|
47
61
|
|
48
62
|
def all_rb_files(file_or_dir)
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
if EXTENSIONS.include?(File.extname(basename)) || FILENAMES.include?(basename)
|
56
|
-
files << path
|
57
|
-
end
|
58
|
-
end
|
63
|
+
Dir.chdir(file_or_dir) do
|
64
|
+
fl = Rake::FileList.new(*DEFAULT_PATTERNS)
|
65
|
+
fl.exclude(*EXCLUDE_PATTERNS)
|
66
|
+
fl.exclude(*excludes)
|
67
|
+
fl.include(*includes)
|
68
|
+
fl.to_a
|
59
69
|
end
|
60
|
-
files
|
61
70
|
end
|
62
71
|
end
|
data/lib/rufo/formatter.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "ripper"
|
4
|
-
|
5
3
|
class Rufo::Formatter
|
6
4
|
include Rufo::Settings
|
7
5
|
|
8
6
|
INDENT_SIZE = 2
|
7
|
+
EMPTY_STRING = [:string_literal, [:string_content]]
|
8
|
+
EMPTY_HASH = [:hash, nil]
|
9
9
|
|
10
10
|
def self.format(code, **options)
|
11
11
|
formatter = new(code, **options)
|
@@ -15,12 +15,13 @@ class Rufo::Formatter
|
|
15
15
|
|
16
16
|
def initialize(code, **options)
|
17
17
|
@code = code
|
18
|
-
@tokens = Ripper.lex(code).reverse!
|
19
|
-
@sexp = Ripper.sexp(code)
|
20
18
|
|
21
|
-
|
22
|
-
|
23
|
-
|
19
|
+
@tokens = Rufo::Parser.lex(code).reverse!
|
20
|
+
@sexp = Rufo::Parser.sexp(code)
|
21
|
+
|
22
|
+
# sexp being nil means that the code is not valid.
|
23
|
+
# Parse the code so we get better error messages.
|
24
|
+
Rufo::Parser.parse(code) if @sexp.nil?
|
24
25
|
|
25
26
|
@indent = 0
|
26
27
|
@line = 0
|
@@ -179,6 +180,8 @@ class Rufo::Formatter
|
|
179
180
|
indent_literals
|
180
181
|
do_align_case_when if align_case_when
|
181
182
|
remove_lines_before_inline_declarations
|
183
|
+
@output.lstrip!
|
184
|
+
@output = "\n" if @output.empty?
|
182
185
|
end
|
183
186
|
|
184
187
|
def visit(node)
|
@@ -2378,7 +2381,7 @@ class Rufo::Formatter
|
|
2378
2381
|
skip_space_or_newline
|
2379
2382
|
consume_op(inclusive ? ".." : "...")
|
2380
2383
|
skip_space_or_newline
|
2381
|
-
visit right
|
2384
|
+
visit right unless right.nil?
|
2382
2385
|
end
|
2383
2386
|
|
2384
2387
|
def visit_regexp_literal(node)
|
@@ -3848,15 +3851,13 @@ class Rufo::Formatter
|
|
3848
3851
|
when :hash, :string_literal, :symbol_literal, :symbol, :vcall, :string_content, :assoc_splat, :var_ref
|
3849
3852
|
node_line(node[1], beginning: beginning)
|
3850
3853
|
when :assoc_new
|
3851
|
-
|
3854
|
+
# There's no line number info for empty strings or hashes.
|
3855
|
+
if node[1] != EMPTY_STRING && node[1] != EMPTY_HASH
|
3852
3856
|
node_line(node[1], beginning: beginning)
|
3857
|
+
elsif node.last != EMPTY_STRING && node.last != EMPTY_HASH
|
3858
|
+
node_line(node.last, beginning: beginning)
|
3853
3859
|
else
|
3854
|
-
|
3855
|
-
# there's no line number for [:string_literal, [:string_content]] or [:hash, nil]
|
3856
|
-
node_line(node[1], beginning: beginning)
|
3857
|
-
else
|
3858
|
-
node_line(node.last, beginning: beginning)
|
3859
|
-
end
|
3860
|
+
return
|
3860
3861
|
end
|
3861
3862
|
when :assoclist_from_args
|
3862
3863
|
node_line(beginning ? node[1][0] : node[1].last, beginning: beginning)
|
data/lib/rufo/parser.rb
ADDED
data/lib/rufo/settings.rb
CHANGED
@@ -5,15 +5,17 @@ module Rufo::Settings
|
|
5
5
|
align_chained_calls: [false, true],
|
6
6
|
trailing_commas: [true, false],
|
7
7
|
quote_style: [:double, :single],
|
8
|
+
includes: nil,
|
9
|
+
excludes: nil,
|
8
10
|
}
|
9
11
|
|
10
12
|
attr_accessor(*OPTIONS.keys)
|
11
13
|
|
12
14
|
def init_settings(options)
|
13
15
|
OPTIONS.each do |name, valid_options|
|
14
|
-
default = valid_options
|
16
|
+
default = valid_options&.first
|
15
17
|
value = options.fetch(name, default)
|
16
|
-
|
18
|
+
if !valid_options.nil? && !valid_options.include?(value)
|
17
19
|
$stderr.puts "Invalid value for #{name}: #{value.inspect}. Valid " \
|
18
20
|
"values are: #{valid_options.map(&:inspect).join(", ")}"
|
19
21
|
value = default
|
data/lib/rufo/version.rb
CHANGED
data/lib/rufo.rb
CHANGED
@@ -3,7 +3,14 @@
|
|
3
3
|
module Rufo
|
4
4
|
class Bug < StandardError; end
|
5
5
|
|
6
|
-
class SyntaxError < StandardError
|
6
|
+
class SyntaxError < StandardError
|
7
|
+
attr_reader :lineno
|
8
|
+
|
9
|
+
def initialize(message, lineno)
|
10
|
+
super(message)
|
11
|
+
@lineno = lineno
|
12
|
+
end
|
13
|
+
end
|
7
14
|
|
8
15
|
def self.format(code, **options)
|
9
16
|
Formatter.format(code, **options)
|
@@ -14,6 +21,8 @@ require_relative "rufo/command"
|
|
14
21
|
require_relative "rufo/logger"
|
15
22
|
require_relative "rufo/dot_file"
|
16
23
|
require_relative "rufo/settings"
|
24
|
+
require_relative "rufo/parser"
|
17
25
|
require_relative "rufo/formatter"
|
26
|
+
require_relative "rufo/erb_formatter"
|
18
27
|
require_relative "rufo/version"
|
19
28
|
require_relative "rufo/file_finder"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rufo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ary Borenszweig
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-01-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -130,6 +130,7 @@ files:
|
|
130
130
|
- Rakefile
|
131
131
|
- bin/console
|
132
132
|
- bin/setup
|
133
|
+
- bin/verify-sample-code
|
133
134
|
- docs/developing-rufo.md
|
134
135
|
- docs/releasing-a-gem.md
|
135
136
|
- docs/settings.md
|
@@ -137,9 +138,11 @@ files:
|
|
137
138
|
- lib/rufo.rb
|
138
139
|
- lib/rufo/command.rb
|
139
140
|
- lib/rufo/dot_file.rb
|
141
|
+
- lib/rufo/erb_formatter.rb
|
140
142
|
- lib/rufo/file_finder.rb
|
141
143
|
- lib/rufo/formatter.rb
|
142
144
|
- lib/rufo/logger.rb
|
145
|
+
- lib/rufo/parser.rb
|
143
146
|
- lib/rufo/settings.rb
|
144
147
|
- lib/rufo/version.rb
|
145
148
|
- rakelib/rufo.rake
|
@@ -163,7 +166,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
163
166
|
- !ruby/object:Gem::Version
|
164
167
|
version: '0'
|
165
168
|
requirements: []
|
166
|
-
rubygems_version: 3.0.
|
169
|
+
rubygems_version: 3.0.3
|
167
170
|
signing_key:
|
168
171
|
specification_version: 4
|
169
172
|
summary: Ruby code formatter
|