feat(rules): introduce block DSL, phase-based execution (#203)

* chore(deps): update submodule goutils

* docs(http): remove default client from README.md

* refactor(rules): introduce block DSL, phase-based execution, and flow validation

- add block syntax parser/scanner with nested @blocks and elif/else support
- restructure rule execution into explicit pre/post phases with phase flags
- classify commands by phase and termination behavior
- enforce flow semantics (default rule handling, dead-rule detection)
- expand HTTP flow coverage with block + YAML parity tests and benches
- refresh rules README/spec and update playground/docs integration
- Default rules act as fallback handlers that execute only when no matching non-default rule exists in the pre phase
- IfElseBlockCommand now returns early when a condition matches with a nil Do block, instead of falling through to else blocks
- Add nil check for auth handler to allow requests when no auth is configured

* fix(rules): buffer log output before writing to stdout/stderr

* refactor(api/rules): remove IsResponseRule field from ParsedRule and related logic

* docs(rules): update examples to use block syntax
This commit is contained in:
Yuzerion
2026-02-24 10:44:47 +08:00
committed by GitHub
parent 169358659a
commit d2d686b4d1
37 changed files with 5074 additions and 1127 deletions

View File

@@ -131,12 +131,13 @@ Error generates help string as error, e.g.
from: the path to rewrite, must start with /
to: the path to rewrite to, must start with /
*/
func (h *Help) Error() error {
var lines gperr.MultilineError
func (h *Help) Error() gperr.Error {
help := gperr.New(ansi.WithANSI(h.command, ansi.HighlightGreen))
for _, line := range h.description {
help = help.Withf("%s", line)
}
lines.Adds(ansi.WithANSI(h.command, ansi.HighlightGreen))
lines.AddStrings(h.description...)
lines.Adds(" args:")
args := gperr.New("args")
argKeys := make([]string, 0, len(h.args))
longestArg := 0
@@ -151,7 +152,9 @@ func (h *Help) Error() error {
slices.Sort(argKeys)
for _, arg := range argKeys {
desc := h.args[arg]
lines.Addf(" %-"+strconv.Itoa(longestArg)+"s: %s", ansi.WithANSI(arg, ansi.HighlightCyan), desc)
paddedArg := fmt.Sprintf("%-"+strconv.Itoa(longestArg)+"s", arg)
args = args.Withf("%s%s", ansi.WithANSI(paddedArg, ansi.HighlightCyan)+": ", desc)
}
return &lines
return help.With(args)
}