herb 0.3.1-arm-linux-gnu → 0.4.2-arm-linux-gnu
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 +4 -4
- data/LICENSE.txt +2 -2
- data/README.md +80 -115
- data/ext/herb/error_helpers.c +1 -1
- data/ext/herb/error_helpers.h +1 -1
- data/ext/herb/nodes.c +2 -2
- data/ext/herb/nodes.h +1 -1
- data/lib/herb/3.0/herb.so +0 -0
- data/lib/herb/3.1/herb.so +0 -0
- data/lib/herb/3.2/herb.so +0 -0
- data/lib/herb/3.3/herb.so +0 -0
- data/lib/herb/3.4/herb.so +0 -0
- data/lib/herb/ast/node.rb +6 -1
- data/lib/herb/ast/nodes.rb +1 -1
- data/lib/herb/cli.rb +18 -2
- data/lib/herb/errors.rb +1 -1
- data/lib/herb/parse_result.rb +7 -2
- data/lib/herb/project.rb +79 -33
- data/lib/herb/version.rb +1 -1
- data/lib/herb/visitor.rb +1 -1
- data/sig/herb/ast/node.rbs +3 -0
- data/sig/herb/parse_result.rbs +3 -0
- data/sig/serialized_ast_errors.rbs +1 -1
- data/sig/serialized_ast_nodes.rbs +1 -1
- data/src/analyze.c +61 -16
- data/src/analyze_helpers.c +15 -6
- data/src/ast_nodes.c +1 -1
- data/src/ast_pretty_print.c +1 -1
- data/src/errors.c +1 -1
- data/src/extract.c +6 -2
- data/src/include/analyze_helpers.h +1 -1
- data/src/include/ast_nodes.h +1 -1
- data/src/include/ast_pretty_print.h +1 -1
- data/src/include/errors.h +1 -1
- data/src/include/parser_helpers.h +7 -2
- data/src/include/pretty_print.h +48 -8
- data/src/include/prism_helpers.h +4 -1
- data/src/include/token_struct.h +2 -1
- data/src/include/version.h +1 -1
- data/src/lexer.c +12 -2
- data/src/parser.c +13 -4
- data/src/parser_helpers.c +10 -3
- data/src/pretty_print.c +50 -10
- data/src/prism_helpers.c +4 -1
- data/src/token.c +1 -0
- data/src/visitor.c +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f27aaaad81ad225f5316278ca8a3c2412d624597d2a28e7eb5cafce3db32316e
|
4
|
+
data.tar.gz: d6c58ecbfed32f6c6afda64e1956d24f8b354bff4647ec6b01c93846742e51c5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 871f6d51b0eb6be8d052b4ede53807e598a4e65a2b1d94139b2e834f731d11b136624dbe1e9351cc357e100afb1b98f4fe447b114b45328a51d6858747b6d2d2
|
7
|
+
data.tar.gz: 8ad246404e5f6e1e3c6926bfba00a7ea99860d82e8824b0290c29123edc71a11ab0a52801f196819b4e714754ec0a985d28f6f1151ae47987a7d19a0380b1b06
|
data/LICENSE.txt
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
The MIT License (MIT)
|
2
2
|
|
3
|
-
Copyright (c) 2024 Marco Roth
|
3
|
+
Copyright (c) 2024-2025 Marco Roth
|
4
4
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
@@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
18
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
19
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
20
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
-
THE SOFTWARE.
|
21
|
+
THE SOFTWARE.
|
data/README.md
CHANGED
@@ -1,170 +1,135 @@
|
|
1
1
|
<div align="center">
|
2
|
-
<img alt="Herb HTML+ERB parser" height="256px" src="https://github.com/user-attachments/assets/d0714ee1-ca33-4aa4-aaa9-d632ba79d54a">
|
2
|
+
<img alt="Herb HTML+ERB parser" style="height: 256px" height="256px" src="https://github.com/user-attachments/assets/d0714ee1-ca33-4aa4-aaa9-d632ba79d54a">
|
3
3
|
</div>
|
4
4
|
|
5
5
|
<h2 align="center">Herb</h2>
|
6
6
|
|
7
7
|
<h4 align="center">HTML+ERB (HTML + Embedded Ruby)</h4>
|
8
8
|
|
9
|
-
<div align="center">Powerful and seamless HTML-aware ERB parsing and tooling.</div
|
9
|
+
<div align="center">Powerful and seamless HTML-aware ERB parsing and tooling.</div><br/>
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
- [**Clang 19**](https://clang.llvm.org): The compiler used to build this project.
|
19
|
-
- [**Clang Format 19**](https://clang.llvm.org/docs/ClangFormat.html): For formatting the project.
|
20
|
-
- [**Clang Tidy 19**](https://clang.llvm.org/extra/clang-tidy/): For linting the project.
|
21
|
-
- [**Prism Ruby Parser v1.4.0**](https://github.com/ruby/prism/releases/tag/v1.4.0): We use Prism for Parsing the Ruby Source Code in the HTML+ERB files.
|
22
|
-
- [**Ruby**](https://www.ruby-lang.org/en/): We need Ruby as a dependency for `bundler`.
|
23
|
-
- [**Bundler**](https://bundler.io): We are using `bundler` to build [`prism`](https://github.com/ruby/prism) from source so we can build `herb` against it.
|
24
|
-
- [**Emscripten**](https://emscripten.org): For the WebAssembly build of `libherb` so it can be used in the browser using the [`@herb-tools/browser`](https://github.com/marcoroth/herb/blob/main/javascript/packages/browser) package.
|
25
|
-
- [**Doxygen**](https://www.doxygen.nl): For building the C-Reference documentation pages.
|
11
|
+
<p align="center">
|
12
|
+
<a href="https://rubygems.org/gems/herb"><img alt="Gem Version" src="https://img.shields.io/gem/v/herb"></a>
|
13
|
+
<a href="https://herb-tools.dev"><img alt="Documentation" src="https://img.shields.io/badge/documentation-available-green"></a>
|
14
|
+
<a href="https://herb-tools.dev/playground"><img alt="playground" src="https://img.shields.io/badge/playground-Try_it_in_the_browser!-green"></a>
|
15
|
+
<a href="https://github.com/marcoroth/herb/blob/main/LICENSE.txt"><img alt="License" src="https://img.shields.io/github/license/marcoroth/herb"></a>
|
16
|
+
<a href="https://github.com/marcoroth/herb/issues"><img alt="Issues" src="https://img.shields.io/github/issues/marcoroth/herb"></a>
|
17
|
+
</p>
|
26
18
|
|
27
|
-
|
19
|
+
<br/><br/><br/>
|
28
20
|
|
29
|
-
|
30
|
-
xargs sudo apt-get install < Aptfile
|
31
|
-
```
|
32
|
-
or:
|
21
|
+
## What is Herb?
|
33
22
|
|
34
|
-
|
35
|
-
sudo apt-get install check clang-19 clang-tidy-19 clang-format-19 emscripten doxygen
|
36
|
-
```
|
23
|
+
**Herb** is an ecosystem of developer tooling built specifically around **HTML+ERB** (`.html.erb`) files. It is designed to simplify and enhance the experience of working with HTML+ERB templates through precise, accurate tooling.
|
37
24
|
|
38
|
-
|
25
|
+
At the core of Herb is the **Herb Parser**, a fast, portable, and HTML-aware ERB parser written in C. The parser generates a detailed, accurate syntax tree that serves as the foundation for reliable code analysis, transformations, and developer tooling.
|
39
26
|
|
40
|
-
|
41
|
-
brew bundle
|
42
|
-
```
|
43
|
-
or:
|
27
|
+
The Herb ecosystem includes **developer tools** (CLI, language server, formatter, linter), **language bindings** (for Ruby, Node.js, and the Browser using WebAssembly), and **utility libraries** (language service, highlighter, minifier, printer). All these components leverage the Herb Parser's syntax tree to provide consistent, accurate, and helpful tooling experiences.
|
44
28
|
|
45
|
-
|
46
|
-
brew install check llvm@19 emscripten doxygen
|
47
|
-
```
|
29
|
+
## What Herb Can Do for You
|
48
30
|
|
49
|
-
|
31
|
+
Herb provides a complete ecosystem of HTML+ERB tooling, designed to simplify and enhance your daily workflow. Built on the **Herb Parser**, it offers multiple tools that integrate seamlessly into editors, developer environments, and CI pipelines:
|
50
32
|
|
51
|
-
|
33
|
+
- **Herb Language Server** ([available now](https://herb-tools.dev/projects/language-server)):
|
34
|
+
Rich integration for editors like VS Code, Zed, Neovim, and more. It provides diagnostics and real-time feedback to keep your templates error-free.
|
52
35
|
|
53
|
-
|
36
|
+
- **Herb Formatter** ([experimental preview](https://herb-tools.dev/projects/formatter)):
|
37
|
+
Automatic, consistent formatting for HTML+ERB files, reducing manual styling and enforcing a standard across projects. Currently in experimental preview - use with caution on version-controlled files.
|
54
38
|
|
55
|
-
|
56
|
-
|
57
|
-
```
|
39
|
+
- **Herb Linter** ([available now](https://herb-tools.dev/projects/linter)):
|
40
|
+
Static analysis for your HTML+ERB templates to enforce best practices and quickly identify common mistakes with 17 configurable rules.
|
58
41
|
|
59
|
-
|
42
|
+
You can use Herb programmatically in **Ruby**, as well as in **JavaScript** via Node.js, WebAssembly, or directly in browsers.
|
60
43
|
|
61
|
-
|
44
|
+
For a complete overview of all available tools, libraries, and integrations, visit the [**Projects page**](https://herb-tools.dev/projects) on our documentation site.
|
62
45
|
|
63
|
-
|
64
|
-
make all
|
65
|
-
```
|
46
|
+
## Motivation
|
66
47
|
|
67
|
-
|
68
|
-
For any consecutive builds you can just run `make`/`make all`.
|
48
|
+
HTML+ERB templates never really had good, accurate, and reliable tooling. While developer tooling for Ruby code improved significantly in the last few years (especially with the introduction of the new Prism parser), HTML+ERB files remained underserved, lacking fundamental support like syntax checking, auto-formatting, linting, and structural understanding.
|
69
49
|
|
70
|
-
|
50
|
+
At the same time, with the rise of tools like [Hotwire](https://hotwired.dev), [Stimulus](https://stimulus.hotwired.dev), [Turbo](https://turbo.hotwired.dev), [HTMX](https://htmx.org), [Unpoly](https://unpoly.com), and [Alpine.js](https://alpinejs.dev), advanced HTML templating became increasingly relevant (again). Developers expect modern, reliable, and precise tooling, especially given the robust ecosystem available to JavaScript frameworks and libraries.
|
71
51
|
|
72
|
-
|
52
|
+
Herb was built to close this tooling gap, providing proper tooling for HTML+ERB that matches what modern developers expect in the age of language servers, LLMs, and AI-driven workflows.
|
73
53
|
|
74
|
-
|
75
|
-
❯ ./herb
|
76
|
-
./herb [command] [options]
|
54
|
+
## Command-Line Usage
|
77
55
|
|
78
|
-
|
56
|
+
Install the Herb gem via RubyGems:
|
79
57
|
|
80
|
-
|
81
|
-
|
82
|
-
./herb parse [file] - Parse a file
|
83
|
-
./herb ruby [file] - Extract Ruby from a file
|
84
|
-
./herb html [file] - Extract HTML from a file
|
85
|
-
./herb prism [file] - Extract Ruby from a file and parse the Ruby source with Prism
|
58
|
+
```sh
|
59
|
+
gem install herb
|
86
60
|
```
|
87
61
|
|
88
|
-
|
62
|
+
Basic usage to analyze all HTML+ERB files in your project:
|
89
63
|
|
64
|
+
```sh
|
65
|
+
herb analyze .
|
90
66
|
```
|
91
|
-
❯ ./herb lex examples/simple_erb.html.erb
|
92
|
-
|
93
|
-
#<Herb::Token type="TOKEN_ERB_START" value="<%" range=[0, 2] start=(1:0) end=(1:2)>
|
94
|
-
#<Herb::Token type="TOKEN_ERB_CONTENT" value=" title " range=[2, 9] start=(1:2) end=(1:9)>
|
95
|
-
#<Herb::Token type="TOKEN_ERB_END" value="%>" range=[9, 11] start=(1:9) end=(1:11)>
|
96
|
-
#<Herb::Token type="TOKEN_NEWLINE" value="\n" range=[11, 12] start=(1:0) end=(2:1)>
|
97
|
-
#<Herb::Token type="TOKEN_EOF" value="" range=[12, 12] start=(2:1) end=(2:1)>
|
98
67
|
|
99
|
-
|
100
|
-
|
101
|
-
12 µs
|
102
|
-
0.012 ms
|
103
|
-
0.000012 s
|
68
|
+
This will give you an overview of how the Herb Parser sees your project:
|
104
69
|
```
|
70
|
+
--- SUMMARY --------------------------------------------------------------------
|
71
|
+
Total files: 145
|
72
|
+
✅ Successful: 143 (98.6%)
|
73
|
+
❌ Failed: 0 (0.0%)
|
74
|
+
⚠️ Parse errors: 2 (1.4%)
|
75
|
+
⏱️ Timed out: 0 (0.0%)
|
105
76
|
|
106
|
-
|
107
|
-
|
108
|
-
|
77
|
+
Files with parse errors:
|
78
|
+
- app/views/contributions/index.html.erb
|
79
|
+
- index.html.erb
|
109
80
|
|
110
|
-
|
111
|
-
rake
|
81
|
+
Results saved to 2025-06-29_12-16-23_erb_parsing_result_rubyevents.log
|
112
82
|
```
|
113
83
|
|
114
|
-
|
84
|
+
Herb also comes with other useful commands:
|
115
85
|
|
116
|
-
```bash
|
117
|
-
bundle console
|
118
|
-
```
|
119
|
-
|
120
|
-
```
|
121
|
-
irb(main):001> Herb.parse("<div></div>")
|
122
|
-
|
123
|
-
# => #<Herb::ParseResult:0x0000000 ... >
|
124
|
-
```
|
125
|
-
|
126
|
-
### Test
|
127
|
-
|
128
|
-
Builds the test suite from files in `test/` and creates the `run_herb_tests` executable to run the tests:
|
129
|
-
|
130
|
-
#### For the C Tests
|
131
|
-
|
132
|
-
```bash
|
133
|
-
make test && ./run_herb_tests
|
134
86
|
```
|
87
|
+
Herb 🌿 Powerful and seamless HTML-aware ERB parsing and tooling.
|
135
88
|
|
136
|
-
|
89
|
+
Usage:
|
90
|
+
bundle exec herb [command] [options]
|
137
91
|
|
138
|
-
|
139
|
-
|
92
|
+
Commands:
|
93
|
+
bundle exec herb lex [file] Lex a file.
|
94
|
+
bundle exec herb parse [file] Parse a file.
|
95
|
+
bundle exec herb analyze [path] Analyze a project by passing a directory to the root of the project
|
96
|
+
bundle exec herb ruby [file] Extract Ruby from a file.
|
97
|
+
bundle exec herb html [file] Extract HTML from a file.
|
98
|
+
bundle exec herb playground [file] Open the content of the source file in the playground
|
99
|
+
bundle exec herb version Prints the versions of the Herb gem and the libherb library.
|
140
100
|
```
|
141
101
|
|
142
|
-
|
102
|
+
For detailed information, like how you can use Herb progamatiacally in Ruby and JavaScript, visit the [documentation site](https://herb-tools.dev/bindings/ruby/reference).
|
143
103
|
|
144
|
-
Removes the `herb`, `run_herb_tests`, `prism` installation, and all `.o` files.
|
145
104
|
|
146
|
-
|
147
|
-
make clean
|
148
|
-
```
|
105
|
+
## Background and Talk
|
149
106
|
|
150
|
-
|
107
|
+
**Herb** was first introduced at [**RubyKaigi 2025**](https://rubykaigi.org/2025/presentations/marcoroth.html) in April 2025 with the talk [*Empowering Developers with HTML-Aware ERB Tooling*](https://www.rubyevents.org/talks/empowering-developers-with-html-aware-erb-tooling-rubykaigi-2025).
|
151
108
|
|
152
|
-
|
109
|
+
## Contributing
|
153
110
|
|
154
|
-
|
155
|
-
bin/integration
|
156
|
-
```
|
111
|
+
Bug reports and pull requests are welcome on [GitHub](https://github.com/marcoroth/herb). Please see the [CONTRIBUTING.md](https://github.com/marcoroth/herb/blob/main/CONTRIBUTING.md) document for guidelines on how to set up Herb for local development and how to contribute to **Herb**.
|
157
112
|
|
158
|
-
|
113
|
+
## Prior Art & Inspiration
|
159
114
|
|
160
|
-
|
161
|
-
❯ bin/integration
|
115
|
+
While Herb brings a fresh approach to HTML+ERB tooling, it builds upon and learns from several existing tools and approaches in the ecosystem:
|
162
116
|
|
163
|
-
[
|
117
|
+
- [**Tree-sitter**](https://tree-sitter.github.io/tree-sitter/)
|
118
|
+
- [**tree-sitter-embedded-template**](https://github.com/tree-sitter/tree-sitter-embedded-template)
|
119
|
+
- [**Prism Ruby Parser**](https://github.com/ruby/prism)
|
120
|
+
- [**Ruby LSP**](https://github.com/Shopify/ruby-lsp)
|
121
|
+
- [**better-html**](https://github.com/Shopify/better-html)
|
122
|
+
- [**erb_lint**](https://github.com/Shopify/erb_lint)
|
123
|
+
- [**erb-formatter**](https://github.com/nebulab/erb-formatter)
|
124
|
+
- [**erb-formatter-vscode**](https://github.com/nebulab/erb-formatter-vscode)
|
125
|
+
- [**deface**](https://github.com/spree/deface)
|
126
|
+
- [**html_press**](https://github.com/stereobooster/html_press)
|
127
|
+
- [**htmlbeautifier**](https://github.com/threedaymonk/htmlbeautifier)
|
128
|
+
- [**vscode-erb-beautify**](https://github.com/aliariff/vscode-erb-beautify)
|
129
|
+
- [**vscode-erb-linter**](https://github.com/manuelpuyol/vscode-erb-linter)
|
164
130
|
|
165
|
-
|
166
|
-
```
|
131
|
+
Herb differentiates itself by being HTML-aware from the ground up, providing a unified parsing approach that understands both HTML and ERB as first-class citizens, rather than treating one as embedded within the other.
|
167
132
|
|
168
133
|
## License
|
169
134
|
|
170
|
-
This project is
|
135
|
+
This project is available as open source under the terms of the [MIT License](https://github.com/marcoroth/herb/blob/main/LICENSE.txt).
|
data/ext/herb/error_helpers.c
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
// NOTE: This file is generated by the templates/template.rb script and should not
|
2
|
-
// be modified manually. See /Users/marcoroth/Development/herb-release/templates/ext/herb/error_helpers.c.erb
|
2
|
+
// be modified manually. See /Users/marcoroth/Development/herb-release-6/templates/ext/herb/error_helpers.c.erb
|
3
3
|
|
4
4
|
#include <ruby.h>
|
5
5
|
|
data/ext/herb/error_helpers.h
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
// NOTE: This file is generated by the templates/template.rb script and should not
|
2
|
-
// be modified manually. See /Users/marcoroth/Development/herb-release/templates/ext/herb/error_helpers.h.erb
|
2
|
+
// be modified manually. See /Users/marcoroth/Development/herb-release-6/templates/ext/herb/error_helpers.h.erb
|
3
3
|
|
4
4
|
#ifndef HERB_EXTENSION_ERROR_HELPERS_H
|
5
5
|
#define HERB_EXTENSION_ERROR_HELPERS_H
|
data/ext/herb/nodes.c
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
// NOTE: This file is generated by the templates/template.rb script and should not
|
2
|
-
// be modified manually. See /Users/marcoroth/Development/herb-release/templates/ext/herb/nodes.c.erb
|
2
|
+
// be modified manually. See /Users/marcoroth/Development/herb-release-6/templates/ext/herb/nodes.c.erb
|
3
3
|
|
4
4
|
#include <ruby.h>
|
5
5
|
|
@@ -415,7 +415,7 @@ static VALUE rb_erb_content_node_from_c_struct(AST_ERB_CONTENT_NODE_T* erb_conte
|
|
415
415
|
VALUE erb_content_node_tag_opening = rb_token_from_c_struct(erb_content_node->tag_opening);
|
416
416
|
VALUE erb_content_node_content = rb_token_from_c_struct(erb_content_node->content);
|
417
417
|
VALUE erb_content_node_tag_closing = rb_token_from_c_struct(erb_content_node->tag_closing);
|
418
|
-
/* #<Herb::Template::AnalyzedRubyField:
|
418
|
+
/* #<Herb::Template::AnalyzedRubyField:0x00007fffe335ba20 @name="analyzed_ruby", @options={kind: nil}> */
|
419
419
|
VALUE erb_content_node_analyzed_ruby = Qnil;
|
420
420
|
VALUE erb_content_node_parsed = (erb_content_node->parsed) ? Qtrue : Qfalse;
|
421
421
|
VALUE erb_content_node_valid = (erb_content_node->valid) ? Qtrue : Qfalse;
|
data/ext/herb/nodes.h
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
// NOTE: This file is generated by the templates/template.rb script and should not
|
2
|
-
// be modified manually. See /Users/marcoroth/Development/herb-release/templates/ext/herb/nodes.h.erb
|
2
|
+
// be modified manually. See /Users/marcoroth/Development/herb-release-6/templates/ext/herb/nodes.h.erb
|
3
3
|
|
4
4
|
#ifndef HERB_EXTENSION_NODES_H
|
5
5
|
#define HERB_EXTENSION_NODES_H
|
data/lib/herb/3.0/herb.so
CHANGED
Binary file
|
data/lib/herb/3.1/herb.so
CHANGED
Binary file
|
data/lib/herb/3.2/herb.so
CHANGED
Binary file
|
data/lib/herb/3.3/herb.so
CHANGED
Binary file
|
data/lib/herb/3.4/herb.so
CHANGED
Binary file
|
data/lib/herb/ast/node.rb
CHANGED
@@ -51,7 +51,7 @@ module Herb
|
|
51
51
|
output = +""
|
52
52
|
|
53
53
|
if array.any?
|
54
|
-
output += "(#{array.count} #{array.
|
54
|
+
output += "(#{array.count} #{array.one? ? item_name : "#{item_name}s"})"
|
55
55
|
output += "\n"
|
56
56
|
|
57
57
|
items = array.map { |item|
|
@@ -92,6 +92,11 @@ module Herb
|
|
92
92
|
def compact_child_nodes
|
93
93
|
child_nodes.compact
|
94
94
|
end
|
95
|
+
|
96
|
+
#: () -> Array[Herb::Errors::Error]
|
97
|
+
def recursive_errors
|
98
|
+
errors + compact_child_nodes.flat_map(&:recursive_errors)
|
99
|
+
end
|
95
100
|
end
|
96
101
|
end
|
97
102
|
end
|
data/lib/herb/ast/nodes.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
# typed: true
|
3
3
|
|
4
4
|
# NOTE: This file is generated by the templates/template.rb script and should not be
|
5
|
-
# modified manually. See /Users/marcoroth/Development/herb-release/templates/lib/herb/ast/nodes.rb.erb
|
5
|
+
# modified manually. See /Users/marcoroth/Development/herb-release-6/templates/lib/herb/ast/nodes.rb.erb
|
6
6
|
|
7
7
|
module Herb
|
8
8
|
module AST
|
data/lib/herb/cli.rb
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
require "optparse"
|
7
7
|
|
8
8
|
class Herb::CLI
|
9
|
-
attr_accessor :json, :silent
|
9
|
+
attr_accessor :json, :silent, :no_interactive, :no_log_file, :no_timing
|
10
10
|
|
11
11
|
def initialize(args)
|
12
12
|
@args = args
|
@@ -106,7 +106,11 @@ class Herb::CLI
|
|
106
106
|
def result
|
107
107
|
@result ||= case @command
|
108
108
|
when "analyze"
|
109
|
-
Herb::Project.new(directory)
|
109
|
+
project = Herb::Project.new(directory)
|
110
|
+
project.no_interactive = no_interactive
|
111
|
+
project.no_log_file = no_log_file
|
112
|
+
project.no_timing = no_timing
|
113
|
+
project.parse!
|
110
114
|
exit(0)
|
111
115
|
when "parse"
|
112
116
|
Herb.parse(file_content)
|
@@ -162,6 +166,18 @@ class Herb::CLI
|
|
162
166
|
parser.on("-s", "--silent", "Log no result to stdout") do
|
163
167
|
self.silent = true
|
164
168
|
end
|
169
|
+
|
170
|
+
parser.on("-n", "--non-interactive", "Disable interactive output (progress bars, terminal clearing)") do
|
171
|
+
self.no_interactive = true
|
172
|
+
end
|
173
|
+
|
174
|
+
parser.on("--no-log-file", "Disable log file generation") do
|
175
|
+
self.no_log_file = true
|
176
|
+
end
|
177
|
+
|
178
|
+
parser.on("--no-timing", "Disable timing output") do
|
179
|
+
self.no_timing = true
|
180
|
+
end
|
165
181
|
end
|
166
182
|
end
|
167
183
|
|
data/lib/herb/errors.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
# typed: true
|
3
3
|
|
4
4
|
# NOTE: This file is generated by the templates/template.rb script and should not be
|
5
|
-
# modified manually. See /Users/marcoroth/Development/herb-release/templates/lib/herb/errors.rb.erb
|
5
|
+
# modified manually. See /Users/marcoroth/Development/herb-release-6/templates/lib/herb/errors.rb.erb
|
6
6
|
|
7
7
|
module Herb
|
8
8
|
module Errors
|
data/lib/herb/parse_result.rb
CHANGED
@@ -12,9 +12,14 @@ module Herb
|
|
12
12
|
super(source, warnings, errors)
|
13
13
|
end
|
14
14
|
|
15
|
+
#: () -> Array[Herb::Errors::Error]
|
16
|
+
def errors
|
17
|
+
super + value.recursive_errors
|
18
|
+
end
|
19
|
+
|
15
20
|
#: () -> bool
|
16
21
|
def failed?
|
17
|
-
errors.any?
|
22
|
+
errors.any?
|
18
23
|
end
|
19
24
|
|
20
25
|
#: () -> bool
|
@@ -24,7 +29,7 @@ module Herb
|
|
24
29
|
|
25
30
|
#: () -> String
|
26
31
|
def pretty_errors
|
27
|
-
JSON.pretty_generate(errors
|
32
|
+
JSON.pretty_generate(errors)
|
28
33
|
end
|
29
34
|
|
30
35
|
#: (Visitor) -> void
|
data/lib/herb/project.rb
CHANGED
@@ -8,10 +8,17 @@ require "timeout"
|
|
8
8
|
require "tempfile"
|
9
9
|
require "pathname"
|
10
10
|
require "English"
|
11
|
+
require "stringio"
|
11
12
|
|
12
13
|
module Herb
|
13
14
|
class Project
|
14
|
-
attr_accessor :project_path, :output_file
|
15
|
+
attr_accessor :project_path, :output_file, :no_interactive, :no_log_file, :no_timing
|
16
|
+
|
17
|
+
def interactive?
|
18
|
+
return false if no_interactive
|
19
|
+
|
20
|
+
!IO.console.nil?
|
21
|
+
end
|
15
22
|
|
16
23
|
def initialize(project_path, output_file: nil)
|
17
24
|
@project_path = Pathname.new(
|
@@ -39,7 +46,15 @@ module Herb
|
|
39
46
|
end
|
40
47
|
|
41
48
|
def parse!
|
42
|
-
|
49
|
+
start_time = Time.now unless no_timing
|
50
|
+
|
51
|
+
log = if no_log_file
|
52
|
+
StringIO.new
|
53
|
+
else
|
54
|
+
File.open(output_file, "w")
|
55
|
+
end
|
56
|
+
|
57
|
+
begin
|
43
58
|
log.puts heading("METADATA")
|
44
59
|
log.puts "Herb Version: #{Herb.version}"
|
45
60
|
log.puts "Reported at: #{Time.now.strftime("%Y-%m-%dT%H:%M:%S")}\n\n"
|
@@ -54,10 +69,10 @@ module Herb
|
|
54
69
|
message = "No .html.erb files found using #{full_path_glob}"
|
55
70
|
log.puts message
|
56
71
|
puts message
|
57
|
-
|
72
|
+
return
|
58
73
|
end
|
59
74
|
|
60
|
-
print "\e[H\e[2J"
|
75
|
+
print "\e[H\e[2J" if interactive?
|
61
76
|
|
62
77
|
successful_files = []
|
63
78
|
failed_files = []
|
@@ -77,37 +92,43 @@ module Herb
|
|
77
92
|
lines_to_clear += 3 if total_timeout.positive?
|
78
93
|
lines_to_clear += 3 if total_errors.positive?
|
79
94
|
|
80
|
-
lines_to_clear.times { print "\e[1A\e[K" } if index.positive?
|
95
|
+
lines_to_clear.times { print "\e[1A\e[K" } if index.positive? && interactive?
|
81
96
|
|
82
|
-
|
83
|
-
|
97
|
+
if interactive?
|
98
|
+
puts "Parsing .html.erb files in: #{project_path}"
|
99
|
+
puts "Total files to process: #{files.count}\n"
|
84
100
|
|
85
|
-
|
101
|
+
relative_path = file_path.sub("#{project_path}/", "")
|
86
102
|
|
87
|
-
puts
|
88
|
-
puts progress_bar(index + 1, files.count)
|
89
|
-
puts
|
90
|
-
puts "Processing [#{index + 1}/#{files.count}]: #{relative_path}"
|
91
|
-
|
92
|
-
if failed_files.any?
|
93
103
|
puts
|
94
|
-
puts
|
95
|
-
failed_files.each { |file| puts " - #{file}" }
|
104
|
+
puts progress_bar(index + 1, files.count)
|
96
105
|
puts
|
106
|
+
else
|
107
|
+
relative_path = file_path.sub("#{project_path}/", "")
|
97
108
|
end
|
109
|
+
puts "Processing [#{index + 1}/#{files.count}]: #{relative_path}"
|
98
110
|
|
99
|
-
if
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
111
|
+
if interactive?
|
112
|
+
if failed_files.any?
|
113
|
+
puts
|
114
|
+
puts "Files that failed:"
|
115
|
+
failed_files.each { |file| puts " - #{file}" }
|
116
|
+
puts
|
117
|
+
end
|
105
118
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
119
|
+
if timeout_files.any?
|
120
|
+
puts
|
121
|
+
puts "Files that timed out:"
|
122
|
+
timeout_files.each { |file| puts " - #{file}" }
|
123
|
+
puts
|
124
|
+
end
|
125
|
+
|
126
|
+
if error_files.any?
|
127
|
+
puts
|
128
|
+
puts "Files with parse errors:"
|
129
|
+
error_files.each { |file| puts " - #{file}" }
|
130
|
+
puts
|
131
|
+
end
|
111
132
|
end
|
112
133
|
|
113
134
|
begin
|
@@ -214,10 +235,13 @@ module Herb
|
|
214
235
|
end
|
215
236
|
end
|
216
237
|
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
238
|
+
if interactive?
|
239
|
+
print "\e[1A\e[K"
|
240
|
+
puts "Completed processing all files."
|
241
|
+
print "\e[H\e[2J"
|
242
|
+
else
|
243
|
+
puts "Completed processing all files."
|
244
|
+
end
|
221
245
|
|
222
246
|
log.puts ""
|
223
247
|
|
@@ -333,13 +357,23 @@ module Herb
|
|
333
357
|
end
|
334
358
|
end
|
335
359
|
|
336
|
-
|
360
|
+
unless no_timing
|
361
|
+
end_time = Time.now
|
362
|
+
duration = end_time - start_time
|
363
|
+
timing_message = "\n⏱️ Total time: #{format_duration(duration)}"
|
364
|
+
log.puts timing_message
|
365
|
+
puts timing_message
|
366
|
+
end
|
367
|
+
|
368
|
+
puts "\nResults saved to #{output_file}" unless no_log_file
|
369
|
+
ensure
|
370
|
+
log.close unless no_log_file
|
337
371
|
end
|
338
372
|
end
|
339
373
|
|
340
374
|
private
|
341
375
|
|
342
|
-
def progress_bar(current, total, width = IO.console
|
376
|
+
def progress_bar(current, total, width = (IO.console&.winsize&.[](1) || 80) - "[] 100% (#{total}/#{total})".length)
|
343
377
|
progress = current.to_f / total
|
344
378
|
completed_length = (progress * width).to_i
|
345
379
|
completed = "█" * completed_length
|
@@ -366,5 +400,17 @@ module Herb
|
|
366
400
|
|
367
401
|
prefix + ("-" * (80 - prefix.length))
|
368
402
|
end
|
403
|
+
|
404
|
+
def format_duration(seconds)
|
405
|
+
if seconds < 1
|
406
|
+
"#{(seconds * 1000).round(2)}ms"
|
407
|
+
elsif seconds < 60
|
408
|
+
"#{seconds.round(2)}s"
|
409
|
+
else
|
410
|
+
minutes = (seconds / 60).to_i
|
411
|
+
remaining_seconds = seconds % 60
|
412
|
+
"#{minutes}m #{remaining_seconds.round(2)}s"
|
413
|
+
end
|
414
|
+
end
|
369
415
|
end
|
370
416
|
end
|
data/lib/herb/version.rb
CHANGED
data/lib/herb/visitor.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
# typed: true
|
3
3
|
|
4
4
|
# NOTE: This file is generated by the templates/template.rb script and should not be
|
5
|
-
# modified manually. See /Users/marcoroth/Development/herb-release/templates/lib/herb/visitor.rb.erb
|
5
|
+
# modified manually. See /Users/marcoroth/Development/herb-release-6/templates/lib/herb/visitor.rb.erb
|
6
6
|
|
7
7
|
module Herb
|
8
8
|
class Visitor
|
data/sig/herb/ast/node.rbs
CHANGED