erb-linter 0.0.1 → 0.2.0

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: 7852edfabee0e8808f79b8722b4256a3ddb37cd0d4dcd5581ebd4c505eeb7aca
4
- data.tar.gz: 7988dbbceb52230a05fbb67a6ab638b37ea5eb068b1d6963b5fe278e66abdf66
3
+ metadata.gz: 44674209663a884ffa87821eea1396fdcfa779c67b7c1480c625b04111ffc645
4
+ data.tar.gz: f450b5dd3c9321c7f8854dcf68bb6dc38cf348b1cfab3c62b91fb73a6ebf5608
5
5
  SHA512:
6
- metadata.gz: 39f296bfb232df44446f560f44e27ff8c67a4f9302fd64eb3f73005a35bf60de786c55d59a520e84fa08ac5c241ea5534b26d16ddcfba5d00847e34542651b70
7
- data.tar.gz: f02389ff2ab6cfd34ff41596c26f93be8e8d2bec559a50c0978282e2de47997fae104ec59b498128ae27423531325d5e2750ccf0ae8ce92b01573dbd06b1e628
6
+ metadata.gz: 8a37692b76c98aa006fab462b58936a6b00cf4902a3badaf328406622267414abdd32a88c871bf742f10ce6a93793cf39b2239a9bfb55745a2c11a06edbcfc36
7
+ data.tar.gz: e14e4343a76cf0964e95ad73406a4e271be504ff1319096445778de58ddc2fa777e3638856650135ec6332f5b022d25382621f01d091009b6f7279fe4b0c0c4a
@@ -0,0 +1,26 @@
1
+ on:
2
+ - push
3
+ - pull_request
4
+
5
+ name: test
6
+
7
+ jobs:
8
+ test:
9
+ name: "ruby ${{ matrix.ruby }}"
10
+
11
+ strategy:
12
+ matrix:
13
+ os: [ 'ubuntu-latest' ]
14
+ ruby: [ "3.0", "2.7", "2.6", "2.5" ]
15
+
16
+ runs-on: ${{ matrix.os }}
17
+
18
+ steps:
19
+ - uses: actions/checkout@v2
20
+ - uses: ruby/setup-ruby@v1
21
+ with:
22
+ ruby-version: ${{ matrix.ruby }}
23
+ - name: Setup project
24
+ run: bin/setup
25
+ - name: Run test
26
+ run: bin/rake
data/.gitignore CHANGED
@@ -6,3 +6,4 @@
6
6
  /pkg/
7
7
  /spec/reports/
8
8
  /tmp/
9
+ Gemfile.lock
data/README.md CHANGED
@@ -2,7 +2,9 @@
2
2
 
3
3
  <a href="https://nebulab.it?utm_source=github&utm_medium=badge"><img src="https://img.shields.io/static/v1?label=Nebulab&message=Open+Source&color=%235dbefd&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAAcCAYAAAByDd+UAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAMQSURBVHgBrZZNTxNRFIbfczsgIMQiLBCRFDaGhUr9A9iiIa5EEneIwE/AlRsNv8KlIKwFl35RTUBX8rFBdiVKAgqmXSCY0M71nJl+zJTOdKh9k6Yzc8/cZ86555x7CQE0mji5hSyGlQoNaOgIPwrnhtIArWszu4EQFudjdR8rzUV+gw8/ZMZB9IwvIwimJJGafhmjWZwFOJ7QkYzWCwTdj+qUDJGKz8Rou3RAlT4YS+hHWW2u/QdM1MNzrI6+zwyXDrg8FANStIDaSXOIJ5whLgAljOIZiglRK6U4vDfz4S2ElGGJWsEaQkCTUbhtNbV+lb+xgFY2Bs9ET0h/GzBxlfAkqnCUKY5xKfVLbsi1/R126lcF6WgCYp2ES42EBp6tvQFY+alLTUlrUxizJEVNWiVwBkVagGg7oe+CDclLYOfrgMdfTBz8PfWa1lkzbsDEsH/5FyF9YUK0zQ1xwpoZtsm9pwxMRLyA9wyi0A2Jcjl1NNqeeEFEimxYPkmWd014ikIDnDTeBb53DOweaRxnvWGyhnmYfPZWGt487sNi6lsK67/lZ1oZGOtUaD3nhtU7etXXfe0VzrzCBgLKCR68rNDX6oaJlvd0xXnklbSfgSTL/QghXF8EP980cVKyVL/Ys9UDVFJa8Tdt+1lYmcmJM3Vd4UEvWeslRf32h9ubrVRl77gBrCto85OfUU+LXTMGx+JuN2Hoin3/Zkfjj6ObBAknV+KG4jpc9BqXMEpiCMz6Z9ZQ12kvJZxb6co4Zr1W83esY8F2OYsIe+eEyfTiVXczCl7uM2wliHfMEJaRc3Wa++mLUotrF4EW7h6f94Dvh6aVFM60Fy8Xkya+BfBOjh5yUWhqY0vmKi9q1GnVxZ7sHKIWSs7FQ71yUagkRTTCfymnVY1gsgHHC5z8hbUjaz0Fr8ZanXhX0pPOw5SrV8wNGjNscMrTKpXKaj05f9twVYHnMZGPHEuwTwEBNi+3NGiNt6GRcsfEIAfhp2cAV3cQLtXoOz7q8+ZJRLx3kmxn4dy7aas1SrfiBpKraV/9A+PSJLDAXLUvAAAAAElFTkSuQmCC"></a>
4
4
 
5
- It's all to easy to introduce errors inside ERB files, unclosed tags, wrong attribute names, bad indentation.
5
+ [![test](https://github.com/nebulab/erb-linter/actions/workflows/test.yml/badge.svg)](https://github.com/nebulab/erb-linter/actions/workflows/test.yml)
6
+
7
+ It's all too easy to introduce errors inside ERB files, unclosed tags, wrong attribute names, bad indentation.
6
8
 
7
9
  ERB::Linter can check for those errors by turning your ERB tags into HTML-ish tags and run a proper HTML linter on the result:
8
10
 
@@ -45,13 +47,9 @@ Add this line to your application's Gemfile:
45
47
  gem 'erb-linter'
46
48
  ```
47
49
 
48
- And then execute:
49
-
50
- $ bundle install
50
+ And add `linthtml` to yarn:
51
51
 
52
- Or install it yourself as:
53
-
54
- $ gem install erb-linter
52
+ $ yarn add --dev @linthtml/linthtml
55
53
 
56
54
  ## Usage
57
55
 
@@ -81,7 +79,9 @@ ERB::Linter::Task.new do |task|
81
79
  end
82
80
  ```
83
81
 
84
- Add a `linthtml` configuration:
82
+ ### Example linthtml configuration
83
+
84
+ And then add a `linthtml` configuration like this:
85
85
 
86
86
  `.linthtmlrc.js`
87
87
 
data/bin/rake ADDED
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ #
5
+ # This file was generated by Bundler.
6
+ #
7
+ # The application 'rake' is installed as part of a gem, and
8
+ # this file is here to facilitate running it.
9
+ #
10
+
11
+ require "pathname"
12
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13
+ Pathname.new(__FILE__).realpath)
14
+
15
+ bundle_binstub = File.expand_path("../bundle", __FILE__)
16
+
17
+ if File.file?(bundle_binstub)
18
+ if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19
+ load(bundle_binstub)
20
+ else
21
+ abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22
+ Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23
+ end
24
+ end
25
+
26
+ require "rubygems"
27
+ require "bundler/setup"
28
+
29
+ load Gem.bin_path("rake", "rake")
data/lib/erb/linter.rb CHANGED
@@ -3,7 +3,7 @@
3
3
  require "erb"
4
4
 
5
5
  module ERB::Linter
6
- VERSION = "0.0.1"
6
+ VERSION = "0.2.0"
7
7
 
8
8
  class Error < StandardError; end
9
9
 
@@ -2,43 +2,82 @@
2
2
 
3
3
  require "cgi"
4
4
  require "ripper"
5
+ require 'securerandom'
6
+ require 'strscan'
5
7
 
6
8
  module ERB::Linter::Converter
7
9
  extend self
8
10
 
9
- # Credit to the Deface gem
11
+ # https://stackoverflow.com/a/317081
12
+ ATTR_NAME = %r{[^\r\n\t\f\v= '"<>]*[^\r\n\t\f\v= '"<>/]} # not ending with a slash
13
+ UNQUOTED_VALUE = ATTR_NAME
14
+ UNQUOTED_ATTR = %r{#{ATTR_NAME}=#{UNQUOTED_VALUE}}
15
+ SINGLE_QUOTE_ATTR = %r{(?:#{ATTR_NAME}='[^']*')}
16
+ DOUBLE_QUOTE_ATTR = %r{(?:#{ATTR_NAME}="[^"]*")}
17
+
18
+ ERB_TAG = %r{<%.*?%>}
19
+ HTML_ATTR = %r{\s+#{SINGLE_QUOTE_ATTR}|\s+#{DOUBLE_QUOTE_ATTR}|\s+#{UNQUOTED_ATTR}|\s+#{ATTR_NAME}}
20
+ HTML_TAG = %r{(<\w+)((?:#{HTML_ATTR})*)(\s*)(/>|>)}m
21
+
22
+ # (credit goes to the Deface gem for the original implementation)
10
23
  def erb2html(source)
11
24
  source = +source
12
25
 
13
- # all opening html tags that contain <% %> blocks
14
- source.scan(/<\w+[^<>]+(?:<%.*?%>[^<>]*)+/m).each do |line|
15
- # regexs to catch <% %> inside attributes id="<% something %>" - with double, single or no quotes
16
- erb_attrs_regexs = [
17
- /([\w-]+)(\s?=\s?)(")([^"]*<%.*?%>[^"]*)/m,
18
- /([\w-]+)(\s?=\s?)(')([^']*<%.*?%>[^']*)'/m,
19
- /([\w-]+)(\s?=\s?)()(<%.*?%>)(?:\s|>|\z)/m,
20
- ]
21
-
22
- # rubocop:disable Linter/ShadowingOuterLocalVariable
23
- replace_line = erb_attrs_regexs.inject(line.clone) do |replace_line, regex|
24
- replace_line = line.scan(regex).inject(replace_line) do |replace_line, match|
25
- replace_line.sub("#{match[0]}#{match[1]}#{match[2]}#{match[3]}#{match[2]}") { "data-erb-#{match[0]}=\"#{CGI.escapeHTML(match[3])}\"" }
26
- end
26
+ # encode all erb tags so that the HTML looks valid
27
+ erb_tags = {}
28
+ source.gsub!(ERB_TAG) do |tag|
29
+ uid = ["ERB_", SecureRandom.uuid].join.delete('-')
30
+ erb_tags[uid] = tag
31
+ uid
32
+ end
27
33
 
28
- replace_line
29
- end
30
- # rubocop:enable Linter/ShadowingOuterLocalVariable
34
+ erb_tags_matcher = Regexp.union(erb_tags.keys)
35
+
36
+ # transform/escape all the erb-attributes first
37
+ source.gsub!(HTML_TAG).each do |match|
38
+ line = Regexp.last_match.to_a[1..-1]
39
+ tag = [line[0], line[2]+line[3]]
40
+
41
+ # scan each attribute into an array
42
+ attr_scanner = StringScanner.new(line[1])
43
+ attributes = []
44
+ attributes << (attr_scanner.scan(HTML_ATTR) or raise "Can't scan: #{attr_scanner.string}") until attr_scanner.eos?
45
+ # attributes.compact!
31
46
 
32
47
  i = -1
48
+ attributes.map! do |attribute|
49
+ if attribute.match?(erb_tags_matcher)
50
+ space, attribute = attribute.scan(/\A(\s+)(.*)\z/m).flatten
51
+ attribute.gsub!(erb_tags_matcher, erb_tags)
52
+
53
+ attribute =
54
+ case attribute
55
+ when /\A#{ERB_TAG}\z/
56
+ %{data-erb-#{i += 1}="#{CGI.escapeHTML(attribute)}"}
57
+ when /\A#{ATTR_NAME}=/
58
+ name, value = attribute.split("=", 2)
59
+ quote = '"'
60
+ if value.match(/\A['"]/)
61
+ quote = value[0]
62
+ value = value[1...-1]
63
+ end
64
+ %{data-erb-#{name}=#{quote}#{CGI.escapeHTML(value)}#{quote}}
65
+ else
66
+ raise "Don't know how to process attribute: #{attribute.inspect}"
67
+ end
33
68
 
34
- # catch all <% %> inside tags id <p <%= test %>> , not inside attrs
35
- replace_line.scan(/(<%.*?%>)/m).each do |match|
36
- replace_line.sub!(match[0], " data-erb-#{i += 1}=\"#{CGI.escapeHTML(match[0])}\"")
69
+ "#{space}#{attribute}"
70
+ else
71
+ attribute
72
+ end
37
73
  end
38
74
 
39
- source.sub!(line, replace_line)
75
+ [tag[0], *attributes, tag[1]].join
40
76
  end
41
77
 
78
+ # restore the encoded erb tags
79
+ source.gsub!(erb_tags_matcher, erb_tags)
80
+
42
81
  # replaces all <% %> not inside opening html tags
43
82
  replacements = [
44
83
  { %r{<%\s*end\s*-?%>} => "</erb>" },
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: erb-linter
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Elia Schito
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-03-31 00:00:00.000000000 Z
11
+ date: 2021-04-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -31,13 +31,14 @@ executables: []
31
31
  extensions: []
32
32
  extra_rdoc_files: []
33
33
  files:
34
+ - ".github/workflows/test.yml"
34
35
  - ".gitignore"
35
36
  - Gemfile
36
- - Gemfile.lock
37
37
  - LICENSE.txt
38
38
  - README.md
39
39
  - Rakefile
40
40
  - bin/console
41
+ - bin/rake
41
42
  - bin/setup
42
43
  - erb-linter.gemspec
43
44
  - lib/erb/linter.rb
data/Gemfile.lock DELETED
@@ -1,22 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- erb-linter (0.0.1)
5
- rake
6
-
7
- GEM
8
- remote: https://rubygems.org/
9
- specs:
10
- minitest (5.14.4)
11
- rake (13.0.3)
12
-
13
- PLATFORMS
14
- x86_64-darwin-20
15
-
16
- DEPENDENCIES
17
- erb-linter!
18
- minitest (~> 5.0)
19
- rake (~> 13.0)
20
-
21
- BUNDLED WITH
22
- 2.2.3