render_me_pretty 0.1.0

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
+ SHA256:
3
+ metadata.gz: bdea15bc599691050a16495af35770790dd186481e8156f500cef67569bd11a3
4
+ data.tar.gz: e2019115f4e08b8de0779017621ebe3f7175866091a04a35575d3a51e88f1c32
5
+ SHA512:
6
+ metadata.gz: 655f3e4be15080b24946f7e373e653ac56adc2abd2423f087e3dbb7a876f7dbc8103c29d4143b1c1617ffc7166ee92ee13dc07443482ce6ab65014f1fc1b44c5
7
+ data.tar.gz: 486e06149bb49c56ac8381bc55543eb42297d13c521bf1e7e1f32650f135093705f208be715e14f592b81da5395f8c1435a213fe3070016a843b2f0da037541f
data/.gitignore ADDED
@@ -0,0 +1,8 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --require spec_helper
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "https://rubygems.org"
2
+
3
+ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ # Specify your gem's dependencies in render_me_pretty.gemspec
6
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,50 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ render_me_pretty (0.1.0)
5
+ activesupport
6
+ colorize
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ activesupport (5.1.4)
12
+ concurrent-ruby (~> 1.0, >= 1.0.2)
13
+ i18n (~> 0.7)
14
+ minitest (~> 5.1)
15
+ tzinfo (~> 1.1)
16
+ colorize (0.8.1)
17
+ concurrent-ruby (1.0.5)
18
+ diff-lcs (1.3)
19
+ i18n (0.9.4)
20
+ concurrent-ruby (~> 1.0)
21
+ minitest (5.11.3)
22
+ rake (12.3.0)
23
+ rspec (3.7.0)
24
+ rspec-core (~> 3.7.0)
25
+ rspec-expectations (~> 3.7.0)
26
+ rspec-mocks (~> 3.7.0)
27
+ rspec-core (3.7.1)
28
+ rspec-support (~> 3.7.0)
29
+ rspec-expectations (3.7.0)
30
+ diff-lcs (>= 1.2.0, < 2.0)
31
+ rspec-support (~> 3.7.0)
32
+ rspec-mocks (3.7.0)
33
+ diff-lcs (>= 1.2.0, < 2.0)
34
+ rspec-support (~> 3.7.0)
35
+ rspec-support (3.7.1)
36
+ thread_safe (0.3.6)
37
+ tzinfo (1.2.5)
38
+ thread_safe (~> 0.1)
39
+
40
+ PLATFORMS
41
+ ruby
42
+
43
+ DEPENDENCIES
44
+ bundler
45
+ rake
46
+ render_me_pretty!
47
+ rspec
48
+
49
+ BUNDLED WITH
50
+ 1.16.1
data/README.md ADDED
@@ -0,0 +1,64 @@
1
+ # Render Me Pretty
2
+
3
+ Let's say you have an error in your ERB template:
4
+
5
+ ```
6
+ line 1
7
+ <%= sdsd %>
8
+ line 3
9
+ ```
10
+
11
+ Normally, when render it with ERB you get an error message that looks something like this:
12
+
13
+ ```sh
14
+ NameError:
15
+ undefined local variable or method `sdsd' for #<RenderMePretty::Context:0x00007fcda414d358>
16
+ (erb):2:in `get_binding'
17
+ ./lib/render_me_pretty.rb:71:in `render'
18
+ ./spec/lib/render_me_pretty/erb_spec.rb:41:in `block (3 levels) in <top (required)>'
19
+ ```
20
+
21
+ Instead, this library produces an output with an error pointing out the original line in the ERB template like so:
22
+
23
+ ```
24
+ NameError evaluating ERB template on line 2 of: spec/fixtures/invalid.erb
25
+ 1 line 1
26
+ 2 <%= sdsd %>
27
+ 3 line 3
28
+ ```
29
+
30
+ The output also colorizes the error line in red so it stands out.
31
+
32
+
33
+ ## Usage
34
+
35
+ Here's a simple example:
36
+
37
+ ```ruby
38
+ erb = RenderMePretty::Erb.new("/path/to/tempate.erb", a: 3) }
39
+ erb.render(a: 4)
40
+ ```
41
+
42
+ A few more examples are in the [erb_spec.rb](spec/lib/erb_spec.rb)
43
+
44
+ ## Installation
45
+
46
+ Add this line to your application's Gemfile:
47
+
48
+ ```ruby
49
+ gem 'render_me_pretty'
50
+ ```
51
+
52
+ And then execute:
53
+
54
+ $ bundle
55
+
56
+ ## Contributing
57
+
58
+ Please fork the project and open a pull request! I'd love your pull requests. Contributions are encouraged and welcomed!
59
+
60
+ 1. Fork it
61
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
62
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
63
+ 4. Push to the branch (`git push origin my-new-feature`)
64
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "render_me_pretty"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,3 @@
1
+ module RenderMePretty
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,145 @@
1
+ require "render_me_pretty/version"
2
+ require "active_support/core_ext/string"
3
+ require "colorize"
4
+
5
+ =begin
6
+ ## Usage examples:
7
+
8
+ Given an example template /path/to/template.erb that contains:
9
+
10
+ a: <%= @a %>
11
+
12
+ ### Variables at initialization
13
+
14
+ erb = RenderMePretty::Erb.new("/path/to/template.erb", a: 1)
15
+ erb.render
16
+
17
+ Result: a: 1
18
+
19
+ ### Variables at render time
20
+
21
+ erb = RenderMePretty::Erb.new("/path/to/template.erb")
22
+ erb.render(a: 2)
23
+
24
+ Result: a: 2
25
+
26
+ ### Variables at both initialization and render time:
27
+
28
+ erb = RenderMePretty::Erb.new("/path/to/template.erb", a: 3)
29
+ erb.render(a: "override", a: 4)
30
+
31
+ Result: a: 4
32
+
33
+ Variables at render time will override variables at initialization time.
34
+
35
+ ## Context Helpers
36
+
37
+ When no context is provided, a built-in context object is created. You can add helpers to the built-in context object with:
38
+
39
+ RenderMePretty::Context.load_helpers("lib/helpers")
40
+
41
+ This loads modules defined in `lib/helpers` folder and adds their methods of the built-in context object. The helper classes must be defined with the following convetion: FooHelper and foo_helper.rb.
42
+
43
+ Note, helpers will only work with the built-in context scope. If you are passing in your own context object to be used, then you should handle adding helper methods to that context object yourself.
44
+
45
+ ## Custom Context Scope
46
+
47
+ A built-in context object is provided for convenience. If you want to use your own context object, pass it as a variable. The context variable is specially treated as a context object. Example:
48
+
49
+ person = Person.new # must implement get_binding
50
+ erb = RenderMePretty::Erb.new("/path/to/template.erb")
51
+ erb.render(context: person, a: 2)
52
+
53
+ The context will be `person`. So person methods and instance variables will be available in the ERB templates.
54
+
55
+ =end
56
+ module RenderMePretty
57
+ class Erb
58
+ def initialize(path, variables={})
59
+ @path = path
60
+ @variables = variables
61
+ if variables[:context]
62
+ @context = variables.delete(:context)
63
+ else
64
+ @context = Context.new(variables)
65
+ end
66
+ end
67
+
68
+ def render(override_vars={})
69
+ @context.override_variables!(override_vars)
70
+ template = IO.read(@path)
71
+ ERB.new(template, nil, "-").result(@context.get_binding)
72
+ rescue Exception => e
73
+ handle_exception(e)
74
+ end
75
+
76
+ # How to know where ERB stopped? - https://www.ruby-forum.com/topic/182051
77
+ # syntax errors have the (erb):xxx info in e.message
78
+ # undefined variables have (erb):xxx info in e.backtrace
79
+ def handle_exception(e)
80
+ error_info = e.message.split("\n").grep(/\(erb\)/)[0]
81
+ error_info ||= e.backtrace.grep(/\(erb\)/)[0]
82
+ raise unless error_info # unable to find the (erb):xxx: error line
83
+
84
+ line = error_info.split(':')[1].to_i
85
+ io = StringIO.new
86
+ io.puts "#{e.class} evaluating ERB template on line #{line.to_s.colorize(:red)} of: #{@path.sub(/^\.\//, '')}"
87
+
88
+ template = IO.read(@path)
89
+ template_lines = template.split("\n")
90
+ context = 5 # lines of context
91
+ top, bottom = [line-context-1, 0].max, line+context-1
92
+ spacing = template_lines.size.to_s.size
93
+ template_lines[top..bottom].each_with_index do |line_content, index|
94
+ line_number = top+index+1
95
+ if line_number == line
96
+ io.printf("%#{spacing}d %s\n".colorize(:red), line_number, line_content)
97
+ else
98
+ io.printf("%#{spacing}d %s\n", line_number, line_content)
99
+ end
100
+ end
101
+
102
+ # Append the original stack trace also
103
+ io.puts("\nOriginal backtrace (last 5 lines):")
104
+ lines = ENV['FULL_STACK_TRACE'] ? e.backtrace : e.backtrace[0..4]
105
+ io.write(lines.join("\n"))
106
+ io.puts("\nRe-run with FULL_STACK_TRACE=1 to see all lines")
107
+
108
+ if ENV['TEST']
109
+ io.string
110
+ else
111
+ puts io.string
112
+ exit 1
113
+ end
114
+ end
115
+ end
116
+
117
+ # http://stackoverflow.com/questions/1338960/ruby-templates-how-to-pass-variables-into-inlined-erb
118
+ class Context
119
+ def initialize(hash={})
120
+ hash.each do |key, value|
121
+ instance_variable_set('@' + key.to_s, value)
122
+ end
123
+ end
124
+
125
+ def override_variables!(vars)
126
+ vars.each do |key, value|
127
+ instance_variable_set('@' + key.to_s, value)
128
+ end
129
+ end
130
+
131
+ def get_binding
132
+ binding
133
+ end
134
+
135
+ def self.load_helpers(base_folder)
136
+ Dir.glob("#{base_folder}/**/*_helper.rb").each do |path|
137
+ relative_path = path.sub("#{base_folder}/", "")
138
+ class_name = File.basename(relative_path, '.rb').classify
139
+
140
+ require path
141
+ include const_get(class_name)
142
+ end
143
+ end
144
+ end
145
+ end
@@ -0,0 +1,27 @@
1
+ lib = File.expand_path("../lib", __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require "render_me_pretty/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "render_me_pretty"
7
+ spec.version = RenderMePretty::VERSION
8
+ spec.authors = ["Tung Nguyen"]
9
+ spec.email = ["tongueroo@gmail.com"]
10
+
11
+ spec.summary = %q{Render ERB template and provide more useful message pointing out the line with the error in the view}
12
+ spec.homepage = "https://github.com/tongueroo/render_me_pretty"
13
+
14
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
15
+ f.match(%r{^(test|spec|features)/})
16
+ end
17
+ spec.bindir = "exe"
18
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency "activesupport"
22
+ spec.add_dependency "colorize"
23
+
24
+ spec.add_development_dependency "bundler"
25
+ spec.add_development_dependency "rake"
26
+ spec.add_development_dependency "rspec"
27
+ end
data/tilt_examples.rb ADDED
@@ -0,0 +1,18 @@
1
+ require 'tilt/erb'
2
+ template = Tilt::ERBTemplate.new('templates/foo.erb')
3
+ joe = Person.find('joe')
4
+ output = template.render(joe, :x => 35, :y => 42)
5
+ # If no scope is provided, the template is evaluated within the context of an object created with Object.new.
6
+
7
+ # A single Template instance's render method may be called multiple times with different scope and locals arguments. Continuing the previous example, we render the same compiled template but this time in jane's scope:
8
+
9
+ jane = Person.find('jane')
10
+ output = template.render(jane, :x => 22, :y => nil)
11
+ # Blocks can be passed to render for templates that support running arbitrary ruby code (usually with some form of yield). For instance, assuming the following in foo.erb:
12
+
13
+ # Hey <%= yield %>!
14
+ # The block passed to render is called on yield:
15
+
16
+ template = Tilt::ERBTemplate.new('foo.erb')
17
+ template.render { 'Joe' }
18
+ # => "Hey Joe!"
metadata ADDED
@@ -0,0 +1,126 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: render_me_pretty
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Tung Nguyen
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2018-02-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: colorize
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description:
84
+ email:
85
+ - tongueroo@gmail.com
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - ".gitignore"
91
+ - ".rspec"
92
+ - Gemfile
93
+ - Gemfile.lock
94
+ - README.md
95
+ - Rakefile
96
+ - bin/console
97
+ - bin/setup
98
+ - lib/render_me_pretty.rb
99
+ - lib/render_me_pretty/version.rb
100
+ - render_me_pretty.gemspec
101
+ - tilt_examples.rb
102
+ homepage: https://github.com/tongueroo/render_me_pretty
103
+ licenses: []
104
+ metadata: {}
105
+ post_install_message:
106
+ rdoc_options: []
107
+ require_paths:
108
+ - lib
109
+ required_ruby_version: !ruby/object:Gem::Requirement
110
+ requirements:
111
+ - - ">="
112
+ - !ruby/object:Gem::Version
113
+ version: '0'
114
+ required_rubygems_version: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ requirements: []
120
+ rubyforge_project:
121
+ rubygems_version: 2.7.3
122
+ signing_key:
123
+ specification_version: 4
124
+ summary: Render ERB template and provide more useful message pointing out the line
125
+ with the error in the view
126
+ test_files: []