chusaku 0.5.0 → 0.6.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 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