herb 0.0.1 → 0.1.0
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 +5 -5
- data/{LICENSE → LICENSE.txt} +4 -3
- data/Makefile +121 -0
- data/README.md +102 -107
- data/Rakefile +184 -0
- data/exe/herb +5 -0
- data/ext/herb/error_helpers.c +302 -0
- data/ext/herb/error_helpers.h +15 -0
- data/ext/herb/extconf.rb +75 -0
- data/ext/herb/extension.c +110 -0
- data/ext/herb/extension.h +6 -0
- data/ext/herb/extension_helpers.c +117 -0
- data/ext/herb/extension_helpers.h +24 -0
- data/ext/herb/nodes.c +936 -0
- data/ext/herb/nodes.h +12 -0
- data/herb.gemspec +49 -0
- data/lib/herb/ast/node.rb +61 -0
- data/lib/herb/ast/nodes.rb +1542 -0
- data/lib/herb/ast.rb +6 -0
- data/lib/herb/cli.rb +164 -0
- data/lib/herb/errors.rb +352 -0
- data/lib/herb/lex_result.rb +20 -0
- data/lib/herb/libherb/array.rb +48 -0
- data/lib/herb/libherb/ast_node.rb +47 -0
- data/lib/herb/libherb/buffer.rb +53 -0
- data/lib/herb/libherb/extract_result.rb +17 -0
- data/lib/herb/libherb/lex_result.rb +29 -0
- data/lib/herb/libherb/libherb.rb +49 -0
- data/lib/herb/libherb/parse_result.rb +17 -0
- data/lib/herb/libherb/token.rb +43 -0
- data/lib/herb/libherb.rb +32 -0
- data/lib/herb/location.rb +42 -0
- data/lib/herb/parse_result.rb +26 -0
- data/lib/herb/position.rb +36 -0
- data/lib/herb/project.rb +361 -0
- data/lib/herb/range.rb +40 -0
- data/lib/herb/result.rb +21 -0
- data/lib/herb/token.rb +43 -0
- data/lib/herb/token_list.rb +11 -0
- data/lib/herb/version.rb +5 -0
- data/lib/herb.rb +21 -68
- data/src/analyze.c +989 -0
- data/src/analyze_helpers.c +241 -0
- data/src/analyzed_ruby.c +35 -0
- data/src/array.c +137 -0
- data/src/ast_node.c +81 -0
- data/src/ast_nodes.c +866 -0
- data/src/ast_pretty_print.c +588 -0
- data/src/buffer.c +199 -0
- data/src/errors.c +740 -0
- data/src/extract.c +110 -0
- data/src/herb.c +103 -0
- data/src/html_util.c +143 -0
- data/src/include/analyze.h +36 -0
- data/src/include/analyze_helpers.h +43 -0
- data/src/include/analyzed_ruby.h +33 -0
- data/src/include/array.h +33 -0
- data/src/include/ast_node.h +35 -0
- data/src/include/ast_nodes.h +303 -0
- data/src/include/ast_pretty_print.h +17 -0
- data/src/include/buffer.h +36 -0
- data/src/include/errors.h +125 -0
- data/src/include/extract.h +20 -0
- data/src/include/herb.h +32 -0
- data/src/include/html_util.h +13 -0
- data/src/include/io.h +9 -0
- data/src/include/json.h +28 -0
- data/src/include/lexer.h +13 -0
- data/src/include/lexer_peek_helpers.h +23 -0
- data/src/include/lexer_struct.h +32 -0
- data/src/include/location.h +25 -0
- data/src/include/macros.h +10 -0
- data/src/include/memory.h +12 -0
- data/src/include/parser.h +22 -0
- data/src/include/parser_helpers.h +33 -0
- data/src/include/position.h +22 -0
- data/src/include/pretty_print.h +53 -0
- data/src/include/prism_helpers.h +18 -0
- data/src/include/range.h +23 -0
- data/src/include/ruby_parser.h +6 -0
- data/src/include/token.h +25 -0
- data/src/include/token_matchers.h +21 -0
- data/src/include/token_struct.h +51 -0
- data/src/include/util.h +25 -0
- data/src/include/version.h +6 -0
- data/src/include/visitor.h +11 -0
- data/src/io.c +30 -0
- data/src/json.c +205 -0
- data/src/lexer.c +284 -0
- data/src/lexer_peek_helpers.c +59 -0
- data/src/location.c +41 -0
- data/src/main.c +162 -0
- data/src/memory.c +53 -0
- data/src/parser.c +704 -0
- data/src/parser_helpers.c +161 -0
- data/src/position.c +33 -0
- data/src/pretty_print.c +242 -0
- data/src/prism_helpers.c +50 -0
- data/src/range.c +38 -0
- data/src/ruby_parser.c +47 -0
- data/src/token.c +194 -0
- data/src/token_matchers.c +32 -0
- data/src/util.c +128 -0
- data/src/visitor.c +321 -0
- metadata +126 -82
- data/test/helper.rb +0 -7
- data/test/helpers_test.rb +0 -25
- data/test/parsing_test.rb +0 -110
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 7181a99a7c115d405967410785ab43baae8a4b135224160b49e653e7150774a4
|
4
|
+
data.tar.gz: 915521c5e89f18dd4ee0197f0518d59749ba6f19f4452662400c45c8706ac364
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0aa709590f400e64270e3c20ebf598ab7be7195812415e90426f0380a0237780f171e4cd9c7583acf3ab03edf7cd8f0166873f82633c75ed1b35c27e92a07073
|
7
|
+
data.tar.gz: 3ddddf73d9303d9807a41acbcf6fc09a00983bdeffcfa732715e1f921d2edb4ef2f7b1bd4bd9b4d75b21473f75bef1cfd547caba84e310db05f7c287186eec39
|
data/{LICENSE → LICENSE.txt}
RENAMED
@@ -1,5 +1,6 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2024 Marco Roth
|
3
4
|
|
4
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
5
6
|
of this software and associated documentation files (the "Software"), to deal
|
@@ -17,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
17
18
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
18
19
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
19
20
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
20
|
-
THE SOFTWARE.
|
21
|
+
THE SOFTWARE.
|
data/Makefile
ADDED
@@ -0,0 +1,121 @@
|
|
1
|
+
exec = herb
|
2
|
+
test_exec = run_herb_tests
|
3
|
+
|
4
|
+
sources = $(wildcard src/*.c) $(wildcard src/**/*.c)
|
5
|
+
headers = $(wildcard src/*.h) $(wildcard src/**/*.h)
|
6
|
+
objects = $(sources:.c=.o)
|
7
|
+
|
8
|
+
extension_sources = $(wildcard ext/**/*.c)
|
9
|
+
extension_headers = $(wildcard ext/**/*.h)
|
10
|
+
extension_objects = $(extension_sources:.o)
|
11
|
+
|
12
|
+
prism_objects = $(filter-out src/main.c, $(sources))
|
13
|
+
|
14
|
+
project_files = $(sources) $(headers)
|
15
|
+
extension_files = $(extension_sources) $(extension_headers)
|
16
|
+
nodejs_extension_files = $(wildcard node/**/*.cpp) $(wildcard node/**/*.h) $(wildcard node/**/*.hpp)
|
17
|
+
project_and_extension_files = $(project_files) $(extension_files) $(nodejs_extension_files)
|
18
|
+
|
19
|
+
test_sources = $(wildcard test/**/*.c)
|
20
|
+
test_objects = $(test_sources:.c=.o)
|
21
|
+
non_main_objects = $(filter-out src/main.o, $(objects))
|
22
|
+
|
23
|
+
soext ?= $(shell ruby -e 'puts RbConfig::CONFIG["DLEXT"]')
|
24
|
+
lib_name = $(build_dir)/lib$(exec).$(soext)
|
25
|
+
static_lib_name = $(build_dir)/lib$(exec).a
|
26
|
+
ruby_extension = ext/herb/$(lib_name)
|
27
|
+
|
28
|
+
build_dir = build
|
29
|
+
$(shell mkdir -p $(build_dir))
|
30
|
+
|
31
|
+
os := $(shell uname -s)
|
32
|
+
|
33
|
+
prism_path = $(shell bundle show prism)
|
34
|
+
prism_include = $(prism_path)/include
|
35
|
+
prism_build = $(prism_path)/build
|
36
|
+
|
37
|
+
prism_flags = -I$(prism_include)
|
38
|
+
prism_ldflags = $(prism_build)/libprism.a
|
39
|
+
|
40
|
+
# Enable strict warnings
|
41
|
+
warning_flags = -Wall -Wextra -Werror -pedantic
|
42
|
+
|
43
|
+
# Debug build (no optimizations, debug symbols)
|
44
|
+
debug_flags = -g -O0 -Wno-unused-parameter
|
45
|
+
|
46
|
+
# Production build (optimized)
|
47
|
+
production_flags = $(warning_flags) -O3 -march=native -flto
|
48
|
+
|
49
|
+
# Shared library flags (only for `.so`/`.dylib`/`.bundle`)
|
50
|
+
shared_library_flags = -fPIC
|
51
|
+
|
52
|
+
# Default build mode (change this as needed)
|
53
|
+
flags = $(warning_flags) $(debug_flags) $(prism_flags) -std=c99
|
54
|
+
|
55
|
+
# Separate test compilation flags
|
56
|
+
test_flags = $(debug_flags) $(prism_flags) -std=gnu99
|
57
|
+
|
58
|
+
# Shared library build (if needed)
|
59
|
+
shared_flags = $(production_flags) $(shared_library_flags) $(prism_flags)
|
60
|
+
|
61
|
+
ifeq ($(os),Linux)
|
62
|
+
test_cflags = $(test_flags) -I/usr/include/check
|
63
|
+
test_ldflags = -L/usr/lib/x86_64-linux-gnu -lcheck -lm -lsubunit $(prism_ldflags)
|
64
|
+
cc = clang-19
|
65
|
+
clang_format = clang-format-19
|
66
|
+
clang_tidy = clang-tidy-19
|
67
|
+
endif
|
68
|
+
|
69
|
+
ifeq ($(os),Darwin)
|
70
|
+
brew_prefix := $(shell brew --prefix check)
|
71
|
+
test_cflags = $(test_flags) -I$(brew_prefix)/include
|
72
|
+
test_ldflags = -L$(brew_prefix)/lib -lcheck -lm $(prism_ldflags)
|
73
|
+
llvm_path = $(shell brew --prefix llvm@19)
|
74
|
+
cc = $(llvm_path)/bin/clang
|
75
|
+
clang_format = $(llvm_path)/bin/clang-format
|
76
|
+
clang_tidy = $(llvm_path)/bin/clang-tidy
|
77
|
+
endif
|
78
|
+
|
79
|
+
all: prism $(exec) $(lib_name) $(static_lib_name) test wasm
|
80
|
+
|
81
|
+
$(exec): $(objects)
|
82
|
+
$(cc) $(objects) $(flags) $(ldflags) $(prism_ldflags) -o $(exec)
|
83
|
+
|
84
|
+
$(lib_name): $(objects)
|
85
|
+
$(cc) -shared $(objects) $(shared_flags) $(ldflags) $(prism_ldflags) -o $(lib_name)
|
86
|
+
# cp $(lib_name) $(ruby_extension)
|
87
|
+
|
88
|
+
$(static_lib_name): $(objects)
|
89
|
+
ar rcs $(static_lib_name) $(objects)
|
90
|
+
|
91
|
+
src/%.o: src/%.c
|
92
|
+
$(cc) -c $(flags) -fPIC $< -o $@
|
93
|
+
|
94
|
+
test/%.o: test/%.c
|
95
|
+
$(cc) -c $(test_cflags) $(test_flags) $(prism_flags) $< -o $@
|
96
|
+
|
97
|
+
test: $(test_objects) $(non_main_objects)
|
98
|
+
$(cc) $(test_objects) $(non_main_objects) $(test_cflags) $(test_ldflags) -o $(test_exec)
|
99
|
+
|
100
|
+
clean:
|
101
|
+
rm -f $(exec) $(test_exec) $(lib_name) $(shared_lib_name) $(ruby_extension)
|
102
|
+
rm -rf $(objects) $(test_objects) $(extension_objects) lib/herb/*.bundle tmp
|
103
|
+
rm -rf $(prism_path)
|
104
|
+
|
105
|
+
bundle_install:
|
106
|
+
bundle install
|
107
|
+
|
108
|
+
prism: bundle_install
|
109
|
+
cd $(prism_path) && ruby templates/template.rb && make static && cd -
|
110
|
+
|
111
|
+
format:
|
112
|
+
$(clang_format) -i $(project_and_extension_files)
|
113
|
+
|
114
|
+
lint:
|
115
|
+
$(clang_format) --dry-run --Werror $(project_and_extension_files)
|
116
|
+
|
117
|
+
tidy:
|
118
|
+
$(clang_tidy) $(project_files) -- $(flags)
|
119
|
+
|
120
|
+
wasm:
|
121
|
+
cd wasm && make
|
data/README.md
CHANGED
@@ -1,171 +1,166 @@
|
|
1
|
-
|
2
|
-
====
|
1
|
+
# 🌿 Herb
|
3
2
|
|
4
|
-
|
3
|
+
#### HTML + ERB (HTML Embedded Ruby)
|
5
4
|
|
6
|
-
|
7
|
-
-----------
|
5
|
+
Powerful and seamless HTML-aware ERB parsing.
|
8
6
|
|
9
|
-
|
7
|
+
## Contributing
|
10
8
|
|
11
|
-
|
12
|
-
------------
|
9
|
+
This project builds the Herb program and its associated unit tests using a Makefile for automation. The Makefile provides several useful commands for compiling, running tests, and cleaning the project.
|
13
10
|
|
14
|
-
|
11
|
+
### Requirements
|
15
12
|
|
16
|
-
|
17
|
-
|
18
|
-
|
13
|
+
- [**Check**](https://libcheck.github.io/check/): For unit testing.
|
14
|
+
- [**Clang 19**](https://clang.llvm.org): The compiler used to build this project.
|
15
|
+
- [**Clang Format 19**](https://clang.llvm.org/docs/ClangFormat.html): For formatting the project.
|
16
|
+
- [**Clang Tidy 19**](https://clang.llvm.org/extra/clang-tidy/): For linting the project.
|
17
|
+
- [**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.
|
18
|
+
- [**Ruby**](https://www.ruby-lang.org/en/): We need Ruby as a dependency for `bundler`.
|
19
|
+
- [**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.
|
20
|
+
- [**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.
|
21
|
+
- [**Doxygen**](https://www.doxygen.nl): For building the C-Reference documentation pages.
|
19
22
|
|
20
|
-
|
23
|
+
##### For Linux
|
21
24
|
|
25
|
+
```bash
|
26
|
+
xargs sudo apt-get install < Aptfile
|
22
27
|
```
|
23
|
-
|
28
|
+
or:
|
29
|
+
|
30
|
+
```bash
|
31
|
+
sudo apt-get install check clang-19 clang-tidy-19 clang-format-19 emscripten doxygen
|
24
32
|
```
|
25
33
|
|
26
|
-
|
34
|
+
##### For macOS (using Homebrew)
|
27
35
|
|
36
|
+
```bash
|
37
|
+
brew bundle
|
28
38
|
```
|
29
|
-
|
39
|
+
or:
|
40
|
+
|
41
|
+
```bash
|
42
|
+
brew install check llvm@19 emscripten doxygen
|
30
43
|
```
|
31
44
|
|
32
|
-
|
33
|
-
-----------
|
45
|
+
### Building
|
34
46
|
|
35
|
-
|
47
|
+
#### Clone the Repo
|
36
48
|
|
37
|
-
|
38
|
-
require "herb"
|
49
|
+
Clone the Git Repository:
|
39
50
|
|
40
|
-
|
41
|
-
|
42
|
-
# => "your template goes here!"
|
51
|
+
```
|
52
|
+
git clone https://github.com/marcoroth/herb && cd herb/
|
43
53
|
```
|
44
54
|
|
45
|
-
|
55
|
+
#### Build Herb
|
46
56
|
|
47
|
-
|
57
|
+
We can now compile all source files in `src/` and generate the `herb` executable.
|
48
58
|
|
49
|
-
```
|
50
|
-
|
51
|
-
|
59
|
+
```bash
|
60
|
+
make all
|
61
|
+
```
|
52
62
|
|
53
|
-
|
54
|
-
|
55
|
-
sorted = gems.sort
|
56
|
-
%>
|
63
|
+
> [!NOTE]
|
64
|
+
For any consecutive builds you can just run `make`/`make all`.
|
57
65
|
|
58
|
-
|
59
|
-
<% sorted.each do |name| %>
|
60
|
-
<li><%= name %></li>
|
61
|
-
<% end %>
|
62
|
-
</ul>
|
63
|
-
```
|
66
|
+
### Run
|
64
67
|
|
65
|
-
The
|
68
|
+
The `herb` executable exposes a few commands for interacting with `.html.erb` files:
|
66
69
|
|
67
|
-
```html
|
68
|
-
<ul>
|
69
|
-
<li>cuba</li>
|
70
|
-
<li>herb</li>
|
71
|
-
<li>rack</li>
|
72
|
-
</ul>
|
73
70
|
```
|
71
|
+
❯ ./herb
|
72
|
+
./herb [command] [options]
|
74
73
|
|
75
|
-
|
76
|
-
----------
|
77
|
-
|
78
|
-
The values passed to the template are available as local variables:
|
74
|
+
Herb 🌿 Powerful and seamless HTML-aware ERB parsing.
|
79
75
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
76
|
+
./herb lex [file] - Lex a file
|
77
|
+
./herb lex_json [file] - Lex a file and return the result as json.
|
78
|
+
./herb parse [file] - Parse a file
|
79
|
+
./herb ruby [file] - Extract Ruby from a file
|
80
|
+
./herb html [file] - Extract HTML from a file
|
81
|
+
./herb prism [file] - Extract Ruby from a file and parse the Ruby source with Prism
|
84
82
|
```
|
85
83
|
|
86
|
-
|
84
|
+
Running the executable shows a pretty-printed output for the respective command and the time it took to execute:
|
87
85
|
|
88
|
-
```ruby
|
89
|
-
template = Herb.parse("Hello {{ params[:name] }}")
|
90
|
-
template.call(name: "Ruby")
|
91
|
-
# => Hello Ruby
|
92
86
|
```
|
87
|
+
❯ ./herb lex examples/simple_erb.html.erb
|
93
88
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
89
|
+
#<Herb::Token type="TOKEN_ERB_START" value="<%" range=[0, 2] start=(1:0) end=(1:2)>
|
90
|
+
#<Herb::Token type="TOKEN_ERB_CONTENT" value=" title " range=[2, 9] start=(1:2) end=(1:9)>
|
91
|
+
#<Herb::Token type="TOKEN_ERB_END" value="%>" range=[9, 11] start=(1:9) end=(1:11)>
|
92
|
+
#<Herb::Token type="TOKEN_NEWLINE" value="\n" range=[11, 12] start=(1:0) end=(2:1)>
|
93
|
+
#<Herb::Token type="TOKEN_EOF" value="" range=[12, 12] start=(2:1) end=(2:1)>
|
98
94
|
|
99
|
-
|
100
|
-
template = Herb.parse("Hello {{ name }}", [:name])
|
101
|
-
template.call(name: "<b>World</b>")
|
102
|
-
# => Hello <b>World<b>
|
95
|
+
Finished lexing in:
|
103
96
|
|
104
|
-
|
105
|
-
|
106
|
-
|
97
|
+
12 µs
|
98
|
+
0.012 ms
|
99
|
+
0.000012 s
|
107
100
|
```
|
108
101
|
|
109
|
-
|
110
|
-
--------------
|
102
|
+
### Building the Ruby extension
|
111
103
|
|
112
|
-
|
113
|
-
free to include it in your code. To do it, just type:
|
104
|
+
We use `rake` and `rake-compiler` to compile the Ruby extension. Running rake will generate the needed templates, run make, build the needed artifacts, and run the Ruby tests.
|
114
105
|
|
115
|
-
```
|
116
|
-
|
106
|
+
```bash
|
107
|
+
rake
|
117
108
|
```
|
118
109
|
|
119
|
-
|
110
|
+
If `rake` was successful you can use `bundle console` to interact with `Herb`:
|
120
111
|
|
121
|
-
|
112
|
+
```bash
|
113
|
+
bundle console
|
114
|
+
```
|
122
115
|
|
123
|
-
```ruby
|
124
|
-
herb("test/basic.erb", n: 3)
|
125
|
-
# => "***\n"
|
126
116
|
```
|
117
|
+
irb(main):001> Herb.parse("<div></div>")
|
127
118
|
|
128
|
-
|
119
|
+
# => #<Herb::ParseResult:0x0000000 ... >
|
120
|
+
```
|
129
121
|
|
130
|
-
|
122
|
+
### Test
|
131
123
|
|
132
|
-
|
124
|
+
Builds the test suite from files in `test/` and creates the `run_herb_tests` executable to run the tests:
|
133
125
|
|
134
|
-
|
135
|
-
# First call
|
136
|
-
herb("foo.erb", a: 1, b: 2)
|
137
|
-
```
|
126
|
+
#### For the C Tests
|
138
127
|
|
139
|
-
|
140
|
-
|
128
|
+
```bash
|
129
|
+
make test && ./run_herb_tests
|
130
|
+
```
|
141
131
|
|
142
|
-
|
132
|
+
#### For the Ruby Tests
|
143
133
|
|
144
|
-
```
|
145
|
-
|
134
|
+
```bash
|
135
|
+
rake test
|
146
136
|
```
|
147
137
|
|
148
|
-
|
138
|
+
### Clean
|
149
139
|
|
150
|
-
|
151
|
-
|
140
|
+
Removes the `herb`, `run_herb_tests`, `prism` installation, and all `.o` files.
|
141
|
+
|
142
|
+
```bash
|
143
|
+
make clean
|
152
144
|
```
|
153
145
|
|
154
|
-
|
146
|
+
### Local Integration Testing
|
155
147
|
|
148
|
+
The `bin/integration` script allows for quick local iteration. On every run it cleans the directory, builds the source from scratch and runs all checks, including the C-Tests, Ruby Tests, Linters, and examples in succession.
|
149
|
+
|
150
|
+
```bash
|
151
|
+
bin/integration
|
156
152
|
```
|
157
|
-
|
153
|
+
|
154
|
+
The integration was successful if you see:
|
155
|
+
|
158
156
|
```
|
157
|
+
❯ bin/integration
|
159
158
|
|
160
|
-
|
159
|
+
[...]
|
161
160
|
|
162
|
-
|
163
|
-
|
161
|
+
Integration successful!
|
162
|
+
```
|
164
163
|
|
165
|
-
|
164
|
+
## License
|
166
165
|
|
167
|
-
[
|
168
|
-
[issues]: https://github.com/frodsan/herb/issues
|
169
|
-
[mit]: http://www.opensource.org/licenses/MIT
|
170
|
-
[mote]: https://github.com/soveran/mote
|
171
|
-
[xss]: http://en.wikipedia.org/wiki/Cross-Site_Scripting
|
166
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE.txt) file for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,184 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "English"
|
4
|
+
require "bundler/gem_tasks"
|
5
|
+
require "rake/testtask"
|
6
|
+
|
7
|
+
Rake::TestTask.new(:test) do |t|
|
8
|
+
t.libs << "test"
|
9
|
+
t.libs << "lib"
|
10
|
+
t.test_files = FileList["test/**/*_test.rb"]
|
11
|
+
end
|
12
|
+
|
13
|
+
task "make" do
|
14
|
+
puts "Running make..."
|
15
|
+
IO.popen("make") do |output|
|
16
|
+
output.each_line do |line|
|
17
|
+
puts line
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
begin
|
23
|
+
require "rake/extensiontask"
|
24
|
+
|
25
|
+
PLATFORMS = %w[
|
26
|
+
aarch64-linux-gnu
|
27
|
+
aarch64-linux-musl
|
28
|
+
arm-linux-gnu
|
29
|
+
arm-linux-musl
|
30
|
+
arm64-darwin
|
31
|
+
x86_64-darwin
|
32
|
+
x86_64-linux-gnu
|
33
|
+
x86_64-linux-musl
|
34
|
+
x86-linux-gnu
|
35
|
+
x86-linux-musl
|
36
|
+
].freeze
|
37
|
+
|
38
|
+
exttask = Rake::ExtensionTask.new do |ext|
|
39
|
+
ext.name = "herb"
|
40
|
+
ext.source_pattern = "*.{c,h}"
|
41
|
+
ext.ext_dir = "ext/herb"
|
42
|
+
ext.lib_dir = "lib/herb"
|
43
|
+
ext.gem_spec = Gem::Specification.load("herb.gemspec")
|
44
|
+
ext.cross_compile = true
|
45
|
+
ext.cross_platform = PLATFORMS
|
46
|
+
end
|
47
|
+
|
48
|
+
Rake::Task[:compile].enhance do
|
49
|
+
raise "src/* could not be compiled #{$CHILD_STATUS.exitstatus}" if $CHILD_STATUS.exitstatus != 0
|
50
|
+
end
|
51
|
+
|
52
|
+
Rake::Task[:clean].enhance do
|
53
|
+
IO.popen("make clean") do |output|
|
54
|
+
output.each_line do |line|
|
55
|
+
puts line
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
task "gem:native" do
|
61
|
+
require "rake_compiler_dock"
|
62
|
+
# sh "bundle config set cache_all true"
|
63
|
+
|
64
|
+
PLATFORMS.each do |platform|
|
65
|
+
RakeCompilerDock.sh "bundle && rake native:#{platform} gem", platform: platform
|
66
|
+
end
|
67
|
+
|
68
|
+
RakeCompilerDock.sh "bundle && rake java gem", rubyvm: :jruby
|
69
|
+
rescue LoadError
|
70
|
+
abort "rake_compiler_dock is required to build native gems"
|
71
|
+
end
|
72
|
+
|
73
|
+
namespace "gem" do
|
74
|
+
task "prepare" do
|
75
|
+
require "rake_compiler_dock"
|
76
|
+
require "io/console"
|
77
|
+
|
78
|
+
# sh "bundle config set cache_all true"
|
79
|
+
sh "cp ~/.gem/gem-*.pem build/gem/ || true"
|
80
|
+
|
81
|
+
gemspec_path = File.expand_path("./herb.gemspec", __dir__)
|
82
|
+
spec = eval(File.read(gemspec_path), binding, gemspec_path)
|
83
|
+
|
84
|
+
RakeCompilerDock.set_ruby_cc_version(spec.required_ruby_version.as_list)
|
85
|
+
|
86
|
+
# ENV["GEM_PRIVATE_KEY_PASSPHRASE"] = STDIN.getpass("Enter passphrase of gem signature key: ")
|
87
|
+
rescue LoadError
|
88
|
+
abort "rake_compiler_dock is required for this task"
|
89
|
+
end
|
90
|
+
|
91
|
+
exttask.cross_platform.each do |platform|
|
92
|
+
desc "Build all native binary gems in parallel"
|
93
|
+
multitask "native" => platform
|
94
|
+
|
95
|
+
desc "Build the native gem for #{platform}"
|
96
|
+
task platform => "prepare" do
|
97
|
+
RakeCompilerDock.sh(
|
98
|
+
"bundle && rake native:#{platform} gem RUBY_CC_VERSION='#{ENV.fetch("RUBY_CC_VERSION", nil)}'",
|
99
|
+
platform: platform
|
100
|
+
)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
rescue LoadError => e
|
105
|
+
desc "Compile task not available (rake-compiler not installed)"
|
106
|
+
task :compile do
|
107
|
+
puts e
|
108
|
+
abort <<~MESSAGE
|
109
|
+
|
110
|
+
"rake-compiler is required for this task.
|
111
|
+
|
112
|
+
Are you running `rake` using `bundle exec rake`?
|
113
|
+
|
114
|
+
Otherwise
|
115
|
+
* try to run bundle install
|
116
|
+
* add it to your Gemfile
|
117
|
+
* or install it with: gem install rake-compiler
|
118
|
+
MESSAGE
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
desc "Render out template files"
|
123
|
+
task :templates do
|
124
|
+
require_relative "templates/template"
|
125
|
+
|
126
|
+
Dir.glob("#{__dir__}/templates/**/*.erb").each do |template|
|
127
|
+
Herb::Template.render(template)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
namespace :templates do
|
132
|
+
desc "Watch template files and regenerate on changes"
|
133
|
+
task :watch do
|
134
|
+
require "listen"
|
135
|
+
|
136
|
+
Rake::Task[:templates].execute
|
137
|
+
|
138
|
+
puts
|
139
|
+
puts "Watching config.yml and templates/**/*.erb for changes..."
|
140
|
+
|
141
|
+
ignore = Dir.glob("*/").map { |dir| Regexp.escape(dir.chomp("/")) }.map { |dir| %r{^#{dir}/} }
|
142
|
+
|
143
|
+
config_listener = Listen.to(".", only: /config\.yml$/, ignore: ignore) do
|
144
|
+
puts
|
145
|
+
puts "#{Time.now.strftime("[%Y-%m-%d %H:%M:%S]")} config.yml changed, regenerating all templates ..."
|
146
|
+
puts
|
147
|
+
|
148
|
+
Rake::Task[:templates].execute
|
149
|
+
end
|
150
|
+
|
151
|
+
template_listener = Listen.to("templates", only: /\.erb$/) do |modified, added, removed|
|
152
|
+
puts
|
153
|
+
(added + modified).each do |template|
|
154
|
+
template_file = template.delete_prefix("#{__dir__}/")
|
155
|
+
|
156
|
+
puts "#{Time.now.strftime("[%Y-%m-%d %H:%M:%S]")} Detected change, regenerating #{template_file} ..."
|
157
|
+
Herb::Template.render(template_file)
|
158
|
+
end
|
159
|
+
|
160
|
+
removed.each do |template|
|
161
|
+
puts
|
162
|
+
puts "#{template} was removed. Make sure to also remove the generated file."
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
config_listener.start
|
167
|
+
template_listener.start
|
168
|
+
|
169
|
+
sleep
|
170
|
+
rescue LoadError
|
171
|
+
abort "listen gem is required for this task. Add it to your Gemfile or install it with: gem install listen"
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
namespace :parse do
|
176
|
+
desc "Parse ERB files in a project directory"
|
177
|
+
task :project, [:path, :output_file] do |_t, args|
|
178
|
+
require_relative "lib/herb"
|
179
|
+
|
180
|
+
Herb::Project.new(args[:path], output_file: args[:output_file]).parse!
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
task default: [:templates, :make, :compile, :test]
|