mirror of
https://github.com/foomo/walker.git
synced 2026-11-08 23:00:22 +00:00
69 lines
1.8 KiB
Go
69 lines
1.8 KiB
Go
package main
|
|
|
|
import (
|
|
"errors"
|
|
"flag"
|
|
"fmt"
|
|
"io"
|
|
"log/slog"
|
|
"net/http"
|
|
"net/url"
|
|
"os"
|
|
|
|
"github.com/foomo/walker/go/internal/semanticshape"
|
|
)
|
|
|
|
func main() {
|
|
flagHelp := flag.Bool("help", false, "show help")
|
|
flag.Parse()
|
|
|
|
if len(flag.Args()) != 3 || *flagHelp {
|
|
fmt.Println("foomo walker validator - validate a html page against an html shape")
|
|
fmt.Println("usage:", os.Args[0], "path/to/shape-root", "group", "http://server.com/doc-to-validate|path/to/file.html")
|
|
fmt.Println("exit codes: 1 usage or shape errors, 2 page could not be loaded, 3 the page has error findings")
|
|
os.Exit(1)
|
|
}
|
|
shapeRoot, group, target := flag.Arg(0), flag.Arg(1), flag.Arg(2)
|
|
|
|
root, errLoad := semanticshape.LoadRoot(shapeRoot)
|
|
if errLoad != nil {
|
|
slog.Error("could not load the shape root", "root", shapeRoot)
|
|
// the lint errors, one per line - file:line message
|
|
fmt.Fprintln(os.Stderr, errLoad)
|
|
os.Exit(1)
|
|
}
|
|
|
|
htmlBytes, errRead := read(target)
|
|
if errRead != nil {
|
|
slog.Error("could not load the page", "target", target, "error", errRead)
|
|
os.Exit(2)
|
|
}
|
|
|
|
report, errValidate := root.Validate(group, htmlBytes)
|
|
if errValidate != nil {
|
|
slog.Error("could not validate", "target", target, "error", errValidate)
|
|
os.Exit(2)
|
|
}
|
|
report.Print(os.Stdout)
|
|
if report.Count(semanticshape.SeverityError) > 0 {
|
|
os.Exit(3)
|
|
}
|
|
}
|
|
|
|
// read loads an http(s) url or a local file
|
|
func read(target string) ([]byte, error) {
|
|
u, errParse := url.Parse(target)
|
|
if errParse != nil || (u.Scheme != "http" && u.Scheme != "https") {
|
|
return os.ReadFile(target)
|
|
}
|
|
resp, errGet := http.Get(target)
|
|
if errGet != nil {
|
|
return nil, errGet
|
|
}
|
|
defer resp.Body.Close()
|
|
if resp.StatusCode != http.StatusOK {
|
|
return nil, errors.New("unexpected status: " + resp.Status)
|
|
}
|
|
return io.ReadAll(resp.Body)
|
|
}
|