chusaku 0.5.0 → 0.6.0

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: 006eca0c4d1c3b87363edd35f9070dd48bc0693e1b56b01fd3900696fa50387d
4
- data.tar.gz: d5d3816c84eaba7c36d4e06e30eb7b8783b1dbb69f3c42190a278bf82fd01619
3
+ metadata.gz: 46b0340d8c2c5cde79a47703b564be4bec987b2fed0e9561ce658227ac3a2076
4
+ data.tar.gz: 8d2384684ad0c72d2f763446177b16d97d76f2c84c95bf4a7b5ff8e08cf32c23
5
5
  SHA512:
6
- metadata.gz: b103a27205545c18aba9e7570e0f0c63aafa558b0cb6b870520e8a25d60cbb73cdfceccc7937c09c3de5090cc304b08c1151a29ba16602802b0fdf685f8fe360
7
- data.tar.gz: ff6eb6258eea5a27f0422d633975251827c114af744f229ab3f4eca101a6ce840b39c4bf47300f16813944b055502f78d1a88d89725d827edf90649003b43b22
6
+ metadata.gz: a8e8d607f077c5de894d5fd70989d595fda9f4fab5d5111eeedb4acfa526d4f94cc7cb64abc64b42ac2968ef9e7f16bbf413a4329b46e919f0b46d8e9bc5c527
7
+ data.tar.gz: 72a674b922b87067ea2c3276f111603ee377a25bff277862187aa879b11ac83909877749b6b0cd5ff3315429e95b482da211f54b74b460eff129015780734e6c
@@ -0,0 +1,18 @@
1
+ name: Linting
2
+ on: [pull_request]
3
+ jobs:
4
+ rubocop:
5
+ runs-on: ubuntu-latest
6
+ steps:
7
+ - uses: actions/checkout@v2
8
+ - name: Set up Ruby
9
+ uses: ruby/setup-ruby@473e4d8fe5dd94ee328fdfca9f8c9c7afc9dae5e
10
+ with:
11
+ ruby-version: 3.0.0
12
+ bundler-cache: true
13
+ - name: Run RuboCop
14
+ uses: reviewdog/action-rubocop@v2
15
+ with:
16
+ rubocop_version: gemfile
17
+ github_token: ${{ secrets.github_token }}
18
+ reporter: github-pr-review
@@ -0,0 +1,17 @@
1
+ name: Testing
2
+ on: [pull_request]
3
+ jobs:
4
+ test:
5
+ runs-on: ubuntu-latest
6
+ strategy:
7
+ matrix:
8
+ ruby-version: ['2.6', '2.7', '3.0']
9
+ steps:
10
+ - uses: actions/checkout@v2
11
+ - name: Set up Ruby
12
+ uses: ruby/setup-ruby@473e4d8fe5dd94ee328fdfca9f8c9c7afc9dae5e
13
+ with:
14
+ ruby-version: ${{ matrix.ruby-version }}
15
+ bundler-cache: true
16
+ - name: Run tests
17
+ run: bundle exec rake
data/.rubocop.yml CHANGED
@@ -1,12 +1,20 @@
1
1
  require:
2
2
  - rubocop-performance
3
3
 
4
+ inherit_mode:
5
+ merge:
6
+ - Exclude
7
+
4
8
  AllCops:
9
+ NewCops: enable
5
10
  Exclude:
6
11
  - 'bin/**/*'
7
12
  - 'test/mock/app/**/*'
8
13
  - 'test/mock/examples/**/*'
9
14
 
15
+ Gemspec/RequiredRubyVersion:
16
+ Enabled: false
17
+
10
18
  Layout/LineLength:
11
19
  Max: 120
12
20
 
data/README.md CHANGED
@@ -1,8 +1,6 @@
1
1
  # Chusaku
2
2
 
3
- | Gem | CI | Quality |
4
- |-----|----|---------|
5
- |[![Gem Version](https://badge.fury.io/rb/chusaku.svg)](https://badge.fury.io/rb/chusaku)|[![CircleCI](https://circleci.com/gh/nshki/chusaku.svg?style=svg&circle-token=e1917972632f242932171de0ca5443148e83151c)](https://circleci.com/gh/nshki/chusaku)|[![Maintainability](https://api.codeclimate.com/v1/badges/e21235bd513aadf0407b/maintainability)](https://codeclimate.com/github/nshki/chusaku/maintainability)
3
+ [![Gem Version](https://badge.fury.io/rb/chusaku.svg)](https://badge.fury.io/rb/chusaku)
6
4
 
7
5
  Add comments above your Rails actions that look like:
8
6
 
@@ -54,9 +52,10 @@ Chusaku has some flags available for use as well:
54
52
  ```
55
53
  $ bundle exec chusaku --help
56
54
  Usage: chusaku [options]
55
+ --dry-run Run without file modifications
57
56
  --exit-with-error-on-annotation
58
57
  Fail if any file was annotated
59
- --dry-run Run without file modifications
58
+ --verbose Print all annotations
60
59
  -v, --version Show Chusaku version number and quit
61
60
  -h, --help Show this help message and quit
62
61
  ```
data/chusaku.gemspec CHANGED
@@ -26,7 +26,7 @@ Gem::Specification.new do |spec|
26
26
  spec.metadata['changelog_uri'] = spec.homepage
27
27
  else
28
28
  raise 'RubyGems 2.0 or newer is required to protect against ' \
29
- 'public gem pushes.'
29
+ 'public gem pushes.'
30
30
  end
31
31
 
32
32
  # Specify which files should be added to the gem when it is released.
data/lib/chusaku/cli.rb CHANGED
@@ -54,36 +54,41 @@ module Chusaku
54
54
  def optparser
55
55
  OptionParser.new do |opts|
56
56
  opts.banner = 'Usage: chusaku [options]'
57
- add_error_on_annotation_flag(opts)
58
57
  add_dry_run_flag(opts)
58
+ add_error_on_annotation_flag(opts)
59
+ add_verbose_flag(opts)
59
60
  add_version_flag(opts)
60
61
  add_help_flag(opts)
61
62
  end
62
63
  end
63
64
 
65
+ # Adds `--dry-run` flag.
66
+ #
67
+ # @param opts [OptionParser] OptionParser instance
68
+ # @return [void]
69
+ def add_dry_run_flag(opts)
70
+ opts.on('--dry-run', 'Run without file modifications') do
71
+ @options[:dry] = true
72
+ end
73
+ end
74
+
64
75
  # Adds `--exit-with-error-on-annotation` flag.
65
76
  #
66
77
  # @param opts [OptionParser] OptionParser instance
67
78
  # @return [void]
68
79
  def add_error_on_annotation_flag(opts)
69
- opts.on(
70
- '--exit-with-error-on-annotation',
71
- 'Fail if any file was annotated'
72
- ) do
80
+ opts.on('--exit-with-error-on-annotation', 'Fail if any file was annotated') do
73
81
  @options[:error_on_annotation] = true
74
82
  end
75
83
  end
76
84
 
77
- # Adds `--dry-run` flag.
85
+ # Adds `--verbose` flag.
78
86
  #
79
87
  # @param opts [OptionParser] OptionParser instance
80
88
  # @return [void]
81
- def add_dry_run_flag(opts)
82
- opts.on(
83
- '--dry-run',
84
- 'Run without file modifications'
85
- ) do
86
- @options[:dry] = true
89
+ def add_verbose_flag(opts)
90
+ opts.on('--verbose', 'Print all annotations') do
91
+ @options[:verbose] = true
87
92
  end
88
93
  end
89
94
 
@@ -92,11 +97,7 @@ module Chusaku
92
97
  # @param opts [OptionParser] OptionParser instance
93
98
  # @return [void]
94
99
  def add_version_flag(opts)
95
- opts.on(
96
- '-v',
97
- '--version',
98
- 'Show Chusaku version number and quit'
99
- ) do
100
+ opts.on('-v', '--version', 'Show Chusaku version number and quit') do
100
101
  puts(Chusaku::VERSION)
101
102
  raise Finished
102
103
  end
@@ -107,11 +108,7 @@ module Chusaku
107
108
  # @param opts [OptionParser] OptionParser instance
108
109
  # @return [void]
109
110
  def add_help_flag(opts)
110
- opts.on(
111
- '-h',
112
- '--help',
113
- 'Show this help message and quit'
114
- ) do
111
+ opts.on('-h', '--help', 'Show this help message and quit') do
115
112
  puts(opts)
116
113
  raise Finished
117
114
  end
@@ -13,22 +13,26 @@ module Chusaku
13
13
  # {
14
14
  # type: :code,
15
15
  # body: 'class Foo\n',
16
- # action: nil
16
+ # action: nil,
17
+ # line_number: 1
17
18
  # },
18
19
  # {
19
20
  # type: :comment,
20
21
  # body: ' # Bar\n # Baz\n',
21
- # action: nil
22
+ # action: nil,
23
+ # line_number: 2
22
24
  # },
23
25
  # {
24
26
  # type: :action,
25
27
  # body: ' def action_name; end\n',
26
- # action: 'action_name'
28
+ # action: 'action_name',
29
+ # line_number: 4
27
30
  # }
28
31
  # {
29
32
  # type: :code,
30
33
  # body: 'end # vanilla is the best flavor\n',
31
- # action: nil
34
+ # action: nil,
35
+ # line_number: 5
32
36
  # }
33
37
  # ]
34
38
  # }
@@ -41,17 +45,17 @@ module Chusaku
41
45
  group = {}
42
46
  content = IO.read(path)
43
47
 
44
- content.each_line do |line|
48
+ content.each_line.with_index do |line, index|
45
49
  parsed_line = parse_line(line: line, actions: actions)
46
50
 
47
- if group[:type] != parsed_line[:type]
51
+ if group[:type] == parsed_line[:type]
52
+ # Same group. Push the current line into the current group.
53
+ group[:body] += line
54
+ else
48
55
  # Now looking at a new group. Push the current group onto the array
49
56
  # and start a new one.
50
57
  groups.push(group) unless group.empty?
51
- group = parsed_line
52
- else
53
- # Same group. Push the current line into the current group.
54
- group[:body] += line
58
+ group = parsed_line.merge(line_number: index + 1)
55
59
  end
56
60
  end
57
61
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Chusaku
4
- VERSION = '0.5.0'
4
+ VERSION = '0.6.0'
5
5
  end
data/lib/chusaku.rb CHANGED
@@ -20,11 +20,11 @@ module Chusaku
20
20
  def call(flags = {})
21
21
  @flags = flags
22
22
  @routes = Chusaku::Routes.call
23
- @annotated_paths = []
23
+ @changes = []
24
24
  controllers_pattern = 'app/controllers/**/*_controller.rb'
25
25
 
26
26
  Dir.glob(Rails.root.join(controllers_pattern)).each do |path|
27
- controller = %r{controllers\/(.*)_controller\.rb}.match(path)[1]
27
+ controller = %r{controllers/(.*)_controller\.rb}.match(path)[1]
28
28
  actions = @routes[controller]
29
29
  next if actions.nil?
30
30
 
@@ -45,18 +45,46 @@ module Chusaku
45
45
  def annotate_file(path:, controller:, actions:)
46
46
  parsed_file = Chusaku::Parser.call(path: path, actions: actions)
47
47
  parsed_file[:groups].each_cons(2) do |prev, curr|
48
- clean_group(prev)
48
+ record_change(group: prev, type: :clean, path: path)
49
49
  next unless curr[:type] == :action
50
50
 
51
51
  route_data = @routes[controller][curr[:action]]
52
52
  next unless route_data.any?
53
53
 
54
- annotate_group(group: curr, route_data: route_data)
54
+ record_change(group: curr, type: :annotate, route_data: route_data, path: path)
55
55
  end
56
56
 
57
57
  write_to_file(path: path, parsed_file: parsed_file)
58
58
  end
59
59
 
60
+ # Clean or annotate a group and track the group as changed if applicable.
61
+ #
62
+ # @param group [Hash] { type => Symbol, body => String }
63
+ # @param type [Symbol] [:clean, :annotate]
64
+ # @param path [String] File path
65
+ # @param route_data [Array<Hash>] [{
66
+ # verb: String,
67
+ # path: String,
68
+ # name: String }]
69
+ # @return [void]
70
+ def record_change(group:, type:, path:, route_data: [])
71
+ old_body = group[:body]
72
+
73
+ case type
74
+ when :clean
75
+ clean_group(group)
76
+ when :annotate
77
+ annotate_group(group: group, route_data: route_data)
78
+ end
79
+ return if old_body == group[:body]
80
+
81
+ @changes.push \
82
+ old_body: old_body,
83
+ new_body: group[:body],
84
+ path: path,
85
+ line_number: group[:line_number]
86
+ end
87
+
60
88
  # Given a parsed group, clean out its contents.
61
89
  #
62
90
  # @param group [Hash] { type => Symbol, body => String }
@@ -66,7 +94,7 @@ module Chusaku
66
94
 
67
95
  group[:body] = group[:body].gsub(/^\s*#\s*@route.*$\n/, '')
68
96
  group[:body] =
69
- group[:body].gsub(%r{^\s*# (GET|POST|PATCH\/PUT|DELETE) \/\S+$\n}, '')
97
+ group[:body].gsub(%r{^\s*# (GET|POST|PATCH/PUT|DELETE) /\S+$\n}, '')
70
98
  end
71
99
 
72
100
  # Add an annotation to the given group given by Chusaku::Parser that looks
@@ -112,10 +140,9 @@ module Chusaku
112
140
  # @return [void]
113
141
  def write_to_file(path:, parsed_file:)
114
142
  new_content = new_content_for(parsed_file)
115
- return unless parsed_file[:content] != new_content
143
+ return if parsed_file[:content] == new_content
116
144
 
117
145
  !@flags.include?(:dry) && perform_write(path: path, content: new_content)
118
- @annotated_paths.push(path)
119
146
  end
120
147
 
121
148
  # Extracts the new file content for the given parsed file.
@@ -156,7 +183,7 @@ module Chusaku
156
183
  def output_results
157
184
  puts(output_copy)
158
185
  exit_code = 0
159
- exit_code = 1 if @annotated_paths.any? && @flags.include?(:error_on_annotation)
186
+ exit_code = 1 if @changes.any? && @flags.include?(:error_on_annotation)
160
187
  exit_code
161
188
  end
162
189
 
@@ -164,25 +191,36 @@ module Chusaku
164
191
  #
165
192
  # @return [String] Copy to be outputted to user
166
193
  def output_copy
167
- return 'Nothing to annotate.' if @annotated_paths.empty?
168
-
169
- annotated_paths = @annotated_paths.join(', ')
170
- dry_run = @flags.include?(:dry)
171
- error_on_annotation = @flags.include?(:error_on_annotation)
172
-
173
- if dry_run && error_on_annotation
174
- <<~COPY
175
- Annotations missing in the following files: #{annotated_paths}
176
-
177
- Run `chusaku` to annotate them. Exiting with status code 1.
178
- COPY
179
- elsif dry_run
180
- "The following files would be annotated without `--dry-run`: #{annotated_paths}"
181
- elsif error_on_annotation
182
- "Annotated #{annotated_paths}.\n\nExiting with status code 1."
183
- else
184
- "Annotated #{annotated_paths}."
185
- end
194
+ return 'Nothing to annotate.' if @changes.empty?
195
+
196
+ copy = changes_copy
197
+ copy += "\nChusaku has finished running."
198
+ copy += "\nThis was a dry run so no files were changed." if @flags.include?(:dry)
199
+ copy += "\nExited with status code 1." if @flags.include?(:error_on_annotation)
200
+ copy
201
+ end
202
+
203
+ # Returns the copy for recorded changes if `--verbose` flag is passed.
204
+ #
205
+ # @return [String] Copy of recorded changes
206
+ def changes_copy
207
+ return '' unless @flags.include?(:verbose)
208
+
209
+ @changes.map do |change|
210
+ <<~CHANGE_OUTPUT
211
+ [#{change[:path]}:#{change[:line_number]}]
212
+
213
+ Before:
214
+ ```ruby
215
+ #{change[:old_body].chomp}
216
+ ```
217
+
218
+ After:
219
+ ```ruby
220
+ #{change[:new_body].chomp}
221
+ ```
222
+ CHANGE_OUTPUT
223
+ end.join("\n")
186
224
  end
187
225
  end
188
226
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chusaku
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nishiki Liu
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-04-22 00:00:00.000000000 Z
11
+ date: 2021-10-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -102,8 +102,8 @@ executables:
102
102
  extensions: []
103
103
  extra_rdoc_files: []
104
104
  files:
105
- - ".circleci/config.yml"
106
- - ".codeclimate.yml"
105
+ - ".github/workflows/linting.yml"
106
+ - ".github/workflows/testing.yml"
107
107
  - ".gitignore"
108
108
  - ".rubocop.yml"
109
109
  - Gemfile
@@ -127,7 +127,7 @@ metadata:
127
127
  homepage_uri: https://github.com/nshki/chusaku
128
128
  source_code_uri: https://github.com/nshki/chusaku
129
129
  changelog_uri: https://github.com/nshki/chusaku
130
- post_install_message:
130
+ post_install_message:
131
131
  rdoc_options: []
132
132
  require_paths:
133
133
  - lib
@@ -142,8 +142,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
142
142
  - !ruby/object:Gem::Version
143
143
  version: '0'
144
144
  requirements: []
145
- rubygems_version: 3.2.15
146
- signing_key:
145
+ rubygems_version: 3.1.6
146
+ signing_key:
147
147
  specification_version: 4
148
148
  summary: Annotate your Rails controllers with route info.
149
149
  test_files: []
data/.circleci/config.yml DELETED
@@ -1,29 +0,0 @@
1
- version: 2
2
- jobs:
3
- build:
4
- working_directory: ~/chusaku
5
- docker:
6
- - image: circleci/ruby
7
- steps:
8
- - checkout
9
- - run:
10
- name: Install Bundler
11
- command: |
12
- gem install bundler
13
- - restore_cache:
14
- keys:
15
- - dep-v1-{{ .Branch }}-{{ checksum "chusaku.gemspec" }}
16
- - dep-v1-{{ .Branch }}
17
- - dep-v1-
18
- - run:
19
- name: Install dependencies
20
- command: |
21
- bundle install --path vendor/bundle
22
- - save_cache:
23
- key: dep-v1-{{ .Branch }}-{{ checksum "chusaku.gemspec" }}
24
- paths:
25
- - vendor/bundle
26
- - run:
27
- name: Run tests
28
- command: |
29
- bundle exec rake test
data/.codeclimate.yml DELETED
@@ -1,4 +0,0 @@
1
- plugins:
2
- rubocop:
3
- enabled: true
4
- channel: rubocop-0-77