chusaku 1.1.0 → 1.3.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: 62bb838dd76c648a120303c3a0bde8c67ea7232f90accb9f3e739a3b69764026
4
- data.tar.gz: 9af1726825550cb4ce7d642e6a80217b8810cb6a56e8703c6d7f4f23a8643f3a
3
+ metadata.gz: 48034ba3796c8cd1ab1a16b0db1065dcdf487ea5e6bc1b08a7fcd18db4ad1d33
4
+ data.tar.gz: 65cf7dbbf5571f547aeb9cefc8cd804ccab9467b0765edcc00691c777c158554
5
5
  SHA512:
6
- metadata.gz: 0baeb0a41404f911ef11b3d12709773a44ecc18aa542f5dcb854e1b67023b7fd79f640d10d7d8a4368121a33714327c5120ed701c9a67c238537023db78603e7
7
- data.tar.gz: 1e5026ac8d35af5ff8c5d8c02d32d7d634716966dad3a61947398ee870203795ff91286bb43b7daf6802c4bace3df42b1ffb325c130e88b1fe26495d72100118
6
+ metadata.gz: 83c00966e23c6d8a63f9b68e35cc48a975689f21473e83344927764ac200d9eb378274c6ad82fa90a0ac6a06d286763f45661f4b2433983f903cf93371158167
7
+ data.tar.gz: 70afe36985465e34f3fa18e5eea3d51d130daaada6414a51b680a0e4f32f31e14a3e3225f8f70b594d19d8c23e9ad3b00ac9f43c4dd83c493bdd5befba483e8a
@@ -6,9 +6,9 @@ jobs:
6
6
  steps:
7
7
  - uses: actions/checkout@v2
8
8
  - name: Set up Ruby
9
- uses: ruby/setup-ruby@473e4d8fe5dd94ee328fdfca9f8c9c7afc9dae5e
9
+ uses: ruby/setup-ruby@v1
10
10
  with:
11
- ruby-version: 3.0.0
11
+ ruby-version: 3.3
12
12
  bundler-cache: true
13
13
  - name: Run Standard
14
14
  run: bundle exec standardrb --fail-level A
@@ -5,11 +5,11 @@ jobs:
5
5
  runs-on: ubuntu-latest
6
6
  strategy:
7
7
  matrix:
8
- ruby-version: ["2.6", "2.7", "3.0"]
8
+ ruby-version: ["3.1", "3.2", "3.3"]
9
9
  steps:
10
10
  - uses: actions/checkout@v2
11
11
  - name: Set up Ruby
12
- uses: ruby/setup-ruby@473e4d8fe5dd94ee328fdfca9f8c9c7afc9dae5e
12
+ uses: ruby/setup-ruby@v1
13
13
  with:
14
14
  ruby-version: ${{ matrix.ruby-version }}
15
15
  bundler-cache: true
data/.gitignore CHANGED
@@ -7,4 +7,7 @@
7
7
  /spec/reports/
8
8
  /tmp/
9
9
 
10
+ .DS_Store
11
+
12
+ .ruby-version
10
13
  Gemfile.lock
data/README.md CHANGED
@@ -26,16 +26,14 @@ Add this line to your Rails application's Gemfile:
26
26
 
27
27
  ```ruby
28
28
  group :development do
29
- # ...
30
29
  gem "chusaku", require: false
31
- # ...
32
30
  end
33
31
  ```
34
32
 
35
33
  And then execute:
36
34
 
37
- ```
38
- $ bundle install
35
+ ```sh
36
+ bundle install
39
37
  ```
40
38
 
41
39
 
@@ -43,8 +41,8 @@ $ bundle install
43
41
 
44
42
  From the root of your Rails application, run:
45
43
 
46
- ```
47
- $ bundle exec chusaku
44
+ ```sh
45
+ bundle exec chusaku
48
46
  ```
49
47
 
50
48
  Chusaku has some flags available for use as well:
@@ -55,23 +53,37 @@ Usage: chusaku [options]
55
53
  --dry-run Run without file modifications
56
54
  --exit-with-error-on-annotation Fail if any file was annotated
57
55
  -c, --controllers-pattern=GLOB Specify alternative controller files glob pattern
58
- --verbose Print all annotations
56
+ --verbose Print all annotated files
59
57
  -v, --version Show Chusaku version number and quit
60
58
  -h, --help Show this help message and quit
59
+ ```
60
+
61
+ ### Rake usage
62
+
63
+ If you'd like to use Chusaku as a Rake task, add the following line to your `Rakefile`:
64
+
65
+ ```ruby
66
+ require "chusaku"
67
+ Chusaku.load_tasks
68
+ ```
69
+
70
+ This will then allow you to call:
71
+
72
+ ```sh
73
+ bin/rake chusaku
74
+ ```
75
+
76
+ To pass flags, pass them like you would from the CLI executable:
61
77
 
78
+ ```sh
79
+ bin/rake chusaku -- --dry-run --exit-with-error-on-annotation
62
80
  ```
63
81
 
64
82
 
65
83
  ## Development
66
84
 
67
- Read the blog post explaining how the gem works at a high level:
68
- https://nshki.com/chusaku-a-controller-annotation-gem.
85
+ Read the blog post explaining how the gem works at a high level: https://nshki.com/chusaku-a-controller-annotation-gem.
69
86
 
70
- After checking out the repo, run `bin/setup` to install dependencies. Then, run
71
- `bundle exec rake test` to run the tests. You can also run `bin/console` for an
72
- interactive prompt that will allow you to experiment.
87
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `bundle exec rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
73
88
 
74
- To release a new version, update the version number in `version.rb`, and then
75
- run `bundle exec rake release`, which will create a git tag for the version,
76
- git commits and tags, and push the `.gem` file to
77
- [rubygems.org](https://rubygems.org).
89
+ To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
data/lib/chusaku/cli.rb CHANGED
@@ -41,7 +41,8 @@ module Chusaku
41
41
  # @raise [Chusaku::CLI::NotARailsProject] Exception if not Rails project
42
42
  # @return [void]
43
43
  def check_for_rails_project
44
- has_controllers = File.directory?("./app/controllers")
44
+ controllers_pattern = options[:controllers_pattern] || DEFAULT_CONTROLLERS_PATTERN
45
+ has_controllers = !Dir.glob(Rails.root.join(controllers_pattern)).empty?
45
46
  has_rakefile = File.exist?("./Rakefile")
46
47
  raise NotARailsProject unless has_controllers && has_rakefile
47
48
  end
@@ -97,7 +98,7 @@ module Chusaku
97
98
  # @param opts [OptionParser] OptionParser instance
98
99
  # @return [void]
99
100
  def add_verbose_flag(opts)
100
- opts.on("--verbose", "Print all annotations") do
101
+ opts.on("--verbose", "Print all annotated files") do
101
102
  @options[:verbose] = true
102
103
  end
103
104
  end
@@ -27,7 +27,19 @@ module Chusaku
27
27
  def call
28
28
  routes = {}
29
29
 
30
- Rails.application.routes.routes.each do |route|
30
+ populate_routes(Rails.application, routes)
31
+ backfill_routes(routes)
32
+ end
33
+
34
+ private
35
+
36
+ def populate_routes(app, routes)
37
+ app.routes.routes.each do |route|
38
+ if route.app.engine?
39
+ populate_routes(route.app.app, routes)
40
+ next
41
+ end
42
+
31
43
  controller, action, defaults = extract_data_from(route)
32
44
  routes[controller] ||= {}
33
45
  routes[controller][action] ||= []
@@ -39,12 +51,8 @@ module Chusaku
39
51
  action: action,
40
52
  defaults: defaults
41
53
  end
42
-
43
- backfill_routes(routes)
44
54
  end
45
55
 
46
- private
47
-
48
56
  # Adds formatted route info for the given param combination.
49
57
  #
50
58
  # @param route [Hash] Route info
@@ -1,3 +1,3 @@
1
1
  module Chusaku
2
- VERSION = "1.1.0"
2
+ VERSION = "1.3.0"
3
3
  end
data/lib/chusaku.rb CHANGED
@@ -4,6 +4,8 @@ require "chusaku/routes"
4
4
 
5
5
  # Handles core functionality of annotating projects.
6
6
  module Chusaku
7
+ DEFAULT_CONTROLLERS_PATTERN = "**/*_controller.rb".freeze
8
+
7
9
  class << self
8
10
  # The main method to run Chusaku. Annotate all actions in a Rails project as
9
11
  # follows:
@@ -18,72 +20,57 @@ module Chusaku
18
20
  def call(flags = {})
19
21
  @flags = flags
20
22
  @routes = Chusaku::Routes.call
21
- @changes = []
22
23
  @changed_files = []
23
- controllers_pattern = @flags[:controllers_pattern] || "app/controllers/**/*_controller.rb"
24
+ controllers_pattern = @flags[:controllers_pattern] || DEFAULT_CONTROLLERS_PATTERN
25
+ controllers_paths = Dir.glob(Rails.root.join(controllers_pattern))
26
+
27
+ @routes.each do |controller, actions|
28
+ next unless controller
24
29
 
25
- Dir.glob(Rails.root.join(controllers_pattern)).each do |path|
26
- controller = %r{controllers/(.*)_controller\.rb}.match(path)[1]
27
- actions = @routes[controller]
28
- next if actions.nil?
30
+ controller_class = "#{controller.underscore.camelize}Controller".constantize
31
+ action_method_name = actions.keys.first&.to_sym
32
+ next unless !action_method_name.nil? && controller_class.method_defined?(action_method_name)
29
33
 
30
- annotate_file(path: path, controller: controller, actions: actions.keys)
34
+ source_path = controller_class.instance_method(action_method_name).source_location&.[](0)
35
+ next unless controllers_paths.include?(source_path)
36
+
37
+ annotate_file(path: source_path, actions: actions)
31
38
  end
32
39
 
33
40
  output_results
34
41
  end
35
42
 
43
+ # Load Rake tasks for Chusaku. Should be called in your project's `Rakefile`.
44
+ #
45
+ # @return [void]
46
+ def load_tasks
47
+ Dir[File.join(File.dirname(__FILE__), "tasks", "**/*.rake")].each do |task|
48
+ load(task)
49
+ end
50
+ end
51
+
36
52
  private
37
53
 
38
54
  # Adds annotations to the given file.
39
55
  #
40
56
  # @param path [String] Path to file
41
- # @param controller [String] Controller name
42
- # @param actions [Array<String>] List of valid actions for the controller
57
+ # @param actions [Hash<String, Hash>] List of valid action data for the controller
43
58
  # @return [void]
44
- def annotate_file(path:, controller:, actions:)
45
- parsed_file = Chusaku::Parser.call(path: path, actions: actions)
59
+ def annotate_file(path:, actions:)
60
+ parsed_file = Chusaku::Parser.call(path: path, actions: actions.keys)
46
61
  parsed_file[:groups].each_cons(2) do |prev, curr|
47
- record_change(group: prev, type: :clean, path: path)
62
+ clean_group(prev)
48
63
  next unless curr[:type] == :action
49
64
 
50
- route_data = @routes[controller][curr[:action]]
65
+ route_data = actions[curr[:action]]
51
66
  next unless route_data.any?
52
67
 
53
- record_change(group: curr, type: :annotate, route_data: route_data, path: path)
68
+ annotate_group(group: curr, route_data: route_data)
54
69
  end
55
70
 
56
71
  write_to_file(path: path, parsed_file: parsed_file)
57
72
  end
58
73
 
59
- # Clean or annotate a group and track the group as changed if applicable.
60
- #
61
- # @param group [Hash] { type => Symbol, body => String }
62
- # @param type [Symbol] [:clean, :annotate]
63
- # @param path [String] File path
64
- # @param route_data [Array<Hash>] [{
65
- # verb: String,
66
- # path: String,
67
- # name: String }]
68
- # @return [void]
69
- def record_change(group:, type:, path:, route_data: [])
70
- old_body = group[:body]
71
-
72
- case type
73
- when :clean
74
- clean_group(group)
75
- when :annotate
76
- annotate_group(group: group, route_data: route_data)
77
- end
78
- return if old_body == group[:body]
79
-
80
- @changes.push \
81
- old_body: old_body,
82
- new_body: group[:body],
83
- path: path,
84
- line_number: group[:line_number]
85
- end
86
-
87
74
  # Given a parsed group, clean out its contents.
88
75
  #
89
76
  # @param group [Hash] { type => Symbol, body => String }
@@ -191,36 +178,22 @@ module Chusaku
191
178
  #
192
179
  # @return [String] Copy to be outputted to user
193
180
  def output_copy
194
- return "Nothing to annotate." if @changed_files.empty?
181
+ return "Controller files unchanged." if @changed_files.empty?
195
182
 
196
183
  copy = changes_copy
197
- copy += "\nChusaku has finished running."
184
+ copy += "Chusaku has finished running."
198
185
  copy += "\nThis was a dry run so no files were changed." if @flags.include?(:dry)
199
186
  copy += "\nExited with status code 1." if @flags.include?(:error_on_annotation)
200
187
  copy
201
188
  end
202
189
 
203
- # Returns the copy for recorded changes if `--verbose` flag is passed.
190
+ # Returns the copy for changed files if `--verbose` flag is passed.
204
191
  #
205
- # @return [String] Copy of recorded changes
192
+ # @return [String] Copy for changed files
206
193
  def changes_copy
207
194
  return "" unless @flags.include?(:verbose)
208
195
 
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")
196
+ @changed_files.map { |file| "Annotated #{file}" }.join("\n") + "\n"
224
197
  end
225
198
  end
226
199
  end
@@ -0,0 +1,8 @@
1
+ chusaku_lib = File.expand_path(File.dirname(__FILE__, 2))
2
+
3
+ desc "Add route annotations to your Rails actions"
4
+ task chusaku: :environment do
5
+ require "#{chusaku_lib}/chusaku/cli"
6
+
7
+ Chusaku::CLI.new.call(ARGV[2...] || [])
8
+ 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: 1.1.0
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nishiki Liu
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-09-03 00:00:00.000000000 Z
11
+ date: 2024-08-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -105,6 +105,7 @@ files:
105
105
  - lib/chusaku/parser.rb
106
106
  - lib/chusaku/routes.rb
107
107
  - lib/chusaku/version.rb
108
+ - lib/tasks/chusaku.rake
108
109
  homepage: https://github.com/nshki/chusaku
109
110
  licenses:
110
111
  - MIT
@@ -128,7 +129,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
128
129
  - !ruby/object:Gem::Version
129
130
  version: '0'
130
131
  requirements: []
131
- rubygems_version: 3.4.19
132
+ rubygems_version: 3.5.17
132
133
  signing_key:
133
134
  specification_version: 4
134
135
  summary: Annotate your Rails controllers with route info.