loose_erbs 0.0.1 → 0.0.2

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: a199c48574375f7ba4180d6b80b2f5bac67ed8a9a7c77f12c57d5a2fb7f1d53a
4
- data.tar.gz: cd693a62b42d1f2eec23ce25bec589b03586da8ae646d9d0a5a478a02e540e36
3
+ metadata.gz: ea8ec541c2125968aefd0a01e59febda8749e70a9a14b0ad4357167bd244fa02
4
+ data.tar.gz: 2c61f02374508721143bd510f840d2a87f3a928ec5b83df04e5eec54a005e228
5
5
  SHA512:
6
- metadata.gz: 5678e042d65edac1b9868f7d2438860973f3830d6766f943e81e234af9dfcaf1065f9f0034be43221de7e72a3dc9037130cdac84a5c43406da91334cad52d71e
7
- data.tar.gz: b96dda47a01a131505b6585fbc87f43cab4e93df845d096ee61983577f17b71919717ea3f3a0713f76bc994165bd9624c38797e1389f56d778d34e9a90092509
6
+ metadata.gz: 7a77cde39405160382448bc969e1ad9e8f9f1cbfd9e77d572f0e3f982d14ac3d860d6bd6f4b326b6ae1074ba9d09a91b053f632d2208c2f8109b08ef7e98958e
7
+ data.tar.gz: 9987b543cfcf9ea1c22e72ae59731753965da6213994762d4e8c311c139a3ce02d5fd4281c8de55e31e7df7062992e8e108d9cce45d8d938015605f71c0ba673
data/.rubocop.yml ADDED
@@ -0,0 +1,6 @@
1
+ inherit_gem:
2
+ rubocop-rails_config:
3
+ - config/rails.yml
4
+
5
+ Rails/RefuteMethods:
6
+ Enabled: false
data/README.md CHANGED
@@ -1,35 +1,55 @@
1
- # LooseErbs
1
+ # Loose ERBs
2
2
 
3
- TODO: Delete this and the text below, and describe your gem
4
-
5
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/loose_erbs`. To experiment with that code, run `bin/console` for an interactive prompt.
3
+ A tool to help find Loose ERBs in your app!
6
4
 
7
5
  ## Installation
8
6
 
9
- TODO: Replace `UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG` with your gem name right after releasing it to RubyGems.org. Please do not do it earlier due to security reasons. Alternatively, replace this section with instructions to install your gem from git if you don't plan to release to RubyGems.org.
10
-
11
7
  Install the gem and add to the application's Gemfile by executing:
12
8
 
13
- $ bundle add UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG
9
+ $ bundle add loose_erbs
14
10
 
15
11
  If bundler is not being used to manage dependencies, install the gem by executing:
16
12
 
17
- $ gem install UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG
13
+ $ gem install loose_erbs
18
14
 
19
15
  ## Usage
20
16
 
21
- TODO: Write usage instructions here
17
+ ```shell
18
+ $ loose_erbs --all
19
+ /home/hartley/test/dm/app/views/layouts/application.html.erb
20
+
21
+ /home/hartley/test/dm/app/views/posts/edit.html.erb
22
+ └── /home/hartley/test/dm/app/views/posts/_form.html.erb
23
+
24
+ /home/hartley/test/dm/app/views/posts/index.html.erb
25
+ └── /home/hartley/test/dm/app/views/posts/_post.html.erb
26
+
27
+ /home/hartley/test/dm/app/views/posts/new.html.erb
28
+ └── /home/hartley/test/dm/app/views/posts/_form.html.erb
29
+
30
+ /home/hartley/test/dm/app/views/posts/show.html.erb
31
+ └── /home/hartley/test/dm/app/views/posts/_post.html.erb
32
+ ```
22
33
 
23
34
  ## Development
24
35
 
25
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
36
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run
37
+ `rake test` to run the tests. You can also run `bin/console` for an interactive
38
+ prompt that will allow you to experiment.
26
39
 
27
- To install this gem onto your local machine, run `bundle exec rake install`. 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, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
40
+ To install this gem onto your local machine, run `bundle exec rake install`. To
41
+ release a new version, update the version number in `version.rb`, and then run
42
+ `bundle exec rake release`, which will create a git tag for the version, push
43
+ git commits and the created tag, and push the `.gem` file to
44
+ [rubygems.org](https://rubygems.org).
28
45
 
29
46
  ## Contributing
30
47
 
31
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/loose_erbs.
48
+ Bug reports and pull requests are welcome on GitHub at
49
+ https://github.com/skipkayhil/loose_erbs.
32
50
 
33
51
  ## License
34
52
 
35
- The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
53
+ The gem is available as open source under the terms of the [MIT License][].
54
+
55
+ [MIT License]: https://opensource.org/licenses/MIT
data/Rakefile CHANGED
@@ -2,7 +2,9 @@
2
2
 
3
3
  require "bundler/gem_tasks"
4
4
  require "minitest/test_task"
5
+ require "rubocop/rake_task"
5
6
 
6
7
  Minitest::TestTask.create
8
+ RuboCop::RakeTask.new
7
9
 
8
- task default: :test
10
+ task default: [:test, :rubocop]
data/exe/loose_erbs CHANGED
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
4
  require "loose_erbs"
4
5
 
5
- LooseErbs::Cli.new.run
6
+ LooseErbs::Cli.new(ARGV).run
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LooseErbs
4
+ class Registry
5
+ def initialize(view_paths)
6
+ @map = {}
7
+ @view_paths = view_paths
8
+
9
+ @view_paths.each do |view_path|
10
+ Dir["#{view_path}/**/*.erb"].each { register _1 }
11
+ end
12
+ end
13
+
14
+ def dependencies_for(identifier)
15
+ template = @map.fetch(identifier)
16
+
17
+ LooseErbs.parser_class.call(identifier, template, @view_paths).uniq.map { lookup(_1) }
18
+ end
19
+
20
+ # this feels like a hack around not using view paths...
21
+ def lookup(pathish)
22
+ wrapper = Pathname.new(pathish)
23
+
24
+ if wrapper.absolute?
25
+ # /home/hartley/test/dm/app/views/posts/form
26
+ partial_path = wrapper.join("../_#{wrapper.basename}.html.erb").to_s
27
+
28
+ return partial_path if @map.key? partial_path
29
+
30
+ # The DependencyTracker always puts the partial under the parent's
31
+ # namespace even if it could be found under a controller's super's
32
+ # namespace.
33
+ @view_paths.each do |view_path|
34
+ partial_path = Pathname.new(view_path).join("application/_#{wrapper.basename}.html.erb").to_s
35
+
36
+ return partial_path if @map.key? partial_path
37
+ end
38
+ else
39
+ # posts/post
40
+ @view_paths.each do |view_path|
41
+ partial_path = Pathname.new(view_path).join(pathish).join("../_#{wrapper.basename}.html.erb").to_s
42
+
43
+ return partial_path if @map.key? partial_path
44
+ end
45
+ end
46
+
47
+ warn("Couldn't resolve pathish: #{pathish}")
48
+
49
+ "UNKNOWN TEMPLATE: #{pathish}"
50
+ end
51
+
52
+ def register(path)
53
+ @map[path] = ActionView::Template.new(
54
+ File.read(path),
55
+ path,
56
+ ActionView::Template::Handlers::ERB,
57
+ locals: nil,
58
+ format: :html,
59
+ )
60
+ end
61
+
62
+ def to_graph
63
+ Graph.new(@map.keys, self)
64
+ end
65
+ end
66
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module LooseErbs
4
- VERSION = "0.0.1"
4
+ VERSION = "0.0.2"
5
5
  end
data/lib/loose_erbs.rb CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  require "action_view"
4
4
  require "action_view/dependency_tracker"
5
+ require "optparse"
5
6
 
6
7
  require_relative "loose_erbs/version"
7
8
 
@@ -14,70 +15,129 @@ module LooseErbs
14
15
  ActionView::DependencyTracker::RipperTracker
15
16
  end
16
17
 
17
- class Template
18
- class << self
19
- def from(path)
20
- new(path, File.read(path))
21
- end
22
- end
18
+ NoParentFilter = ->(node) { node.parents.empty? }
19
+ PartialFilter = ->(node) { Pathname.new(node.identifier).basename.to_s.start_with?("_") }
23
20
 
24
- attr_reader :path, :source
21
+ RegexpIncludeFactory = ->(regexp) {
22
+ ->(node) { node.identifier.match?(regexp) }
23
+ }
24
+ RegexpExcludeFactory = ->(regexp) {
25
+ ->(node) { !node.identifier.match?(regexp) }
26
+ }
25
27
 
26
- def initialize(path, source)
27
- @path = path
28
- @source = source
29
- end
28
+ class Cli
29
+ def initialize(argv)
30
+ @options = {}
30
31
 
31
- def dependencies
32
- LooseErbs.parser_class.call(path, self)
32
+ option_parser.parse!(into: @options)
33
33
  end
34
34
 
35
- def handler
36
- ActionView::Template::Handlers::ERB
37
- end
35
+ def run
36
+ require File.expand_path("./config/environment")
38
37
 
39
- def type
40
- ["text/html"]
38
+ Registry.new(ActionController::Base.view_paths).to_graph.print(filters)
41
39
  end
42
40
 
43
- def inspect
44
- path
45
- end
41
+ private
42
+ attr_reader :options
43
+
44
+ def filters
45
+ [
46
+ NoParentFilter,
47
+ (RegexpIncludeFactory.call(options[:include]) if options[:include]),
48
+ (RegexpExcludeFactory.call(options[:exclude]) if options[:exclude]),
49
+ (PartialFilter unless options[:all]),
50
+ ].compact
51
+ end
52
+
53
+ def option_parser
54
+ OptionParser.new do |parser|
55
+ parser.on("--all", "Print all files with no parents (defaults to only partials)")
56
+ parser.on("--include [REGEXP]", Regexp, "Only print files that match [REGEXP]")
57
+ parser.on("--exclude [REGEXP]", Regexp, "Do not print files that match [REGEXP]")
58
+ end
59
+ end
46
60
  end
47
61
 
48
- class Registry
49
- def initialize
50
- @map = {}
51
- end
62
+ class Graph
63
+ class Printer
64
+ def initialize(root)
65
+ @node_stack = [[root, -1]]
66
+ @seen_nodes = Set.new
67
+ end
52
68
 
53
- def print
54
- @map.values.each do |template|
55
- puts template.inspect
69
+ def print
70
+ while !@node_stack.empty?
71
+ node, depth = @node_stack.pop
56
72
 
57
- template.dependencies.each do |dependency|
58
- puts "└── #{dependency}"
73
+ puts "#{(" " * depth) + "└── " if depth >= 0}#{node.identifier}"
74
+
75
+ if @seen_nodes.include?(node) && !node.children.empty?
76
+ puts (" " * (depth + 1)) + "└── ..."
77
+ else
78
+ @seen_nodes << node
79
+
80
+ node.children.each do |child|
81
+ @node_stack << [child, depth + 1]
82
+ end
83
+ end
59
84
  end
85
+ puts
86
+ end
87
+ end
88
+
89
+ class Node
90
+ attr_reader :children, :identifier, :parents
91
+
92
+ def initialize(identifier)
93
+ @identifier = identifier
94
+ @children = []
95
+ @parents = []
60
96
  end
61
97
  end
62
98
 
63
- def register(path)
64
- @map[path] = Template.from(path)
99
+ def initialize(keys, registry)
100
+ @node_map = keys.to_h { [_1, Node.new(_1)] }
101
+ @registry = registry
102
+
103
+ nodes.each { process(_1) }
65
104
  end
66
- end
67
105
 
68
- class Cli
69
- def run
70
- registry = Registry.new
106
+ def print(filters)
107
+ nodes_to_print = nodes
71
108
 
72
- views.each { registry.register(_1) }
109
+ filters.each do |filter|
110
+ nodes_to_print.filter!(&filter)
111
+ end
73
112
 
74
- registry.print
113
+ nodes_to_print.each { Printer.new(_1).print }
75
114
  end
76
115
 
77
116
  private
117
+ attr_reader :registry
78
118
 
79
- def views
80
- Dir["#{Dir.pwd}/app/views/**/*.html.erb"]
81
- end
119
+ def nodes
120
+ @node_map.values
121
+ end
122
+
123
+ def process(node)
124
+ assign_children!(node)
125
+ assign_parents!(node)
126
+ end
127
+
128
+ def assign_children!(node)
129
+ registry.dependencies_for(node.identifier).each do |identifier|
130
+ # warn("No template registered for path: #{template.identifier}")
131
+ node.children << @node_map.fetch(identifier) { Node.new(identifier) }
132
+ end
133
+ end
134
+
135
+ def assign_parents!(node)
136
+ node.children.each do |child_node|
137
+ child_node.parents << node
138
+ end
139
+ end
82
140
  end
83
141
  end
142
+
143
+ require_relative "loose_erbs/registry"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: loose_erbs
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hartley McGuire
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-01-31 00:00:00.000000000 Z
11
+ date: 2024-02-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: actionview
@@ -32,11 +32,13 @@ executables:
32
32
  extensions: []
33
33
  extra_rdoc_files: []
34
34
  files:
35
+ - ".rubocop.yml"
35
36
  - LICENSE.txt
36
37
  - README.md
37
38
  - Rakefile
38
39
  - exe/loose_erbs
39
40
  - lib/loose_erbs.rb
41
+ - lib/loose_erbs/registry.rb
40
42
  - lib/loose_erbs/version.rb
41
43
  homepage: https://github.com/skipkayhil/loose_erbs
42
44
  licenses: