chusaku 0.1.4 → 0.2.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: 519cb59d3970def8c48a1f9995f8208e2455d17c6f3061ff56ceed1e9cd2e593
4
- data.tar.gz: 4de2d9aae8d0e9d97d998a53b47fd4428855ed7f5898926ae3e1f14d1b6fe90e
3
+ metadata.gz: be8c03a0fe70a6b717b8fb204ae3d2d1b9eaaa89597c7ada8c169cb49919d2ef
4
+ data.tar.gz: 28736b04b639cba7eed34695691433a0cf4defd3f48eaf7a15faced2e04540e8
5
5
  SHA512:
6
- metadata.gz: f619946e1d2a43aacec4d8bd2488d5b5af4c4e24f64bc233c294097ffc51e2c4bf3c3028530302397c026d099835d2587df1cc96356643102812bf93754a8265
7
- data.tar.gz: 871f3aab82d32b5dff9dd508fbc8119ace1125cc88e14f0e36489b094228e3843bd47fa418a0314017fe974c5ee1a149fd86585f47f494e888de92e82fa3da54
6
+ metadata.gz: 178db8776a7bfeaccbe2eea70346753cf203531c7836f706988a65c3527ac6de733580ed6e324f93658fbbeec4812fff9196f460985abdab140eea99e794ab61
7
+ data.tar.gz: f8307518e4df5d74a3c5703efed73f167138c04ae2a0d2a1f314c16bc0b1e6d101c64355d994349dc238be2a486745dbea4703389bf485dbb681412e03ae21f8
data/README.md CHANGED
@@ -49,6 +49,21 @@ From the root of your Rails application, run:
49
49
  $ bundle exec chusaku
50
50
  ```
51
51
 
52
+ Chusaku has some flags available for use as well:
53
+
54
+ ```
55
+ $ bundle exec chusaku --help
56
+ Usage: chusaku [options]
57
+ --exit-with-error-on-annotation
58
+ Fail if any file was annotated
59
+ --dry-run Run without file modifications
60
+ -v, --version Show Chusaku version number and quit
61
+ -h, --help Show this help message and quit
62
+ ```
63
+
64
+ If you'd like to use Chusaku as a Git hook, take a look at
65
+ [Lefthook](https://github.com/Arkweid/lefthook).
66
+
52
67
 
53
68
  ## Development
54
69
 
@@ -1,9 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- unless File.directory?('./app/controllers') && File.exist?('./Rakefile')
4
- abort 'Please run chusaku from the root of your project.'
5
- end
6
-
7
3
  require 'rubygems'
8
4
 
9
5
  begin
@@ -18,5 +14,6 @@ begin
18
14
  rescue StandardError
19
15
  end
20
16
 
21
- require 'chusaku'
22
- Chusaku.call
17
+ require 'chusaku/cli'
18
+
19
+ exit Chusaku::CLI.new.call
@@ -12,10 +12,14 @@ module Chusaku
12
12
  # def show
13
13
  # # ...
14
14
  # end
15
- def self.call
15
+ #
16
+ # @param {Array<String>} args - CLI flags
17
+ # @return {Integer} 0 on success, 1 on error
18
+ def self.call(args = [])
16
19
  routes = Chusaku::Routes.call
17
20
  controller_pattern = 'app/controllers/**/*_controller.rb'
18
21
  controller_paths = Dir.glob(Rails.root.join(controller_pattern))
22
+ annotated_paths = []
19
23
 
20
24
  # Loop over all controller file paths.
21
25
  controller_paths.each do |path|
@@ -26,7 +30,7 @@ module Chusaku
26
30
  # Parse the file and iterate over the parsed content, two entries at a
27
31
  # time.
28
32
  parsed_file = Chusaku::Parser.call(path: path, actions: actions.keys)
29
- parsed_file.each_cons(2) do |prev, curr|
33
+ parsed_file[:groups].each_cons(2) do |prev, curr|
30
34
  # Remove all @route comments in the previous group.
31
35
  if prev[:type] == :comment
32
36
  prev[:body] = prev[:body].gsub(/^\s*#\s*@route.*$\n/, '')
@@ -50,23 +54,33 @@ module Chusaku
50
54
  end
51
55
 
52
56
  # Write to file.
53
- parsed_content = parsed_file.map { |pf| pf[:body] }
54
- write(path, parsed_content.join)
57
+ parsed_content = parsed_file[:groups].map { |pf| pf[:body] }
58
+ new_content = parsed_content.join
59
+ if parsed_file[:content] != new_content
60
+ write(path, new_content) unless args.include?(:dry)
61
+ annotated_paths << path
62
+ end
55
63
  end
56
64
 
57
65
  # Output results to user.
58
- if controller_paths.any?
59
- puts "Annotated #{controller_paths.join(', ')}"
66
+ if annotated_paths.any?
67
+ puts "Annotated #{annotated_paths.join(', ')}"
68
+ if args.include?(:error_on_annotation)
69
+ 1
70
+ else
71
+ 0
72
+ end
60
73
  else
61
74
  puts "Nothing to annotate"
75
+ 0
62
76
  end
63
77
  end
64
78
 
65
79
  # Write given content to a file. If we're using an overridden version of File,
66
80
  # then use its method instead for testing purposes.
67
81
  #
68
- # @param {String} path
69
- # @param {String} content
82
+ # @param {String} path - File path to write to
83
+ # @param {String} content - Contents of the file
70
84
  # @return {void}
71
85
  def self.write(path, content)
72
86
  File.open(path, 'r+') do |file|
@@ -82,8 +96,8 @@ module Chusaku
82
96
  #
83
97
  # @route GET /waterlilies/:id (waterlilies)
84
98
  #
85
- # @param {Hash} action_info
86
- # @return {String}
99
+ # @param {Hash} action_info - Parsed line given by Chusaku::Parser
100
+ # @return {String} Annotation for given parsed line
87
101
  def self.annotate(action_info)
88
102
  verb = action_info[:verb]
89
103
  path = action_info[:path]
@@ -0,0 +1,91 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'optparse'
4
+ require 'chusaku'
5
+
6
+ module Chusaku
7
+ class CLI
8
+ STATUS_SUCCESS = 0
9
+ STATUS_ERROR = 1
10
+
11
+ attr_reader :options
12
+
13
+ Finished = Class.new(RuntimeError)
14
+ NotARailsProject = Class.new(RuntimeError)
15
+
16
+ # Initializes a new instance of Chusaku::CLI.
17
+ #
18
+ # @return {Chusaku::CLI} Instance of this class
19
+ def initialize
20
+ @options = {}
21
+ end
22
+
23
+ # Parse CLI flags, if any, and handle applicable behaviors.
24
+ #
25
+ # @param {Array<String>} args - CLI arguments
26
+ # @return {Integer} 0 on success, 1 on error
27
+ def call(args = ARGV)
28
+ optparser.parse!(args)
29
+ check_for_rails_project
30
+ Chusaku.call(options)
31
+ rescue NotARailsProject
32
+ warn('Please run chusaku from the root of your project.')
33
+ STATUS_ERROR
34
+ rescue Finished
35
+ STATUS_SUCCESS
36
+ end
37
+
38
+ private
39
+
40
+ # Raises exception if Rails project cannot be detected.
41
+ #
42
+ # @raise {Chusaku::CLI::NotARailsProject} Exception if not Rails project
43
+ # @return {void}
44
+ def check_for_rails_project
45
+ unless File.directory?('./app/controllers') && File.exist?('./Rakefile')
46
+ raise NotARailsProject
47
+ end
48
+ end
49
+
50
+ # Returns an instance of OptionParser with supported flags.
51
+ #
52
+ # @return {OptionParser} Preconfigured OptionParser instance
53
+ def optparser
54
+ OptionParser.new do |opts|
55
+ opts.banner = 'Usage: chusaku [options]'
56
+
57
+ opts.on(
58
+ '--exit-with-error-on-annotation',
59
+ 'Fail if any file was annotated'
60
+ ) do
61
+ @options[:error_on_annotation] = true
62
+ end
63
+
64
+ opts.on(
65
+ '--dry-run',
66
+ 'Run without file modifications'
67
+ ) do
68
+ @options[:dry] = true
69
+ end
70
+
71
+ opts.on(
72
+ '-v',
73
+ '--version',
74
+ 'Show Chusaku version number and quit'
75
+ ) do
76
+ puts(Chusaku::VERSION)
77
+ raise Finished
78
+ end
79
+
80
+ opts.on(
81
+ '-h',
82
+ '--help',
83
+ 'Show this help message and quit'
84
+ ) do
85
+ puts(opts)
86
+ raise Finished
87
+ end
88
+ end
89
+ end
90
+ end
91
+ end
@@ -19,14 +19,15 @@ module Chusaku
19
19
  # body: 'end # vanilla is the best flavor\n',
20
20
  # action: nil } ]
21
21
  #
22
- # @param {String} path
23
- # @param {Array<String>} actions
24
- # @return {Array<Hash>}
22
+ # @param {String} path - File path to parse
23
+ # @param {Array<String>} actions - List of valid actions for this route
24
+ # @return {Hash} Parsed groups of the file and original content
25
25
  def self.call(path:, actions:)
26
26
  groups = []
27
27
  group = {}
28
+ content = IO.read(path)
28
29
 
29
- File.open(path, 'r').each_line do |line|
30
+ content.each_line do |line|
30
31
  parsed_line = parse_line(line: line, actions: actions)
31
32
 
32
33
  if group[:type] != parsed_line[:type]
@@ -42,7 +43,10 @@ module Chusaku
42
43
 
43
44
  # Push the last group onto the array and return.
44
45
  groups.push(group)
45
- groups
46
+ {
47
+ content: content,
48
+ groups: groups
49
+ }
46
50
  end
47
51
 
48
52
  # Given a line and actions, returns the line's type:
@@ -56,9 +60,9 @@ module Chusaku
56
60
  #
57
61
  # { type: :action, body: 'def foo', action: 'foo' }
58
62
  #
59
- # @param {String} line
60
- # @param {Array<String>} actions
61
- # @return {Hash}
63
+ # @param {String} line - A line of a file
64
+ # @param {Array<String>} actions - List of valid actions for this route
65
+ # @return {Hash} Parsed line
62
66
  def self.parse_line(line:, actions:)
63
67
  comment_match = /^\s*#.*$/.match(line)
64
68
  def_match = /^\s*def\s+(\w*)\s*\w*.*$/.match(line)
@@ -9,11 +9,10 @@ module Chusaku
9
9
  # {
10
10
  # 'users' => {
11
11
  # 'edit' => [
12
- # { verb: ['GET'], path: '/users/:id', name: ['edit_user'] }],
12
+ # { verb: 'GET', path: '/users/:id', name: 'edit_user' }],
13
13
  # 'update' => [
14
- # { verb: ['PUT', 'PATCH'],
15
- # path: '/users',
16
- # name: ['edit_user', 'edit_user2'] }]
14
+ # { verb: 'PATCH', path: '/users', name: 'edit_user' },
15
+ # { verb: 'PUT', path: '/users', name: 'edit_user' }]
17
16
  # },
18
17
  # 'empanadas' => {
19
18
  # 'create' => [
@@ -61,7 +60,7 @@ module Chusaku
61
60
  paths = {}
62
61
 
63
62
  routes.each do |_controller, actions|
64
- actions.each do |action, data|
63
+ actions.each do |_action, data|
65
64
  data.each do |datum|
66
65
  paths[datum[:path]] ||= datum[:name]
67
66
  datum[:name] ||= paths[datum[:path]]
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Chusaku
4
- VERSION = '0.1.4'
4
+ VERSION = '0.2.0'
5
5
  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.1.4
4
+ version: 0.2.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: 2019-10-05 00:00:00.000000000 Z
11
+ date: 2019-10-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -86,6 +86,7 @@ files:
86
86
  - bin/setup
87
87
  - chusaku.gemspec
88
88
  - lib/chusaku.rb
89
+ - lib/chusaku/cli.rb
89
90
  - lib/chusaku/parser.rb
90
91
  - lib/chusaku/routes.rb
91
92
  - lib/chusaku/version.rb