annotate_controllers 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: bbb6d466aa6f6e2d2d126315a62503b618c8005f
4
+ data.tar.gz: cc628056893005ff9c6412a44a7383b2ff9c5b18
5
+ SHA512:
6
+ metadata.gz: 1df0df7202add63a2ba5c45c6d504509347c2d7c987426e5856f13738e2b863b78e258824e2e1693edd82bd64ffd4cd2f66b4c5fd3b2e26f1f71c122bfddd6c3
7
+ data.tar.gz: 3046a18e3042ec2d3067974b240ffdf9db1490c9ca7be1259096e6a2ae3e82d08be92441697039bf0fa807546ef7ec96ccbc8ccc0e5418f7f9dad309edadd3fb
data/.gitignore ADDED
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in annotate_controllers.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2016 Michael Michaelevich
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,80 @@
1
+ # Annotate Controllers
2
+
3
+ Annotate Rails controllers with routes information.
4
+
5
+ class PagesController < ApplicationController
6
+
7
+ # GET / (root_path)
8
+ # GET /pages (pages_path)
9
+ def index
10
+ end
11
+
12
+ # POST /pages (pages_path)
13
+ def create
14
+ end
15
+
16
+ # GET /pages/new (new_page_path)
17
+ def new
18
+ end
19
+
20
+ # GET /pages/:id (page_path)
21
+ def show
22
+ end
23
+
24
+ # GET /pages/:id/edit (edit_page_path)
25
+ def edit
26
+ end
27
+
28
+ # PATCH /pages/:id (page_path)
29
+ # PUT /pages/:id (page_path)
30
+ def update
31
+ end
32
+
33
+ # DELETE /pages/:id (page_path)
34
+ def destroy
35
+ end
36
+
37
+ end
38
+
39
+ **Note: This tool assumes you are using Rails standards for folder structures (e.g. /app/controllers) as well as naming conventions (snake\_case) for your controllers.** For example, if you have a class `HomeController`, your filename should be `home_controller.rb` as opposed to `HomeController.rb`. This isn't Javascript :stuck\_out\_tongue\_winking\_eye:
40
+
41
+ ## Installation
42
+
43
+ Add this line to your application's Gemfile:
44
+
45
+ gem 'annotate_controllers'
46
+
47
+ And then execute:
48
+
49
+ $ bundle
50
+
51
+ Or install it yourself as:
52
+
53
+ $ gem install annotate_controllers
54
+
55
+ ## Usage
56
+
57
+ $ rake annotate_controllers
58
+
59
+ ## WARNING
60
+
61
+ **Be sure to check the changes that this tool makes!** If you are using Git, you may simply check your project's status after annotating:
62
+
63
+ $ git status
64
+
65
+ If you are not using a VCS (like Git, Subversion or similar), then you should consider stopping being a pleb, and just do it.
66
+
67
+ ## Contributing
68
+
69
+ 1. Fork it ( https://github.com/mmichael0413/annotate_controllers/fork )
70
+ 2. Create your feature branch (`git checkout -b my_dope_new_feature`)
71
+ 3. Commit your changes (`git commit -m 'Add some feature'`)
72
+ 4. Push to the branch (`git push origin my_dope_new_feature`)
73
+ 5. Create a new Pull Request
74
+
75
+
76
+ ## TODOs
77
+
78
+ - Handle multi-route annotations (e.g. root & named path)
79
+ - TESTS!
80
+ - Considering modularizing the `annotate!` method a bit more. At 44 lines, it's a bit much.
data/Rakefile.rb ADDED
@@ -0,0 +1 @@
1
+ require 'bundler/gem_tasks'
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'annotate_controllers/version'
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = 'annotate_controllers'
8
+ s.version = AnnotateControllers::VERSION
9
+ s.authors = ['Michael Michaelevich']
10
+ s.description = 'Annotate Rails controllers with routes information.'
11
+ s.email = ['monkeysquirrel7@gmail.com']
12
+ s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
13
+ s.files = `git ls-files -z`.split("\x0")
14
+ s.homepage = 'https://github.com/mmichael0413/annotate_controllers'
15
+ s.license = 'MIT'
16
+ s.require_paths = ['lib']
17
+ s.required_ruby_version = '>= 1.9.3'
18
+ s.summary = 'Annotate Rails controllers'
19
+ s.test_files = s.files.grep(%r{^(test|spec|features)/})
20
+
21
+ s.add_development_dependency 'bundler', '~> 1.12.3'
22
+ s.add_development_dependency 'rake', '~> 11.1.2'
23
+
24
+ s.add_dependency 'rails', '> 4.2'
25
+ end
@@ -0,0 +1,9 @@
1
+ require 'annotate_controllers/version'
2
+
3
+ module AnnotateControllers
4
+ class Railtie < ::Rails::Railtie
5
+ rake_tasks do
6
+ require 'annotate_controllers/tasks'
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,125 @@
1
+ require 'annotate_controllers/errors'
2
+
3
+ module AnnotateControllers
4
+ class Annotator
5
+
6
+ class << self
7
+
8
+ VERBS = ['GET', 'POST', 'PATCH', 'PUT', 'DELETE']
9
+
10
+ def annotate!
11
+ rake_output = []
12
+ mapped_routes = routes
13
+ pattern = /.*\/controllers\/(.*)\_controller\./
14
+ controller_paths = Dir[Rails.root.join('app/controllers/**/*_controller.rb')]
15
+
16
+ controller_paths.each do |path|
17
+ raise ControllerNotFound.new(path) unless File.exists?(path)
18
+
19
+ lines = []
20
+ prefixes = []
21
+ controller_name = pattern.match(path)[-1] # ignore match for entire filename
22
+ original_file_digest = Digest::SHA1.hexdigest(File.read(path))
23
+
24
+ IO.readlines(path).each do |line|
25
+ action_name = /def\W(.*)/.match(line).try(:[], -1)
26
+
27
+ if action_name && matches = select_routes_from_method(mapped_routes, controller_name, action_name)
28
+ matches.each do |match|
29
+ # add matched line to global array in order to reuse prefixes
30
+ prefixes << { action: action_name, prefix: match[:prefix] }
31
+ # replace existing annotation (if exists)
32
+ if overwrite_self?(match[:verb], lines[-1])
33
+ lines[-1] = comment(prefixes, match)
34
+ # otherwise, insert comment
35
+ else
36
+ lines << comment(prefixes, match)
37
+ end
38
+ end
39
+ end
40
+
41
+ lines << line
42
+ end
43
+
44
+ File.open(path, 'w') do |file|
45
+ file.puts lines
46
+ end
47
+
48
+ new_file_digest = Digest::SHA1.hexdigest(File.read(path))
49
+ rake_output << "Annotated #{controller_name}_controller" unless original_file_digest == new_file_digest
50
+ end
51
+
52
+ puts rake_output.any? ? rake_output : 'Nothing annotated'
53
+ end
54
+
55
+ def select_routes_from_method(routes, controller, action)
56
+ results = routes.select{ |r|
57
+ r[:controller] == controller && r[:action] == action
58
+ }
59
+ results.any? ? results : nil
60
+ end
61
+
62
+ def comment(prefixes, match)
63
+ "\t# #{match[:verb]} #{trim(match[:uri])}"\
64
+ "#{prefix_or_shared(prefixes, match[:verb], match[:prefix], match[:action])}\n"
65
+ end
66
+
67
+ def prefix_or_shared(prefixes, verb, prefix, action)
68
+ if prefix.present?
69
+ ' (' + prefix + '_path)'
70
+ else
71
+ shared_prefix(prefixes, verb, action)
72
+ end
73
+ end
74
+
75
+ def shared_prefix(prefixes, verb, action)
76
+ if VERBS.include? verb
77
+ ' (' +
78
+ prefixes.detect{ |l| l[:action] == shared_action_prefix(action) }.try(:[], :prefix) +
79
+ '_path)'
80
+ else
81
+ ''
82
+ end
83
+ end
84
+
85
+ def shared_action_prefix(action)
86
+ case action
87
+ when 'create'
88
+ 'index'
89
+ when 'update'
90
+ 'show'
91
+ when 'destroy'
92
+ 'show'
93
+ end
94
+ end
95
+
96
+ def overwrite_self?(verb, line)
97
+ "# #{verb}" == /(\#\s\w*)/.match(line).try(:[], 0)
98
+ end
99
+
100
+ def routes
101
+ mapped_routes = []
102
+ AnnotateControllers::Inspector.map_all_routes.each do |route|
103
+ r = route.split(' ')
104
+ contraction = r[-1].split('#') # controller, action, controlleraction...
105
+ mapped_routes << {
106
+ prefix: r.size > 3 ? r.try(:[], 0) : nil,
107
+ verb: r.size > 3 ? r[1] : r[0],
108
+ uri: r.size > 3 ? r[2] : r[1],
109
+ controller: contraction.first,
110
+ action: contraction.last
111
+ }
112
+ end
113
+ mapped_routes
114
+ end
115
+
116
+ # Removes (.:format) from URI pattern string
117
+ def trim(string)
118
+ string.slice! '(.:format)'
119
+ string
120
+ end
121
+
122
+ end
123
+
124
+ end
125
+ end
@@ -0,0 +1,3 @@
1
+ module AnnotateControllers
2
+ class ControllerNotFound < StandardError; end
3
+ end
@@ -0,0 +1,23 @@
1
+ require 'action_dispatch/routing/inspector'
2
+
3
+ module AnnotateControllers
4
+ class Inspector
5
+
6
+ class << self
7
+
8
+ def map_all_routes
9
+ all_routes = Rails.application.routes.routes
10
+ inspector = ActionDispatch::Routing::RoutesInspector.new(all_routes)
11
+ remove_constraints(
12
+ inspector.format(ActionDispatch::Routing::ConsoleFormatter.new).split("\n").drop(1)
13
+ )
14
+ end
15
+
16
+ def remove_constraints(routes)
17
+ routes.each{ |r| r.slice!(/ \{(.*)}/) }
18
+ end
19
+
20
+ end
21
+
22
+ end
23
+ end
@@ -0,0 +1 @@
1
+ load 'annotate_controllers/tasks/annotate_controllers.rake'
@@ -0,0 +1,17 @@
1
+ namespace :annotate_controllers do
2
+ task run: [:environment, :setup] do
3
+ begin
4
+ AnnotateControllers::Annotator.annotate!
5
+ rescue => e
6
+ puts e.message
7
+ end
8
+ end
9
+
10
+ task :setup do
11
+ require 'annotate_controllers/annotator'
12
+ require 'annotate_controllers/inspector'
13
+ end
14
+ end
15
+
16
+ desc 'Annotate controllers'
17
+ task annotate_controllers: 'annotate_controllers:run'
@@ -0,0 +1,3 @@
1
+ module AnnotateControllers
2
+ VERSION = '0.0.1'
3
+ end
metadata ADDED
@@ -0,0 +1,99 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: annotate_controllers
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Michael Michaelevich
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-05-25 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 1.12.3
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 1.12.3
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 11.1.2
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 11.1.2
41
+ - !ruby/object:Gem::Dependency
42
+ name: rails
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">"
46
+ - !ruby/object:Gem::Version
47
+ version: '4.2'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">"
53
+ - !ruby/object:Gem::Version
54
+ version: '4.2'
55
+ description: Annotate Rails controllers with routes information.
56
+ email:
57
+ - monkeysquirrel7@gmail.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".gitignore"
63
+ - Gemfile
64
+ - LICENSE.txt
65
+ - README.md
66
+ - Rakefile.rb
67
+ - annotate_controllers.gemspec
68
+ - lib/annotate_controllers.rb
69
+ - lib/annotate_controllers/annotator.rb
70
+ - lib/annotate_controllers/errors.rb
71
+ - lib/annotate_controllers/inspector.rb
72
+ - lib/annotate_controllers/tasks.rb
73
+ - lib/annotate_controllers/tasks/annotate_controllers.rake
74
+ - lib/annotate_controllers/version.rb
75
+ homepage: https://github.com/mmichael0413/annotate_controllers
76
+ licenses:
77
+ - MIT
78
+ metadata: {}
79
+ post_install_message:
80
+ rdoc_options: []
81
+ require_paths:
82
+ - lib
83
+ required_ruby_version: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ version: 1.9.3
88
+ required_rubygems_version: !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: '0'
93
+ requirements: []
94
+ rubyforge_project:
95
+ rubygems_version: 2.5.1
96
+ signing_key:
97
+ specification_version: 4
98
+ summary: Annotate Rails controllers
99
+ test_files: []