Class: Herb::CLI
Constant Summary
Constants included from Colors
Herb::Colors::CLEAR_SCREEN, Herb::Colors::HIDE_CURSOR, Herb::Colors::SHOW_CURSOR
Instance Attribute Summary collapse
-
#action_view_helpers ⇒ Object
Returns the value of attribute action_view_helpers.
-
#analyze ⇒ Object
Returns the value of attribute analyze.
-
#arena_stats ⇒ Object
Returns the value of attribute arena_stats.
-
#debug ⇒ Object
Returns the value of attribute debug.
-
#escape ⇒ Object
Returns the value of attribute escape.
-
#freeze ⇒ Object
Returns the value of attribute freeze.
-
#isolate ⇒ Object
Returns the value of attribute isolate.
-
#json ⇒ Object
Returns the value of attribute json.
-
#leak_check ⇒ Object
Returns the value of attribute leak_check.
-
#local ⇒ Object
Returns the value of attribute local.
-
#log_file ⇒ Object
Returns the value of attribute log_file.
-
#no_escape ⇒ Object
Returns the value of attribute no_escape.
-
#no_timing ⇒ Object
Returns the value of attribute no_timing.
-
#optimize ⇒ Object
Returns the value of attribute optimize.
-
#silent ⇒ Object
Returns the value of attribute silent.
-
#strict ⇒ Object
Returns the value of attribute strict.
-
#tool ⇒ Object
Returns the value of attribute tool.
-
#track_whitespace ⇒ Object
Returns the value of attribute track_whitespace.
-
#trim ⇒ Object
Returns the value of attribute trim.
-
#verbose ⇒ Object
Returns the value of attribute verbose.
Instance Method Summary collapse
- #call ⇒ Object
- #directory ⇒ Object
- #file_content ⇒ Object
- #help(exit_code = 0) ⇒ Object
-
#initialize(args) ⇒ CLI
constructor
A new instance of CLI.
- #option_parser ⇒ Object
- #options ⇒ Object
- #result ⇒ Object
Methods included from Colors
bold, bright_magenta, cyan, dimmed, enabled?, fg, fg_bg, green, magenta, red, white, yellow
Constructor Details
#initialize(args) ⇒ CLI
Returns a new instance of CLI.
13 14 15 16 |
# File 'lib/herb/cli.rb', line 13 def initialize(args) @args = args @command = args[0] end |
Instance Attribute Details
#action_view_helpers ⇒ Object
Returns the value of attribute action_view_helpers.
11 12 13 |
# File 'lib/herb/cli.rb', line 11 def action_view_helpers @action_view_helpers end |
#analyze ⇒ Object
Returns the value of attribute analyze.
11 12 13 |
# File 'lib/herb/cli.rb', line 11 def analyze @analyze end |
#arena_stats ⇒ Object
Returns the value of attribute arena_stats.
11 12 13 |
# File 'lib/herb/cli.rb', line 11 def arena_stats @arena_stats end |
#debug ⇒ Object
Returns the value of attribute debug.
11 12 13 |
# File 'lib/herb/cli.rb', line 11 def debug @debug end |
#escape ⇒ Object
Returns the value of attribute escape.
11 12 13 |
# File 'lib/herb/cli.rb', line 11 def escape @escape end |
#freeze ⇒ Object
Returns the value of attribute freeze.
11 12 13 |
# File 'lib/herb/cli.rb', line 11 def freeze @freeze end |
#isolate ⇒ Object
Returns the value of attribute isolate.
11 12 13 |
# File 'lib/herb/cli.rb', line 11 def isolate @isolate end |
#json ⇒ Object
Returns the value of attribute json.
11 12 13 |
# File 'lib/herb/cli.rb', line 11 def json @json end |
#leak_check ⇒ Object
Returns the value of attribute leak_check.
11 12 13 |
# File 'lib/herb/cli.rb', line 11 def leak_check @leak_check end |
#local ⇒ Object
Returns the value of attribute local.
11 12 13 |
# File 'lib/herb/cli.rb', line 11 def local @local end |
#log_file ⇒ Object
Returns the value of attribute log_file.
11 12 13 |
# File 'lib/herb/cli.rb', line 11 def log_file @log_file end |
#no_escape ⇒ Object
Returns the value of attribute no_escape.
11 12 13 |
# File 'lib/herb/cli.rb', line 11 def no_escape @no_escape end |
#no_timing ⇒ Object
Returns the value of attribute no_timing.
11 12 13 |
# File 'lib/herb/cli.rb', line 11 def no_timing @no_timing end |
#optimize ⇒ Object
Returns the value of attribute optimize.
11 12 13 |
# File 'lib/herb/cli.rb', line 11 def optimize @optimize end |
#silent ⇒ Object
Returns the value of attribute silent.
11 12 13 |
# File 'lib/herb/cli.rb', line 11 def silent @silent end |
#strict ⇒ Object
Returns the value of attribute strict.
11 12 13 |
# File 'lib/herb/cli.rb', line 11 def strict @strict end |
#tool ⇒ Object
Returns the value of attribute tool.
11 12 13 |
# File 'lib/herb/cli.rb', line 11 def tool @tool end |
#track_whitespace ⇒ Object
Returns the value of attribute track_whitespace.
11 12 13 |
# File 'lib/herb/cli.rb', line 11 def track_whitespace @track_whitespace end |
#trim ⇒ Object
Returns the value of attribute trim.
11 12 13 |
# File 'lib/herb/cli.rb', line 11 def trim @trim end |
#verbose ⇒ Object
Returns the value of attribute verbose.
11 12 13 |
# File 'lib/herb/cli.rb', line 11 def verbose @verbose end |
Instance Method Details
#call ⇒ Object
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
# File 'lib/herb/cli.rb', line 18 def call @file = @args[1] unless @command == "dev" if silent if result.failed? puts "Failed" else puts "Success" end elsif json puts result.value.to_json else puts result.value.inspect print_error_summary(result.errors) if @command == "parse" && result.respond_to?(:errors) && result.errors.any? end end |
#directory ⇒ Object
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/herb/cli.rb', line 37 def directory unless @file puts "No directory provided." puts puts "Usage:" puts " bundle exec herb #{@command} [directory] [options]" puts puts "Tip: Use `.` for the current directory" puts " bundle exec herb #{@command} . [options]" exit(1) end unless File.exist?(@file) puts "Not a file: '#{@file}'." puts end unless File.directory?(@file) puts "Not a directory: '#{@file}'." puts end @file end |
#file_content ⇒ Object
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/herb/cli.rb', line 63 def file_content if @file && @file != "-" && File.exist?(@file) File.read(@file) elsif @file && @file != "-" puts "File doesn't exist: #{@file}" exit(1) elsif @file == "-" || !$stdin.tty? $stdin.read else puts "No file provided." puts puts "Usage:" puts " bundle exec herb #{@command} [file] [options]" puts puts "You can also pipe content via stdin:" puts " echo \"<div>Hello</div>\" | bundle exec herb #{@command}" puts " cat file.html.erb | bundle exec herb #{@command}" puts " bundle exec herb #{@command} -" exit(1) end end |
#help(exit_code = 0) ⇒ Object
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
# File 'lib/herb/cli.rb', line 85 def help(exit_code = 0) = <<~HELP Herb 🌿 Powerful and seamless HTML-aware ERB toolchain. Usage: bundle exec herb [command] [options] Commands: bundle exec herb lex [file] Lex a file. bundle exec herb parse [file] Parse a file. bundle exec herb compile [file] Compile ERB template to Ruby code. bundle exec herb render [file] Compile and render ERB template to final output. bundle exec herb analyze [path] Analyze a project by passing a directory to the root of the project. bundle exec herb report [file] Generate a Markdown bug report for a file. bundle exec herb config [path] Show configuration and file patterns for a project. bundle exec herb ruby [file] Extract Ruby from a file. bundle exec herb html [file] Extract HTML from a file. bundle exec herb diff [old] [new] Diff two files and show the minimal set of AST differences. bundle exec herb playground [file] Open the content of the source file in the playground. bundle exec herb dev Start the dev server and watch for file changes. bundle exec herb version Prints the versions of the Herb gem and the libherb library. bundle exec herb actionview check [path] Check if render calls resolve to valid partial files. bundle exec herb actionview graph [path] Show render dependency graph for a project or file. bundle exec herb actionview render [file] Render ERB template using ActionView helpers. bundle exec herb lint [patterns] Lint templates (delegates to @herb-tools/linter) bundle exec herb format [patterns] Format templates (delegates to @herb-tools/formatter) bundle exec herb highlight [file] Syntax highlight templates (delegates to @herb-tools/highlighter) bundle exec herb print [file] Print AST (delegates to @herb-tools/printer) bundle exec herb lsp Start the language server (delegates to @herb-tools/language-server) stdin: Commands that accept [file] also accept input via stdin: echo "<div>Hello</div>" | bundle exec herb lex cat file.html.erb | bundle exec herb parse Use `-` to explicitly read from stdin: bundle exec herb compile - Options: #{option_parser.to_s.strip.gsub(/^ /, " ")} HELP puts exit(exit_code) end |
#option_parser ⇒ Object
243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 |
# File 'lib/herb/cli.rb', line 243 def option_parser @option_parser ||= OptionParser.new do |parser| parser. = "" parser.on_tail("-v", "--version", "Show the version") do print_version end parser.on_tail("-h", "--help", "Show this message") do help exit(0) end parser.on("-j", "--json", "Return result in the JSON format") do self.json = true end parser.on("-s", "--silent", "Log no result to stdout") do self.silent = true end parser.on("--verbose", "Show detailed per-file progress (default in CI)") do self.verbose = true end parser.on("--isolate", "Fork each file into its own process for crash isolation (slower)") do self.isolate = true end parser.on("--log-file", "Enable log file generation") do self.log_file = true end parser.on("--no-timing", "Disable timing output") do self.no_timing = true end parser.on("--local", "Use localhost for playground command instead of herb-tools.dev") do self.local = true end parser.on("--escape", "Enable HTML escaping by default (for compile command)") do self.escape = true end parser.on("--no-escape", "Disable HTML escaping by default (for compile command)") do self.no_escape = true end parser.on("--freeze", "Add frozen string literal pragma (for compile command)") do self.freeze = true end parser.on("--debug", "Enable debug mode with ERB expression wrapping (for compile command)") do self.debug = true end parser.on("--strict", "Enable strict mode - report errors for omitted closing tags (for parse/compile/render commands) (default: true)") do self.strict = true end parser.on("--no-strict", "Disable strict mode (for parse/compile/render commands)") do self.strict = false end parser.on("--analyze", "Enable analyze mode (for parse command) (default: true)") do self.analyze = true end parser.on("--no-analyze", "Disable analyze mode (for parse command)") do self.analyze = false end parser.on("--track-whitespace", "Enable whitespace tracking (for parse command) (default: false)") do self.track_whitespace = true end parser.on("--action-view-helpers", "Enable Action View helper detection (for parse command) (default: false)") do self.action_view_helpers = true end parser.on("--trim", "Enable trimming of leading/trailing whitespace (for compile/render commands)") do self.trim = true end parser.on("--optimize", "Enable compile-time optimizations for Action View helpers (for compile/render commands) (default: false)") do self.optimize = true end parser.on("--tool TOOL", "Show config for specific tool: linter, formatter (for config command)") do |t| self.tool = t.to_sym end parser.on("--arena-stats", "Print arena memory statistics (for lex/parse/analyze commands)") do self.arena_stats = true end parser.on("--leak-check", "Check for memory leaks in lex/parse/extract operations (for analyze command)") do self.leak_check = true end end end |
#options ⇒ Object
346 347 348 349 350 |
# File 'lib/herb/cli.rb', line 346 def return if ["lint", "format", "print", "highlight", "lsp"].include?(@command) option_parser.parse!(@args) end |
#result ⇒ Object
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 |
# File 'lib/herb/cli.rb', line 135 def result @result ||= case @command when "analyze" path = @file || "." if path != "-" && File.file?(path) project = Herb::Project.new(File.dirname(path)) project.file_paths = [File.(path)] else unless File.directory?(path) puts "Not a file or directory: '#{path}'." exit(1) end project = Herb::Project.new(path) end project.no_log_file = log_file ? false : true project.no_timing = no_timing project.silent = silent project.verbose = verbose || ci? project.isolate = isolate project.validate_ruby = true project.arena_stats = arena_stats project.leak_check = leak_check has_issues = project.analyze! exit(has_issues ? 1 : 0) when "report" generate_report exit(0) when "config" show_config exit(0) when "parse" Herb.parse(file_content, strict: strict.nil? || strict, analyze: analyze.nil? || analyze, track_whitespace: track_whitespace || false, arena_stats: arena_stats, action_view_helpers: action_view_helpers || false) when "compile" compile_template when "render" render_template when "lex" Herb.lex(file_content, arena_stats: arena_stats) when "ruby" puts Herb.extract_ruby(file_content) exit(0) when "html" puts Herb.extract_html(file_content) exit(0) when "playground" require "bundler/inline" gemfile do source "https://rubygems.org" gem "lz_string" end hash = LZString::UriSafe.compress(file_content) local_url = "http://localhost:5173" url = "https://herb-tools.dev/playground" if local if Dir.pwd.include?("/herb") system(%(npx concurrently "nx dev playground" "sleep 1 && open #{local_url}##{hash}")) exit(0) else puts "This command can currently only be run within the herb repo itself" exit(1) end else system(%(open "#{url}##{hash}")) exit(0) end when "dev" case @args[1] when "stop" then dev_stop when "restart" then dev_restart when "status" then dev_status else @file = @args[1] run_dev_server end when "actionview" run_actionview_command when "diff" diff_files when "lint" run_node_tool("herb-lint", "@herb-tools/linter") when "format" run_node_tool("herb-format", "@herb-tools/formatter") when "print" run_node_tool("herb-print", "@herb-tools/printer") when "highlight" run_node_tool("herb-highlight", "@herb-tools/highlighter") when "lsp" run_node_tool("herb-language-server", "@herb-tools/language-server") when "help" help when "version" print_version when String puts "Unknown command: '#{@command}'" puts help(1) else help(1) end end |