herb 0.1.0-x86_64-linux-musl

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.
Files changed (110) hide show
  1. checksums.yaml +7 -0
  2. data/License.txt +21 -0
  3. data/Makefile +121 -0
  4. data/README.md +166 -0
  5. data/Rakefile +184 -0
  6. data/exe/herb +5 -0
  7. data/ext/herb/error_helpers.c +302 -0
  8. data/ext/herb/error_helpers.h +15 -0
  9. data/ext/herb/extconf.rb +75 -0
  10. data/ext/herb/extension.c +110 -0
  11. data/ext/herb/extension.h +6 -0
  12. data/ext/herb/extension_helpers.c +117 -0
  13. data/ext/herb/extension_helpers.h +24 -0
  14. data/ext/herb/nodes.c +936 -0
  15. data/ext/herb/nodes.h +12 -0
  16. data/herb.gemspec +49 -0
  17. data/lib/herb/3.0/herb.so +0 -0
  18. data/lib/herb/3.1/herb.so +0 -0
  19. data/lib/herb/3.2/herb.so +0 -0
  20. data/lib/herb/3.3/herb.so +0 -0
  21. data/lib/herb/3.4/herb.so +0 -0
  22. data/lib/herb/ast/node.rb +61 -0
  23. data/lib/herb/ast/nodes.rb +1542 -0
  24. data/lib/herb/ast.rb +6 -0
  25. data/lib/herb/cli.rb +164 -0
  26. data/lib/herb/errors.rb +352 -0
  27. data/lib/herb/lex_result.rb +20 -0
  28. data/lib/herb/libherb/array.rb +48 -0
  29. data/lib/herb/libherb/ast_node.rb +47 -0
  30. data/lib/herb/libherb/buffer.rb +53 -0
  31. data/lib/herb/libherb/extract_result.rb +17 -0
  32. data/lib/herb/libherb/lex_result.rb +29 -0
  33. data/lib/herb/libherb/libherb.rb +49 -0
  34. data/lib/herb/libherb/parse_result.rb +17 -0
  35. data/lib/herb/libherb/token.rb +43 -0
  36. data/lib/herb/libherb.rb +32 -0
  37. data/lib/herb/location.rb +42 -0
  38. data/lib/herb/parse_result.rb +26 -0
  39. data/lib/herb/position.rb +36 -0
  40. data/lib/herb/project.rb +361 -0
  41. data/lib/herb/range.rb +40 -0
  42. data/lib/herb/result.rb +21 -0
  43. data/lib/herb/token.rb +43 -0
  44. data/lib/herb/token_list.rb +11 -0
  45. data/lib/herb/version.rb +5 -0
  46. data/lib/herb.rb +32 -0
  47. data/src/analyze.c +989 -0
  48. data/src/analyze_helpers.c +241 -0
  49. data/src/analyzed_ruby.c +35 -0
  50. data/src/array.c +137 -0
  51. data/src/ast_node.c +81 -0
  52. data/src/ast_nodes.c +866 -0
  53. data/src/ast_pretty_print.c +588 -0
  54. data/src/buffer.c +199 -0
  55. data/src/errors.c +740 -0
  56. data/src/extract.c +110 -0
  57. data/src/herb.c +103 -0
  58. data/src/html_util.c +143 -0
  59. data/src/include/analyze.h +36 -0
  60. data/src/include/analyze_helpers.h +43 -0
  61. data/src/include/analyzed_ruby.h +33 -0
  62. data/src/include/array.h +33 -0
  63. data/src/include/ast_node.h +35 -0
  64. data/src/include/ast_nodes.h +303 -0
  65. data/src/include/ast_pretty_print.h +17 -0
  66. data/src/include/buffer.h +36 -0
  67. data/src/include/errors.h +125 -0
  68. data/src/include/extract.h +20 -0
  69. data/src/include/herb.h +32 -0
  70. data/src/include/html_util.h +13 -0
  71. data/src/include/io.h +9 -0
  72. data/src/include/json.h +28 -0
  73. data/src/include/lexer.h +13 -0
  74. data/src/include/lexer_peek_helpers.h +23 -0
  75. data/src/include/lexer_struct.h +32 -0
  76. data/src/include/location.h +25 -0
  77. data/src/include/macros.h +10 -0
  78. data/src/include/memory.h +12 -0
  79. data/src/include/parser.h +22 -0
  80. data/src/include/parser_helpers.h +33 -0
  81. data/src/include/position.h +22 -0
  82. data/src/include/pretty_print.h +53 -0
  83. data/src/include/prism_helpers.h +18 -0
  84. data/src/include/range.h +23 -0
  85. data/src/include/ruby_parser.h +6 -0
  86. data/src/include/token.h +25 -0
  87. data/src/include/token_matchers.h +21 -0
  88. data/src/include/token_struct.h +51 -0
  89. data/src/include/util.h +25 -0
  90. data/src/include/version.h +6 -0
  91. data/src/include/visitor.h +11 -0
  92. data/src/io.c +30 -0
  93. data/src/json.c +205 -0
  94. data/src/lexer.c +284 -0
  95. data/src/lexer_peek_helpers.c +59 -0
  96. data/src/location.c +41 -0
  97. data/src/main.c +162 -0
  98. data/src/memory.c +53 -0
  99. data/src/parser.c +704 -0
  100. data/src/parser_helpers.c +161 -0
  101. data/src/position.c +33 -0
  102. data/src/pretty_print.c +242 -0
  103. data/src/prism_helpers.c +50 -0
  104. data/src/range.c +38 -0
  105. data/src/ruby_parser.c +47 -0
  106. data/src/token.c +194 -0
  107. data/src/token_matchers.c +32 -0
  108. data/src/util.c +128 -0
  109. data/src/visitor.c +321 -0
  110. metadata +159 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 207b59d88e1dcc35e371d5054b6a47ef1266057d2f56e0c2fcf16e366d19d6af
4
+ data.tar.gz: e240adb86a4318064234bf1dd963b37306c37d720dc41db10ffd77926f876831
5
+ SHA512:
6
+ metadata.gz: 6d4446e88628c5a9cb19d695bc4bf6068ed4f566c129500044d32811d961ed7cb5ad4d26df1e7c402c2eb2534e49c83d2e3b72805a05c7f960a70839d993ab03
7
+ data.tar.gz: a6101618f63d40668bfc303afcfbd2eac4d952e11c2b6110582cc3f25aa070d2c493408de110192f75bbf85104bd8108ef715f2a53082675d8594ea2350d129a
data/License.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2024 Marco Roth
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
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 ADDED
@@ -0,0 +1,166 @@
1
+ # 🌿 Herb
2
+
3
+ #### HTML + ERB (HTML Embedded Ruby)
4
+
5
+ Powerful and seamless HTML-aware ERB parsing.
6
+
7
+ ## Contributing
8
+
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.
10
+
11
+ ### Requirements
12
+
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.
22
+
23
+ ##### For Linux
24
+
25
+ ```bash
26
+ xargs sudo apt-get install < Aptfile
27
+ ```
28
+ or:
29
+
30
+ ```bash
31
+ sudo apt-get install check clang-19 clang-tidy-19 clang-format-19 emscripten doxygen
32
+ ```
33
+
34
+ ##### For macOS (using Homebrew)
35
+
36
+ ```bash
37
+ brew bundle
38
+ ```
39
+ or:
40
+
41
+ ```bash
42
+ brew install check llvm@19 emscripten doxygen
43
+ ```
44
+
45
+ ### Building
46
+
47
+ #### Clone the Repo
48
+
49
+ Clone the Git Repository:
50
+
51
+ ```
52
+ git clone https://github.com/marcoroth/herb && cd herb/
53
+ ```
54
+
55
+ #### Build Herb
56
+
57
+ We can now compile all source files in `src/` and generate the `herb` executable.
58
+
59
+ ```bash
60
+ make all
61
+ ```
62
+
63
+ > [!NOTE]
64
+ For any consecutive builds you can just run `make`/`make all`.
65
+
66
+ ### Run
67
+
68
+ The `herb` executable exposes a few commands for interacting with `.html.erb` files:
69
+
70
+ ```
71
+ ❯ ./herb
72
+ ./herb [command] [options]
73
+
74
+ Herb 🌿 Powerful and seamless HTML-aware ERB parsing.
75
+
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
82
+ ```
83
+
84
+ Running the executable shows a pretty-printed output for the respective command and the time it took to execute:
85
+
86
+ ```
87
+ ❯ ./herb lex examples/simple_erb.html.erb
88
+
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)>
94
+
95
+ Finished lexing in:
96
+
97
+ 12 µs
98
+ 0.012 ms
99
+ 0.000012 s
100
+ ```
101
+
102
+ ### Building the Ruby extension
103
+
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.
105
+
106
+ ```bash
107
+ rake
108
+ ```
109
+
110
+ If `rake` was successful you can use `bundle console` to interact with `Herb`:
111
+
112
+ ```bash
113
+ bundle console
114
+ ```
115
+
116
+ ```
117
+ irb(main):001> Herb.parse("<div></div>")
118
+
119
+ # => #<Herb::ParseResult:0x0000000 ... >
120
+ ```
121
+
122
+ ### Test
123
+
124
+ Builds the test suite from files in `test/` and creates the `run_herb_tests` executable to run the tests:
125
+
126
+ #### For the C Tests
127
+
128
+ ```bash
129
+ make test && ./run_herb_tests
130
+ ```
131
+
132
+ #### For the Ruby Tests
133
+
134
+ ```bash
135
+ rake test
136
+ ```
137
+
138
+ ### Clean
139
+
140
+ Removes the `herb`, `run_herb_tests`, `prism` installation, and all `.o` files.
141
+
142
+ ```bash
143
+ make clean
144
+ ```
145
+
146
+ ### Local Integration Testing
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
152
+ ```
153
+
154
+ The integration was successful if you see:
155
+
156
+ ```
157
+ ❯ bin/integration
158
+
159
+ [...]
160
+
161
+ Integration successful!
162
+ ```
163
+
164
+ ## License
165
+
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]
data/exe/herb ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require_relative "../lib/herb"
5
+ Herb::CLI.new(ARGV).call