From 65f4049c2869288ff0909c66ee000feaa79a9d2e Mon Sep 17 00:00:00 2001 From: Simon Vieille Date: Mon, 15 Jan 2024 12:38:30 +0100 Subject: [PATCH] refactor all by using PHP instead of Golang --- .dockerignore | 12 +- .gitignore | 31 +- .woodpecker.yml | 7 - CHANGELOG.md | 11 - DOCS.md | 237 +- Dockerfile | 9 +- Dockerfile.armhf | 13 - LICENSE | 201 - MAINTAINERS | 51 - Makefile | 8 - README.md | 51 +- bin/console | 133 + composer.json | 11 + defaults.go | 270 -- go.mod | 24 - go.sum | 56 - main.go | 438 --- plugin.go | 320 -- src/Factory/EmailFactory.php | 76 + src/Factory/TwigFactory.php | 22 + src/Loader/EnvVarLoader.php | 41 + src/Loader/functions.php | 38 + src/Pipeline/Evaluation.php | 21 + templates/_base.html.twig | 170 + templates/build_status.html.twig | 93 + .../PuerkitoBio/goquery/.gitattributes | 1 - .../github.com/PuerkitoBio/goquery/.gitignore | 16 - .../PuerkitoBio/goquery/.travis.yml | 11 - vendor/github.com/PuerkitoBio/goquery/LICENSE | 12 - .../github.com/PuerkitoBio/goquery/README.md | 123 - .../github.com/PuerkitoBio/goquery/array.go | 103 - vendor/github.com/PuerkitoBio/goquery/doc.go | 123 - .../github.com/PuerkitoBio/goquery/expand.go | 46 - .../github.com/PuerkitoBio/goquery/filter.go | 163 - .../PuerkitoBio/goquery/iteration.go | 39 - .../PuerkitoBio/goquery/manipulation.go | 550 --- .../PuerkitoBio/goquery/property.go | 275 -- .../github.com/PuerkitoBio/goquery/query.go | 53 - .../PuerkitoBio/goquery/traversal.go | 698 ---- vendor/github.com/PuerkitoBio/goquery/type.go | 135 - .../PuerkitoBio/goquery/utilities.go | 161 - vendor/github.com/Sirupsen/logrus/.gitignore | 1 - vendor/github.com/Sirupsen/logrus/.travis.yml | 8 - .../github.com/Sirupsen/logrus/CHANGELOG.md | 66 - vendor/github.com/Sirupsen/logrus/LICENSE | 21 - vendor/github.com/Sirupsen/logrus/README.md | 432 --- vendor/github.com/Sirupsen/logrus/alt_exit.go | 64 - vendor/github.com/Sirupsen/logrus/doc.go | 26 - vendor/github.com/Sirupsen/logrus/entry.go | 275 -- vendor/github.com/Sirupsen/logrus/exported.go | 193 - .../github.com/Sirupsen/logrus/formatter.go | 45 - vendor/github.com/Sirupsen/logrus/hooks.go | 34 - .../Sirupsen/logrus/json_formatter.go | 74 - vendor/github.com/Sirupsen/logrus/logger.go | 308 -- vendor/github.com/Sirupsen/logrus/logrus.go | 143 - .../Sirupsen/logrus/terminal_appengine.go | 8 - .../Sirupsen/logrus/terminal_bsd.go | 10 - .../Sirupsen/logrus/terminal_linux.go | 14 - .../Sirupsen/logrus/terminal_notwindows.go | 22 - .../Sirupsen/logrus/terminal_solaris.go | 15 - .../Sirupsen/logrus/terminal_windows.go | 27 - .../Sirupsen/logrus/text_formatter.go | 168 - vendor/github.com/Sirupsen/logrus/writer.go | 53 - .../andybalholm/cascadia/.travis.yml | 14 - .../github.com/andybalholm/cascadia/LICENSE | 24 - .../github.com/andybalholm/cascadia/README.md | 7 - .../github.com/andybalholm/cascadia/parser.go | 835 ----- .../andybalholm/cascadia/selector.go | 622 ---- vendor/github.com/antonmedv/expr/.gitignore | 7 - vendor/github.com/antonmedv/expr/.travis.yml | 3 - vendor/github.com/antonmedv/expr/LICENSE | 21 - vendor/github.com/antonmedv/expr/README.md | 163 - vendor/github.com/antonmedv/expr/ast/node.go | 171 - vendor/github.com/antonmedv/expr/ast/print.go | 59 - .../github.com/antonmedv/expr/ast/visitor.go | 108 - .../antonmedv/expr/checker/checker.go | 615 ---- .../antonmedv/expr/checker/types.go | 349 -- .../antonmedv/expr/compiler/compiler.go | 673 ---- .../antonmedv/expr/compiler/patcher.go | 44 - .../github.com/antonmedv/expr/conf/config.go | 89 - .../antonmedv/expr/conf/operators_table.go | 26 - .../antonmedv/expr/conf/types_table.go | 100 - vendor/github.com/antonmedv/expr/expr.go | 187 - .../github.com/antonmedv/expr/file/error.go | 58 - .../antonmedv/expr/file/location.go | 10 - .../github.com/antonmedv/expr/file/source.go | 95 - .../antonmedv/expr/optimizer/const_expr.go | 77 - .../antonmedv/expr/optimizer/const_range.go | 41 - .../antonmedv/expr/optimizer/fold.go | 133 - .../antonmedv/expr/optimizer/in_array.go | 65 - .../antonmedv/expr/optimizer/in_range.go | 41 - .../antonmedv/expr/optimizer/optimizer.go | 37 - .../antonmedv/expr/parser/lexer/lexer.go | 212 -- .../antonmedv/expr/parser/lexer/state.go | 148 - .../antonmedv/expr/parser/lexer/token.go | 47 - .../antonmedv/expr/parser/lexer/utils.go | 194 - .../antonmedv/expr/parser/parser.go | 588 --- .../github.com/antonmedv/expr/vm/helpers.go | 3247 ---------------- .../github.com/antonmedv/expr/vm/opcodes.go | 56 - .../github.com/antonmedv/expr/vm/program.go | 225 -- .../github.com/antonmedv/expr/vm/runtime.go | 370 -- vendor/github.com/antonmedv/expr/vm/vm.go | 484 --- vendor/github.com/aymerick/douceur/LICENSE | 22 - .../aymerick/douceur/css/declaration.go | 60 - .../github.com/aymerick/douceur/css/rule.go | 230 -- .../aymerick/douceur/css/stylesheet.go | 25 - .../aymerick/douceur/inliner/element.go | 181 - .../aymerick/douceur/inliner/inliner.go | 243 -- .../douceur/inliner/style_declaration.go | 26 - .../aymerick/douceur/inliner/style_rule.go | 87 - .../aymerick/douceur/parser/parser.go | 409 --- .../github.com/aymerick/raymond/.gitmodules | 3 - .../github.com/aymerick/raymond/.travis.yml | 10 - .../github.com/aymerick/raymond/BENCHMARKS.md | 46 - .../github.com/aymerick/raymond/CHANGELOG.md | 33 - vendor/github.com/aymerick/raymond/LICENSE | 22 - vendor/github.com/aymerick/raymond/README.md | 1417 ------- vendor/github.com/aymerick/raymond/VERSION | 1 - .../github.com/aymerick/raymond/ast/node.go | 785 ---- .../github.com/aymerick/raymond/ast/print.go | 279 -- .../github.com/aymerick/raymond/data_frame.go | 95 - vendor/github.com/aymerick/raymond/escape.go | 65 - vendor/github.com/aymerick/raymond/eval.go | 1005 ----- vendor/github.com/aymerick/raymond/helper.go | 382 -- .../aymerick/raymond/lexer/lexer.go | 639 ---- .../aymerick/raymond/lexer/token.go | 183 - .../aymerick/raymond/parser/parser.go | 846 ----- .../aymerick/raymond/parser/whitespace.go | 360 -- vendor/github.com/aymerick/raymond/partial.go | 85 - vendor/github.com/aymerick/raymond/raymond.go | 28 - .../github.com/aymerick/raymond/raymond.png | Bin 13661 -> 0 bytes vendor/github.com/aymerick/raymond/string.go | 84 - .../github.com/aymerick/raymond/template.go | 248 -- vendor/github.com/aymerick/raymond/utils.go | 85 - vendor/github.com/drone/drone-go/LICENSE | 202 - .../drone/drone-go/template/template.go | 128 - vendor/github.com/gorilla/css/LICENSE | 27 - vendor/github.com/gorilla/css/scanner/doc.go | 33 - .../github.com/gorilla/css/scanner/scanner.go | 348 -- .../github.com/jaytaylor/html2text/.gitignore | 24 - .../jaytaylor/html2text/.travis.yml | 13 - vendor/github.com/jaytaylor/html2text/LICENSE | 22 - .../github.com/jaytaylor/html2text/README.md | 116 - .../jaytaylor/html2text/html2text.go | 300 -- vendor/github.com/joho/godotenv/.gitignore | 1 - vendor/github.com/joho/godotenv/LICENCE | 23 - vendor/github.com/joho/godotenv/README.md | 127 - vendor/github.com/joho/godotenv/godotenv.go | 235 -- vendor/github.com/joho/godotenv/wercker.yml | 1 - vendor/github.com/urfave/cli/.gitignore | 2 - vendor/github.com/urfave/cli/.travis.yml | 39 - vendor/github.com/urfave/cli/CHANGELOG.md | 392 -- vendor/github.com/urfave/cli/LICENSE | 21 - vendor/github.com/urfave/cli/README.md | 1364 ------- vendor/github.com/urfave/cli/app.go | 492 --- vendor/github.com/urfave/cli/appveyor.yml | 24 - vendor/github.com/urfave/cli/category.go | 44 - vendor/github.com/urfave/cli/cli.go | 21 - vendor/github.com/urfave/cli/command.go | 286 -- vendor/github.com/urfave/cli/context.go | 276 -- vendor/github.com/urfave/cli/errors.go | 110 - vendor/github.com/urfave/cli/flag-types.json | 93 - vendor/github.com/urfave/cli/flag.go | 799 ---- .../github.com/urfave/cli/flag_generated.go | 627 ---- vendor/github.com/urfave/cli/funcs.go | 28 - .../github.com/urfave/cli/generate-flag-types | 255 -- vendor/github.com/urfave/cli/help.go | 294 -- vendor/github.com/urfave/cli/runtests | 122 - vendor/golang.org/x/net/AUTHORS | 3 - vendor/golang.org/x/net/CONTRIBUTORS | 3 - vendor/golang.org/x/net/LICENSE | 27 - vendor/golang.org/x/net/PATENTS | 22 - vendor/golang.org/x/net/html/atom/atom.go | 78 - vendor/golang.org/x/net/html/atom/table.go | 713 ---- vendor/golang.org/x/net/html/const.go | 102 - vendor/golang.org/x/net/html/doc.go | 106 - vendor/golang.org/x/net/html/doctype.go | 156 - vendor/golang.org/x/net/html/entity.go | 2253 ------------ vendor/golang.org/x/net/html/escape.go | 258 -- vendor/golang.org/x/net/html/foreign.go | 226 -- vendor/golang.org/x/net/html/node.go | 193 - vendor/golang.org/x/net/html/parse.go | 2094 ----------- vendor/golang.org/x/net/html/render.go | 271 -- vendor/golang.org/x/net/html/token.go | 1219 ------ vendor/golang.org/x/sys/AUTHORS | 3 - vendor/golang.org/x/sys/CONTRIBUTORS | 3 - vendor/golang.org/x/sys/LICENSE | 27 - vendor/golang.org/x/sys/PATENTS | 22 - vendor/golang.org/x/sys/unix/.gitignore | 2 - vendor/golang.org/x/sys/unix/README.md | 173 - .../golang.org/x/sys/unix/affinity_linux.go | 86 - vendor/golang.org/x/sys/unix/aliases.go | 14 - vendor/golang.org/x/sys/unix/asm_aix_ppc64.s | 17 - vendor/golang.org/x/sys/unix/asm_darwin_386.s | 29 - .../golang.org/x/sys/unix/asm_darwin_amd64.s | 29 - vendor/golang.org/x/sys/unix/asm_darwin_arm.s | 30 - .../golang.org/x/sys/unix/asm_darwin_arm64.s | 30 - .../x/sys/unix/asm_dragonfly_amd64.s | 29 - .../golang.org/x/sys/unix/asm_freebsd_386.s | 29 - .../golang.org/x/sys/unix/asm_freebsd_amd64.s | 29 - .../golang.org/x/sys/unix/asm_freebsd_arm.s | 29 - .../golang.org/x/sys/unix/asm_freebsd_arm64.s | 29 - vendor/golang.org/x/sys/unix/asm_linux_386.s | 65 - .../golang.org/x/sys/unix/asm_linux_amd64.s | 57 - vendor/golang.org/x/sys/unix/asm_linux_arm.s | 56 - .../golang.org/x/sys/unix/asm_linux_arm64.s | 52 - .../golang.org/x/sys/unix/asm_linux_mips64x.s | 56 - .../golang.org/x/sys/unix/asm_linux_mipsx.s | 54 - .../golang.org/x/sys/unix/asm_linux_ppc64x.s | 44 - .../golang.org/x/sys/unix/asm_linux_riscv64.s | 47 - .../golang.org/x/sys/unix/asm_linux_s390x.s | 56 - vendor/golang.org/x/sys/unix/asm_netbsd_386.s | 29 - .../golang.org/x/sys/unix/asm_netbsd_amd64.s | 29 - vendor/golang.org/x/sys/unix/asm_netbsd_arm.s | 29 - .../golang.org/x/sys/unix/asm_netbsd_arm64.s | 29 - .../golang.org/x/sys/unix/asm_openbsd_386.s | 29 - .../golang.org/x/sys/unix/asm_openbsd_amd64.s | 29 - .../golang.org/x/sys/unix/asm_openbsd_arm.s | 29 - .../golang.org/x/sys/unix/asm_openbsd_arm64.s | 29 - .../golang.org/x/sys/unix/asm_solaris_amd64.s | 17 - .../golang.org/x/sys/unix/bluetooth_linux.go | 36 - vendor/golang.org/x/sys/unix/cap_freebsd.go | 195 - vendor/golang.org/x/sys/unix/constants.go | 13 - vendor/golang.org/x/sys/unix/dev_aix_ppc.go | 27 - vendor/golang.org/x/sys/unix/dev_aix_ppc64.go | 29 - vendor/golang.org/x/sys/unix/dev_darwin.go | 24 - vendor/golang.org/x/sys/unix/dev_dragonfly.go | 30 - vendor/golang.org/x/sys/unix/dev_freebsd.go | 30 - vendor/golang.org/x/sys/unix/dev_linux.go | 42 - vendor/golang.org/x/sys/unix/dev_netbsd.go | 29 - vendor/golang.org/x/sys/unix/dev_openbsd.go | 29 - vendor/golang.org/x/sys/unix/dirent.go | 102 - vendor/golang.org/x/sys/unix/endian_big.go | 9 - vendor/golang.org/x/sys/unix/endian_little.go | 9 - vendor/golang.org/x/sys/unix/env_unix.go | 31 - .../x/sys/unix/errors_freebsd_386.go | 227 -- .../x/sys/unix/errors_freebsd_amd64.go | 227 -- .../x/sys/unix/errors_freebsd_arm.go | 226 -- vendor/golang.org/x/sys/unix/fcntl.go | 36 - vendor/golang.org/x/sys/unix/fcntl_darwin.go | 18 - .../x/sys/unix/fcntl_linux_32bit.go | 13 - vendor/golang.org/x/sys/unix/fdset.go | 29 - vendor/golang.org/x/sys/unix/gccgo.go | 62 - vendor/golang.org/x/sys/unix/gccgo_c.c | 39 - .../x/sys/unix/gccgo_linux_amd64.go | 20 - vendor/golang.org/x/sys/unix/ioctl.go | 65 - vendor/golang.org/x/sys/unix/mkall.sh | 229 -- vendor/golang.org/x/sys/unix/mkerrors.sh | 692 ---- vendor/golang.org/x/sys/unix/pagesize_unix.go | 15 - .../golang.org/x/sys/unix/pledge_openbsd.go | 163 - vendor/golang.org/x/sys/unix/race.go | 30 - vendor/golang.org/x/sys/unix/race0.go | 25 - .../x/sys/unix/readdirent_getdents.go | 12 - .../x/sys/unix/readdirent_getdirentries.go | 19 - .../x/sys/unix/sockcmsg_dragonfly.go | 16 - .../golang.org/x/sys/unix/sockcmsg_linux.go | 36 - vendor/golang.org/x/sys/unix/sockcmsg_unix.go | 92 - .../x/sys/unix/sockcmsg_unix_other.go | 38 - vendor/golang.org/x/sys/unix/str.go | 26 - vendor/golang.org/x/sys/unix/syscall.go | 53 - vendor/golang.org/x/sys/unix/syscall_aix.go | 536 --- .../golang.org/x/sys/unix/syscall_aix_ppc.go | 54 - .../x/sys/unix/syscall_aix_ppc64.go | 85 - vendor/golang.org/x/sys/unix/syscall_bsd.go | 631 ---- .../x/sys/unix/syscall_darwin.1_12.go | 29 - .../x/sys/unix/syscall_darwin.1_13.go | 101 - .../golang.org/x/sys/unix/syscall_darwin.go | 667 ---- .../x/sys/unix/syscall_darwin_386.1_11.go | 9 - .../x/sys/unix/syscall_darwin_386.go | 68 - .../x/sys/unix/syscall_darwin_amd64.1_11.go | 9 - .../x/sys/unix/syscall_darwin_amd64.go | 68 - .../x/sys/unix/syscall_darwin_arm.1_11.go | 11 - .../x/sys/unix/syscall_darwin_arm.go | 68 - .../x/sys/unix/syscall_darwin_arm64.1_11.go | 11 - .../x/sys/unix/syscall_darwin_arm64.go | 70 - .../x/sys/unix/syscall_darwin_libSystem.go | 33 - .../x/sys/unix/syscall_dragonfly.go | 539 --- .../x/sys/unix/syscall_dragonfly_amd64.go | 56 - .../golang.org/x/sys/unix/syscall_freebsd.go | 878 ----- .../x/sys/unix/syscall_freebsd_386.go | 62 - .../x/sys/unix/syscall_freebsd_amd64.go | 62 - .../x/sys/unix/syscall_freebsd_arm.go | 62 - .../x/sys/unix/syscall_freebsd_arm64.go | 62 - vendor/golang.org/x/sys/unix/syscall_linux.go | 2124 ----------- .../x/sys/unix/syscall_linux_386.go | 390 -- .../x/sys/unix/syscall_linux_amd64.go | 194 - .../x/sys/unix/syscall_linux_amd64_gc.go | 13 - .../x/sys/unix/syscall_linux_arm.go | 291 -- .../x/sys/unix/syscall_linux_arm64.go | 227 -- .../golang.org/x/sys/unix/syscall_linux_gc.go | 14 - .../x/sys/unix/syscall_linux_gc_386.go | 16 - .../x/sys/unix/syscall_linux_gccgo_386.go | 30 - .../x/sys/unix/syscall_linux_gccgo_arm.go | 20 - .../x/sys/unix/syscall_linux_mips64x.go | 231 -- .../x/sys/unix/syscall_linux_mipsx.go | 238 -- .../x/sys/unix/syscall_linux_ppc64x.go | 156 - .../x/sys/unix/syscall_linux_riscv64.go | 230 -- .../x/sys/unix/syscall_linux_s390x.go | 342 -- .../x/sys/unix/syscall_linux_sparc64.go | 151 - .../golang.org/x/sys/unix/syscall_netbsd.go | 614 ---- .../x/sys/unix/syscall_netbsd_386.go | 37 - .../x/sys/unix/syscall_netbsd_amd64.go | 37 - .../x/sys/unix/syscall_netbsd_arm.go | 37 - .../x/sys/unix/syscall_netbsd_arm64.go | 37 - .../golang.org/x/sys/unix/syscall_openbsd.go | 401 -- .../x/sys/unix/syscall_openbsd_386.go | 41 - .../x/sys/unix/syscall_openbsd_amd64.go | 41 - .../x/sys/unix/syscall_openbsd_arm.go | 41 - .../x/sys/unix/syscall_openbsd_arm64.go | 41 - .../golang.org/x/sys/unix/syscall_solaris.go | 724 ---- .../x/sys/unix/syscall_solaris_amd64.go | 27 - vendor/golang.org/x/sys/unix/syscall_unix.go | 431 --- .../golang.org/x/sys/unix/syscall_unix_gc.go | 15 - .../x/sys/unix/syscall_unix_gc_ppc64x.go | 24 - vendor/golang.org/x/sys/unix/timestruct.go | 82 - .../golang.org/x/sys/unix/unveil_openbsd.go | 42 - vendor/golang.org/x/sys/unix/xattr_bsd.go | 240 -- .../golang.org/x/sys/unix/zerrors_aix_ppc.go | 1384 ------- .../x/sys/unix/zerrors_aix_ppc64.go | 1385 ------- .../x/sys/unix/zerrors_darwin_386.go | 1784 --------- .../x/sys/unix/zerrors_darwin_amd64.go | 1784 --------- .../x/sys/unix/zerrors_darwin_arm.go | 1784 --------- .../x/sys/unix/zerrors_darwin_arm64.go | 1784 --------- .../x/sys/unix/zerrors_dragonfly_amd64.go | 1651 --------- .../x/sys/unix/zerrors_freebsd_386.go | 1794 --------- .../x/sys/unix/zerrors_freebsd_amd64.go | 1795 --------- .../x/sys/unix/zerrors_freebsd_arm.go | 1803 --------- .../x/sys/unix/zerrors_freebsd_arm64.go | 1795 --------- .../x/sys/unix/zerrors_linux_386.go | 3202 ---------------- .../x/sys/unix/zerrors_linux_amd64.go | 3202 ---------------- .../x/sys/unix/zerrors_linux_arm.go | 3208 ---------------- .../x/sys/unix/zerrors_linux_arm64.go | 3195 ---------------- .../x/sys/unix/zerrors_linux_mips.go | 3209 ---------------- .../x/sys/unix/zerrors_linux_mips64.go | 3209 ---------------- .../x/sys/unix/zerrors_linux_mips64le.go | 3209 ---------------- .../x/sys/unix/zerrors_linux_mipsle.go | 3209 ---------------- .../x/sys/unix/zerrors_linux_ppc64.go | 3265 ----------------- .../x/sys/unix/zerrors_linux_ppc64le.go | 3265 ----------------- .../x/sys/unix/zerrors_linux_riscv64.go | 3189 ---------------- .../x/sys/unix/zerrors_linux_s390x.go | 3262 ---------------- .../x/sys/unix/zerrors_linux_sparc64.go | 3259 ---------------- .../x/sys/unix/zerrors_netbsd_386.go | 1773 --------- .../x/sys/unix/zerrors_netbsd_amd64.go | 1763 --------- .../x/sys/unix/zerrors_netbsd_arm.go | 1752 --------- .../x/sys/unix/zerrors_netbsd_arm64.go | 1763 --------- .../x/sys/unix/zerrors_openbsd_386.go | 1657 --------- .../x/sys/unix/zerrors_openbsd_amd64.go | 1767 --------- .../x/sys/unix/zerrors_openbsd_arm.go | 1659 --------- .../x/sys/unix/zerrors_openbsd_arm64.go | 1790 --------- .../x/sys/unix/zerrors_solaris_amd64.go | 1533 -------- .../x/sys/unix/zptrace_armnn_linux.go | 41 - .../x/sys/unix/zptrace_linux_arm64.go | 17 - .../x/sys/unix/zptrace_mipsnn_linux.go | 50 - .../x/sys/unix/zptrace_mipsnnle_linux.go | 50 - .../x/sys/unix/zptrace_x86_linux.go | 80 - .../golang.org/x/sys/unix/zsyscall_aix_ppc.go | 1484 -------- .../x/sys/unix/zsyscall_aix_ppc64.go | 1442 -------- .../x/sys/unix/zsyscall_aix_ppc64_gc.go | 1192 ------ .../x/sys/unix/zsyscall_aix_ppc64_gccgo.go | 1070 ------ .../x/sys/unix/zsyscall_darwin_386.1_11.go | 1811 --------- .../x/sys/unix/zsyscall_darwin_386.1_13.go | 41 - .../x/sys/unix/zsyscall_darwin_386.1_13.s | 12 - .../x/sys/unix/zsyscall_darwin_386.go | 2499 ------------- .../x/sys/unix/zsyscall_darwin_386.s | 284 -- .../x/sys/unix/zsyscall_darwin_amd64.1_11.go | 1811 --------- .../x/sys/unix/zsyscall_darwin_amd64.1_13.go | 41 - .../x/sys/unix/zsyscall_darwin_amd64.1_13.s | 12 - .../x/sys/unix/zsyscall_darwin_amd64.go | 2499 ------------- .../x/sys/unix/zsyscall_darwin_amd64.s | 284 -- .../x/sys/unix/zsyscall_darwin_arm.1_11.go | 1784 --------- .../x/sys/unix/zsyscall_darwin_arm.1_13.go | 41 - .../x/sys/unix/zsyscall_darwin_arm.1_13.s | 12 - .../x/sys/unix/zsyscall_darwin_arm.go | 2484 ------------- .../x/sys/unix/zsyscall_darwin_arm.s | 282 -- .../x/sys/unix/zsyscall_darwin_arm64.1_11.go | 1784 --------- .../x/sys/unix/zsyscall_darwin_arm64.1_13.go | 41 - .../x/sys/unix/zsyscall_darwin_arm64.1_13.s | 12 - .../x/sys/unix/zsyscall_darwin_arm64.go | 2484 ------------- .../x/sys/unix/zsyscall_darwin_arm64.s | 282 -- .../x/sys/unix/zsyscall_dragonfly_amd64.go | 1666 --------- .../x/sys/unix/zsyscall_freebsd_386.go | 2015 ---------- .../x/sys/unix/zsyscall_freebsd_amd64.go | 2015 ---------- .../x/sys/unix/zsyscall_freebsd_arm.go | 2015 ---------- .../x/sys/unix/zsyscall_freebsd_arm64.go | 2015 ---------- .../x/sys/unix/zsyscall_linux_386.go | 2393 ------------ .../x/sys/unix/zsyscall_linux_amd64.go | 2560 ------------- .../x/sys/unix/zsyscall_linux_arm.go | 2530 ------------- .../x/sys/unix/zsyscall_linux_arm64.go | 2417 ------------ .../x/sys/unix/zsyscall_linux_mips.go | 2573 ------------- .../x/sys/unix/zsyscall_linux_mips64.go | 2544 ------------- .../x/sys/unix/zsyscall_linux_mips64le.go | 2544 ------------- .../x/sys/unix/zsyscall_linux_mipsle.go | 2573 ------------- .../x/sys/unix/zsyscall_linux_ppc64.go | 2622 ------------- .../x/sys/unix/zsyscall_linux_ppc64le.go | 2622 ------------- .../x/sys/unix/zsyscall_linux_riscv64.go | 2397 ------------ .../x/sys/unix/zsyscall_linux_s390x.go | 2392 ------------ .../x/sys/unix/zsyscall_linux_sparc64.go | 2555 ------------- .../x/sys/unix/zsyscall_netbsd_386.go | 1851 ---------- .../x/sys/unix/zsyscall_netbsd_amd64.go | 1851 ---------- .../x/sys/unix/zsyscall_netbsd_arm.go | 1851 ---------- .../x/sys/unix/zsyscall_netbsd_arm64.go | 1851 ---------- .../x/sys/unix/zsyscall_openbsd_386.go | 1692 --------- .../x/sys/unix/zsyscall_openbsd_amd64.go | 1692 --------- .../x/sys/unix/zsyscall_openbsd_arm.go | 1692 --------- .../x/sys/unix/zsyscall_openbsd_arm64.go | 1692 --------- .../x/sys/unix/zsyscall_solaris_amd64.go | 1954 ---------- .../x/sys/unix/zsysctl_openbsd_386.go | 272 -- .../x/sys/unix/zsysctl_openbsd_amd64.go | 270 -- .../x/sys/unix/zsysctl_openbsd_arm.go | 272 -- .../x/sys/unix/zsysctl_openbsd_arm64.go | 275 -- .../x/sys/unix/zsysnum_darwin_386.go | 436 --- .../x/sys/unix/zsysnum_darwin_amd64.go | 438 --- .../x/sys/unix/zsysnum_darwin_arm.go | 436 --- .../x/sys/unix/zsysnum_darwin_arm64.go | 436 --- .../x/sys/unix/zsysnum_dragonfly_amd64.go | 315 -- .../x/sys/unix/zsysnum_freebsd_386.go | 396 -- .../x/sys/unix/zsysnum_freebsd_amd64.go | 396 -- .../x/sys/unix/zsysnum_freebsd_arm.go | 396 -- .../x/sys/unix/zsysnum_freebsd_arm64.go | 396 -- .../x/sys/unix/zsysnum_linux_386.go | 434 --- .../x/sys/unix/zsysnum_linux_amd64.go | 356 -- .../x/sys/unix/zsysnum_linux_arm.go | 398 -- .../x/sys/unix/zsysnum_linux_arm64.go | 301 -- .../x/sys/unix/zsysnum_linux_mips.go | 419 --- .../x/sys/unix/zsysnum_linux_mips64.go | 349 -- .../x/sys/unix/zsysnum_linux_mips64le.go | 349 -- .../x/sys/unix/zsysnum_linux_mipsle.go | 419 --- .../x/sys/unix/zsysnum_linux_ppc64.go | 398 -- .../x/sys/unix/zsysnum_linux_ppc64le.go | 398 -- .../x/sys/unix/zsysnum_linux_riscv64.go | 300 -- .../x/sys/unix/zsysnum_linux_s390x.go | 363 -- .../x/sys/unix/zsysnum_linux_sparc64.go | 377 -- .../x/sys/unix/zsysnum_netbsd_386.go | 274 -- .../x/sys/unix/zsysnum_netbsd_amd64.go | 274 -- .../x/sys/unix/zsysnum_netbsd_arm.go | 274 -- .../x/sys/unix/zsysnum_netbsd_arm64.go | 274 -- .../x/sys/unix/zsysnum_openbsd_386.go | 218 -- .../x/sys/unix/zsysnum_openbsd_amd64.go | 218 -- .../x/sys/unix/zsysnum_openbsd_arm.go | 218 -- .../x/sys/unix/zsysnum_openbsd_arm64.go | 217 -- .../golang.org/x/sys/unix/ztypes_aix_ppc.go | 352 -- .../golang.org/x/sys/unix/ztypes_aix_ppc64.go | 356 -- .../x/sys/unix/ztypes_darwin_386.go | 499 --- .../x/sys/unix/ztypes_darwin_amd64.go | 509 --- .../x/sys/unix/ztypes_darwin_arm.go | 500 --- .../x/sys/unix/ztypes_darwin_arm64.go | 509 --- .../x/sys/unix/ztypes_dragonfly_amd64.go | 479 --- .../x/sys/unix/ztypes_freebsd_386.go | 710 ---- .../x/sys/unix/ztypes_freebsd_amd64.go | 716 ---- .../x/sys/unix/ztypes_freebsd_arm.go | 693 ---- .../x/sys/unix/ztypes_freebsd_arm64.go | 694 ---- .../golang.org/x/sys/unix/ztypes_linux_386.go | 2808 -------------- .../x/sys/unix/ztypes_linux_amd64.go | 2823 -------------- .../golang.org/x/sys/unix/ztypes_linux_arm.go | 2800 -------------- .../x/sys/unix/ztypes_linux_arm64.go | 2802 -------------- .../x/sys/unix/ztypes_linux_mips.go | 2806 -------------- .../x/sys/unix/ztypes_linux_mips64.go | 2805 -------------- .../x/sys/unix/ztypes_linux_mips64le.go | 2805 -------------- .../x/sys/unix/ztypes_linux_mipsle.go | 2806 -------------- .../x/sys/unix/ztypes_linux_ppc64.go | 2812 -------------- .../x/sys/unix/ztypes_linux_ppc64le.go | 2812 -------------- .../x/sys/unix/ztypes_linux_riscv64.go | 2830 -------------- .../x/sys/unix/ztypes_linux_s390x.go | 2826 -------------- .../x/sys/unix/ztypes_linux_sparc64.go | 2807 -------------- .../x/sys/unix/ztypes_netbsd_386.go | 498 --- .../x/sys/unix/ztypes_netbsd_amd64.go | 506 --- .../x/sys/unix/ztypes_netbsd_arm.go | 503 --- .../x/sys/unix/ztypes_netbsd_arm64.go | 506 --- .../x/sys/unix/ztypes_openbsd_386.go | 571 --- .../x/sys/unix/ztypes_openbsd_amd64.go | 571 --- .../x/sys/unix/ztypes_openbsd_arm.go | 572 --- .../x/sys/unix/ztypes_openbsd_arm64.go | 565 --- .../x/sys/unix/ztypes_solaris_amd64.go | 449 --- .../alexcesaro/quotedprintable.v3/LICENSE | 20 - .../alexcesaro/quotedprintable.v3/README.md | 16 - .../quotedprintable.v3/encodedword.go | 279 -- .../alexcesaro/quotedprintable.v3/pool.go | 26 - .../quotedprintable.v3/pool_go12.go | 24 - .../alexcesaro/quotedprintable.v3/reader.go | 121 - .../alexcesaro/quotedprintable.v3/writer.go | 166 - vendor/gopkg.in/mail.v2/.gitignore | 17 - vendor/gopkg.in/mail.v2/.travis.yml | 25 - vendor/gopkg.in/mail.v2/CHANGELOG.md | 88 - vendor/gopkg.in/mail.v2/CONTRIBUTING.md | 20 - vendor/gopkg.in/mail.v2/LICENSE | 20 - vendor/gopkg.in/mail.v2/README.md | 129 - vendor/gopkg.in/mail.v2/auth.go | 49 - vendor/gopkg.in/mail.v2/doc.go | 6 - vendor/gopkg.in/mail.v2/errors.go | 16 - vendor/gopkg.in/mail.v2/message.go | 359 -- vendor/gopkg.in/mail.v2/mime.go | 21 - vendor/gopkg.in/mail.v2/mime_go14.go | 25 - vendor/gopkg.in/mail.v2/send.go | 116 - vendor/gopkg.in/mail.v2/smtp.go | 292 -- vendor/gopkg.in/mail.v2/writeto.go | 313 -- vendor/modules.txt | 64 - 496 files changed, 706 insertions(+), 274792 deletions(-) delete mode 100644 CHANGELOG.md delete mode 100644 Dockerfile.armhf delete mode 100644 LICENSE delete mode 100644 MAINTAINERS delete mode 100644 Makefile create mode 100755 bin/console create mode 100644 composer.json delete mode 100644 defaults.go delete mode 100644 go.mod delete mode 100644 go.sum delete mode 100644 main.go delete mode 100644 plugin.go create mode 100644 src/Factory/EmailFactory.php create mode 100644 src/Factory/TwigFactory.php create mode 100644 src/Loader/EnvVarLoader.php create mode 100644 src/Loader/functions.php create mode 100644 src/Pipeline/Evaluation.php create mode 100644 templates/_base.html.twig create mode 100644 templates/build_status.html.twig delete mode 100644 vendor/github.com/PuerkitoBio/goquery/.gitattributes delete mode 100644 vendor/github.com/PuerkitoBio/goquery/.gitignore delete mode 100644 vendor/github.com/PuerkitoBio/goquery/.travis.yml delete mode 100644 vendor/github.com/PuerkitoBio/goquery/LICENSE delete mode 100644 vendor/github.com/PuerkitoBio/goquery/README.md delete mode 100644 vendor/github.com/PuerkitoBio/goquery/array.go delete mode 100644 vendor/github.com/PuerkitoBio/goquery/doc.go delete mode 100644 vendor/github.com/PuerkitoBio/goquery/expand.go delete mode 100644 vendor/github.com/PuerkitoBio/goquery/filter.go delete mode 100644 vendor/github.com/PuerkitoBio/goquery/iteration.go delete mode 100644 vendor/github.com/PuerkitoBio/goquery/manipulation.go delete mode 100644 vendor/github.com/PuerkitoBio/goquery/property.go delete mode 100644 vendor/github.com/PuerkitoBio/goquery/query.go delete mode 100644 vendor/github.com/PuerkitoBio/goquery/traversal.go delete mode 100644 vendor/github.com/PuerkitoBio/goquery/type.go delete mode 100644 vendor/github.com/PuerkitoBio/goquery/utilities.go delete mode 100644 vendor/github.com/Sirupsen/logrus/.gitignore delete mode 100644 vendor/github.com/Sirupsen/logrus/.travis.yml delete mode 100644 vendor/github.com/Sirupsen/logrus/CHANGELOG.md delete mode 100644 vendor/github.com/Sirupsen/logrus/LICENSE delete mode 100644 vendor/github.com/Sirupsen/logrus/README.md delete mode 100644 vendor/github.com/Sirupsen/logrus/alt_exit.go delete mode 100644 vendor/github.com/Sirupsen/logrus/doc.go delete mode 100644 vendor/github.com/Sirupsen/logrus/entry.go delete mode 100644 vendor/github.com/Sirupsen/logrus/exported.go delete mode 100644 vendor/github.com/Sirupsen/logrus/formatter.go delete mode 100644 vendor/github.com/Sirupsen/logrus/hooks.go delete mode 100644 vendor/github.com/Sirupsen/logrus/json_formatter.go delete mode 100644 vendor/github.com/Sirupsen/logrus/logger.go delete mode 100644 vendor/github.com/Sirupsen/logrus/logrus.go delete mode 100644 vendor/github.com/Sirupsen/logrus/terminal_appengine.go delete mode 100644 vendor/github.com/Sirupsen/logrus/terminal_bsd.go delete mode 100644 vendor/github.com/Sirupsen/logrus/terminal_linux.go delete mode 100644 vendor/github.com/Sirupsen/logrus/terminal_notwindows.go delete mode 100644 vendor/github.com/Sirupsen/logrus/terminal_solaris.go delete mode 100644 vendor/github.com/Sirupsen/logrus/terminal_windows.go delete mode 100644 vendor/github.com/Sirupsen/logrus/text_formatter.go delete mode 100644 vendor/github.com/Sirupsen/logrus/writer.go delete mode 100644 vendor/github.com/andybalholm/cascadia/.travis.yml delete mode 100644 vendor/github.com/andybalholm/cascadia/LICENSE delete mode 100644 vendor/github.com/andybalholm/cascadia/README.md delete mode 100644 vendor/github.com/andybalholm/cascadia/parser.go delete mode 100644 vendor/github.com/andybalholm/cascadia/selector.go delete mode 100644 vendor/github.com/antonmedv/expr/.gitignore delete mode 100644 vendor/github.com/antonmedv/expr/.travis.yml delete mode 100644 vendor/github.com/antonmedv/expr/LICENSE delete mode 100644 vendor/github.com/antonmedv/expr/README.md delete mode 100644 vendor/github.com/antonmedv/expr/ast/node.go delete mode 100644 vendor/github.com/antonmedv/expr/ast/print.go delete mode 100644 vendor/github.com/antonmedv/expr/ast/visitor.go delete mode 100644 vendor/github.com/antonmedv/expr/checker/checker.go delete mode 100644 vendor/github.com/antonmedv/expr/checker/types.go delete mode 100644 vendor/github.com/antonmedv/expr/compiler/compiler.go delete mode 100644 vendor/github.com/antonmedv/expr/compiler/patcher.go delete mode 100644 vendor/github.com/antonmedv/expr/conf/config.go delete mode 100644 vendor/github.com/antonmedv/expr/conf/operators_table.go delete mode 100644 vendor/github.com/antonmedv/expr/conf/types_table.go delete mode 100644 vendor/github.com/antonmedv/expr/expr.go delete mode 100644 vendor/github.com/antonmedv/expr/file/error.go delete mode 100644 vendor/github.com/antonmedv/expr/file/location.go delete mode 100644 vendor/github.com/antonmedv/expr/file/source.go delete mode 100644 vendor/github.com/antonmedv/expr/optimizer/const_expr.go delete mode 100644 vendor/github.com/antonmedv/expr/optimizer/const_range.go delete mode 100644 vendor/github.com/antonmedv/expr/optimizer/fold.go delete mode 100644 vendor/github.com/antonmedv/expr/optimizer/in_array.go delete mode 100644 vendor/github.com/antonmedv/expr/optimizer/in_range.go delete mode 100644 vendor/github.com/antonmedv/expr/optimizer/optimizer.go delete mode 100644 vendor/github.com/antonmedv/expr/parser/lexer/lexer.go delete mode 100644 vendor/github.com/antonmedv/expr/parser/lexer/state.go delete mode 100644 vendor/github.com/antonmedv/expr/parser/lexer/token.go delete mode 100644 vendor/github.com/antonmedv/expr/parser/lexer/utils.go delete mode 100644 vendor/github.com/antonmedv/expr/parser/parser.go delete mode 100644 vendor/github.com/antonmedv/expr/vm/helpers.go delete mode 100644 vendor/github.com/antonmedv/expr/vm/opcodes.go delete mode 100644 vendor/github.com/antonmedv/expr/vm/program.go delete mode 100644 vendor/github.com/antonmedv/expr/vm/runtime.go delete mode 100644 vendor/github.com/antonmedv/expr/vm/vm.go delete mode 100644 vendor/github.com/aymerick/douceur/LICENSE delete mode 100644 vendor/github.com/aymerick/douceur/css/declaration.go delete mode 100644 vendor/github.com/aymerick/douceur/css/rule.go delete mode 100644 vendor/github.com/aymerick/douceur/css/stylesheet.go delete mode 100644 vendor/github.com/aymerick/douceur/inliner/element.go delete mode 100644 vendor/github.com/aymerick/douceur/inliner/inliner.go delete mode 100644 vendor/github.com/aymerick/douceur/inliner/style_declaration.go delete mode 100644 vendor/github.com/aymerick/douceur/inliner/style_rule.go delete mode 100644 vendor/github.com/aymerick/douceur/parser/parser.go delete mode 100644 vendor/github.com/aymerick/raymond/.gitmodules delete mode 100644 vendor/github.com/aymerick/raymond/.travis.yml delete mode 100644 vendor/github.com/aymerick/raymond/BENCHMARKS.md delete mode 100644 vendor/github.com/aymerick/raymond/CHANGELOG.md delete mode 100644 vendor/github.com/aymerick/raymond/LICENSE delete mode 100644 vendor/github.com/aymerick/raymond/README.md delete mode 100644 vendor/github.com/aymerick/raymond/VERSION delete mode 100644 vendor/github.com/aymerick/raymond/ast/node.go delete mode 100644 vendor/github.com/aymerick/raymond/ast/print.go delete mode 100644 vendor/github.com/aymerick/raymond/data_frame.go delete mode 100644 vendor/github.com/aymerick/raymond/escape.go delete mode 100644 vendor/github.com/aymerick/raymond/eval.go delete mode 100644 vendor/github.com/aymerick/raymond/helper.go delete mode 100644 vendor/github.com/aymerick/raymond/lexer/lexer.go delete mode 100644 vendor/github.com/aymerick/raymond/lexer/token.go delete mode 100644 vendor/github.com/aymerick/raymond/parser/parser.go delete mode 100644 vendor/github.com/aymerick/raymond/parser/whitespace.go delete mode 100644 vendor/github.com/aymerick/raymond/partial.go delete mode 100644 vendor/github.com/aymerick/raymond/raymond.go delete mode 100644 vendor/github.com/aymerick/raymond/raymond.png delete mode 100644 vendor/github.com/aymerick/raymond/string.go delete mode 100644 vendor/github.com/aymerick/raymond/template.go delete mode 100644 vendor/github.com/aymerick/raymond/utils.go delete mode 100644 vendor/github.com/drone/drone-go/LICENSE delete mode 100644 vendor/github.com/drone/drone-go/template/template.go delete mode 100644 vendor/github.com/gorilla/css/LICENSE delete mode 100644 vendor/github.com/gorilla/css/scanner/doc.go delete mode 100644 vendor/github.com/gorilla/css/scanner/scanner.go delete mode 100644 vendor/github.com/jaytaylor/html2text/.gitignore delete mode 100644 vendor/github.com/jaytaylor/html2text/.travis.yml delete mode 100644 vendor/github.com/jaytaylor/html2text/LICENSE delete mode 100644 vendor/github.com/jaytaylor/html2text/README.md delete mode 100644 vendor/github.com/jaytaylor/html2text/html2text.go delete mode 100644 vendor/github.com/joho/godotenv/.gitignore delete mode 100644 vendor/github.com/joho/godotenv/LICENCE delete mode 100644 vendor/github.com/joho/godotenv/README.md delete mode 100644 vendor/github.com/joho/godotenv/godotenv.go delete mode 100644 vendor/github.com/joho/godotenv/wercker.yml delete mode 100644 vendor/github.com/urfave/cli/.gitignore delete mode 100644 vendor/github.com/urfave/cli/.travis.yml delete mode 100644 vendor/github.com/urfave/cli/CHANGELOG.md delete mode 100644 vendor/github.com/urfave/cli/LICENSE delete mode 100644 vendor/github.com/urfave/cli/README.md delete mode 100644 vendor/github.com/urfave/cli/app.go delete mode 100644 vendor/github.com/urfave/cli/appveyor.yml delete mode 100644 vendor/github.com/urfave/cli/category.go delete mode 100644 vendor/github.com/urfave/cli/cli.go delete mode 100644 vendor/github.com/urfave/cli/command.go delete mode 100644 vendor/github.com/urfave/cli/context.go delete mode 100644 vendor/github.com/urfave/cli/errors.go delete mode 100644 vendor/github.com/urfave/cli/flag-types.json delete mode 100644 vendor/github.com/urfave/cli/flag.go delete mode 100644 vendor/github.com/urfave/cli/flag_generated.go delete mode 100644 vendor/github.com/urfave/cli/funcs.go delete mode 100644 vendor/github.com/urfave/cli/generate-flag-types delete mode 100644 vendor/github.com/urfave/cli/help.go delete mode 100644 vendor/github.com/urfave/cli/runtests delete mode 100644 vendor/golang.org/x/net/AUTHORS delete mode 100644 vendor/golang.org/x/net/CONTRIBUTORS delete mode 100644 vendor/golang.org/x/net/LICENSE delete mode 100644 vendor/golang.org/x/net/PATENTS delete mode 100644 vendor/golang.org/x/net/html/atom/atom.go delete mode 100644 vendor/golang.org/x/net/html/atom/table.go delete mode 100644 vendor/golang.org/x/net/html/const.go delete mode 100644 vendor/golang.org/x/net/html/doc.go delete mode 100644 vendor/golang.org/x/net/html/doctype.go delete mode 100644 vendor/golang.org/x/net/html/entity.go delete mode 100644 vendor/golang.org/x/net/html/escape.go delete mode 100644 vendor/golang.org/x/net/html/foreign.go delete mode 100644 vendor/golang.org/x/net/html/node.go delete mode 100644 vendor/golang.org/x/net/html/parse.go delete mode 100644 vendor/golang.org/x/net/html/render.go delete mode 100644 vendor/golang.org/x/net/html/token.go delete mode 100644 vendor/golang.org/x/sys/AUTHORS delete mode 100644 vendor/golang.org/x/sys/CONTRIBUTORS delete mode 100644 vendor/golang.org/x/sys/LICENSE delete mode 100644 vendor/golang.org/x/sys/PATENTS delete mode 100644 vendor/golang.org/x/sys/unix/.gitignore delete mode 100644 vendor/golang.org/x/sys/unix/README.md delete mode 100644 vendor/golang.org/x/sys/unix/affinity_linux.go delete mode 100644 vendor/golang.org/x/sys/unix/aliases.go delete mode 100644 vendor/golang.org/x/sys/unix/asm_aix_ppc64.s delete mode 100644 vendor/golang.org/x/sys/unix/asm_darwin_386.s delete mode 100644 vendor/golang.org/x/sys/unix/asm_darwin_amd64.s delete mode 100644 vendor/golang.org/x/sys/unix/asm_darwin_arm.s delete mode 100644 vendor/golang.org/x/sys/unix/asm_darwin_arm64.s delete mode 100644 vendor/golang.org/x/sys/unix/asm_dragonfly_amd64.s delete mode 100644 vendor/golang.org/x/sys/unix/asm_freebsd_386.s delete mode 100644 vendor/golang.org/x/sys/unix/asm_freebsd_amd64.s delete mode 100644 vendor/golang.org/x/sys/unix/asm_freebsd_arm.s delete mode 100644 vendor/golang.org/x/sys/unix/asm_freebsd_arm64.s delete mode 100644 vendor/golang.org/x/sys/unix/asm_linux_386.s delete mode 100644 vendor/golang.org/x/sys/unix/asm_linux_amd64.s delete mode 100644 vendor/golang.org/x/sys/unix/asm_linux_arm.s delete mode 100644 vendor/golang.org/x/sys/unix/asm_linux_arm64.s delete mode 100644 vendor/golang.org/x/sys/unix/asm_linux_mips64x.s delete mode 100644 vendor/golang.org/x/sys/unix/asm_linux_mipsx.s delete mode 100644 vendor/golang.org/x/sys/unix/asm_linux_ppc64x.s delete mode 100644 vendor/golang.org/x/sys/unix/asm_linux_riscv64.s delete mode 100644 vendor/golang.org/x/sys/unix/asm_linux_s390x.s delete mode 100644 vendor/golang.org/x/sys/unix/asm_netbsd_386.s delete mode 100644 vendor/golang.org/x/sys/unix/asm_netbsd_amd64.s delete mode 100644 vendor/golang.org/x/sys/unix/asm_netbsd_arm.s delete mode 100644 vendor/golang.org/x/sys/unix/asm_netbsd_arm64.s delete mode 100644 vendor/golang.org/x/sys/unix/asm_openbsd_386.s delete mode 100644 vendor/golang.org/x/sys/unix/asm_openbsd_amd64.s delete mode 100644 vendor/golang.org/x/sys/unix/asm_openbsd_arm.s delete mode 100644 vendor/golang.org/x/sys/unix/asm_openbsd_arm64.s delete mode 100644 vendor/golang.org/x/sys/unix/asm_solaris_amd64.s delete mode 100644 vendor/golang.org/x/sys/unix/bluetooth_linux.go delete mode 100644 vendor/golang.org/x/sys/unix/cap_freebsd.go delete mode 100644 vendor/golang.org/x/sys/unix/constants.go delete mode 100644 vendor/golang.org/x/sys/unix/dev_aix_ppc.go delete mode 100644 vendor/golang.org/x/sys/unix/dev_aix_ppc64.go delete mode 100644 vendor/golang.org/x/sys/unix/dev_darwin.go delete mode 100644 vendor/golang.org/x/sys/unix/dev_dragonfly.go delete mode 100644 vendor/golang.org/x/sys/unix/dev_freebsd.go delete mode 100644 vendor/golang.org/x/sys/unix/dev_linux.go delete mode 100644 vendor/golang.org/x/sys/unix/dev_netbsd.go delete mode 100644 vendor/golang.org/x/sys/unix/dev_openbsd.go delete mode 100644 vendor/golang.org/x/sys/unix/dirent.go delete mode 100644 vendor/golang.org/x/sys/unix/endian_big.go delete mode 100644 vendor/golang.org/x/sys/unix/endian_little.go delete mode 100644 vendor/golang.org/x/sys/unix/env_unix.go delete mode 100644 vendor/golang.org/x/sys/unix/errors_freebsd_386.go delete mode 100644 vendor/golang.org/x/sys/unix/errors_freebsd_amd64.go delete mode 100644 vendor/golang.org/x/sys/unix/errors_freebsd_arm.go delete mode 100644 vendor/golang.org/x/sys/unix/fcntl.go delete mode 100644 vendor/golang.org/x/sys/unix/fcntl_darwin.go delete mode 100644 vendor/golang.org/x/sys/unix/fcntl_linux_32bit.go delete mode 100644 vendor/golang.org/x/sys/unix/fdset.go delete mode 100644 vendor/golang.org/x/sys/unix/gccgo.go delete mode 100644 vendor/golang.org/x/sys/unix/gccgo_c.c delete mode 100644 vendor/golang.org/x/sys/unix/gccgo_linux_amd64.go delete mode 100644 vendor/golang.org/x/sys/unix/ioctl.go delete mode 100644 vendor/golang.org/x/sys/unix/mkall.sh delete mode 100644 vendor/golang.org/x/sys/unix/mkerrors.sh delete mode 100644 vendor/golang.org/x/sys/unix/pagesize_unix.go delete mode 100644 vendor/golang.org/x/sys/unix/pledge_openbsd.go delete mode 100644 vendor/golang.org/x/sys/unix/race.go delete mode 100644 vendor/golang.org/x/sys/unix/race0.go delete mode 100644 vendor/golang.org/x/sys/unix/readdirent_getdents.go delete mode 100644 vendor/golang.org/x/sys/unix/readdirent_getdirentries.go delete mode 100644 vendor/golang.org/x/sys/unix/sockcmsg_dragonfly.go delete mode 100644 vendor/golang.org/x/sys/unix/sockcmsg_linux.go delete mode 100644 vendor/golang.org/x/sys/unix/sockcmsg_unix.go delete mode 100644 vendor/golang.org/x/sys/unix/sockcmsg_unix_other.go delete mode 100644 vendor/golang.org/x/sys/unix/str.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_aix.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_aix_ppc.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_aix_ppc64.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_bsd.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_darwin.1_12.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_darwin.1_13.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_darwin.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_darwin_386.1_11.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_darwin_386.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_darwin_amd64.1_11.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_darwin_amd64.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_darwin_arm.1_11.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_darwin_arm.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_darwin_arm64.1_11.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_darwin_arm64.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_darwin_libSystem.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_dragonfly.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_dragonfly_amd64.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_freebsd.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_freebsd_386.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_freebsd_amd64.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_freebsd_arm.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_freebsd_arm64.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_linux.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_386.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_amd64.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_amd64_gc.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_arm.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_arm64.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_gc.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_gc_386.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_gccgo_386.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_gccgo_arm.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_mips64x.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_mipsx.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_ppc64x.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_riscv64.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_s390x.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_sparc64.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_netbsd.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_netbsd_386.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_netbsd_amd64.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_netbsd_arm.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_netbsd_arm64.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_openbsd.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_openbsd_386.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_openbsd_amd64.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_openbsd_arm.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_openbsd_arm64.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_solaris.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_solaris_amd64.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_unix.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_unix_gc.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_unix_gc_ppc64x.go delete mode 100644 vendor/golang.org/x/sys/unix/timestruct.go delete mode 100644 vendor/golang.org/x/sys/unix/unveil_openbsd.go delete mode 100644 vendor/golang.org/x/sys/unix/xattr_bsd.go delete mode 100644 vendor/golang.org/x/sys/unix/zerrors_aix_ppc.go delete mode 100644 vendor/golang.org/x/sys/unix/zerrors_aix_ppc64.go delete mode 100644 vendor/golang.org/x/sys/unix/zerrors_darwin_386.go delete mode 100644 vendor/golang.org/x/sys/unix/zerrors_darwin_amd64.go delete mode 100644 vendor/golang.org/x/sys/unix/zerrors_darwin_arm.go delete mode 100644 vendor/golang.org/x/sys/unix/zerrors_darwin_arm64.go delete mode 100644 vendor/golang.org/x/sys/unix/zerrors_dragonfly_amd64.go delete mode 100644 vendor/golang.org/x/sys/unix/zerrors_freebsd_386.go delete mode 100644 vendor/golang.org/x/sys/unix/zerrors_freebsd_amd64.go delete mode 100644 vendor/golang.org/x/sys/unix/zerrors_freebsd_arm.go delete mode 100644 vendor/golang.org/x/sys/unix/zerrors_freebsd_arm64.go delete mode 100644 vendor/golang.org/x/sys/unix/zerrors_linux_386.go delete mode 100644 vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go delete mode 100644 vendor/golang.org/x/sys/unix/zerrors_linux_arm.go delete mode 100644 vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go delete mode 100644 vendor/golang.org/x/sys/unix/zerrors_linux_mips.go delete mode 100644 vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go delete mode 100644 vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go delete mode 100644 vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go delete mode 100644 vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go delete mode 100644 vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go delete mode 100644 vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go delete mode 100644 vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go delete mode 100644 vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go delete mode 100644 vendor/golang.org/x/sys/unix/zerrors_netbsd_386.go delete mode 100644 vendor/golang.org/x/sys/unix/zerrors_netbsd_amd64.go delete mode 100644 vendor/golang.org/x/sys/unix/zerrors_netbsd_arm.go delete mode 100644 vendor/golang.org/x/sys/unix/zerrors_netbsd_arm64.go delete mode 100644 vendor/golang.org/x/sys/unix/zerrors_openbsd_386.go delete mode 100644 vendor/golang.org/x/sys/unix/zerrors_openbsd_amd64.go delete mode 100644 vendor/golang.org/x/sys/unix/zerrors_openbsd_arm.go delete mode 100644 vendor/golang.org/x/sys/unix/zerrors_openbsd_arm64.go delete mode 100644 vendor/golang.org/x/sys/unix/zerrors_solaris_amd64.go delete mode 100644 vendor/golang.org/x/sys/unix/zptrace_armnn_linux.go delete mode 100644 vendor/golang.org/x/sys/unix/zptrace_linux_arm64.go delete mode 100644 vendor/golang.org/x/sys/unix/zptrace_mipsnn_linux.go delete mode 100644 vendor/golang.org/x/sys/unix/zptrace_mipsnnle_linux.go delete mode 100644 vendor/golang.org/x/sys/unix/zptrace_x86_linux.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_aix_ppc.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64_gc.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64_gccgo.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_darwin_386.1_11.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_darwin_386.1_13.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_darwin_386.1_13.s delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_darwin_386.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_darwin_386.s delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.1_11.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.1_13.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.1_13.s delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_darwin_arm.1_11.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_darwin_arm.1_13.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_darwin_arm.1_13.s delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_darwin_arm.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_darwin_arm.s delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.1_11.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.1_13.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.1_13.s delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_dragonfly_amd64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_freebsd_386.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_freebsd_amd64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_linux_386.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_linux_amd64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_linux_arm.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_linux_arm64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_linux_mips.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_linux_mips64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_linux_mips64le.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_linux_mipsle.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64le.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_linux_riscv64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_linux_s390x.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_linux_sparc64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_netbsd_386.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_netbsd_amd64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysctl_openbsd_386.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysctl_openbsd_amd64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysctl_openbsd_arm.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysctl_openbsd_arm64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysnum_darwin_386.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysnum_darwin_amd64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysnum_darwin_arm.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysnum_darwin_arm64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysnum_dragonfly_amd64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysnum_freebsd_386.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysnum_freebsd_amd64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysnum_freebsd_arm.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysnum_freebsd_arm64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysnum_linux_386.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysnum_netbsd_386.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysnum_netbsd_amd64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysnum_netbsd_arm.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysnum_netbsd_arm64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysnum_openbsd_386.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysnum_openbsd_amd64.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysnum_openbsd_arm.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysnum_openbsd_arm64.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_aix_ppc.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_aix_ppc64.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_darwin_386.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_darwin_arm.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_darwin_arm64.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_dragonfly_amd64.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_freebsd_386.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_freebsd_amd64.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_freebsd_arm.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_freebsd_arm64.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_linux_386.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_linux_arm.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_linux_mips.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_netbsd_386.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_netbsd_amd64.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_netbsd_arm.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_netbsd_arm64.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_openbsd_386.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_openbsd_amd64.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_openbsd_arm.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_openbsd_arm64.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_solaris_amd64.go delete mode 100644 vendor/gopkg.in/alexcesaro/quotedprintable.v3/LICENSE delete mode 100644 vendor/gopkg.in/alexcesaro/quotedprintable.v3/README.md delete mode 100644 vendor/gopkg.in/alexcesaro/quotedprintable.v3/encodedword.go delete mode 100644 vendor/gopkg.in/alexcesaro/quotedprintable.v3/pool.go delete mode 100644 vendor/gopkg.in/alexcesaro/quotedprintable.v3/pool_go12.go delete mode 100644 vendor/gopkg.in/alexcesaro/quotedprintable.v3/reader.go delete mode 100644 vendor/gopkg.in/alexcesaro/quotedprintable.v3/writer.go delete mode 100644 vendor/gopkg.in/mail.v2/.gitignore delete mode 100644 vendor/gopkg.in/mail.v2/.travis.yml delete mode 100644 vendor/gopkg.in/mail.v2/CHANGELOG.md delete mode 100644 vendor/gopkg.in/mail.v2/CONTRIBUTING.md delete mode 100644 vendor/gopkg.in/mail.v2/LICENSE delete mode 100644 vendor/gopkg.in/mail.v2/README.md delete mode 100644 vendor/gopkg.in/mail.v2/auth.go delete mode 100644 vendor/gopkg.in/mail.v2/doc.go delete mode 100644 vendor/gopkg.in/mail.v2/errors.go delete mode 100644 vendor/gopkg.in/mail.v2/message.go delete mode 100644 vendor/gopkg.in/mail.v2/mime.go delete mode 100644 vendor/gopkg.in/mail.v2/mime_go14.go delete mode 100644 vendor/gopkg.in/mail.v2/send.go delete mode 100644 vendor/gopkg.in/mail.v2/smtp.go delete mode 100644 vendor/gopkg.in/mail.v2/writeto.go delete mode 100644 vendor/modules.txt diff --git a/.dockerignore b/.dockerignore index a49be61..f279409 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,9 +1,3 @@ -/.env -/.gitignore -/Docker* -/DOCS.md -/LICENSE -/logo.svg -/MAINTAINERS -/publish.sh -/README.md +/Dockerfile +/vendor +/.git diff --git a/.gitignore b/.gitignore index 0c1a1fe..ea4fca0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,28 +1,3 @@ -# Compiled Object files, Static and Dynamic libs (Shared Objects) -*.o -*.a -*.so - -# Folders -_obj -_test - -# Architecture specific extensions/prefixes -*.[568vq] -[568vq].out - -*.cgo1.go -*.cgo2.c -_cgo_defun.c -_cgo_gotypes.go -_cgo_export.* - -_testmain.go - -*.exe -*.test -*.prof -.env - -coverage.out -woodpecker-email +/vendor +/.php-cs-fixer.cache +/test* diff --git a/.woodpecker.yml b/.woodpecker.yml index c289a13..c81b729 100644 --- a/.woodpecker.yml +++ b/.woodpecker.yml @@ -1,11 +1,4 @@ steps: - tests: - image: golang:1.18 - commands: - - test -n "$CI_COMMIT_TAG" && sed "s/{app_version}/$CI_COMMIT_TAG/g" -i main.go || true - - test -n "$CI_COMMIT_SHA" && sed "s/{app_version}/${CI_COMMIT_SHA:0:7}/g" -i main.go || true - - make test - build_push_latest_gitnet: image: plugins/docker secrets: [registry_user, registry_password] diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index fd2c079..0000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,11 +0,0 @@ -## [Unreleased] - -## 1.0.1-wp -### Fixed -* fix fatal error when the env var `CI_COMMIT_PULL_REQUEST` is empty (#2) - -## 1.0.0-wp -### Added -* add environment variables of woodpecker -* add ci -* add evaluate setting diff --git a/DOCS.md b/DOCS.md index 10af825..dd8afe2 100644 --- a/DOCS.md +++ b/DOCS.md @@ -1,5 +1,6 @@ --- name: Woodpecker Email +author: Simon Vieille icon: https://gitnet.fr/deblan/woodpecker-email/raw/branch/develop/logo.svg description: plugin to send build status notifications via Email. tags: [notifications, email] @@ -8,165 +9,107 @@ containerImageUrl: https://hub.docker.com/r/deblan/woodpecker-email url: https://gitnet.fr/deblan/woodpecker-email --- -Use the Email plugin for sending build status notifications via email. +## Settings -## Config -You can configure the plugin using the following parameters: +| Settings Name | Required | Type | Description | Documentation | +| --- | --- | --- | --- | --- | +| dsn | yes | `string` | Mail transport configuration | [Documentation](https://symfony.com/doc/current/mailer.html#tls-peer-verification) | +| from.address | yes | `string` | Email address of the sender | | +| from.name | no | `0string` | Name of the sender | | +| recipients | no | `string` or `list` | List of recipients to send this mail to (besides the commit author) | YAML list or comma separated list | +| recipients_only | no | `boolean` | Exclude the committer | | +| content.subject | no | `string` | Define the email subject template | | +| content.body | no | `string` | Define the email body template | | +| attachments | no | `string` or `list` | List of files to attach | YAML list or comma separated list | -* **from.address** - Send notifications from this address -* **from.name** - Notifications sender name -* **host** - SMTP server host -* **port** - SMTP server port, defaults to `587` -* **username** - SMTP username -* **password** - SMTP password -* **skip_verify** - Skip verification of SSL certificates, defaults to `false` -* **no_starttls** - Enable/Disable STARTTLS -* **recipients** - List of recipients to send this mail to (besides the commit author) -* **recipients_file** - Filename to load additional recipients from (textfile with one email per line) (besides the commit author) -* **recipients_only** - Do not send mails to the commit author, but only to **recipients**, defaults to `false` -* **subject** - The subject line template -* **body** - The email body template -* **attachment** - An optional file to attach to the sent mail(s), can be an absolute path or relative to the working directory. -* **evaluate** - An optional expression to evaluate (on the fly) whether the mail should be sent or not ([https://woodpecker-ci.org/docs/next/usage/pipeline-syntax#evaluate](https://woodpecker-ci.org/docs/next/usage/pipeline-syntax#evaluate)). -## Example -The following is a sample configuration in your .woodpecker.yml file: +### Example -```yaml -pipeline: + +``` +steps: mail: - image: deblan/woodpecker-email + image: deblan/woodpecker-email-php settings: - from.address: noreply@github.com - from.name: John Smith - host: smtp.mailgun.org - username: octocat - password: 12345 + dsn: "smtp://username:password@mail.example.com:587?verify_peer=1" + from: + address: "woodpecker@example.com" + name: "Woodpecker" + evaluate: "build.status == 'failure' or prev_pipeline.status == 'failure'" recipients: - - octocat@github.com + - dev1@example.com + - dev2@example.com + recipients_only: false + content: + subject: "[{{ pipeline.status }}] {{ repo.full_name }} ({{ commit.branch }} - {{ commit.sha[0:8] }}" + body: | + {{ commit.sha }}
+ {{ pipeline.status }}
+ {{ commit.author_email }}
+ attachments: + - log/* ``` -### Secrets -The Email plugin supports reading credentials and other parameters from the Drone secret store. This is strongly recommended instead of storing credentials in the pipeline configuration in plain text. +### Evaluation and content -```diff -pipeline: - mail: - image: deblan/woodpecker-email - settings: - from.address: noreply@github.com - host: smtp.mailgun.org -+ username: -+ from_secret: email_username -+ password: 12345 -+ from_secret: email_password - recipients: - - octocat@github.com -``` - -### Evaluation - -This plugin introduces an optional expression to evaluate (on the fly) whether the mail should be sent or not. +See the [Twig documentation](https://twig.symfony.com/doc/3.x/). -```diff -pipeline: - mail: - image: deblan/woodpecker-email - settings: - ... - when: - - evaluate: 'CI_STEP_STATUS == "failure" || CI_PREV_PIPELINE_STATUS == "failure"' -``` +| Variable | Value | +| --- | --- | +| `workspace` | `CI_WORKSPACE` | +| `repo.full_name` | `CI_REPO` | +| `repo.owner` | `CI_REPO_OWNER` | +| `repo.name` | `CI_REPO_NAME` | +| `repo.url` | `CI_REPO_URL` | +| `commit.sha` | `CI_COMMIT_SHA` | +| `commit.ref` | `CI_COMMIT_REF` | +| `commit.branch` | `CI_COMMIT_BRANCH` | +| `commit.source_branch` | `CI_COMMIT_SOURCE_BRANCH` | +| `commit.target_branch` | `CI_COMMIT_TARGET_BRANCH` | +| `commit.tag` | `CI_COMMIT_TAG` | +| `commit.pull_request` | `CI_COMMIT_PULL_REQUEST` | +| `commit.pull_request_labels` | `CI_COMMIT_PULL_REQUEST_LABELS` | +| `commit.message` | `CI_COMMIT_MESSAGE` | +| `commit.author` | `CI_COMMIT_AUTHOR` | +| `commit.author_email` | `CI_COMMIT_AUTHOR_EMAIL` | +| `commit.author_avatar` | `CI_COMMIT_AUTHOR_AVATAR` | +| `prev_commit.sha` | `CI_PREV_COMMIT_SHA` | +| `prev_commit.ref` | `CI_PREV_COMMIT_REF` | +| `prev_commit.branch` | `CI_PREV_COMMIT_BRANCH` | +| `prev_commit.source_branch` | `CI_PREV_COMMIT_SOURCE_BRANCH` | +| `prev_commit.target_branch` | `CI_PREV_COMMIT_TARGET_BRANCH` | +| `prev_commit.message` | `CI_PREV_COMMIT_MESSAGE` | +| `prev_commit.author` | `CI_PREV_COMMIT_AUTHOR` | +| `prev_commit.author_email` | `CI_PREV_COMMIT_AUTHOR_EMAIL` | +| `prev_commit.author_avatar` | `CI_PREV_COMMIT_AUTHOR_AVATAR` | +| `prev_commit.url` | `CI_PREV_COMMIT_URL` | +| `pipeline.number` | `CI_PIPELINE_NUMBER` | +| `pipeline.parent` | `CI_PIPELINE_PARENT` | +| `pipeline.event` | `CI_PIPELINE_EVENT` | +| `pipeline.url` | `CI_PIPELINE_URL` | +| `pipeline.deploy_target` | `CI_PIPELINE_DEPLOY_TARGET` | +| `pipeline.status` | `CI_PIPELINE_STATUS` | +| `pipeline.created_at` | `CI_PIPELINE_CREATED` | +| `pipeline.stared_at` | `CI_PIPELINE_STARTED` | +| `pipeline.finished_at` | `CI_PIPELINE_FINISHED` | +| `prev_pipeline.number` | `CI_PREV_PIPELINE_NUMBER` | +| `prev_pipeline.parent` | `CI_PREV_PIPELINE_PARENT` | +| `prev_pipeline.event` | `CI_PREV_PIPELINE_EVENT` | +| `prev_pipeline.url` | `CI_PREV_PIPELINE_URL` | +| `prev_pipeline.deploy_target` | `CI_PREV_PIPELINE_DEPLOY_TARGET` | +| `prev_pipeline.status` | `CI_PREV_PIPELINE_STATUS` | +| `prev_pipeline.created_at` | `CI_PREV_PIPELINE_CREATED` | +| `prev_pipeline.stared_at` | `CI_PREV_PIPELINE_STARTED` | +| `prev_pipeline.finished_at` | `CI_PREV_PIPELINE_FINISHED` | +| `workflow.name` | `WORKFLOW_NAME` | +| `step.name` | `CI_STEP_NAME` | +| `step.number` | `CI_STEP_NUMBER` | +| `step.status` | `CI_STEP_STATUS` | +| `step.start_at` | `CI_STEP_STARTED` | +| `step.finished_at` | `CI_STEP_FINISHED` | +| `step.url` | `CI_STEP_URL` | -The problem is that the expression is evaluated before the pipeline is generated. In this case, `CI_STEP_STATUS` does not exist yet and the mail step is ignored unless the previous pipeline failed. - -```diff -pipeline: - mail: - image: deblan/woodpecker-email - settings: - ... -+ evaluate: 'CI_STEP_STATUS == "failure" || CI_PREV_PIPELINE_STATUS == "failure"' - when: -- - evaluate: 'CI_STEP_STATUS == "failure" || CI_PREV_PIPELINE_STATUS == "failure"' -``` - -More information about the syntaxe on ([https://woodpecker-ci.org/docs/next/usage/pipeline-syntax#evaluate](https://woodpecker-ci.org/docs/next/usage/pipeline-syntax#evaluate)). - -### Custom Templates - -In some cases you may want to customize the look and feel of the email message -so you can use custom templates. For the use case we expose the following -additional parameters, all of the accept a custom handlebars template, directly -provided as a string or as a remote URL which gets fetched and parsed: - -* **subject** - A handlebars template to create a custom subject. For more - details take a look at the [docs](http://handlebarsjs.com/). You can see the - default template [here](https://github.com/Drillster/drone-email/blob/master/defaults.go#L14) -* **body** - A handlebars template to create a custom template. For more - details take a look at the [docs](http://handlebarsjs.com/). You can see the - default template [here](https://github.com/Drillster/drone-email/blob/master/defaults.go#L19-L267) - -Example configuration that generate a custom email: - -```yaml -pipeline: - mail: - image: deblan/woodpecker-email - settings: - from.address: noreply@github.com - host: smtp.mailgun.org - username: octocat - password: 12345 - subject: > - [{{ build.status }}] - {{ repo.owner }}/{{ repo.name }} - ({{ build.branch }} - {{ truncate build.commit 8 }}) - body: - https://git.io/vgvPz -``` - -### Skip SSL verify - -In some cases you may want to skip SSL verification, even if we discourage that -as it leads to an unsecure environment. Please use this option only within your -intranet and/or with truested resources. For this use case we expose the -following additional parameter: - -* **skip_verify** - Skip verification of SSL certificates - -Example configuration that skips SSL verification: - -```diff -pipeline: - mail: - image: deblan/woodpecker-email - settings: - from: noreply@github.com - host: smtp.mailgun.org - username: octocat - password: 12345 -+ skip_verify: true -``` - -### STARTTLS - -By default, STARTTLS is being used opportunistically meaning, if advertised -by the server, traffic is going to be encrypted. - -You may want to disable STARTTLS, e.g., with faulty and/or internal servers: - -```diff -pipeline: - mail: - image: deblan/woodpecker-email - settings: - from: noreply@github.com - host: smtp.mailgun.org - username: octocat - password: 12345 -+ no_starttls: true -``` +[dsn_doc]: https://symfony.com/doc/current/mailer.html#tls-peer-verification diff --git a/Dockerfile b/Dockerfile index b897037..f64aa72 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,10 +1,9 @@ -FROM golang:1.18 +FROM deblan/php:8.2 -WORKDIR /go/src/woodpecker-email +WORKDIR /opt/app COPY . . -RUN apt-get update && apt-get -y install ca-certificates tzdata -RUN make build && cp /go/src/woodpecker-email/woodpecker-email /bin +RUN composer install -ENTRYPOINT ["/bin/woodpecker-email"] +ENTRYPOINT ["php", "/opt/app/bin/console"] diff --git a/Dockerfile.armhf b/Dockerfile.armhf deleted file mode 100644 index 7392d9a..0000000 --- a/Dockerfile.armhf +++ /dev/null @@ -1,13 +0,0 @@ -FROM golang:1.15-alpine as builder - -WORKDIR /go/src/drone-email -COPY . . - -RUN GOOS=linux GOARCH=arm GOARM=7 CGO_ENABLED=0 go build - -FROM alpine:3.14 - -RUN apk add --no-cache ca-certificates tzdata - -COPY --from=builder /go/src/drone-email/drone-email /bin/ -ENTRYPOINT ["/bin/drone-email"] diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 8dada3e..0000000 --- a/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright {yyyy} {name of copyright owner} - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/MAINTAINERS b/MAINTAINERS deleted file mode 100644 index fe583f2..0000000 --- a/MAINTAINERS +++ /dev/null @@ -1,51 +0,0 @@ -[people] - [people.bradrydzewski] - name = "Brad Rydzewski" - email = "brad@drone.io" - login = "bradrydzewski" - [people.Bugagazavr] - name = "Kirill" - email = "" - login = "Bugagazavr" - [people.donny-dont] - name = "Don Olmstead" - email = "donny-dont@gmail.com" - login = "donny-dont" - [people.jackspirou] - name = "Jack Spirou" - email = "" - login = "jackspirou" - [people.msteinert] - name = "Mike Steinert" - email = "" - login = "msteinert" - [people.nlf] - name = "Nathan LaFreniere" - email = "" - login = "nlf" - [people.tboerger] - name = "Thomas Boerger" - email = "thomas@webhippie.de" - login = "tboerger" - [people.athieriot] - name = "Aurélien Thieriot" - email = "a.thieriot@gmail.com" - login = "athieriot" - [people.mjwwit] - name = "Michael de Wit" - email = "mjwwit@gmail.com" - login = "mjwwit" - -[org] - [org.core] - people = [ - "bradrydzewski", - "Bugagazavr", - "donny-dont", - "jackspirou", - "msteinert", - "nlf", - "tboerger", - "athieriot", - "mjwwit" - ] diff --git a/Makefile b/Makefile deleted file mode 100644 index 183e2cb..0000000 --- a/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -all: test build - -test: - go vet - go test -cover -coverprofile=coverage.out - -build: - GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build diff --git a/README.md b/README.md index d83331e..dc81636 100644 --- a/README.md +++ b/README.md @@ -1,52 +1,3 @@ -# woodpecker-email +# woodpecker-email-php Woodpecker plugin to send build status notifications via Email. For the usage information and a listing of the available options please take a look at [the docs](DOCS.md). - -## Binary - -Build the binary with the following command: - -``` -go build -``` - -## Docker - -Build the docker image with the following commands: - -``` -docker build -t deblan/woodpecker-email:latest . -``` - -This will create a Docker image called `deblan/woodpecker-email:latest`. -Please note incorrectly building the image for the correct x64 linux and with GCO disabled will result in an error when running the Docker image: - -``` -docker: Error response from daemon: Container command -'/bin/woodpecker-email' not found or does not exist.. -``` - -### Example -Execute from the working directory: - -```sh -docker run --rm \ - -e PLUGIN_FROM.ADDRESS=drone@test.test \ - -e PLUGIN_FROM.NAME="John Smith" \ - -e PLUGIN_HOST=smtp.test.test \ - -e PLUGIN_USERNAME=drone \ - -e PLUGIN_PASSWORD=test \ - -e CI_REPO_OWNER=octocat \ - -e CI_REPO_NAME=hello-world \ - -e CI_COMMIT_SHA=7fd1a60b01f91b314f59955a4e4d4e80d8edf11d \ - -e CI_COMMIT_BRANCH=master \ - -e CI_COMMIT_AUTHOR=octocat \ - -e CI_COMMIT_AUTHOR_EMAIL=octocat@test.test \ - -e CI_BUILD_NUMBER=1 \ - -e CI_PIPELINE_STATUS=success \ - -e CI_PIPELINE_LINK=http://github.com/octocat/hello-world \ - -e CI_COMMIT_MESSAGE="Hello world!" \ - -v $(pwd):$(pwd) \ - -w $(pwd) \ - deblan/woodpecker-email -``` diff --git a/bin/console b/bin/console new file mode 100755 index 0000000..a4da810 --- /dev/null +++ b/bin/console @@ -0,0 +1,133 @@ +#!/usr/bin/php + 'CI_WORKSPACE', + 'repo' => [ + 'full_name' => 'CI_REPO', + 'owner' => 'CI_REPO_OWNER', + 'name' => 'CI_REPO_NAME', + 'url' => 'CI_REPO_URL', + ], + 'commit' => [ + 'sha' => 'CI_COMMIT_SHA', + 'ref' => 'CI_COMMIT_REF', + 'branch' => 'CI_COMMIT_BRANCH', + 'source_branch' => 'CI_COMMIT_SOURCE_BRANCH', + 'target_branch' => 'CI_COMMIT_TARGET_BRANCH', + 'tag' => 'CI_COMMIT_TAG', + 'pull_request' => 'CI_COMMIT_PULL_REQUEST', + 'pull_request_labels' => 'CI_COMMIT_PULL_REQUEST_LABELS', + 'tag' => 'CI_COMMIT_TAG', + 'message' => 'CI_COMMIT_MESSAGE', + 'author' => 'CI_COMMIT_AUTHOR', + 'author_email' => 'CI_COMMIT_AUTHOR_EMAIL', + 'author_avatar' => 'CI_COMMIT_AUTHOR_AVATAR', + ], + 'prev_commit' => [ + 'sha' => 'CI_PREV_COMMIT_SHA', + 'ref' => 'CI_PREV_COMMIT_REF', + 'branch' => 'CI_PREV_COMMIT_BRANCH', + 'source_branch' => 'CI_PREV_COMMIT_SOURCE_BRANCH', + 'target_branch' => 'CI_PREV_COMMIT_TARGET_BRANCH', + 'message' => 'CI_PREV_COMMIT_MESSAGE', + 'author' => 'CI_PREV_COMMIT_AUTHOR', + 'author_email' => 'CI_PREV_COMMIT_AUTHOR_EMAIL', + 'author_avatar' => 'CI_PREV_COMMIT_AUTHOR_AVATAR', + 'url' => 'CI_PREV_COMMIT_URL', + ], + 'pipeline' => [ + 'number' => 'CI_PIPELINE_NUMBER', + 'parent' => 'CI_PIPELINE_PARENT', + 'event' => 'CI_PIPELINE_EVENT', + 'url' => 'CI_PIPELINE_URL', + 'deploy_target' => 'CI_PIPELINE_DEPLOY_TARGET', + 'status' => 'CI_PIPELINE_STATUS', + 'created_at' => 'CI_PIPELINE_CREATED', + 'stared_at' => 'CI_PIPELINE_STARTED', + 'finished_at' => 'CI_PIPELINE_FINISHED', + ], + 'prev_pipeline' => [ + 'number' => 'CI_PREV_PIPELINE_NUMBER', + 'parent' => 'CI_PREV_PIPELINE_PARENT', + 'event' => 'CI_PREV_PIPELINE_EVENT', + 'url' => 'CI_PREV_PIPELINE_URL', + 'deploy_target' => 'CI_PREV_PIPELINE_DEPLOY_TARGET', + 'status' => 'CI_PREV_PIPELINE_STATUS', + 'created_at' => 'CI_PREV_PIPELINE_CREATED', + 'stared_at' => 'CI_PREV_PIPELINE_STARTED', + 'finished_at' => 'CI_PREV_PIPELINE_FINISHED', + ], + 'workflow' => [ + 'name' => 'WORKFLOW_NAME', + ], + 'step' => [ + 'name' => 'CI_STEP_NAME', + 'number' => 'CI_STEP_NUMBER', + 'status' => 'CI_STEP_STATUS', + 'start_at' => 'CI_STEP_STARTED', + 'finished_at' => 'CI_STEP_FINISHED', + 'url' => 'CI_STEP_URL', + ], +]); + +$config = EnvVarLoader::buildArray([ + 'dsn' => 'PLUGIN_DSN', + 'from' => 'PLUGIN_FROM', + 'recipients' => 'PLUGIN_RECIPIENTS', + 'is_recipients_only' => 'PLUGIN_RECIPIENTS_ONLY', + 'attachments' => 'PLUGIN_ATTACHMENTS', + 'evaluate' => 'PLUGIN_EVALUATE', + 'content' => 'PLUGIN_CONTENT', +], [ + 'PLUGIN_RECIPIENTS_ONLY' => true, +]); + +function writeln(...$values) +{ + foreach ($values as $value) { + echo sprintf("%s\n", $value); + } +} + +function handleError($section, Exception $e) +{ + writeln( + sprintf('ERROR - %s', $section), + $e->getMessage() + ); + + exit(1); +} + +$twig = (new TwigFactory())->create(); +$emailFactory = new EmailFactory($twig, $config, $build); +$evaluation = new Evaluation($twig); + +try { + if (!empty($config['evaluate']) && !$evaluation->isTrue($config['evaluate'], $build)) { + writeln('Evaluation returns false.', 'Program aborted!'); + } else { + $emailFactory + ->createMailer($config) + ->send($emailFactory->createEmail($config, $build)) + ; + + writeln('Email sent!'); + } +} catch (SyntaxError $e) { + handleError('Syntax error', $e); +} catch (TransportException $e) { + handleError('Transport error', $e); +} catch (\Exception $e) { + handleError('Generic error', $e); +} diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..e47702c --- /dev/null +++ b/composer.json @@ -0,0 +1,11 @@ +{ + "autoload": { + "psr-4": { + "Plugin\\": "src/" + } + }, + "require": { + "symfony/mailer": "^7.0", + "twig/twig": "^3.8" + } +} diff --git a/defaults.go b/defaults.go deleted file mode 100644 index 3643145..0000000 --- a/defaults.go +++ /dev/null @@ -1,270 +0,0 @@ -package main - -const ( - // DefaultPort is the default SMTP port to use - DefaultPort = 587 - // DefaultOnlyRecipients controls wether to exclude the commit author by default - DefaultOnlyRecipients = false - // DefaultSkipVerify controls wether to skip SSL verification for the SMTP server - DefaultSkipVerify = false - // DefaultClientHostname is the client hostname used in the HELO command sent to the SMTP server - DefaultClientHostname = "localhost" -) - -// DefaultSubject is the default subject template to use for the email -const DefaultSubject = ` -[{{ build.status }}] {{ repo.owner }}/{{ repo.name }} ({{ commit.branch }} - {{ truncate commit.sha 8 }}) -` - -// DefaultTemplate is the default body template to use for the email -const DefaultTemplate = ` - - - - - - - - - - - - - - -
-
- - - {{#success build.status}} - - {{else}} - - {{/success}} - - - - -
- - Successful build #{{ build.number }} - - - - Failed build #{{ build.number }} - -
- - - - - - - - - - - - - - - - - - - - - -
- Repo: - - {{ repo.owner }}/{{ repo.name }} -
- Author: - - {{ commit.author.name }} ({{ commit.author.email }}) -
- Branch: - - {{ commit.branch }} -
- Commit: - - {{ truncate commit.sha 8 }} -
- Started at: - - {{ datetime build.created "Mon Jan 2 15:04:05 MST 2006" "Local" }} -
-
- - - - -
- {{ commit.message }} -
-
-
-
- - -` diff --git a/go.mod b/go.mod deleted file mode 100644 index 318f6e4..0000000 --- a/go.mod +++ /dev/null @@ -1,24 +0,0 @@ -module gitnet.fr/deblan/woodpecker-email - -go 1.18 - -require ( - github.com/PuerkitoBio/goquery v1.0.2 - github.com/Sirupsen/logrus v0.11.1-0.20161202023507-881bee4e20a5 - github.com/andybalholm/cascadia v0.0.0-20161224141413-349dd0209470 - github.com/aymerick/douceur v0.2.1-0.20150827151352-7176f1467381 - github.com/aymerick/raymond v2.0.2-0.20161209220724-72acac220747+incompatible - github.com/davecgh/go-spew v1.1.0 - github.com/drone/drone-go v0.0.0-20160728162628-e34150a175e6 - github.com/gorilla/css v0.0.0-20150317222238-a80e24ada269 - github.com/jaytaylor/html2text v0.0.0-20161112011239-4b9124c9b0a2 - github.com/joho/godotenv v0.0.0-20161216230537-726cc8b906e3 - github.com/urfave/cli v1.19.1 - golang.org/x/net v0.0.0-20170108160505-da2b4fa28524 - golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4 - gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc - gopkg.in/mail.v2 v2.3.1 - gopkg.in/yaml.v2 v2.2.2 -) - -require github.com/antonmedv/expr v1.9.0 // indirect diff --git a/go.sum b/go.sum deleted file mode 100644 index 178aec7..0000000 --- a/go.sum +++ /dev/null @@ -1,56 +0,0 @@ -github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= -github.com/PuerkitoBio/goquery v1.0.2 h1:6eVgli+CgrpInQgyW5Unj3aqfzqFk/ALcKm6m0w7hgA= -github.com/PuerkitoBio/goquery v1.0.2/go.mod h1:T9ezsOHcCrDCgA8aF1Cqr3sSYbO/xgdy8/R/XiIMAhA= -github.com/Sirupsen/logrus v0.11.1-0.20161202023507-881bee4e20a5 h1:FPg0BNxd7fCpXpINIi6LVP8cD/wfE2b13A29PEsdarg= -github.com/Sirupsen/logrus v0.11.1-0.20161202023507-881bee4e20a5/go.mod h1:rmk17hk6i8ZSAJkSDa7nOxamrG+SP4P0mm+DAvExv4U= -github.com/andybalholm/cascadia v0.0.0-20161224141413-349dd0209470 h1:4jHLmof+Hba81591gfH5xYA8QXzuvgksxwPNrmjR2BA= -github.com/andybalholm/cascadia v0.0.0-20161224141413-349dd0209470/go.mod h1:3I+3V7B6gTBYfdpYgIG2ymALS9H+5VDKUl3lHH7ToM4= -github.com/antonmedv/expr v1.9.0 h1:j4HI3NHEdgDnN9p6oI6Ndr0G5QryMY0FNxT4ONrFDGU= -github.com/antonmedv/expr v1.9.0/go.mod h1:5qsM3oLGDND7sDmQGDXHkYfkjYMUX14qsgqmHhwGEk8= -github.com/aymerick/douceur v0.2.1-0.20150827151352-7176f1467381 h1:TvvArQ5hYFgPFFRT8BB/gKaVvxjC9qVZG/3jxYuNACQ= -github.com/aymerick/douceur v0.2.1-0.20150827151352-7176f1467381/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= -github.com/aymerick/raymond v2.0.2-0.20161209220724-72acac220747+incompatible h1:19inhsJJ+VdnrygX+s0qvnhR54idpjmGhpI8a2SMZCw= -github.com/aymerick/raymond v2.0.2-0.20161209220724-72acac220747+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= -github.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/drone/drone-go v0.0.0-20160728162628-e34150a175e6 h1:UKxrkVtfsHSd+0fTupjAQ8ZkcYWRrEtOWGTzAkE1ZhU= -github.com/drone/drone-go v0.0.0-20160728162628-e34150a175e6/go.mod h1:qVb1k1w9X5jgoGyLtbnfWNnd4XZfAwokxBmiutbpGqw= -github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo5dl+VrEg= -github.com/gdamore/tcell v1.3.0/go.mod h1:Hjvr+Ofd+gLglo7RYKxxnzCBmev3BzsS67MebKS4zMM= -github.com/gorilla/css v0.0.0-20150317222238-a80e24ada269 h1:WZP7qUFY1dKi7dPHchSRp/ydn2FyagORT0RH6YhaPeg= -github.com/gorilla/css v0.0.0-20150317222238-a80e24ada269/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c= -github.com/jaytaylor/html2text v0.0.0-20161112011239-4b9124c9b0a2 h1:9eH/vcuoJz5ljX/BTyzQjdBh9lHbBBdGT+TJbkcJj5U= -github.com/jaytaylor/html2text v0.0.0-20161112011239-4b9124c9b0a2/go.mod h1:CVKlgaMiht+LXvHG173ujK6JUhZXKb2u/BQtjPDIvyk= -github.com/joho/godotenv v0.0.0-20161216230537-726cc8b906e3 h1:zShOjUfrFegEHgln4TPkWk3KkN9sug3Es3Ml6YpgFJI= -github.com/joho/godotenv v0.0.0-20161216230537-726cc8b906e3/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= -github.com/lucasb-eyer/go-colorful v1.0.2/go.mod h1:0MS4r+7BZKSJ5mw4/S5MPN+qHFF1fYclkSPilDOKW0s= -github.com/lucasb-eyer/go-colorful v1.0.3/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= -github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/mattn/go-runewidth v0.0.8/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= -github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rivo/tview v0.0.0-20200219210816-cd38d7432498/go.mod h1:6lkG1x+13OShEf0EaOCaTQYyB7d5nSbb181KtjlS+84= -github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/sanity-io/litter v1.2.0/go.mod h1:JF6pZUFgu2Q0sBZ+HSV35P8TVPI1TTzEwyu9FXAw2W4= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v0.0.0-20161117074351-18a02ba4a312/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/urfave/cli v1.19.1 h1:0mKm4ZoB74PxYmZVua162y1dGt1qc10MyymYRBf3lb8= -github.com/urfave/cli v1.19.1/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= -golang.org/x/net v0.0.0-20170108160505-da2b4fa28524 h1:h2R5t9TXOJ/PVrYAFToVQe0c5AIMZPmlEKFhmYS1iGs= -golang.org/x/net v0.0.0-20170108160505-da2b4fa28524/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/sys v0.0.0-20161214190518-d75a52659825 h1:4d9VvrP9mESHxCpAwE1G5e1D8Ybj9v7pX19HkGQV0lk= -golang.org/x/sys v0.0.0-20161214190518-d75a52659825/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190626150813-e07cf5db2756/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4 h1:sfkvUWPNGwSV+8/fNqctR5lS2AqCSqYwXdrjCxp/dXo= -golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk= -gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/mail.v2 v2.3.1 h1:WYFn/oANrAGP2C0dcV6/pbkPzv8yGzqTjPmTeO7qoXk= -gopkg.in/mail.v2 v2.3.1/go.mod h1:htwXN1Qh09vZJ1NVKxQqHPBaCBbzKhp5GzuJEA4VJWw= -gopkg.in/yaml.v2 v2.0.0-20160928153709-a5b47d31c556/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/main.go b/main.go deleted file mode 100644 index 7e2b75a..0000000 --- a/main.go +++ /dev/null @@ -1,438 +0,0 @@ -package main - -import ( - "os" - - log "github.com/Sirupsen/logrus" - "github.com/joho/godotenv" - "github.com/urfave/cli" -) - -func main() { - // Load env-file if it exists first - envFile, envFileSet := os.LookupEnv("PLUGIN_ENV_FILE") - if !envFileSet { - envFile = "/run/drone/env" - } - if _, err := os.Stat(envFile); err == nil { - godotenv.Overload(envFile) - } - - app := cli.NewApp() - app.Name = "email plugin" - app.Usage = "email plugin" - app.Action = run - app.Version = "{app_version}" - app.Flags = []cli.Flag{ - // Plugin environment - cli.StringFlag{ - Name: "from", - Usage: "from address", - EnvVar: "PLUGIN_FROM", - }, - cli.StringFlag{ - Name: "from.address", - Usage: "from address", - EnvVar: "PLUGIN_FROM.ADDRESS", - }, - cli.StringFlag{ - Name: "from.name", - Usage: "from name", - EnvVar: "PLUGIN_FROM.NAME", - }, - cli.StringFlag{ - Name: "host", - Usage: "smtp host", - EnvVar: "EMAIL_HOST,PLUGIN_HOST", - }, - cli.IntFlag{ - Name: "port", - Value: DefaultPort, - Usage: "smtp port", - EnvVar: "EMAIL_PORT,PLUGIN_PORT", - }, - cli.StringFlag{ - Name: "username", - Usage: "smtp server username", - EnvVar: "EMAIL_USERNAME,PLUGIN_USERNAME", - }, - cli.StringFlag{ - Name: "password", - Usage: "smtp server password", - EnvVar: "EMAIL_PASSWORD,PLUGIN_PASSWORD", - }, - cli.BoolFlag{ - Name: "skip.verify", - Usage: "skip tls verify", - EnvVar: "PLUGIN_SKIP_VERIFY", - }, - cli.BoolFlag{ - Name: "no.starttls", - Usage: "Enable/Disable STARTTLS", - EnvVar: "PLUGIN_NO_STARTTLS", - }, - cli.StringFlag{ - Name: "recipients.file", - Usage: "file to read recipients from", - EnvVar: "EMAIL_RECIPIENTS_FILE,PLUGIN_RECIPIENTS_FILE", - }, - cli.StringSliceFlag{ - Name: "recipients", - Usage: "recipient addresses", - EnvVar: "EMAIL_RECIPIENTS,PLUGIN_RECIPIENTS", - }, - cli.BoolFlag{ - Name: "recipients.only", - Usage: "send to recipients only", - EnvVar: "PLUGIN_RECIPIENTS_ONLY", - }, - cli.StringFlag{ - Name: "template.subject", - Value: DefaultSubject, - Usage: "subject template", - EnvVar: "PLUGIN_SUBJECT", - }, - cli.StringFlag{ - Name: "template.body", - Value: DefaultTemplate, - Usage: "body template", - EnvVar: "PLUGIN_BODY", - }, - cli.StringFlag{ - Name: "attachment", - Usage: "attachment filename", - EnvVar: "PLUGIN_ATTACHMENT", - }, - cli.StringSliceFlag{ - Name: "attachments", - Usage: "attachment filename(s)", - EnvVar: "PLUGIN_ATTACHMENTS", - }, - cli.StringFlag{ - Name: "evaluate", - Usage: "evaluation expression", - EnvVar: "PLUGIN_EVALUATE", - }, - cli.StringFlag{ - Name: "clienthostname", - Value: DefaultClientHostname, - Usage: "smtp client hostname", - EnvVar: "EMAIL_CLIENTHOSTNAME,PLUGIN_CLIENTHOSTNAME", - }, - - // Drone environment - // Repo - cli.StringFlag{ - Name: "repo.fullName", - Usage: "repository full name", - EnvVar: "CI_REPO_LINK", - }, - cli.StringFlag{ - Name: "repo.owner", - Usage: "repository owner", - EnvVar: "CI_REPO_OWNER", - }, - cli.StringFlag{ - Name: "repo.name", - Usage: "repository name", - EnvVar: "CI_REPO_NAME", - }, - cli.StringFlag{ - Name: "repo.scm", - Value: "git", - Usage: "respository scm", - EnvVar: "CI_REPO_SCM", - }, - cli.StringFlag{ - Name: "repo.link", - Usage: "repository link", - EnvVar: "CI_REPO_LINK", - }, - cli.StringFlag{ - Name: "repo.avatar", - Usage: "repository avatar", - EnvVar: "DRONE_REPO_AVATAR", - }, - cli.StringFlag{ - Name: "repo.branch", - Value: "master", - Usage: "repository default branch", - EnvVar: "CI_REPO_DEFAULT_BRANCH", - }, - cli.BoolFlag{ - Name: "repo.private", - Usage: "repository is private", - EnvVar: "CI_REPO_PRIVATE", - }, - cli.BoolFlag{ - Name: "repo.trusted", - Usage: "repository is trusted", - EnvVar: "DRONE_REPO_TRUSTED", - }, - - // Remote - cli.StringFlag{ - Name: "remote.url", - Usage: "repository clone url", - EnvVar: "CI_REPO_CLONE_URL", - }, - - // Commit - cli.StringFlag{ - Name: "commit.sha", - Usage: "git commit sha", - EnvVar: "CI_COMMIT_SHA", - }, - cli.StringFlag{ - Name: "commit.ref", - Value: "refs/heads/master", - Usage: "git commit ref", - EnvVar: "CI_COMMIT_REF", - }, - cli.StringFlag{ - Name: "commit.branch", - Value: "master", - Usage: "git commit branch", - EnvVar: "CI_COMMIT_BRANCH", - }, - cli.StringFlag{ - Name: "commit.link", - Usage: "commit link", - EnvVar: "CI_COMMIT_LINK", - }, - cli.StringFlag{ - Name: "commit.message", - Usage: "git commit message", - EnvVar: "CI_COMMIT_MESSAGE", - }, - cli.StringFlag{ - Name: "commit.author.name", - Usage: "git author name", - EnvVar: "CI_COMMIT_AUTHOR", - }, - cli.StringFlag{ - Name: "commit.author.email", - Usage: "git author email", - EnvVar: "CI_COMMIT_AUTHOR_EMAIL", - }, - cli.StringFlag{ - Name: "commit.author.avatar", - Usage: "git author avatar", - EnvVar: "CI_COMMIT_AUTHOR_AVATAR", - }, - - // Build - cli.IntFlag{ - Name: "build.number", - Usage: "build number", - EnvVar: "CI_BUILD_NUMBER", - }, - cli.StringFlag{ - Name: "build.event", - Value: "push", - Usage: "build event", - EnvVar: "CI_BUILD_EVENT", - }, - cli.StringFlag{ - Name: "build.status", - Usage: "build status", - Value: "success", - EnvVar: "CI_PIPELINE_STATUS", - }, - cli.StringFlag{ - Name: "build.link", - Usage: "build link", - EnvVar: "CI_PIPELINE_LINK", - }, - cli.Int64Flag{ - Name: "build.created", - Usage: "build created", - EnvVar: "CI_PIPELINE_CREATED", - }, - cli.Int64Flag{ - Name: "build.started", - Usage: "build started", - EnvVar: "CI_PIPELINE_STARTED", - }, - cli.Int64Flag{ - Name: "build.finished", - Usage: "build finished", - EnvVar: "CI_PIPELINE_FINISHED", - }, - - // Prev - cli.StringFlag{ - Name: "prev.build.status", - Usage: "prior build status", - EnvVar: "CI_PREV_PIPELINE_STATUS", - }, - cli.IntFlag{ - Name: "prev.build.number", - Usage: "prior build number", - EnvVar: "CI_PREV_PIPELINE_NUMBER", - }, - cli.StringFlag{ - Name: "prev.commit.sha", - Usage: "prior commit sha", - EnvVar: "CI_PREV_COMMIT_SHA", - }, - - // Job - cli.IntFlag{ - Name: "job.number", - Usage: "job number", - EnvVar: "CI_STEP_NUMBER", - }, - cli.StringFlag{ - Name: "job.status", - Usage: "job status", - EnvVar: "CI_STEP_STATUS", - }, - cli.IntFlag{ - Name: "job.exitCode", - Usage: "job exit code", - EnvVar: "DRONE_JOB_EXIT_CODE", - }, - cli.Int64Flag{ - Name: "job.started", - Usage: "job started", - EnvVar: "CI_STEP_STARTED", - }, - cli.Int64Flag{ - Name: "job.finished", - Usage: "job finished", - EnvVar: "CI_STEP_FINISHED", - }, - - // Yaml - cli.BoolFlag{ - Name: "yaml.signed", - Usage: "yaml is signed", - EnvVar: "DRONE_YAML_SIGNED", - }, - cli.BoolFlag{ - Name: "yaml.verified", - Usage: "yaml is signed and verified", - EnvVar: "DRONE_YAML_VERIFIED", - }, - - // Tag - cli.StringFlag{ - Name: "tag", - Usage: "git tag", - EnvVar: "CI_COMMIT_TAG", - }, - - // PullRequest - cli.StringFlag{ - Name: "pullRequest", - Usage: "pull request number", - EnvVar: "CI_COMMIT_PULL_REQUEST", - }, - - // DeployTo - cli.StringFlag{ - Name: "deployTo", - Usage: "deployment target", - EnvVar: "CI_PIPELINE_DEPLOY_TARGET", - }, - } - - if err := app.Run(os.Args); err != nil { - log.Fatal(err) - os.Exit(1) - } -} - -func run(c *cli.Context) error { - - var fromAddress string = c.String("from") - if fromAddress == "" { - fromAddress = c.String("from.address") - } - - plugin := Plugin{ - Context: c, - Repo: Repo{ - FullName: c.String("repo.fullName"), - Owner: c.String("repo.owner"), - Name: c.String("repo.name"), - SCM: c.String("repo.scm"), - Link: c.String("repo.link"), - Avatar: c.String("repo.avatar"), - Branch: c.String("repo.branch"), - Private: c.Bool("repo.private"), - Trusted: c.Bool("repo.trusted"), - }, - Remote: Remote{ - URL: c.String("remote.url"), - }, - Commit: Commit{ - Sha: c.String("commit.sha"), - Ref: c.String("commit.ref"), - Branch: c.String("commit.branch"), - Link: c.String("commit.link"), - Message: c.String("commit.message"), - Author: Author{ - Name: c.String("commit.author.name"), - Email: c.String("commit.author.email"), - Avatar: c.String("commit.author.avatar"), - }, - }, - Build: Build{ - Number: c.Int("build.number"), - Event: c.String("build.event"), - Status: c.String("build.status"), - Link: c.String("build.link"), - Created: c.Int64("build.created"), - Started: c.Int64("build.started"), - Finished: c.Int64("build.finished"), - }, - Prev: Prev{ - Build: PrevBuild{ - Status: c.String("prev.build.status"), - Number: c.Int("prev.build.number"), - }, - Commit: PrevCommit{ - Sha: c.String("prev.commit.sha"), - }, - }, - Job: Job{ - Status: c.String("job.status"), - ExitCode: c.Int("job.exitCode"), - Started: c.Int64("job.started"), - Finished: c.Int64("job.finished"), - }, - Yaml: Yaml{ - Signed: c.Bool("yaml.signed"), - Verified: c.Bool("yaml.verified"), - }, - Tag: c.String("tag"), - DeployTo: c.String("deployTo"), - Config: Config{ - FromAddress: fromAddress, - FromName: c.String("from.name"), - Host: c.String("host"), - Port: c.Int("port"), - Username: c.String("username"), - Password: c.String("password"), - SkipVerify: c.Bool("skip.verify"), - NoStartTLS: c.Bool("no.starttls"), - Recipients: c.StringSlice("recipients"), - RecipientsFile: c.String("recipients.file"), - RecipientsOnly: c.Bool("recipients.only"), - Subject: c.String("template.subject"), - Body: c.String("template.body"), - Attachment: c.String("attachment"), - Attachments: c.StringSlice("attachments"), - ClientHostname: c.String("clienthostname"), - Evaluation: c.String("evaluate"), - }, - } - - if len(c.String("pullRequest")) > 0 { - plugin.PullRequest = c.Int("pullRequest") - } - - return plugin.Exec() -} diff --git a/plugin.go b/plugin.go deleted file mode 100644 index 51ac460..0000000 --- a/plugin.go +++ /dev/null @@ -1,320 +0,0 @@ -package main - -import ( - "bufio" - "crypto/tls" - "fmt" - "os" - - log "github.com/Sirupsen/logrus" - "github.com/antonmedv/expr" - "github.com/aymerick/douceur/inliner" - "github.com/drone/drone-go/template" - "github.com/jaytaylor/html2text" - "github.com/urfave/cli" - gomail "gopkg.in/mail.v2" -) - -type ( - Repo struct { - FullName string - Owner string - Name string - SCM string - Link string - Avatar string - Branch string - Private bool - Trusted bool - } - - Remote struct { - URL string - } - - Author struct { - Name string - Email string - Avatar string - } - - Commit struct { - Sha string - Ref string - Branch string - Link string - Message string - Author Author - } - - Build struct { - Number int - Event string - Status string - Link string - Created int64 - Started int64 - Finished int64 - } - - PrevBuild struct { - Status string - Number int - } - - PrevCommit struct { - Sha string - } - - Prev struct { - Build PrevBuild - Commit PrevCommit - } - - Job struct { - Status string - ExitCode int - Started int64 - Finished int64 - } - - Yaml struct { - Signed bool - Verified bool - } - - Config struct { - FromAddress string - FromName string - Host string - Port int - Username string - Password string - SkipVerify bool - NoStartTLS bool - Recipients []string - RecipientsFile string - RecipientsOnly bool - Subject string - Body string - Attachment string - Attachments []string - ClientHostname string - Evaluation string - } - - Plugin struct { - Context *cli.Context - Repo Repo - Remote Remote - Commit Commit - Build Build - Prev Prev - Job Job - Yaml Yaml - Tag string - PullRequest int - DeployTo string - Config Config - } -) - -// Exec will send emails over SMTP -func (p Plugin) Exec() error { - if p.Config.Evaluation != "" { - env := p.Environ() - - fmt.Printf("%+v\n", expr.Env(env)) - - out, err := expr.Compile(p.Config.Evaluation, expr.Env(env), expr.AsBool()) - - if err != nil { - return err - } - - result, err := expr.Run(out, env) - - if err != nil { - return err - } - - if result.(bool) == false { - return nil - } - } - - var dialer *gomail.Dialer - - if !p.Config.RecipientsOnly { - exists := false - for _, recipient := range p.Config.Recipients { - if recipient == p.Commit.Author.Email { - exists = true - } - } - - if !exists { - p.Config.Recipients = append(p.Config.Recipients, p.Commit.Author.Email) - } - } - - if p.Config.RecipientsFile != "" { - f, err := os.Open(p.Config.RecipientsFile) - if err == nil { - scanner := bufio.NewScanner(f) - for scanner.Scan() { - p.Config.Recipients = append(p.Config.Recipients, scanner.Text()) - } - } else { - log.Errorf("Could not open RecipientsFile %s: %v", p.Config.RecipientsFile, err) - } - } - - if p.Config.Username == "" && p.Config.Password == "" { - dialer = &gomail.Dialer{Host: p.Config.Host, Port: p.Config.Port} - } else { - dialer = gomail.NewDialer(p.Config.Host, p.Config.Port, p.Config.Username, p.Config.Password) - } - - if p.Config.SkipVerify { - dialer.TLSConfig = &tls.Config{InsecureSkipVerify: true} - } - - if p.Config.NoStartTLS { - dialer.StartTLSPolicy = gomail.NoStartTLS - } - - dialer.LocalName = p.Config.ClientHostname - - closer, err := dialer.Dial() - if err != nil { - log.Errorf("Error while dialing SMTP server: %v", err) - return err - } - - type Context struct { - Repo Repo - Remote Remote - Commit Commit - Build Build - Prev Prev - Job Job - Yaml Yaml - Tag string - PullRequest int - DeployTo string - } - ctx := Context{ - Repo: p.Repo, - Remote: p.Remote, - Commit: p.Commit, - Build: p.Build, - Prev: p.Prev, - Job: p.Job, - Yaml: p.Yaml, - Tag: p.Tag, - PullRequest: p.PullRequest, - DeployTo: p.DeployTo, - } - - // Render body in HTML and plain text - renderedBody, err := template.RenderTrim(p.Config.Body, ctx) - if err != nil { - log.Errorf("Could not render body template: %v", err) - return err - } - html, err := inliner.Inline(renderedBody) - if err != nil { - log.Errorf("Could not inline rendered body: %v", err) - return err - } - plainBody, err := html2text.FromString(html) - if err != nil { - log.Errorf("Could not convert html to text: %v", err) - return err - } - - // Render subject - subject, err := template.RenderTrim(p.Config.Subject, ctx) - if err != nil { - log.Errorf("Could not render subject template: %v", err) - return err - } - - // Send emails - message := gomail.NewMessage() - for _, recipient := range p.Config.Recipients { - if len(recipient) == 0 { - continue - } - message.SetAddressHeader("From", p.Config.FromAddress, p.Config.FromName) - message.SetAddressHeader("To", recipient, "") - message.SetHeader("Subject", subject) - message.AddAlternative("text/plain", plainBody) - message.AddAlternative("text/html", html) - - if p.Config.Attachment != "" { - attach(message, p.Config.Attachment) - } - - for _, attachment := range p.Config.Attachments { - attach(message, attachment) - } - - if err := gomail.Send(closer, message); err != nil { - log.Errorf("Could not send email to %q: %v", recipient, err) - return err - } - message.Reset() - } - - return nil -} - -func (p Plugin) Environ() map[string]string { - return map[string]string{ - "CI_REPO_OWNER": p.Context.String("repo.owner"), - "CI_REPO_NAME": p.Context.String("repo.name"), - "CI_REPO_SCM": p.Context.String("repo.scm"), - "CI_REPO_LINK": p.Context.String("repo.link"), - "DRONE_REPO_AVATAR": p.Context.String("repo.avatar"), - "CI_REPO_DEFAULT_BRANCH": p.Context.String("repo.branch"), - "CI_REPO_PRIVATE": p.Context.String("repo.private"), - "DRONE_REPO_TRUSTED": p.Context.String("repo.trusted"), - "CI_REPO_CLONE_URL": p.Context.String("remote.url"), - "CI_COMMIT_SHA": p.Context.String("commit.sha"), - "CI_COMMIT_REF": p.Context.String("commit.ref"), - "CI_COMMIT_BRANCH": p.Context.String("commit.branch"), - "CI_COMMIT_LINK": p.Context.String("commit.link"), - "CI_COMMIT_MESSAGE": p.Context.String("commit.message"), - "CI_COMMIT_AUTHOR": p.Context.String("commit.author.name"), - "CI_COMMIT_AUTHOR_EMAIL": p.Context.String("commit.author.email"), - "CI_COMMIT_AUTHOR_AVATAR": p.Context.String("commit.author.avatar"), - "CI_BUILD_NUMBER": p.Context.String("build.number"), - "CI_BUILD_EVENT": p.Context.String("build.event"), - "CI_PIPELINE_STATUS": p.Context.String("build.status"), - "CI_PIPELINE_LINK": p.Context.String("build.link"), - "CI_PIPELINE_CREATED": p.Context.String("build.created"), - "CI_PIPELINE_STARTED": p.Context.String("build.started"), - "CI_PIPELINE_FINISHED": p.Context.String("build.finished"), - "CI_PREV_PIPELINE_STATUS": p.Context.String("prev.build.status"), - "CI_PREV_PIPELINE_NUMBER": p.Context.String("prev.build.number"), - "CI_PREV_COMMIT_SHA": p.Context.String("prev.commit.sha"), - "CI_STEP_NUMBER": p.Context.String("job.number"), - "CI_STEP_STATUS": p.Context.String("job.status"), - "DRONE_JOB_EXIT_CODE": p.Context.String("job.exitCode"), - "CI_STEP_STARTED": p.Context.String("job.started"), - "CI_STEP_FINISHED": p.Context.String("job.finished"), - "DRONE_YAML_SIGNED": p.Context.String("yaml.signed"), - "DRONE_YAML_VERIFIED": p.Context.String("yaml.verified"), - "CI_COMMIT_TAG": p.Context.String("tag"), - "CI_COMMIT_PULL_REQUEST": p.Context.String("pullRequest"), - "CI_PIPELINE_DEPLOY_TARGET": p.Context.String("deployTo"), - } -} - -func attach(message *gomail.Message, attachment string) { - if _, err := os.Stat(attachment); err == nil { - message.Attach(attachment) - } -} diff --git a/src/Factory/EmailFactory.php b/src/Factory/EmailFactory.php new file mode 100644 index 0000000..59b6c62 --- /dev/null +++ b/src/Factory/EmailFactory.php @@ -0,0 +1,76 @@ +config['dsn'])); + } + + public function createEmail(): Email + { + $from = json_decode($this->config['from'], true); + $content = json_decode($this->config['content'], true); + + $subject = $this->twig->createTemplate( + $content['subject'] ?? '[{{ pipeline.status }}] {{ repo.full_name }} ({{ commit.branch }} - {{ commit.sha[0:8] }})' + ); + + $email = (new Email()) + ->subject($subject->render($this->build)) + ->from( + new Address( + $from['address'] ?? '', + $from['name'] ?? '' + ) + ) + ; + + $recipients = explode(',', $this->config['recipients']); + $attachments = explode(',', $this->config['attachments']); + + foreach ($recipients as $item) { + $item = filter_var(trim($item), FILTER_VALIDATE_EMAIL); + + if ($item) { + $email->addBcc($item); + } + } + + foreach ($attachments as $item) { + foreach (glob($item) as $file) { + if (is_file($file)) { + $email->addPart(new DataPart(new File($file))); + } + } + } + + if (false === $this->config['is_recipients_only']) { + $email->addBcc($this->build['commit']['author_email']); + } + + $email->html($this->twig->render('build_status.html.twig', [ + 'build' => $this->build, + 'body' => $content['body'] ?? null, + ])); + + return $email; + } +} diff --git a/src/Factory/TwigFactory.php b/src/Factory/TwigFactory.php new file mode 100644 index 0000000..a5b16ca --- /dev/null +++ b/src/Factory/TwigFactory.php @@ -0,0 +1,22 @@ +addExtension(new StringLoaderExtension()); + $twig->addExtension(new DebugExtension()); + + return $twig; + } +} diff --git a/src/Loader/EnvVarLoader.php b/src/Loader/EnvVarLoader.php new file mode 100644 index 0000000..52a53f5 --- /dev/null +++ b/src/Loader/EnvVarLoader.php @@ -0,0 +1,41 @@ + $value) { + if (is_array($value)) { + $container[$key] = self::buildArray($value, $defaultValues); + } else { + $data = getenv($value); + + if (false === $data) { + $data = $defaultValues[$value] ?? null; + } + + if (str_ends_with($key, '_at') && ctype_digit($data)) { + $date = new \DateTime(); + $date->setTimestamp((int) $data); + $data = $date; + } elseif (str_starts_with($key, 'is_')) { + if (in_array(strtolower($data), ['1', 'true', 'yes'])) { + $data = true; + } elseif (in_array(strtolower($data), ['0', 'false', 'no'])) { + $data = false; + } else { + $data = $defaultValues[$value] ?? false; + } + } + + $container[$key] = $data; + } + } + + return $container; + } +} diff --git a/src/Loader/functions.php b/src/Loader/functions.php new file mode 100644 index 0000000..ac2f2db --- /dev/null +++ b/src/Loader/functions.php @@ -0,0 +1,38 @@ + $value) { + if (is_array($value)) { + $container[$key] = loadEnVars($value); + } else { + $data = getenv($value); + + if ($data === false) { + $data = $defaults[$value] ?? null; + } + + if (str_ends_with($key, '_at') && ctype_digit($data)) { + $date = new \DateTime(); + $date->setTimestamp((int) $data); + $data = $date; + } elseif (str_starts_with($key, 'is_')) { + if (in_array(strtolower($data), ['1', 'true', 'yes'])) { + $data = true; + } elseif (in_array(strtolower($data), ['0', 'false', 'no'])) { + $data = false; + } else { + $data = $defaults[$value] ?? false; + } + } + + $container[$key] = $data; + } + } + + return $container; +} diff --git a/src/Pipeline/Evaluation.php b/src/Pipeline/Evaluation.php new file mode 100644 index 0000000..fd297d8 --- /dev/null +++ b/src/Pipeline/Evaluation.php @@ -0,0 +1,21 @@ +twig->createTemplate($rule); + + return 'true' === $template->render($data); + } +} diff --git a/templates/_base.html.twig b/templates/_base.html.twig new file mode 100644 index 0000000..df99245 --- /dev/null +++ b/templates/_base.html.twig @@ -0,0 +1,170 @@ + + + + + + + + + {% block body %} + {% endblock %} + + diff --git a/templates/build_status.html.twig b/templates/build_status.html.twig new file mode 100644 index 0000000..3c272cb --- /dev/null +++ b/templates/build_status.html.twig @@ -0,0 +1,93 @@ +{% extends '_base.html.twig' %} + +{% block body %} + + + + + + +
+
+ + + {% if build.pipeline.status == 'success' %} + + {% else %} + + {% endif %} + + + + +
+ + Successful pipeline #{{ build.pipeline.number }} + + + + Failed pipeline #{{ build.pipeline.number }} + +
+ {% if body is defined %} + + + + +
{{ include(template_from_string(body), build) }}
+ {% else %} + + + + + + + + + + + + + + + + + + + + + +
+ Repo: + + {{ build.repo.full_name }} +
+ Author: + + {{ build.commit.author }} ({{ build.commit.author_email }}) +
+ Branch: + + {{ build.commit.branch }} +
+ Commit: + + {{ build.commit.sha[0:8] }} +
+ Started at: + + {{ build.build.created_at|date('r') }} +
+
+ + + + +
+ {{ build.commit.message }} +
+ {% endif %} +
+
+
+{% endblock %} diff --git a/vendor/github.com/PuerkitoBio/goquery/.gitattributes b/vendor/github.com/PuerkitoBio/goquery/.gitattributes deleted file mode 100644 index 0cc26ec..0000000 --- a/vendor/github.com/PuerkitoBio/goquery/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -testdata/* linguist-vendored diff --git a/vendor/github.com/PuerkitoBio/goquery/.gitignore b/vendor/github.com/PuerkitoBio/goquery/.gitignore deleted file mode 100644 index 970381c..0000000 --- a/vendor/github.com/PuerkitoBio/goquery/.gitignore +++ /dev/null @@ -1,16 +0,0 @@ -# editor temporary files -*.sublime-* -.DS_Store -*.swp -#*.*# -tags - -# direnv config -.env* - -# test binaries -*.test - -# coverage and profilte outputs -*.out - diff --git a/vendor/github.com/PuerkitoBio/goquery/.travis.yml b/vendor/github.com/PuerkitoBio/goquery/.travis.yml deleted file mode 100644 index bc1e7cb..0000000 --- a/vendor/github.com/PuerkitoBio/goquery/.travis.yml +++ /dev/null @@ -1,11 +0,0 @@ -language: go - -go: - - 1.1 - - 1.2 - - 1.3 - - 1.4 - - 1.5 - - 1.6 - - 1.7 - - tip diff --git a/vendor/github.com/PuerkitoBio/goquery/LICENSE b/vendor/github.com/PuerkitoBio/goquery/LICENSE deleted file mode 100644 index f743d37..0000000 --- a/vendor/github.com/PuerkitoBio/goquery/LICENSE +++ /dev/null @@ -1,12 +0,0 @@ -Copyright (c) 2012-2016, Martin Angers & Contributors -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - -* Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/PuerkitoBio/goquery/README.md b/vendor/github.com/PuerkitoBio/goquery/README.md deleted file mode 100644 index 800a8b7..0000000 --- a/vendor/github.com/PuerkitoBio/goquery/README.md +++ /dev/null @@ -1,123 +0,0 @@ -# goquery - a little like that j-thing, only in Go [![build status](https://secure.travis-ci.org/PuerkitoBio/goquery.png)](http://travis-ci.org/PuerkitoBio/goquery) [![GoDoc](https://godoc.org/github.com/PuerkitoBio/goquery?status.png)](http://godoc.org/github.com/PuerkitoBio/goquery) - -goquery brings a syntax and a set of features similar to [jQuery][] to the [Go language][go]. It is based on Go's [net/html package][html] and the CSS Selector library [cascadia][]. Since the net/html parser returns nodes, and not a full-featured DOM tree, jQuery's stateful manipulation functions (like height(), css(), detach()) have been left off. - -Also, because the net/html parser requires UTF-8 encoding, so does goquery: it is the caller's responsibility to ensure that the source document provides UTF-8 encoded HTML. See the [wiki][] for various options to do this. - -Syntax-wise, it is as close as possible to jQuery, with the same function names when possible, and that warm and fuzzy chainable interface. jQuery being the ultra-popular library that it is, I felt that writing a similar HTML-manipulating library was better to follow its API than to start anew (in the same spirit as Go's `fmt` package), even though some of its methods are less than intuitive (looking at you, [index()][index]...). - -## Installation - -Please note that because of the net/html dependency, goquery requires Go1.1+. - - $ go get github.com/PuerkitoBio/goquery - -(optional) To run unit tests: - - $ cd $GOPATH/src/github.com/PuerkitoBio/goquery - $ go test - -(optional) To run benchmarks (warning: it runs for a few minutes): - - $ cd $GOPATH/src/github.com/PuerkitoBio/goquery - $ go test -bench=".*" - -## Changelog - -**Note that goquery's API is now stable, and will not break.** - -* **2016-12-29 (v1.0.2)** : Optimize allocations for `Selection.Text` (thanks to @radovskyb). -* **2016-08-28 (v1.0.1)** : Optimize performance for large documents. -* **2016-07-27 (v1.0.0)** : Tag version 1.0.0. -* **2016-06-15** : Invalid selector strings internally compile to a `Matcher` implementation that never matches any node (instead of a panic). So for example, `doc.Find("~")` returns an empty `*Selection` object. -* **2016-02-02** : Add `NodeName` utility function similar to the DOM's `nodeName` property. It returns the tag name of the first element in a selection, and other relevant values of non-element nodes (see godoc for details). Add `OuterHtml` utility function similar to the DOM's `outerHTML` property (named `OuterHtml` in small caps for consistency with the existing `Html` method on the `Selection`). -* **2015-04-20** : Add `AttrOr` helper method to return the attribute's value or a default value if absent. Thanks to [piotrkowalczuk][piotr]. -* **2015-02-04** : Add more manipulation functions - Prepend* - thanks again to [Andrew Stone][thatguystone]. -* **2014-11-28** : Add more manipulation functions - ReplaceWith*, Wrap* and Unwrap - thanks again to [Andrew Stone][thatguystone]. -* **2014-11-07** : Add manipulation functions (thanks to [Andrew Stone][thatguystone]) and `*Matcher` functions, that receive compiled cascadia selectors instead of selector strings, thus avoiding potential panics thrown by goquery via `cascadia.MustCompile` calls. This results in better performance (selectors can be compiled once and reused) and more idiomatic error handling (you can handle cascadia's compilation errors, instead of recovering from panics, which had been bugging me for a long time). Note that the actual type expected is a `Matcher` interface, that `cascadia.Selector` implements. Other matcher implementations could be used. -* **2014-11-06** : Change import paths of net/html to golang.org/x/net/html (see https://groups.google.com/forum/#!topic/golang-nuts/eD8dh3T9yyA). Make sure to update your code to use the new import path too when you call goquery with `html.Node`s. -* **v0.3.2** : Add `NewDocumentFromReader()` (thanks jweir) which allows creating a goquery document from an io.Reader. -* **v0.3.1** : Add `NewDocumentFromResponse()` (thanks assassingj) which allows creating a goquery document from an http response. -* **v0.3.0** : Add `EachWithBreak()` which allows to break out of an `Each()` loop by returning false. This function was added instead of changing the existing `Each()` to avoid breaking compatibility. -* **v0.2.1** : Make go-getable, now that [go.net/html is Go1.0-compatible][gonet] (thanks to @matrixik for pointing this out). -* **v0.2.0** : Add support for negative indices in Slice(). **BREAKING CHANGE** `Document.Root` is removed, `Document` is now a `Selection` itself (a selection of one, the root element, just like `Document.Root` was before). Add jQuery's Closest() method. -* **v0.1.1** : Add benchmarks to use as baseline for refactorings, refactor Next...() and Prev...() methods to use the new html package's linked list features (Next/PrevSibling, FirstChild). Good performance boost (40+% in some cases). -* **v0.1.0** : Initial release. - -## API - -goquery exposes two structs, `Document` and `Selection`, and the `Matcher` interface. Unlike jQuery, which is loaded as part of a DOM document, and thus acts on its containing document, goquery doesn't know which HTML document to act upon. So it needs to be told, and that's what the `Document` type is for. It holds the root document node as the initial Selection value to manipulate. - -jQuery often has many variants for the same function (no argument, a selector string argument, a jQuery object argument, a DOM element argument, ...). Instead of exposing the same features in goquery as a single method with variadic empty interface arguments, statically-typed signatures are used following this naming convention: - -* When the jQuery equivalent can be called with no argument, it has the same name as jQuery for the no argument signature (e.g.: `Prev()`), and the version with a selector string argument is called `XxxFiltered()` (e.g.: `PrevFiltered()`) -* When the jQuery equivalent **requires** one argument, the same name as jQuery is used for the selector string version (e.g.: `Is()`) -* The signatures accepting a jQuery object as argument are defined in goquery as `XxxSelection()` and take a `*Selection` object as argument (e.g.: `FilterSelection()`) -* The signatures accepting a DOM element as argument in jQuery are defined in goquery as `XxxNodes()` and take a variadic argument of type `*html.Node` (e.g.: `FilterNodes()`) -* The signatures accepting a function as argument in jQuery are defined in goquery as `XxxFunction()` and take a function as argument (e.g.: `FilterFunction()`) -* The goquery methods that can be called with a selector string have a corresponding version that take a `Matcher` interface and are defined as `XxxMatcher()` (e.g.: `IsMatcher()`) - -Utility functions that are not in jQuery but are useful in Go are implemented as functions (that take a `*Selection` as parameter), to avoid a potential naming clash on the `*Selection`'s methods (reserved for jQuery-equivalent behaviour). - -The complete [godoc reference documentation can be found here][doc]. - -Please note that Cascadia's selectors do not necessarily match all supported selectors of jQuery (Sizzle). See the [cascadia project][cascadia] for details. Invalid selector strings compile to a `Matcher` that fails to match any node. Behaviour of the various functions that take a selector string as argument follows from that fact, e.g. (where `~` is an invalid selector string): - -* `Find("~")` returns an empty selection because the selector string doesn't match anything. -* `Add("~")` returns a new selection that holds the same nodes as the original selection, because it didn't add any node (selector string didn't match anything). -* `ParentsFiltered("~")` returns an empty selection because the selector string doesn't match anything. -* `ParentsUntil("~")` returns all parents of the selection because the selector string didn't match any element to stop before the top element. - -## Examples - -See some tips and tricks in the [wiki][]. - -Adapted from example_test.go: - -```Go -package main - -import ( - "fmt" - "log" - - "github.com/PuerkitoBio/goquery" -) - -func ExampleScrape() { - doc, err := goquery.NewDocument("http://metalsucks.net") - if err != nil { - log.Fatal(err) - } - - // Find the review items - doc.Find(".sidebar-reviews article .content-block").Each(func(i int, s *goquery.Selection) { - // For each item found, get the band and title - band := s.Find("a").Text() - title := s.Find("i").Text() - fmt.Printf("Review %d: %s - %s\n", i, band, title) - }) -} - -func main() { - ExampleScrape() -} -``` - -## License - -The [BSD 3-Clause license][bsd], the same as the [Go language][golic]. Cascadia's license is [here][caslic]. - -[jquery]: http://jquery.com/ -[go]: http://golang.org/ -[cascadia]: https://github.com/andybalholm/cascadia -[bsd]: http://opensource.org/licenses/BSD-3-Clause -[golic]: http://golang.org/LICENSE -[caslic]: https://github.com/andybalholm/cascadia/blob/master/LICENSE -[doc]: http://godoc.org/github.com/PuerkitoBio/goquery -[index]: http://api.jquery.com/index/ -[gonet]: https://github.com/golang/net/ -[html]: http://godoc.org/golang.org/x/net/html -[wiki]: https://github.com/PuerkitoBio/goquery/wiki/Tips-and-tricks -[thatguystone]: https://github.com/thatguystone -[piotr]: https://github.com/piotrkowalczuk diff --git a/vendor/github.com/PuerkitoBio/goquery/array.go b/vendor/github.com/PuerkitoBio/goquery/array.go deleted file mode 100644 index d7af5ee..0000000 --- a/vendor/github.com/PuerkitoBio/goquery/array.go +++ /dev/null @@ -1,103 +0,0 @@ -package goquery - -import ( - "golang.org/x/net/html" -) - -// First reduces the set of matched elements to the first in the set. -// It returns a new Selection object, and an empty Selection object if the -// the selection is empty. -func (s *Selection) First() *Selection { - return s.Eq(0) -} - -// Last reduces the set of matched elements to the last in the set. -// It returns a new Selection object, and an empty Selection object if -// the selection is empty. -func (s *Selection) Last() *Selection { - return s.Eq(-1) -} - -// Eq reduces the set of matched elements to the one at the specified index. -// If a negative index is given, it counts backwards starting at the end of the -// set. It returns a new Selection object, and an empty Selection object if the -// index is invalid. -func (s *Selection) Eq(index int) *Selection { - if index < 0 { - index += len(s.Nodes) - } - - if index >= len(s.Nodes) || index < 0 { - return newEmptySelection(s.document) - } - - return s.Slice(index, index+1) -} - -// Slice reduces the set of matched elements to a subset specified by a range -// of indices. -func (s *Selection) Slice(start, end int) *Selection { - if start < 0 { - start += len(s.Nodes) - } - if end < 0 { - end += len(s.Nodes) - } - return pushStack(s, s.Nodes[start:end]) -} - -// Get retrieves the underlying node at the specified index. -// Get without parameter is not implemented, since the node array is available -// on the Selection object. -func (s *Selection) Get(index int) *html.Node { - if index < 0 { - index += len(s.Nodes) // Negative index gets from the end - } - return s.Nodes[index] -} - -// Index returns the position of the first element within the Selection object -// relative to its sibling elements. -func (s *Selection) Index() int { - if len(s.Nodes) > 0 { - return newSingleSelection(s.Nodes[0], s.document).PrevAll().Length() - } - return -1 -} - -// IndexSelector returns the position of the first element within the -// Selection object relative to the elements matched by the selector, or -1 if -// not found. -func (s *Selection) IndexSelector(selector string) int { - if len(s.Nodes) > 0 { - sel := s.document.Find(selector) - return indexInSlice(sel.Nodes, s.Nodes[0]) - } - return -1 -} - -// IndexMatcher returns the position of the first element within the -// Selection object relative to the elements matched by the matcher, or -1 if -// not found. -func (s *Selection) IndexMatcher(m Matcher) int { - if len(s.Nodes) > 0 { - sel := s.document.FindMatcher(m) - return indexInSlice(sel.Nodes, s.Nodes[0]) - } - return -1 -} - -// IndexOfNode returns the position of the specified node within the Selection -// object, or -1 if not found. -func (s *Selection) IndexOfNode(node *html.Node) int { - return indexInSlice(s.Nodes, node) -} - -// IndexOfSelection returns the position of the first node in the specified -// Selection object within this Selection object, or -1 if not found. -func (s *Selection) IndexOfSelection(sel *Selection) int { - if sel != nil && len(sel.Nodes) > 0 { - return indexInSlice(s.Nodes, sel.Nodes[0]) - } - return -1 -} diff --git a/vendor/github.com/PuerkitoBio/goquery/doc.go b/vendor/github.com/PuerkitoBio/goquery/doc.go deleted file mode 100644 index 71146a7..0000000 --- a/vendor/github.com/PuerkitoBio/goquery/doc.go +++ /dev/null @@ -1,123 +0,0 @@ -// Copyright (c) 2012-2016, Martin Angers & Contributors -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without modification, -// are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation and/or -// other materials provided with the distribution. -// * Neither the name of the author nor the names of its contributors may be used to -// endorse or promote products derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS -// OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY -// AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY -// WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -/* -Package goquery implements features similar to jQuery, including the chainable -syntax, to manipulate and query an HTML document. - -It brings a syntax and a set of features similar to jQuery to the Go language. -It is based on Go's net/html package and the CSS Selector library cascadia. -Since the net/html parser returns nodes, and not a full-featured DOM -tree, jQuery's stateful manipulation functions (like height(), css(), detach()) -have been left off. - -Also, because the net/html parser requires UTF-8 encoding, so does goquery: it is -the caller's responsibility to ensure that the source document provides UTF-8 encoded HTML. -See the repository's wiki for various options on how to do this. - -Syntax-wise, it is as close as possible to jQuery, with the same method names when -possible, and that warm and fuzzy chainable interface. jQuery being the -ultra-popular library that it is, writing a similar HTML-manipulating -library was better to follow its API than to start anew (in the same spirit as -Go's fmt package), even though some of its methods are less than intuitive (looking -at you, index()...). - -It is hosted on GitHub, along with additional documentation in the README.md -file: https://github.com/puerkitobio/goquery - -Please note that because of the net/html dependency, goquery requires Go1.1+. - -The various methods are split into files based on the category of behavior. -The three dots (...) indicate that various "overloads" are available. - -* array.go : array-like positional manipulation of the selection. - - Eq() - - First() - - Get() - - Index...() - - Last() - - Slice() - -* expand.go : methods that expand or augment the selection's set. - - Add...() - - AndSelf() - - Union(), which is an alias for AddSelection() - -* filter.go : filtering methods, that reduce the selection's set. - - End() - - Filter...() - - Has...() - - Intersection(), which is an alias of FilterSelection() - - Not...() - -* iteration.go : methods to loop over the selection's nodes. - - Each() - - EachWithBreak() - - Map() - -* manipulation.go : methods for modifying the document - - After...() - - Append...() - - Before...() - - Clone() - - Empty() - - Prepend...() - - Remove...() - - ReplaceWith...() - - Unwrap() - - Wrap...() - - WrapAll...() - - WrapInner...() - -* property.go : methods that inspect and get the node's properties values. - - Attr*(), RemoveAttr(), SetAttr() - - AddClass(), HasClass(), RemoveClass(), ToggleClass() - - Html() - - Length() - - Size(), which is an alias for Length() - - Text() - -* query.go : methods that query, or reflect, a node's identity. - - Contains() - - Is...() - -* traversal.go : methods to traverse the HTML document tree. - - Children...() - - Contents() - - Find...() - - Next...() - - Parent[s]...() - - Prev...() - - Siblings...() - -* type.go : definition of the types exposed by goquery. - - Document - - Selection - - Matcher - -* utilities.go : definition of helper functions (and not methods on a *Selection) -that are not part of jQuery, but are useful to goquery. - - NodeName - - OuterHtml -*/ -package goquery diff --git a/vendor/github.com/PuerkitoBio/goquery/expand.go b/vendor/github.com/PuerkitoBio/goquery/expand.go deleted file mode 100644 index f0c6c86..0000000 --- a/vendor/github.com/PuerkitoBio/goquery/expand.go +++ /dev/null @@ -1,46 +0,0 @@ -package goquery - -import "golang.org/x/net/html" - -// Add adds the selector string's matching nodes to those in the current -// selection and returns a new Selection object. -// The selector string is run in the context of the document of the current -// Selection object. -func (s *Selection) Add(selector string) *Selection { - return s.AddNodes(findWithMatcher([]*html.Node{s.document.rootNode}, compileMatcher(selector))...) -} - -// AddMatcher adds the matcher's matching nodes to those in the current -// selection and returns a new Selection object. -// The matcher is run in the context of the document of the current -// Selection object. -func (s *Selection) AddMatcher(m Matcher) *Selection { - return s.AddNodes(findWithMatcher([]*html.Node{s.document.rootNode}, m)...) -} - -// AddSelection adds the specified Selection object's nodes to those in the -// current selection and returns a new Selection object. -func (s *Selection) AddSelection(sel *Selection) *Selection { - if sel == nil { - return s.AddNodes() - } - return s.AddNodes(sel.Nodes...) -} - -// Union is an alias for AddSelection. -func (s *Selection) Union(sel *Selection) *Selection { - return s.AddSelection(sel) -} - -// AddNodes adds the specified nodes to those in the -// current selection and returns a new Selection object. -func (s *Selection) AddNodes(nodes ...*html.Node) *Selection { - return pushStack(s, appendWithoutDuplicates(s.Nodes, nodes, nil)) -} - -// AndSelf adds the previous set of elements on the stack to the current set. -// It returns a new Selection object containing the current Selection combined -// with the previous one. -func (s *Selection) AndSelf() *Selection { - return s.AddSelection(s.prevSel) -} diff --git a/vendor/github.com/PuerkitoBio/goquery/filter.go b/vendor/github.com/PuerkitoBio/goquery/filter.go deleted file mode 100644 index 9138ffb..0000000 --- a/vendor/github.com/PuerkitoBio/goquery/filter.go +++ /dev/null @@ -1,163 +0,0 @@ -package goquery - -import "golang.org/x/net/html" - -// Filter reduces the set of matched elements to those that match the selector string. -// It returns a new Selection object for this subset of matching elements. -func (s *Selection) Filter(selector string) *Selection { - return s.FilterMatcher(compileMatcher(selector)) -} - -// FilterMatcher reduces the set of matched elements to those that match -// the given matcher. It returns a new Selection object for this subset -// of matching elements. -func (s *Selection) FilterMatcher(m Matcher) *Selection { - return pushStack(s, winnow(s, m, true)) -} - -// Not removes elements from the Selection that match the selector string. -// It returns a new Selection object with the matching elements removed. -func (s *Selection) Not(selector string) *Selection { - return s.NotMatcher(compileMatcher(selector)) -} - -// NotMatcher removes elements from the Selection that match the given matcher. -// It returns a new Selection object with the matching elements removed. -func (s *Selection) NotMatcher(m Matcher) *Selection { - return pushStack(s, winnow(s, m, false)) -} - -// FilterFunction reduces the set of matched elements to those that pass the function's test. -// It returns a new Selection object for this subset of elements. -func (s *Selection) FilterFunction(f func(int, *Selection) bool) *Selection { - return pushStack(s, winnowFunction(s, f, true)) -} - -// NotFunction removes elements from the Selection that pass the function's test. -// It returns a new Selection object with the matching elements removed. -func (s *Selection) NotFunction(f func(int, *Selection) bool) *Selection { - return pushStack(s, winnowFunction(s, f, false)) -} - -// FilterNodes reduces the set of matched elements to those that match the specified nodes. -// It returns a new Selection object for this subset of elements. -func (s *Selection) FilterNodes(nodes ...*html.Node) *Selection { - return pushStack(s, winnowNodes(s, nodes, true)) -} - -// NotNodes removes elements from the Selection that match the specified nodes. -// It returns a new Selection object with the matching elements removed. -func (s *Selection) NotNodes(nodes ...*html.Node) *Selection { - return pushStack(s, winnowNodes(s, nodes, false)) -} - -// FilterSelection reduces the set of matched elements to those that match a -// node in the specified Selection object. -// It returns a new Selection object for this subset of elements. -func (s *Selection) FilterSelection(sel *Selection) *Selection { - if sel == nil { - return pushStack(s, winnowNodes(s, nil, true)) - } - return pushStack(s, winnowNodes(s, sel.Nodes, true)) -} - -// NotSelection removes elements from the Selection that match a node in the specified -// Selection object. It returns a new Selection object with the matching elements removed. -func (s *Selection) NotSelection(sel *Selection) *Selection { - if sel == nil { - return pushStack(s, winnowNodes(s, nil, false)) - } - return pushStack(s, winnowNodes(s, sel.Nodes, false)) -} - -// Intersection is an alias for FilterSelection. -func (s *Selection) Intersection(sel *Selection) *Selection { - return s.FilterSelection(sel) -} - -// Has reduces the set of matched elements to those that have a descendant -// that matches the selector. -// It returns a new Selection object with the matching elements. -func (s *Selection) Has(selector string) *Selection { - return s.HasSelection(s.document.Find(selector)) -} - -// HasMatcher reduces the set of matched elements to those that have a descendant -// that matches the matcher. -// It returns a new Selection object with the matching elements. -func (s *Selection) HasMatcher(m Matcher) *Selection { - return s.HasSelection(s.document.FindMatcher(m)) -} - -// HasNodes reduces the set of matched elements to those that have a -// descendant that matches one of the nodes. -// It returns a new Selection object with the matching elements. -func (s *Selection) HasNodes(nodes ...*html.Node) *Selection { - return s.FilterFunction(func(_ int, sel *Selection) bool { - // Add all nodes that contain one of the specified nodes - for _, n := range nodes { - if sel.Contains(n) { - return true - } - } - return false - }) -} - -// HasSelection reduces the set of matched elements to those that have a -// descendant that matches one of the nodes of the specified Selection object. -// It returns a new Selection object with the matching elements. -func (s *Selection) HasSelection(sel *Selection) *Selection { - if sel == nil { - return s.HasNodes() - } - return s.HasNodes(sel.Nodes...) -} - -// End ends the most recent filtering operation in the current chain and -// returns the set of matched elements to its previous state. -func (s *Selection) End() *Selection { - if s.prevSel != nil { - return s.prevSel - } - return newEmptySelection(s.document) -} - -// Filter based on the matcher, and the indicator to keep (Filter) or -// to get rid of (Not) the matching elements. -func winnow(sel *Selection, m Matcher, keep bool) []*html.Node { - // Optimize if keep is requested - if keep { - return m.Filter(sel.Nodes) - } - // Use grep - return grep(sel, func(i int, s *Selection) bool { - return !m.Match(s.Get(0)) - }) -} - -// Filter based on an array of nodes, and the indicator to keep (Filter) or -// to get rid of (Not) the matching elements. -func winnowNodes(sel *Selection, nodes []*html.Node, keep bool) []*html.Node { - if len(nodes)+len(sel.Nodes) < minNodesForSet { - return grep(sel, func(i int, s *Selection) bool { - return isInSlice(nodes, s.Get(0)) == keep - }) - } - - set := make(map[*html.Node]bool) - for _, n := range nodes { - set[n] = true - } - return grep(sel, func(i int, s *Selection) bool { - return set[s.Get(0)] == keep - }) -} - -// Filter based on a function test, and the indicator to keep (Filter) or -// to get rid of (Not) the matching elements. -func winnowFunction(sel *Selection, f func(int, *Selection) bool, keep bool) []*html.Node { - return grep(sel, func(i int, s *Selection) bool { - return f(i, s) == keep - }) -} diff --git a/vendor/github.com/PuerkitoBio/goquery/iteration.go b/vendor/github.com/PuerkitoBio/goquery/iteration.go deleted file mode 100644 index e246f2e..0000000 --- a/vendor/github.com/PuerkitoBio/goquery/iteration.go +++ /dev/null @@ -1,39 +0,0 @@ -package goquery - -// Each iterates over a Selection object, executing a function for each -// matched element. It returns the current Selection object. The function -// f is called for each element in the selection with the index of the -// element in that selection starting at 0, and a *Selection that contains -// only that element. -func (s *Selection) Each(f func(int, *Selection)) *Selection { - for i, n := range s.Nodes { - f(i, newSingleSelection(n, s.document)) - } - return s -} - -// EachWithBreak iterates over a Selection object, executing a function for each -// matched element. It is identical to Each except that it is possible to break -// out of the loop by returning false in the callback function. It returns the -// current Selection object. -func (s *Selection) EachWithBreak(f func(int, *Selection) bool) *Selection { - for i, n := range s.Nodes { - if !f(i, newSingleSelection(n, s.document)) { - return s - } - } - return s -} - -// Map passes each element in the current matched set through a function, -// producing a slice of string holding the returned values. The function -// f is called for each element in the selection with the index of the -// element in that selection starting at 0, and a *Selection that contains -// only that element. -func (s *Selection) Map(f func(int, *Selection) string) (result []string) { - for i, n := range s.Nodes { - result = append(result, f(i, newSingleSelection(n, s.document))) - } - - return result -} diff --git a/vendor/github.com/PuerkitoBio/goquery/manipulation.go b/vendor/github.com/PuerkitoBio/goquery/manipulation.go deleted file mode 100644 index 3602a5a..0000000 --- a/vendor/github.com/PuerkitoBio/goquery/manipulation.go +++ /dev/null @@ -1,550 +0,0 @@ -package goquery - -import ( - "strings" - - "golang.org/x/net/html" -) - -// After applies the selector from the root document and inserts the matched elements -// after the elements in the set of matched elements. -// -// If one of the matched elements in the selection is not currently in the -// document, it's impossible to insert nodes after it, so it will be ignored. -// -// This follows the same rules as Selection.Append. -func (s *Selection) After(selector string) *Selection { - return s.AfterMatcher(compileMatcher(selector)) -} - -// AfterMatcher applies the matcher from the root document and inserts the matched elements -// after the elements in the set of matched elements. -// -// If one of the matched elements in the selection is not currently in the -// document, it's impossible to insert nodes after it, so it will be ignored. -// -// This follows the same rules as Selection.Append. -func (s *Selection) AfterMatcher(m Matcher) *Selection { - return s.AfterNodes(m.MatchAll(s.document.rootNode)...) -} - -// AfterSelection inserts the elements in the selection after each element in the set of matched -// elements. -// -// This follows the same rules as Selection.Append. -func (s *Selection) AfterSelection(sel *Selection) *Selection { - return s.AfterNodes(sel.Nodes...) -} - -// AfterHtml parses the html and inserts it after the set of matched elements. -// -// This follows the same rules as Selection.Append. -func (s *Selection) AfterHtml(html string) *Selection { - return s.AfterNodes(parseHtml(html)...) -} - -// AfterNodes inserts the nodes after each element in the set of matched elements. -// -// This follows the same rules as Selection.Append. -func (s *Selection) AfterNodes(ns ...*html.Node) *Selection { - return s.manipulateNodes(ns, true, func(sn *html.Node, n *html.Node) { - if sn.Parent != nil { - sn.Parent.InsertBefore(n, sn.NextSibling) - } - }) -} - -// Append appends the elements specified by the selector to the end of each element -// in the set of matched elements, following those rules: -// -// 1) The selector is applied to the root document. -// -// 2) Elements that are part of the document will be moved to the new location. -// -// 3) If there are multiple locations to append to, cloned nodes will be -// appended to all target locations except the last one, which will be moved -// as noted in (2). -func (s *Selection) Append(selector string) *Selection { - return s.AppendMatcher(compileMatcher(selector)) -} - -// AppendMatcher appends the elements specified by the matcher to the end of each element -// in the set of matched elements. -// -// This follows the same rules as Selection.Append. -func (s *Selection) AppendMatcher(m Matcher) *Selection { - return s.AppendNodes(m.MatchAll(s.document.rootNode)...) -} - -// AppendSelection appends the elements in the selection to the end of each element -// in the set of matched elements. -// -// This follows the same rules as Selection.Append. -func (s *Selection) AppendSelection(sel *Selection) *Selection { - return s.AppendNodes(sel.Nodes...) -} - -// AppendHtml parses the html and appends it to the set of matched elements. -func (s *Selection) AppendHtml(html string) *Selection { - return s.AppendNodes(parseHtml(html)...) -} - -// AppendNodes appends the specified nodes to each node in the set of matched elements. -// -// This follows the same rules as Selection.Append. -func (s *Selection) AppendNodes(ns ...*html.Node) *Selection { - return s.manipulateNodes(ns, false, func(sn *html.Node, n *html.Node) { - sn.AppendChild(n) - }) -} - -// Before inserts the matched elements before each element in the set of matched elements. -// -// This follows the same rules as Selection.Append. -func (s *Selection) Before(selector string) *Selection { - return s.BeforeMatcher(compileMatcher(selector)) -} - -// BeforeMatcher inserts the matched elements before each element in the set of matched elements. -// -// This follows the same rules as Selection.Append. -func (s *Selection) BeforeMatcher(m Matcher) *Selection { - return s.BeforeNodes(m.MatchAll(s.document.rootNode)...) -} - -// BeforeSelection inserts the elements in the selection before each element in the set of matched -// elements. -// -// This follows the same rules as Selection.Append. -func (s *Selection) BeforeSelection(sel *Selection) *Selection { - return s.BeforeNodes(sel.Nodes...) -} - -// BeforeHtml parses the html and inserts it before the set of matched elements. -// -// This follows the same rules as Selection.Append. -func (s *Selection) BeforeHtml(html string) *Selection { - return s.BeforeNodes(parseHtml(html)...) -} - -// BeforeNodes inserts the nodes before each element in the set of matched elements. -// -// This follows the same rules as Selection.Append. -func (s *Selection) BeforeNodes(ns ...*html.Node) *Selection { - return s.manipulateNodes(ns, false, func(sn *html.Node, n *html.Node) { - if sn.Parent != nil { - sn.Parent.InsertBefore(n, sn) - } - }) -} - -// Clone creates a deep copy of the set of matched nodes. The new nodes will not be -// attached to the document. -func (s *Selection) Clone() *Selection { - ns := newEmptySelection(s.document) - ns.Nodes = cloneNodes(s.Nodes) - return ns -} - -// Empty removes all children nodes from the set of matched elements. -// It returns the children nodes in a new Selection. -func (s *Selection) Empty() *Selection { - var nodes []*html.Node - - for _, n := range s.Nodes { - for c := n.FirstChild; c != nil; c = n.FirstChild { - n.RemoveChild(c) - nodes = append(nodes, c) - } - } - - return pushStack(s, nodes) -} - -// Prepend prepends the elements specified by the selector to each element in -// the set of matched elements, following the same rules as Append. -func (s *Selection) Prepend(selector string) *Selection { - return s.PrependMatcher(compileMatcher(selector)) -} - -// PrependMatcher prepends the elements specified by the matcher to each -// element in the set of matched elements. -// -// This follows the same rules as Selection.Append. -func (s *Selection) PrependMatcher(m Matcher) *Selection { - return s.PrependNodes(m.MatchAll(s.document.rootNode)...) -} - -// PrependSelection prepends the elements in the selection to each element in -// the set of matched elements. -// -// This follows the same rules as Selection.Append. -func (s *Selection) PrependSelection(sel *Selection) *Selection { - return s.PrependNodes(sel.Nodes...) -} - -// PrependHtml parses the html and prepends it to the set of matched elements. -func (s *Selection) PrependHtml(html string) *Selection { - return s.PrependNodes(parseHtml(html)...) -} - -// PrependNodes prepends the specified nodes to each node in the set of -// matched elements. -// -// This follows the same rules as Selection.Append. -func (s *Selection) PrependNodes(ns ...*html.Node) *Selection { - return s.manipulateNodes(ns, true, func(sn *html.Node, n *html.Node) { - // sn.FirstChild may be nil, in which case this functions like - // sn.AppendChild() - sn.InsertBefore(n, sn.FirstChild) - }) -} - -// Remove removes the set of matched elements from the document. -// It returns the same selection, now consisting of nodes not in the document. -func (s *Selection) Remove() *Selection { - for _, n := range s.Nodes { - if n.Parent != nil { - n.Parent.RemoveChild(n) - } - } - - return s -} - -// RemoveFiltered removes the set of matched elements by selector. -// It returns the Selection of removed nodes. -func (s *Selection) RemoveFiltered(selector string) *Selection { - return s.RemoveMatcher(compileMatcher(selector)) -} - -// RemoveMatcher removes the set of matched elements. -// It returns the Selection of removed nodes. -func (s *Selection) RemoveMatcher(m Matcher) *Selection { - return s.FilterMatcher(m).Remove() -} - -// ReplaceWith replaces each element in the set of matched elements with the -// nodes matched by the given selector. -// It returns the removed elements. -// -// This follows the same rules as Selection.Append. -func (s *Selection) ReplaceWith(selector string) *Selection { - return s.ReplaceWithMatcher(compileMatcher(selector)) -} - -// ReplaceWithMatcher replaces each element in the set of matched elements with -// the nodes matched by the given Matcher. -// It returns the removed elements. -// -// This follows the same rules as Selection.Append. -func (s *Selection) ReplaceWithMatcher(m Matcher) *Selection { - return s.ReplaceWithNodes(m.MatchAll(s.document.rootNode)...) -} - -// ReplaceWithSelection replaces each element in the set of matched elements with -// the nodes from the given Selection. -// It returns the removed elements. -// -// This follows the same rules as Selection.Append. -func (s *Selection) ReplaceWithSelection(sel *Selection) *Selection { - return s.ReplaceWithNodes(sel.Nodes...) -} - -// ReplaceWithHtml replaces each element in the set of matched elements with -// the parsed HTML. -// It returns the removed elements. -// -// This follows the same rules as Selection.Append. -func (s *Selection) ReplaceWithHtml(html string) *Selection { - return s.ReplaceWithNodes(parseHtml(html)...) -} - -// ReplaceWithNodes replaces each element in the set of matched elements with -// the given nodes. -// It returns the removed elements. -// -// This follows the same rules as Selection.Append. -func (s *Selection) ReplaceWithNodes(ns ...*html.Node) *Selection { - s.AfterNodes(ns...) - return s.Remove() -} - -// Unwrap removes the parents of the set of matched elements, leaving the matched -// elements (and their siblings, if any) in their place. -// It returns the original selection. -func (s *Selection) Unwrap() *Selection { - s.Parent().Each(func(i int, ss *Selection) { - // For some reason, jquery allows unwrap to remove the element, so - // allowing it here too. Same for . Why it allows those elements to - // be unwrapped while not allowing body is a mystery to me. - if ss.Nodes[0].Data != "body" { - ss.ReplaceWithSelection(ss.Contents()) - } - }) - - return s -} - -// Wrap wraps each element in the set of matched elements inside the first -// element matched by the given selector. The matched child is cloned before -// being inserted into the document. -// -// It returns the original set of elements. -func (s *Selection) Wrap(selector string) *Selection { - return s.WrapMatcher(compileMatcher(selector)) -} - -// WrapMatcher wraps each element in the set of matched elements inside the -// first element matched by the given matcher. The matched child is cloned -// before being inserted into the document. -// -// It returns the original set of elements. -func (s *Selection) WrapMatcher(m Matcher) *Selection { - return s.wrapNodes(m.MatchAll(s.document.rootNode)...) -} - -// WrapSelection wraps each element in the set of matched elements inside the -// first element in the given Selection. The element is cloned before being -// inserted into the document. -// -// It returns the original set of elements. -func (s *Selection) WrapSelection(sel *Selection) *Selection { - return s.wrapNodes(sel.Nodes...) -} - -// WrapHtml wraps each element in the set of matched elements inside the inner- -// most child of the given HTML. -// -// It returns the original set of elements. -func (s *Selection) WrapHtml(html string) *Selection { - return s.wrapNodes(parseHtml(html)...) -} - -// WrapNode wraps each element in the set of matched elements inside the inner- -// most child of the given node. The given node is copied before being inserted -// into the document. -// -// It returns the original set of elements. -func (s *Selection) WrapNode(n *html.Node) *Selection { - return s.wrapNodes(n) -} - -func (s *Selection) wrapNodes(ns ...*html.Node) *Selection { - s.Each(func(i int, ss *Selection) { - ss.wrapAllNodes(ns...) - }) - - return s -} - -// WrapAll wraps a single HTML structure, matched by the given selector, around -// all elements in the set of matched elements. The matched child is cloned -// before being inserted into the document. -// -// It returns the original set of elements. -func (s *Selection) WrapAll(selector string) *Selection { - return s.WrapAllMatcher(compileMatcher(selector)) -} - -// WrapAllMatcher wraps a single HTML structure, matched by the given Matcher, -// around all elements in the set of matched elements. The matched child is -// cloned before being inserted into the document. -// -// It returns the original set of elements. -func (s *Selection) WrapAllMatcher(m Matcher) *Selection { - return s.wrapAllNodes(m.MatchAll(s.document.rootNode)...) -} - -// WrapAllSelection wraps a single HTML structure, the first node of the given -// Selection, around all elements in the set of matched elements. The matched -// child is cloned before being inserted into the document. -// -// It returns the original set of elements. -func (s *Selection) WrapAllSelection(sel *Selection) *Selection { - return s.wrapAllNodes(sel.Nodes...) -} - -// WrapAllHtml wraps the given HTML structure around all elements in the set of -// matched elements. The matched child is cloned before being inserted into the -// document. -// -// It returns the original set of elements. -func (s *Selection) WrapAllHtml(html string) *Selection { - return s.wrapAllNodes(parseHtml(html)...) -} - -func (s *Selection) wrapAllNodes(ns ...*html.Node) *Selection { - if len(ns) > 0 { - return s.WrapAllNode(ns[0]) - } - return s -} - -// WrapAllNode wraps the given node around the first element in the Selection, -// making all other nodes in the Selection children of the given node. The node -// is cloned before being inserted into the document. -// -// It returns the original set of elements. -func (s *Selection) WrapAllNode(n *html.Node) *Selection { - if s.Size() == 0 { - return s - } - - wrap := cloneNode(n) - - first := s.Nodes[0] - if first.Parent != nil { - first.Parent.InsertBefore(wrap, first) - first.Parent.RemoveChild(first) - } - - for c := getFirstChildEl(wrap); c != nil; c = getFirstChildEl(wrap) { - wrap = c - } - - newSingleSelection(wrap, s.document).AppendSelection(s) - - return s -} - -// WrapInner wraps an HTML structure, matched by the given selector, around the -// content of element in the set of matched elements. The matched child is -// cloned before being inserted into the document. -// -// It returns the original set of elements. -func (s *Selection) WrapInner(selector string) *Selection { - return s.WrapInnerMatcher(compileMatcher(selector)) -} - -// WrapInnerMatcher wraps an HTML structure, matched by the given selector, -// around the content of element in the set of matched elements. The matched -// child is cloned before being inserted into the document. -// -// It returns the original set of elements. -func (s *Selection) WrapInnerMatcher(m Matcher) *Selection { - return s.wrapInnerNodes(m.MatchAll(s.document.rootNode)...) -} - -// WrapInnerSelection wraps an HTML structure, matched by the given selector, -// around the content of element in the set of matched elements. The matched -// child is cloned before being inserted into the document. -// -// It returns the original set of elements. -func (s *Selection) WrapInnerSelection(sel *Selection) *Selection { - return s.wrapInnerNodes(sel.Nodes...) -} - -// WrapInnerHtml wraps an HTML structure, matched by the given selector, around -// the content of element in the set of matched elements. The matched child is -// cloned before being inserted into the document. -// -// It returns the original set of elements. -func (s *Selection) WrapInnerHtml(html string) *Selection { - return s.wrapInnerNodes(parseHtml(html)...) -} - -// WrapInnerNode wraps an HTML structure, matched by the given selector, around -// the content of element in the set of matched elements. The matched child is -// cloned before being inserted into the document. -// -// It returns the original set of elements. -func (s *Selection) WrapInnerNode(n *html.Node) *Selection { - return s.wrapInnerNodes(n) -} - -func (s *Selection) wrapInnerNodes(ns ...*html.Node) *Selection { - if len(ns) == 0 { - return s - } - - s.Each(func(i int, s *Selection) { - contents := s.Contents() - - if contents.Size() > 0 { - contents.wrapAllNodes(ns...) - } else { - s.AppendNodes(cloneNode(ns[0])) - } - }) - - return s -} - -func parseHtml(h string) []*html.Node { - // Errors are only returned when the io.Reader returns any error besides - // EOF, but strings.Reader never will - nodes, err := html.ParseFragment(strings.NewReader(h), &html.Node{Type: html.ElementNode}) - if err != nil { - panic("goquery: failed to parse HTML: " + err.Error()) - } - return nodes -} - -// Get the first child that is an ElementNode -func getFirstChildEl(n *html.Node) *html.Node { - c := n.FirstChild - for c != nil && c.Type != html.ElementNode { - c = c.NextSibling - } - return c -} - -// Deep copy a slice of nodes. -func cloneNodes(ns []*html.Node) []*html.Node { - cns := make([]*html.Node, 0, len(ns)) - - for _, n := range ns { - cns = append(cns, cloneNode(n)) - } - - return cns -} - -// Deep copy a node. The new node has clones of all the original node's -// children but none of its parents or siblings. -func cloneNode(n *html.Node) *html.Node { - nn := &html.Node{ - Type: n.Type, - DataAtom: n.DataAtom, - Data: n.Data, - Attr: make([]html.Attribute, len(n.Attr)), - } - - copy(nn.Attr, n.Attr) - for c := n.FirstChild; c != nil; c = c.NextSibling { - nn.AppendChild(cloneNode(c)) - } - - return nn -} - -func (s *Selection) manipulateNodes(ns []*html.Node, reverse bool, - f func(sn *html.Node, n *html.Node)) *Selection { - - lasti := s.Size() - 1 - - // net.Html doesn't provide document fragments for insertion, so to get - // things in the correct order with After() and Prepend(), the callback - // needs to be called on the reverse of the nodes. - if reverse { - for i, j := 0, len(ns)-1; i < j; i, j = i+1, j-1 { - ns[i], ns[j] = ns[j], ns[i] - } - } - - for i, sn := range s.Nodes { - for _, n := range ns { - if i != lasti { - f(sn, cloneNode(n)) - } else { - if n.Parent != nil { - n.Parent.RemoveChild(n) - } - f(sn, n) - } - } - } - - return s -} diff --git a/vendor/github.com/PuerkitoBio/goquery/property.go b/vendor/github.com/PuerkitoBio/goquery/property.go deleted file mode 100644 index 411126d..0000000 --- a/vendor/github.com/PuerkitoBio/goquery/property.go +++ /dev/null @@ -1,275 +0,0 @@ -package goquery - -import ( - "bytes" - "regexp" - "strings" - - "golang.org/x/net/html" -) - -var rxClassTrim = regexp.MustCompile("[\t\r\n]") - -// Attr gets the specified attribute's value for the first element in the -// Selection. To get the value for each element individually, use a looping -// construct such as Each or Map method. -func (s *Selection) Attr(attrName string) (val string, exists bool) { - if len(s.Nodes) == 0 { - return - } - return getAttributeValue(attrName, s.Nodes[0]) -} - -// AttrOr works like Attr but returns default value if attribute is not present. -func (s *Selection) AttrOr(attrName, defaultValue string) string { - if len(s.Nodes) == 0 { - return defaultValue - } - - val, exists := getAttributeValue(attrName, s.Nodes[0]) - if !exists { - return defaultValue - } - - return val -} - -// RemoveAttr removes the named attribute from each element in the set of matched elements. -func (s *Selection) RemoveAttr(attrName string) *Selection { - for _, n := range s.Nodes { - removeAttr(n, attrName) - } - - return s -} - -// SetAttr sets the given attribute on each element in the set of matched elements. -func (s *Selection) SetAttr(attrName, val string) *Selection { - for _, n := range s.Nodes { - attr := getAttributePtr(attrName, n) - if attr == nil { - n.Attr = append(n.Attr, html.Attribute{Key: attrName, Val: val}) - } else { - attr.Val = val - } - } - - return s -} - -// Text gets the combined text contents of each element in the set of matched -// elements, including their descendants. -func (s *Selection) Text() string { - var buf bytes.Buffer - - // Slightly optimized vs calling Each: no single selection object created - var f func(*html.Node) - f = func(n *html.Node) { - if n.Type == html.TextNode { - // Keep newlines and spaces, like jQuery - buf.WriteString(n.Data) - } - if n.FirstChild != nil { - for c := n.FirstChild; c != nil; c = c.NextSibling { - f(c) - } - } - } - for _, n := range s.Nodes { - f(n) - } - - return buf.String() -} - -// Size is an alias for Length. -func (s *Selection) Size() int { - return s.Length() -} - -// Length returns the number of elements in the Selection object. -func (s *Selection) Length() int { - return len(s.Nodes) -} - -// Html gets the HTML contents of the first element in the set of matched -// elements. It includes text and comment nodes. -func (s *Selection) Html() (ret string, e error) { - // Since there is no .innerHtml, the HTML content must be re-created from - // the nodes using html.Render. - var buf bytes.Buffer - - if len(s.Nodes) > 0 { - for c := s.Nodes[0].FirstChild; c != nil; c = c.NextSibling { - e = html.Render(&buf, c) - if e != nil { - return - } - } - ret = buf.String() - } - - return -} - -// AddClass adds the given class(es) to each element in the set of matched elements. -// Multiple class names can be specified, separated by a space or via multiple arguments. -func (s *Selection) AddClass(class ...string) *Selection { - classStr := strings.TrimSpace(strings.Join(class, " ")) - - if classStr == "" { - return s - } - - tcls := getClassesSlice(classStr) - for _, n := range s.Nodes { - curClasses, attr := getClassesAndAttr(n, true) - for _, newClass := range tcls { - if !strings.Contains(curClasses, " "+newClass+" ") { - curClasses += newClass + " " - } - } - - setClasses(n, attr, curClasses) - } - - return s -} - -// HasClass determines whether any of the matched elements are assigned the -// given class. -func (s *Selection) HasClass(class string) bool { - class = " " + class + " " - for _, n := range s.Nodes { - classes, _ := getClassesAndAttr(n, false) - if strings.Contains(classes, class) { - return true - } - } - return false -} - -// RemoveClass removes the given class(es) from each element in the set of matched elements. -// Multiple class names can be specified, separated by a space or via multiple arguments. -// If no class name is provided, all classes are removed. -func (s *Selection) RemoveClass(class ...string) *Selection { - var rclasses []string - - classStr := strings.TrimSpace(strings.Join(class, " ")) - remove := classStr == "" - - if !remove { - rclasses = getClassesSlice(classStr) - } - - for _, n := range s.Nodes { - if remove { - removeAttr(n, "class") - } else { - classes, attr := getClassesAndAttr(n, true) - for _, rcl := range rclasses { - classes = strings.Replace(classes, " "+rcl+" ", " ", -1) - } - - setClasses(n, attr, classes) - } - } - - return s -} - -// ToggleClass adds or removes the given class(es) for each element in the set of matched elements. -// Multiple class names can be specified, separated by a space or via multiple arguments. -func (s *Selection) ToggleClass(class ...string) *Selection { - classStr := strings.TrimSpace(strings.Join(class, " ")) - - if classStr == "" { - return s - } - - tcls := getClassesSlice(classStr) - - for _, n := range s.Nodes { - classes, attr := getClassesAndAttr(n, true) - for _, tcl := range tcls { - if strings.Contains(classes, " "+tcl+" ") { - classes = strings.Replace(classes, " "+tcl+" ", " ", -1) - } else { - classes += tcl + " " - } - } - - setClasses(n, attr, classes) - } - - return s -} - -func getAttributePtr(attrName string, n *html.Node) *html.Attribute { - if n == nil { - return nil - } - - for i, a := range n.Attr { - if a.Key == attrName { - return &n.Attr[i] - } - } - return nil -} - -// Private function to get the specified attribute's value from a node. -func getAttributeValue(attrName string, n *html.Node) (val string, exists bool) { - if a := getAttributePtr(attrName, n); a != nil { - val = a.Val - exists = true - } - return -} - -// Get and normalize the "class" attribute from the node. -func getClassesAndAttr(n *html.Node, create bool) (classes string, attr *html.Attribute) { - // Applies only to element nodes - if n.Type == html.ElementNode { - attr = getAttributePtr("class", n) - if attr == nil && create { - n.Attr = append(n.Attr, html.Attribute{ - Key: "class", - Val: "", - }) - attr = &n.Attr[len(n.Attr)-1] - } - } - - if attr == nil { - classes = " " - } else { - classes = rxClassTrim.ReplaceAllString(" "+attr.Val+" ", " ") - } - - return -} - -func getClassesSlice(classes string) []string { - return strings.Split(rxClassTrim.ReplaceAllString(" "+classes+" ", " "), " ") -} - -func removeAttr(n *html.Node, attrName string) { - for i, a := range n.Attr { - if a.Key == attrName { - n.Attr[i], n.Attr[len(n.Attr)-1], n.Attr = - n.Attr[len(n.Attr)-1], html.Attribute{}, n.Attr[:len(n.Attr)-1] - return - } - } -} - -func setClasses(n *html.Node, attr *html.Attribute, classes string) { - classes = strings.TrimSpace(classes) - if classes == "" { - removeAttr(n, "class") - return - } - - attr.Val = classes -} diff --git a/vendor/github.com/PuerkitoBio/goquery/query.go b/vendor/github.com/PuerkitoBio/goquery/query.go deleted file mode 100644 index 1a7f873..0000000 --- a/vendor/github.com/PuerkitoBio/goquery/query.go +++ /dev/null @@ -1,53 +0,0 @@ -package goquery - -import "golang.org/x/net/html" - -// Is checks the current matched set of elements against a selector and -// returns true if at least one of these elements matches. -func (s *Selection) Is(selector string) bool { - if len(s.Nodes) > 0 { - return s.IsMatcher(compileMatcher(selector)) - } - - return false -} - -// IsMatcher checks the current matched set of elements against a matcher and -// returns true if at least one of these elements matches. -func (s *Selection) IsMatcher(m Matcher) bool { - if len(s.Nodes) > 0 { - if len(s.Nodes) == 1 { - return m.Match(s.Nodes[0]) - } - return len(m.Filter(s.Nodes)) > 0 - } - - return false -} - -// IsFunction checks the current matched set of elements against a predicate and -// returns true if at least one of these elements matches. -func (s *Selection) IsFunction(f func(int, *Selection) bool) bool { - return s.FilterFunction(f).Length() > 0 -} - -// IsSelection checks the current matched set of elements against a Selection object -// and returns true if at least one of these elements matches. -func (s *Selection) IsSelection(sel *Selection) bool { - return s.FilterSelection(sel).Length() > 0 -} - -// IsNodes checks the current matched set of elements against the specified nodes -// and returns true if at least one of these elements matches. -func (s *Selection) IsNodes(nodes ...*html.Node) bool { - return s.FilterNodes(nodes...).Length() > 0 -} - -// Contains returns true if the specified Node is within, -// at any depth, one of the nodes in the Selection object. -// It is NOT inclusive, to behave like jQuery's implementation, and -// unlike Javascript's .contains, so if the contained -// node is itself in the selection, it returns false. -func (s *Selection) Contains(n *html.Node) bool { - return sliceContains(s.Nodes, n) -} diff --git a/vendor/github.com/PuerkitoBio/goquery/traversal.go b/vendor/github.com/PuerkitoBio/goquery/traversal.go deleted file mode 100644 index 5fa5315..0000000 --- a/vendor/github.com/PuerkitoBio/goquery/traversal.go +++ /dev/null @@ -1,698 +0,0 @@ -package goquery - -import "golang.org/x/net/html" - -type siblingType int - -// Sibling type, used internally when iterating over children at the same -// level (siblings) to specify which nodes are requested. -const ( - siblingPrevUntil siblingType = iota - 3 - siblingPrevAll - siblingPrev - siblingAll - siblingNext - siblingNextAll - siblingNextUntil - siblingAllIncludingNonElements -) - -// Find gets the descendants of each element in the current set of matched -// elements, filtered by a selector. It returns a new Selection object -// containing these matched elements. -func (s *Selection) Find(selector string) *Selection { - return pushStack(s, findWithMatcher(s.Nodes, compileMatcher(selector))) -} - -// FindMatcher gets the descendants of each element in the current set of matched -// elements, filtered by the matcher. It returns a new Selection object -// containing these matched elements. -func (s *Selection) FindMatcher(m Matcher) *Selection { - return pushStack(s, findWithMatcher(s.Nodes, m)) -} - -// FindSelection gets the descendants of each element in the current -// Selection, filtered by a Selection. It returns a new Selection object -// containing these matched elements. -func (s *Selection) FindSelection(sel *Selection) *Selection { - if sel == nil { - return pushStack(s, nil) - } - return s.FindNodes(sel.Nodes...) -} - -// FindNodes gets the descendants of each element in the current -// Selection, filtered by some nodes. It returns a new Selection object -// containing these matched elements. -func (s *Selection) FindNodes(nodes ...*html.Node) *Selection { - return pushStack(s, mapNodes(nodes, func(i int, n *html.Node) []*html.Node { - if sliceContains(s.Nodes, n) { - return []*html.Node{n} - } - return nil - })) -} - -// Contents gets the children of each element in the Selection, -// including text and comment nodes. It returns a new Selection object -// containing these elements. -func (s *Selection) Contents() *Selection { - return pushStack(s, getChildrenNodes(s.Nodes, siblingAllIncludingNonElements)) -} - -// ContentsFiltered gets the children of each element in the Selection, -// filtered by the specified selector. It returns a new Selection -// object containing these elements. Since selectors only act on Element nodes, -// this function is an alias to ChildrenFiltered unless the selector is empty, -// in which case it is an alias to Contents. -func (s *Selection) ContentsFiltered(selector string) *Selection { - if selector != "" { - return s.ChildrenFiltered(selector) - } - return s.Contents() -} - -// ContentsMatcher gets the children of each element in the Selection, -// filtered by the specified matcher. It returns a new Selection -// object containing these elements. Since matchers only act on Element nodes, -// this function is an alias to ChildrenMatcher. -func (s *Selection) ContentsMatcher(m Matcher) *Selection { - return s.ChildrenMatcher(m) -} - -// Children gets the child elements of each element in the Selection. -// It returns a new Selection object containing these elements. -func (s *Selection) Children() *Selection { - return pushStack(s, getChildrenNodes(s.Nodes, siblingAll)) -} - -// ChildrenFiltered gets the child elements of each element in the Selection, -// filtered by the specified selector. It returns a new -// Selection object containing these elements. -func (s *Selection) ChildrenFiltered(selector string) *Selection { - return filterAndPush(s, getChildrenNodes(s.Nodes, siblingAll), compileMatcher(selector)) -} - -// ChildrenMatcher gets the child elements of each element in the Selection, -// filtered by the specified matcher. It returns a new -// Selection object containing these elements. -func (s *Selection) ChildrenMatcher(m Matcher) *Selection { - return filterAndPush(s, getChildrenNodes(s.Nodes, siblingAll), m) -} - -// Parent gets the parent of each element in the Selection. It returns a -// new Selection object containing the matched elements. -func (s *Selection) Parent() *Selection { - return pushStack(s, getParentNodes(s.Nodes)) -} - -// ParentFiltered gets the parent of each element in the Selection filtered by a -// selector. It returns a new Selection object containing the matched elements. -func (s *Selection) ParentFiltered(selector string) *Selection { - return filterAndPush(s, getParentNodes(s.Nodes), compileMatcher(selector)) -} - -// ParentMatcher gets the parent of each element in the Selection filtered by a -// matcher. It returns a new Selection object containing the matched elements. -func (s *Selection) ParentMatcher(m Matcher) *Selection { - return filterAndPush(s, getParentNodes(s.Nodes), m) -} - -// Closest gets the first element that matches the selector by testing the -// element itself and traversing up through its ancestors in the DOM tree. -func (s *Selection) Closest(selector string) *Selection { - cs := compileMatcher(selector) - return s.ClosestMatcher(cs) -} - -// ClosestMatcher gets the first element that matches the matcher by testing the -// element itself and traversing up through its ancestors in the DOM tree. -func (s *Selection) ClosestMatcher(m Matcher) *Selection { - return pushStack(s, mapNodes(s.Nodes, func(i int, n *html.Node) []*html.Node { - // For each node in the selection, test the node itself, then each parent - // until a match is found. - for ; n != nil; n = n.Parent { - if m.Match(n) { - return []*html.Node{n} - } - } - return nil - })) -} - -// ClosestNodes gets the first element that matches one of the nodes by testing the -// element itself and traversing up through its ancestors in the DOM tree. -func (s *Selection) ClosestNodes(nodes ...*html.Node) *Selection { - set := make(map[*html.Node]bool) - for _, n := range nodes { - set[n] = true - } - return pushStack(s, mapNodes(s.Nodes, func(i int, n *html.Node) []*html.Node { - // For each node in the selection, test the node itself, then each parent - // until a match is found. - for ; n != nil; n = n.Parent { - if set[n] { - return []*html.Node{n} - } - } - return nil - })) -} - -// ClosestSelection gets the first element that matches one of the nodes in the -// Selection by testing the element itself and traversing up through its ancestors -// in the DOM tree. -func (s *Selection) ClosestSelection(sel *Selection) *Selection { - if sel == nil { - return pushStack(s, nil) - } - return s.ClosestNodes(sel.Nodes...) -} - -// Parents gets the ancestors of each element in the current Selection. It -// returns a new Selection object with the matched elements. -func (s *Selection) Parents() *Selection { - return pushStack(s, getParentsNodes(s.Nodes, nil, nil)) -} - -// ParentsFiltered gets the ancestors of each element in the current -// Selection. It returns a new Selection object with the matched elements. -func (s *Selection) ParentsFiltered(selector string) *Selection { - return filterAndPush(s, getParentsNodes(s.Nodes, nil, nil), compileMatcher(selector)) -} - -// ParentsMatcher gets the ancestors of each element in the current -// Selection. It returns a new Selection object with the matched elements. -func (s *Selection) ParentsMatcher(m Matcher) *Selection { - return filterAndPush(s, getParentsNodes(s.Nodes, nil, nil), m) -} - -// ParentsUntil gets the ancestors of each element in the Selection, up to but -// not including the element matched by the selector. It returns a new Selection -// object containing the matched elements. -func (s *Selection) ParentsUntil(selector string) *Selection { - return pushStack(s, getParentsNodes(s.Nodes, compileMatcher(selector), nil)) -} - -// ParentsUntilMatcher gets the ancestors of each element in the Selection, up to but -// not including the element matched by the matcher. It returns a new Selection -// object containing the matched elements. -func (s *Selection) ParentsUntilMatcher(m Matcher) *Selection { - return pushStack(s, getParentsNodes(s.Nodes, m, nil)) -} - -// ParentsUntilSelection gets the ancestors of each element in the Selection, -// up to but not including the elements in the specified Selection. It returns a -// new Selection object containing the matched elements. -func (s *Selection) ParentsUntilSelection(sel *Selection) *Selection { - if sel == nil { - return s.Parents() - } - return s.ParentsUntilNodes(sel.Nodes...) -} - -// ParentsUntilNodes gets the ancestors of each element in the Selection, -// up to but not including the specified nodes. It returns a -// new Selection object containing the matched elements. -func (s *Selection) ParentsUntilNodes(nodes ...*html.Node) *Selection { - return pushStack(s, getParentsNodes(s.Nodes, nil, nodes)) -} - -// ParentsFilteredUntil is like ParentsUntil, with the option to filter the -// results based on a selector string. It returns a new Selection -// object containing the matched elements. -func (s *Selection) ParentsFilteredUntil(filterSelector, untilSelector string) *Selection { - return filterAndPush(s, getParentsNodes(s.Nodes, compileMatcher(untilSelector), nil), compileMatcher(filterSelector)) -} - -// ParentsFilteredUntilMatcher is like ParentsUntilMatcher, with the option to filter the -// results based on a matcher. It returns a new Selection object containing the matched elements. -func (s *Selection) ParentsFilteredUntilMatcher(filter, until Matcher) *Selection { - return filterAndPush(s, getParentsNodes(s.Nodes, until, nil), filter) -} - -// ParentsFilteredUntilSelection is like ParentsUntilSelection, with the -// option to filter the results based on a selector string. It returns a new -// Selection object containing the matched elements. -func (s *Selection) ParentsFilteredUntilSelection(filterSelector string, sel *Selection) *Selection { - return s.ParentsMatcherUntilSelection(compileMatcher(filterSelector), sel) -} - -// ParentsMatcherUntilSelection is like ParentsUntilSelection, with the -// option to filter the results based on a matcher. It returns a new -// Selection object containing the matched elements. -func (s *Selection) ParentsMatcherUntilSelection(filter Matcher, sel *Selection) *Selection { - if sel == nil { - return s.ParentsMatcher(filter) - } - return s.ParentsMatcherUntilNodes(filter, sel.Nodes...) -} - -// ParentsFilteredUntilNodes is like ParentsUntilNodes, with the -// option to filter the results based on a selector string. It returns a new -// Selection object containing the matched elements. -func (s *Selection) ParentsFilteredUntilNodes(filterSelector string, nodes ...*html.Node) *Selection { - return filterAndPush(s, getParentsNodes(s.Nodes, nil, nodes), compileMatcher(filterSelector)) -} - -// ParentsMatcherUntilNodes is like ParentsUntilNodes, with the -// option to filter the results based on a matcher. It returns a new -// Selection object containing the matched elements. -func (s *Selection) ParentsMatcherUntilNodes(filter Matcher, nodes ...*html.Node) *Selection { - return filterAndPush(s, getParentsNodes(s.Nodes, nil, nodes), filter) -} - -// Siblings gets the siblings of each element in the Selection. It returns -// a new Selection object containing the matched elements. -func (s *Selection) Siblings() *Selection { - return pushStack(s, getSiblingNodes(s.Nodes, siblingAll, nil, nil)) -} - -// SiblingsFiltered gets the siblings of each element in the Selection -// filtered by a selector. It returns a new Selection object containing the -// matched elements. -func (s *Selection) SiblingsFiltered(selector string) *Selection { - return filterAndPush(s, getSiblingNodes(s.Nodes, siblingAll, nil, nil), compileMatcher(selector)) -} - -// SiblingsMatcher gets the siblings of each element in the Selection -// filtered by a matcher. It returns a new Selection object containing the -// matched elements. -func (s *Selection) SiblingsMatcher(m Matcher) *Selection { - return filterAndPush(s, getSiblingNodes(s.Nodes, siblingAll, nil, nil), m) -} - -// Next gets the immediately following sibling of each element in the -// Selection. It returns a new Selection object containing the matched elements. -func (s *Selection) Next() *Selection { - return pushStack(s, getSiblingNodes(s.Nodes, siblingNext, nil, nil)) -} - -// NextFiltered gets the immediately following sibling of each element in the -// Selection filtered by a selector. It returns a new Selection object -// containing the matched elements. -func (s *Selection) NextFiltered(selector string) *Selection { - return filterAndPush(s, getSiblingNodes(s.Nodes, siblingNext, nil, nil), compileMatcher(selector)) -} - -// NextMatcher gets the immediately following sibling of each element in the -// Selection filtered by a matcher. It returns a new Selection object -// containing the matched elements. -func (s *Selection) NextMatcher(m Matcher) *Selection { - return filterAndPush(s, getSiblingNodes(s.Nodes, siblingNext, nil, nil), m) -} - -// NextAll gets all the following siblings of each element in the -// Selection. It returns a new Selection object containing the matched elements. -func (s *Selection) NextAll() *Selection { - return pushStack(s, getSiblingNodes(s.Nodes, siblingNextAll, nil, nil)) -} - -// NextAllFiltered gets all the following siblings of each element in the -// Selection filtered by a selector. It returns a new Selection object -// containing the matched elements. -func (s *Selection) NextAllFiltered(selector string) *Selection { - return filterAndPush(s, getSiblingNodes(s.Nodes, siblingNextAll, nil, nil), compileMatcher(selector)) -} - -// NextAllMatcher gets all the following siblings of each element in the -// Selection filtered by a matcher. It returns a new Selection object -// containing the matched elements. -func (s *Selection) NextAllMatcher(m Matcher) *Selection { - return filterAndPush(s, getSiblingNodes(s.Nodes, siblingNextAll, nil, nil), m) -} - -// Prev gets the immediately preceding sibling of each element in the -// Selection. It returns a new Selection object containing the matched elements. -func (s *Selection) Prev() *Selection { - return pushStack(s, getSiblingNodes(s.Nodes, siblingPrev, nil, nil)) -} - -// PrevFiltered gets the immediately preceding sibling of each element in the -// Selection filtered by a selector. It returns a new Selection object -// containing the matched elements. -func (s *Selection) PrevFiltered(selector string) *Selection { - return filterAndPush(s, getSiblingNodes(s.Nodes, siblingPrev, nil, nil), compileMatcher(selector)) -} - -// PrevMatcher gets the immediately preceding sibling of each element in the -// Selection filtered by a matcher. It returns a new Selection object -// containing the matched elements. -func (s *Selection) PrevMatcher(m Matcher) *Selection { - return filterAndPush(s, getSiblingNodes(s.Nodes, siblingPrev, nil, nil), m) -} - -// PrevAll gets all the preceding siblings of each element in the -// Selection. It returns a new Selection object containing the matched elements. -func (s *Selection) PrevAll() *Selection { - return pushStack(s, getSiblingNodes(s.Nodes, siblingPrevAll, nil, nil)) -} - -// PrevAllFiltered gets all the preceding siblings of each element in the -// Selection filtered by a selector. It returns a new Selection object -// containing the matched elements. -func (s *Selection) PrevAllFiltered(selector string) *Selection { - return filterAndPush(s, getSiblingNodes(s.Nodes, siblingPrevAll, nil, nil), compileMatcher(selector)) -} - -// PrevAllMatcher gets all the preceding siblings of each element in the -// Selection filtered by a matcher. It returns a new Selection object -// containing the matched elements. -func (s *Selection) PrevAllMatcher(m Matcher) *Selection { - return filterAndPush(s, getSiblingNodes(s.Nodes, siblingPrevAll, nil, nil), m) -} - -// NextUntil gets all following siblings of each element up to but not -// including the element matched by the selector. It returns a new Selection -// object containing the matched elements. -func (s *Selection) NextUntil(selector string) *Selection { - return pushStack(s, getSiblingNodes(s.Nodes, siblingNextUntil, - compileMatcher(selector), nil)) -} - -// NextUntilMatcher gets all following siblings of each element up to but not -// including the element matched by the matcher. It returns a new Selection -// object containing the matched elements. -func (s *Selection) NextUntilMatcher(m Matcher) *Selection { - return pushStack(s, getSiblingNodes(s.Nodes, siblingNextUntil, - m, nil)) -} - -// NextUntilSelection gets all following siblings of each element up to but not -// including the element matched by the Selection. It returns a new Selection -// object containing the matched elements. -func (s *Selection) NextUntilSelection(sel *Selection) *Selection { - if sel == nil { - return s.NextAll() - } - return s.NextUntilNodes(sel.Nodes...) -} - -// NextUntilNodes gets all following siblings of each element up to but not -// including the element matched by the nodes. It returns a new Selection -// object containing the matched elements. -func (s *Selection) NextUntilNodes(nodes ...*html.Node) *Selection { - return pushStack(s, getSiblingNodes(s.Nodes, siblingNextUntil, - nil, nodes)) -} - -// PrevUntil gets all preceding siblings of each element up to but not -// including the element matched by the selector. It returns a new Selection -// object containing the matched elements. -func (s *Selection) PrevUntil(selector string) *Selection { - return pushStack(s, getSiblingNodes(s.Nodes, siblingPrevUntil, - compileMatcher(selector), nil)) -} - -// PrevUntilMatcher gets all preceding siblings of each element up to but not -// including the element matched by the matcher. It returns a new Selection -// object containing the matched elements. -func (s *Selection) PrevUntilMatcher(m Matcher) *Selection { - return pushStack(s, getSiblingNodes(s.Nodes, siblingPrevUntil, - m, nil)) -} - -// PrevUntilSelection gets all preceding siblings of each element up to but not -// including the element matched by the Selection. It returns a new Selection -// object containing the matched elements. -func (s *Selection) PrevUntilSelection(sel *Selection) *Selection { - if sel == nil { - return s.PrevAll() - } - return s.PrevUntilNodes(sel.Nodes...) -} - -// PrevUntilNodes gets all preceding siblings of each element up to but not -// including the element matched by the nodes. It returns a new Selection -// object containing the matched elements. -func (s *Selection) PrevUntilNodes(nodes ...*html.Node) *Selection { - return pushStack(s, getSiblingNodes(s.Nodes, siblingPrevUntil, - nil, nodes)) -} - -// NextFilteredUntil is like NextUntil, with the option to filter -// the results based on a selector string. -// It returns a new Selection object containing the matched elements. -func (s *Selection) NextFilteredUntil(filterSelector, untilSelector string) *Selection { - return filterAndPush(s, getSiblingNodes(s.Nodes, siblingNextUntil, - compileMatcher(untilSelector), nil), compileMatcher(filterSelector)) -} - -// NextFilteredUntilMatcher is like NextUntilMatcher, with the option to filter -// the results based on a matcher. -// It returns a new Selection object containing the matched elements. -func (s *Selection) NextFilteredUntilMatcher(filter, until Matcher) *Selection { - return filterAndPush(s, getSiblingNodes(s.Nodes, siblingNextUntil, - until, nil), filter) -} - -// NextFilteredUntilSelection is like NextUntilSelection, with the -// option to filter the results based on a selector string. It returns a new -// Selection object containing the matched elements. -func (s *Selection) NextFilteredUntilSelection(filterSelector string, sel *Selection) *Selection { - return s.NextMatcherUntilSelection(compileMatcher(filterSelector), sel) -} - -// NextMatcherUntilSelection is like NextUntilSelection, with the -// option to filter the results based on a matcher. It returns a new -// Selection object containing the matched elements. -func (s *Selection) NextMatcherUntilSelection(filter Matcher, sel *Selection) *Selection { - if sel == nil { - return s.NextMatcher(filter) - } - return s.NextMatcherUntilNodes(filter, sel.Nodes...) -} - -// NextFilteredUntilNodes is like NextUntilNodes, with the -// option to filter the results based on a selector string. It returns a new -// Selection object containing the matched elements. -func (s *Selection) NextFilteredUntilNodes(filterSelector string, nodes ...*html.Node) *Selection { - return filterAndPush(s, getSiblingNodes(s.Nodes, siblingNextUntil, - nil, nodes), compileMatcher(filterSelector)) -} - -// NextMatcherUntilNodes is like NextUntilNodes, with the -// option to filter the results based on a matcher. It returns a new -// Selection object containing the matched elements. -func (s *Selection) NextMatcherUntilNodes(filter Matcher, nodes ...*html.Node) *Selection { - return filterAndPush(s, getSiblingNodes(s.Nodes, siblingNextUntil, - nil, nodes), filter) -} - -// PrevFilteredUntil is like PrevUntil, with the option to filter -// the results based on a selector string. -// It returns a new Selection object containing the matched elements. -func (s *Selection) PrevFilteredUntil(filterSelector, untilSelector string) *Selection { - return filterAndPush(s, getSiblingNodes(s.Nodes, siblingPrevUntil, - compileMatcher(untilSelector), nil), compileMatcher(filterSelector)) -} - -// PrevFilteredUntilMatcher is like PrevUntilMatcher, with the option to filter -// the results based on a matcher. -// It returns a new Selection object containing the matched elements. -func (s *Selection) PrevFilteredUntilMatcher(filter, until Matcher) *Selection { - return filterAndPush(s, getSiblingNodes(s.Nodes, siblingPrevUntil, - until, nil), filter) -} - -// PrevFilteredUntilSelection is like PrevUntilSelection, with the -// option to filter the results based on a selector string. It returns a new -// Selection object containing the matched elements. -func (s *Selection) PrevFilteredUntilSelection(filterSelector string, sel *Selection) *Selection { - return s.PrevMatcherUntilSelection(compileMatcher(filterSelector), sel) -} - -// PrevMatcherUntilSelection is like PrevUntilSelection, with the -// option to filter the results based on a matcher. It returns a new -// Selection object containing the matched elements. -func (s *Selection) PrevMatcherUntilSelection(filter Matcher, sel *Selection) *Selection { - if sel == nil { - return s.PrevMatcher(filter) - } - return s.PrevMatcherUntilNodes(filter, sel.Nodes...) -} - -// PrevFilteredUntilNodes is like PrevUntilNodes, with the -// option to filter the results based on a selector string. It returns a new -// Selection object containing the matched elements. -func (s *Selection) PrevFilteredUntilNodes(filterSelector string, nodes ...*html.Node) *Selection { - return filterAndPush(s, getSiblingNodes(s.Nodes, siblingPrevUntil, - nil, nodes), compileMatcher(filterSelector)) -} - -// PrevMatcherUntilNodes is like PrevUntilNodes, with the -// option to filter the results based on a matcher. It returns a new -// Selection object containing the matched elements. -func (s *Selection) PrevMatcherUntilNodes(filter Matcher, nodes ...*html.Node) *Selection { - return filterAndPush(s, getSiblingNodes(s.Nodes, siblingPrevUntil, - nil, nodes), filter) -} - -// Filter and push filters the nodes based on a matcher, and pushes the results -// on the stack, with the srcSel as previous selection. -func filterAndPush(srcSel *Selection, nodes []*html.Node, m Matcher) *Selection { - // Create a temporary Selection with the specified nodes to filter using winnow - sel := &Selection{nodes, srcSel.document, nil} - // Filter based on matcher and push on stack - return pushStack(srcSel, winnow(sel, m, true)) -} - -// Internal implementation of Find that return raw nodes. -func findWithMatcher(nodes []*html.Node, m Matcher) []*html.Node { - // Map nodes to find the matches within the children of each node - return mapNodes(nodes, func(i int, n *html.Node) (result []*html.Node) { - // Go down one level, becausejQuery's Find selects only within descendants - for c := n.FirstChild; c != nil; c = c.NextSibling { - if c.Type == html.ElementNode { - result = append(result, m.MatchAll(c)...) - } - } - return - }) -} - -// Internal implementation to get all parent nodes, stopping at the specified -// node (or nil if no stop). -func getParentsNodes(nodes []*html.Node, stopm Matcher, stopNodes []*html.Node) []*html.Node { - return mapNodes(nodes, func(i int, n *html.Node) (result []*html.Node) { - for p := n.Parent; p != nil; p = p.Parent { - sel := newSingleSelection(p, nil) - if stopm != nil { - if sel.IsMatcher(stopm) { - break - } - } else if len(stopNodes) > 0 { - if sel.IsNodes(stopNodes...) { - break - } - } - if p.Type == html.ElementNode { - result = append(result, p) - } - } - return - }) -} - -// Internal implementation of sibling nodes that return a raw slice of matches. -func getSiblingNodes(nodes []*html.Node, st siblingType, untilm Matcher, untilNodes []*html.Node) []*html.Node { - var f func(*html.Node) bool - - // If the requested siblings are ...Until, create the test function to - // determine if the until condition is reached (returns true if it is) - if st == siblingNextUntil || st == siblingPrevUntil { - f = func(n *html.Node) bool { - if untilm != nil { - // Matcher-based condition - sel := newSingleSelection(n, nil) - return sel.IsMatcher(untilm) - } else if len(untilNodes) > 0 { - // Nodes-based condition - sel := newSingleSelection(n, nil) - return sel.IsNodes(untilNodes...) - } - return false - } - } - - return mapNodes(nodes, func(i int, n *html.Node) []*html.Node { - return getChildrenWithSiblingType(n.Parent, st, n, f) - }) -} - -// Gets the children nodes of each node in the specified slice of nodes, -// based on the sibling type request. -func getChildrenNodes(nodes []*html.Node, st siblingType) []*html.Node { - return mapNodes(nodes, func(i int, n *html.Node) []*html.Node { - return getChildrenWithSiblingType(n, st, nil, nil) - }) -} - -// Gets the children of the specified parent, based on the requested sibling -// type, skipping a specified node if required. -func getChildrenWithSiblingType(parent *html.Node, st siblingType, skipNode *html.Node, - untilFunc func(*html.Node) bool) (result []*html.Node) { - - // Create the iterator function - var iter = func(cur *html.Node) (ret *html.Node) { - // Based on the sibling type requested, iterate the right way - for { - switch st { - case siblingAll, siblingAllIncludingNonElements: - if cur == nil { - // First iteration, start with first child of parent - // Skip node if required - if ret = parent.FirstChild; ret == skipNode && skipNode != nil { - ret = skipNode.NextSibling - } - } else { - // Skip node if required - if ret = cur.NextSibling; ret == skipNode && skipNode != nil { - ret = skipNode.NextSibling - } - } - case siblingPrev, siblingPrevAll, siblingPrevUntil: - if cur == nil { - // Start with previous sibling of the skip node - ret = skipNode.PrevSibling - } else { - ret = cur.PrevSibling - } - case siblingNext, siblingNextAll, siblingNextUntil: - if cur == nil { - // Start with next sibling of the skip node - ret = skipNode.NextSibling - } else { - ret = cur.NextSibling - } - default: - panic("Invalid sibling type.") - } - if ret == nil || ret.Type == html.ElementNode || st == siblingAllIncludingNonElements { - return - } - // Not a valid node, try again from this one - cur = ret - } - } - - for c := iter(nil); c != nil; c = iter(c) { - // If this is an ...Until case, test before append (returns true - // if the until condition is reached) - if st == siblingNextUntil || st == siblingPrevUntil { - if untilFunc(c) { - return - } - } - result = append(result, c) - if st == siblingNext || st == siblingPrev { - // Only one node was requested (immediate next or previous), so exit - return - } - } - return -} - -// Internal implementation of parent nodes that return a raw slice of Nodes. -func getParentNodes(nodes []*html.Node) []*html.Node { - return mapNodes(nodes, func(i int, n *html.Node) []*html.Node { - if n.Parent != nil && n.Parent.Type == html.ElementNode { - return []*html.Node{n.Parent} - } - return nil - }) -} - -// Internal map function used by many traversing methods. Takes the source nodes -// to iterate on and the mapping function that returns an array of nodes. -// Returns an array of nodes mapped by calling the callback function once for -// each node in the source nodes. -func mapNodes(nodes []*html.Node, f func(int, *html.Node) []*html.Node) (result []*html.Node) { - set := make(map[*html.Node]bool) - for i, n := range nodes { - if vals := f(i, n); len(vals) > 0 { - result = appendWithoutDuplicates(result, vals, set) - } - } - return result -} diff --git a/vendor/github.com/PuerkitoBio/goquery/type.go b/vendor/github.com/PuerkitoBio/goquery/type.go deleted file mode 100644 index e2169fa..0000000 --- a/vendor/github.com/PuerkitoBio/goquery/type.go +++ /dev/null @@ -1,135 +0,0 @@ -package goquery - -import ( - "errors" - "io" - "net/http" - "net/url" - - "github.com/andybalholm/cascadia" - - "golang.org/x/net/html" -) - -// Document represents an HTML document to be manipulated. Unlike jQuery, which -// is loaded as part of a DOM document, and thus acts upon its containing -// document, GoQuery doesn't know which HTML document to act upon. So it needs -// to be told, and that's what the Document class is for. It holds the root -// document node to manipulate, and can make selections on this document. -type Document struct { - *Selection - Url *url.URL - rootNode *html.Node -} - -// NewDocumentFromNode is a Document constructor that takes a root html Node -// as argument. -func NewDocumentFromNode(root *html.Node) *Document { - return newDocument(root, nil) -} - -// NewDocument is a Document constructor that takes a string URL as argument. -// It loads the specified document, parses it, and stores the root Document -// node, ready to be manipulated. -func NewDocument(url string) (*Document, error) { - // Load the URL - res, e := http.Get(url) - if e != nil { - return nil, e - } - return NewDocumentFromResponse(res) -} - -// NewDocumentFromReader returns a Document from a generic reader. -// It returns an error as second value if the reader's data cannot be parsed -// as html. It does *not* check if the reader is also an io.Closer, so the -// provided reader is never closed by this call, it is the responsibility -// of the caller to close it if required. -func NewDocumentFromReader(r io.Reader) (*Document, error) { - root, e := html.Parse(r) - if e != nil { - return nil, e - } - return newDocument(root, nil), nil -} - -// NewDocumentFromResponse is another Document constructor that takes an http response as argument. -// It loads the specified response's document, parses it, and stores the root Document -// node, ready to be manipulated. The response's body is closed on return. -func NewDocumentFromResponse(res *http.Response) (*Document, error) { - if res == nil { - return nil, errors.New("Response is nil") - } - defer res.Body.Close() - if res.Request == nil { - return nil, errors.New("Response.Request is nil") - } - - // Parse the HTML into nodes - root, e := html.Parse(res.Body) - if e != nil { - return nil, e - } - - // Create and fill the document - return newDocument(root, res.Request.URL), nil -} - -// CloneDocument creates a deep-clone of a document. -func CloneDocument(doc *Document) *Document { - return newDocument(cloneNode(doc.rootNode), doc.Url) -} - -// Private constructor, make sure all fields are correctly filled. -func newDocument(root *html.Node, url *url.URL) *Document { - // Create and fill the document - d := &Document{nil, url, root} - d.Selection = newSingleSelection(root, d) - return d -} - -// Selection represents a collection of nodes matching some criteria. The -// initial Selection can be created by using Document.Find, and then -// manipulated using the jQuery-like chainable syntax and methods. -type Selection struct { - Nodes []*html.Node - document *Document - prevSel *Selection -} - -// Helper constructor to create an empty selection -func newEmptySelection(doc *Document) *Selection { - return &Selection{nil, doc, nil} -} - -// Helper constructor to create a selection of only one node -func newSingleSelection(node *html.Node, doc *Document) *Selection { - return &Selection{[]*html.Node{node}, doc, nil} -} - -// Matcher is an interface that defines the methods to match -// HTML nodes against a compiled selector string. Cascadia's -// Selector implements this interface. -type Matcher interface { - Match(*html.Node) bool - MatchAll(*html.Node) []*html.Node - Filter([]*html.Node) []*html.Node -} - -// compileMatcher compiles the selector string s and returns -// the corresponding Matcher. If s is an invalid selector string, -// it returns a Matcher that fails all matches. -func compileMatcher(s string) Matcher { - cs, err := cascadia.Compile(s) - if err != nil { - return invalidMatcher{} - } - return cs -} - -// invalidMatcher is a Matcher that always fails to match. -type invalidMatcher struct{} - -func (invalidMatcher) Match(n *html.Node) bool { return false } -func (invalidMatcher) MatchAll(n *html.Node) []*html.Node { return nil } -func (invalidMatcher) Filter(ns []*html.Node) []*html.Node { return nil } diff --git a/vendor/github.com/PuerkitoBio/goquery/utilities.go b/vendor/github.com/PuerkitoBio/goquery/utilities.go deleted file mode 100644 index b4c061a..0000000 --- a/vendor/github.com/PuerkitoBio/goquery/utilities.go +++ /dev/null @@ -1,161 +0,0 @@ -package goquery - -import ( - "bytes" - - "golang.org/x/net/html" -) - -// used to determine if a set (map[*html.Node]bool) should be used -// instead of iterating over a slice. The set uses more memory and -// is slower than slice iteration for small N. -const minNodesForSet = 1000 - -var nodeNames = []string{ - html.ErrorNode: "#error", - html.TextNode: "#text", - html.DocumentNode: "#document", - html.CommentNode: "#comment", -} - -// NodeName returns the node name of the first element in the selection. -// It tries to behave in a similar way as the DOM's nodeName property -// (https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeName). -// -// Go's net/html package defines the following node types, listed with -// the corresponding returned value from this function: -// -// ErrorNode : #error -// TextNode : #text -// DocumentNode : #document -// ElementNode : the element's tag name -// CommentNode : #comment -// DoctypeNode : the name of the document type -// -func NodeName(s *Selection) string { - if s.Length() == 0 { - return "" - } - switch n := s.Get(0); n.Type { - case html.ElementNode, html.DoctypeNode: - return n.Data - default: - if n.Type >= 0 && int(n.Type) < len(nodeNames) { - return nodeNames[n.Type] - } - return "" - } -} - -// OuterHtml returns the outer HTML rendering of the first item in -// the selection - that is, the HTML including the first element's -// tag and attributes. -// -// Unlike InnerHtml, this is a function and not a method on the Selection, -// because this is not a jQuery method (in javascript-land, this is -// a property provided by the DOM). -func OuterHtml(s *Selection) (string, error) { - var buf bytes.Buffer - - if s.Length() == 0 { - return "", nil - } - n := s.Get(0) - if err := html.Render(&buf, n); err != nil { - return "", err - } - return buf.String(), nil -} - -// Loop through all container nodes to search for the target node. -func sliceContains(container []*html.Node, contained *html.Node) bool { - for _, n := range container { - if nodeContains(n, contained) { - return true - } - } - - return false -} - -// Checks if the contained node is within the container node. -func nodeContains(container *html.Node, contained *html.Node) bool { - // Check if the parent of the contained node is the container node, traversing - // upward until the top is reached, or the container is found. - for contained = contained.Parent; contained != nil; contained = contained.Parent { - if container == contained { - return true - } - } - return false -} - -// Checks if the target node is in the slice of nodes. -func isInSlice(slice []*html.Node, node *html.Node) bool { - return indexInSlice(slice, node) > -1 -} - -// Returns the index of the target node in the slice, or -1. -func indexInSlice(slice []*html.Node, node *html.Node) int { - if node != nil { - for i, n := range slice { - if n == node { - return i - } - } - } - return -1 -} - -// Appends the new nodes to the target slice, making sure no duplicate is added. -// There is no check to the original state of the target slice, so it may still -// contain duplicates. The target slice is returned because append() may create -// a new underlying array. If targetSet is nil, a local set is created with the -// target if len(target) + len(nodes) is greater than minNodesForSet. -func appendWithoutDuplicates(target []*html.Node, nodes []*html.Node, targetSet map[*html.Node]bool) []*html.Node { - // if there are not that many nodes, don't use the map, faster to just use nested loops - // (unless a non-nil targetSet is passed, in which case the caller knows better). - if targetSet == nil && len(target)+len(nodes) < minNodesForSet { - for _, n := range nodes { - if !isInSlice(target, n) { - target = append(target, n) - } - } - return target - } - - // if a targetSet is passed, then assume it is reliable, otherwise create one - // and initialize it with the current target contents. - if targetSet == nil { - targetSet = make(map[*html.Node]bool, len(target)) - for _, n := range target { - targetSet[n] = true - } - } - for _, n := range nodes { - if !targetSet[n] { - target = append(target, n) - targetSet[n] = true - } - } - - return target -} - -// Loop through a selection, returning only those nodes that pass the predicate -// function. -func grep(sel *Selection, predicate func(i int, s *Selection) bool) (result []*html.Node) { - for i, n := range sel.Nodes { - if predicate(i, newSingleSelection(n, sel.document)) { - result = append(result, n) - } - } - return result -} - -// Creates a new Selection object based on the specified nodes, and keeps the -// source Selection object on the stack (linked list). -func pushStack(fromSel *Selection, nodes []*html.Node) *Selection { - result := &Selection{nodes, fromSel.document, fromSel} - return result -} diff --git a/vendor/github.com/Sirupsen/logrus/.gitignore b/vendor/github.com/Sirupsen/logrus/.gitignore deleted file mode 100644 index 66be63a..0000000 --- a/vendor/github.com/Sirupsen/logrus/.gitignore +++ /dev/null @@ -1 +0,0 @@ -logrus diff --git a/vendor/github.com/Sirupsen/logrus/.travis.yml b/vendor/github.com/Sirupsen/logrus/.travis.yml deleted file mode 100644 index 804c569..0000000 --- a/vendor/github.com/Sirupsen/logrus/.travis.yml +++ /dev/null @@ -1,8 +0,0 @@ -language: go -go: - - 1.6 - - 1.7 - - tip -install: - - go get -t ./... -script: GOMAXPROCS=4 GORACE="halt_on_error=1" go test -race -v ./... diff --git a/vendor/github.com/Sirupsen/logrus/CHANGELOG.md b/vendor/github.com/Sirupsen/logrus/CHANGELOG.md deleted file mode 100644 index f2c2bc2..0000000 --- a/vendor/github.com/Sirupsen/logrus/CHANGELOG.md +++ /dev/null @@ -1,66 +0,0 @@ -# 0.10.0 - -* feature: Add a test hook (#180) -* feature: `ParseLevel` is now case-insensitive (#326) -* feature: `FieldLogger` interface that generalizes `Logger` and `Entry` (#308) -* performance: avoid re-allocations on `WithFields` (#335) - -# 0.9.0 - -* logrus/text_formatter: don't emit empty msg -* logrus/hooks/airbrake: move out of main repository -* logrus/hooks/sentry: move out of main repository -* logrus/hooks/papertrail: move out of main repository -* logrus/hooks/bugsnag: move out of main repository -* logrus/core: run tests with `-race` -* logrus/core: detect TTY based on `stderr` -* logrus/core: support `WithError` on logger -* logrus/core: Solaris support - -# 0.8.7 - -* logrus/core: fix possible race (#216) -* logrus/doc: small typo fixes and doc improvements - - -# 0.8.6 - -* hooks/raven: allow passing an initialized client - -# 0.8.5 - -* logrus/core: revert #208 - -# 0.8.4 - -* formatter/text: fix data race (#218) - -# 0.8.3 - -* logrus/core: fix entry log level (#208) -* logrus/core: improve performance of text formatter by 40% -* logrus/core: expose `LevelHooks` type -* logrus/core: add support for DragonflyBSD and NetBSD -* formatter/text: print structs more verbosely - -# 0.8.2 - -* logrus: fix more Fatal family functions - -# 0.8.1 - -* logrus: fix not exiting on `Fatalf` and `Fatalln` - -# 0.8.0 - -* logrus: defaults to stderr instead of stdout -* hooks/sentry: add special field for `*http.Request` -* formatter/text: ignore Windows for colors - -# 0.7.3 - -* formatter/\*: allow configuration of timestamp layout - -# 0.7.2 - -* formatter/text: Add configuration option for time format (#158) diff --git a/vendor/github.com/Sirupsen/logrus/LICENSE b/vendor/github.com/Sirupsen/logrus/LICENSE deleted file mode 100644 index f090cb4..0000000 --- a/vendor/github.com/Sirupsen/logrus/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2014 Simon Eskildsen - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/vendor/github.com/Sirupsen/logrus/README.md b/vendor/github.com/Sirupsen/logrus/README.md deleted file mode 100644 index 05d678a..0000000 --- a/vendor/github.com/Sirupsen/logrus/README.md +++ /dev/null @@ -1,432 +0,0 @@ -# Logrus :walrus: [![Build Status](https://travis-ci.org/Sirupsen/logrus.svg?branch=master)](https://travis-ci.org/Sirupsen/logrus) [![GoDoc](https://godoc.org/github.com/Sirupsen/logrus?status.svg)](https://godoc.org/github.com/Sirupsen/logrus) - -**Seeing weird case-sensitive problems?** See [this -issue](https://github.com/sirupsen/logrus/issues/451#issuecomment-264332021). -This change has been reverted. I apologize for causing this. I greatly -underestimated the impact this would have. Logrus strives for stability and -backwards compatibility and failed to provide that. - -Logrus is a structured logger for Go (golang), completely API compatible with -the standard library logger. [Godoc][godoc]. **Please note the Logrus API is not -yet stable (pre 1.0). Logrus itself is completely stable and has been used in -many large deployments. The core API is unlikely to change much but please -version control your Logrus to make sure you aren't fetching latest `master` on -every build.** - -Nicely color-coded in development (when a TTY is attached, otherwise just -plain text): - -![Colored](http://i.imgur.com/PY7qMwd.png) - -With `log.SetFormatter(&log.JSONFormatter{})`, for easy parsing by logstash -or Splunk: - -```json -{"animal":"walrus","level":"info","msg":"A group of walrus emerges from the -ocean","size":10,"time":"2014-03-10 19:57:38.562264131 -0400 EDT"} - -{"level":"warning","msg":"The group's number increased tremendously!", -"number":122,"omg":true,"time":"2014-03-10 19:57:38.562471297 -0400 EDT"} - -{"animal":"walrus","level":"info","msg":"A giant walrus appears!", -"size":10,"time":"2014-03-10 19:57:38.562500591 -0400 EDT"} - -{"animal":"walrus","level":"info","msg":"Tremendously sized cow enters the ocean.", -"size":9,"time":"2014-03-10 19:57:38.562527896 -0400 EDT"} - -{"level":"fatal","msg":"The ice breaks!","number":100,"omg":true, -"time":"2014-03-10 19:57:38.562543128 -0400 EDT"} -``` - -With the default `log.SetFormatter(&log.TextFormatter{})` when a TTY is not -attached, the output is compatible with the -[logfmt](http://godoc.org/github.com/kr/logfmt) format: - -```text -time="2015-03-26T01:27:38-04:00" level=debug msg="Started observing beach" animal=walrus number=8 -time="2015-03-26T01:27:38-04:00" level=info msg="A group of walrus emerges from the ocean" animal=walrus size=10 -time="2015-03-26T01:27:38-04:00" level=warning msg="The group's number increased tremendously!" number=122 omg=true -time="2015-03-26T01:27:38-04:00" level=debug msg="Temperature changes" temperature=-4 -time="2015-03-26T01:27:38-04:00" level=panic msg="It's over 9000!" animal=orca size=9009 -time="2015-03-26T01:27:38-04:00" level=fatal msg="The ice breaks!" err=&{0x2082280c0 map[animal:orca size:9009] 2015-03-26 01:27:38.441574009 -0400 EDT panic It's over 9000!} number=100 omg=true -exit status 1 -``` - -#### Example - -The simplest way to use Logrus is simply the package-level exported logger: - -```go -package main - -import ( - log "github.com/Sirupsen/logrus" -) - -func main() { - log.WithFields(log.Fields{ - "animal": "walrus", - }).Info("A walrus appears") -} -``` - -Note that it's completely api-compatible with the stdlib logger, so you can -replace your `log` imports everywhere with `log "github.com/Sirupsen/logrus"` -and you'll now have the flexibility of Logrus. You can customize it all you -want: - -```go -package main - -import ( - "os" - log "github.com/Sirupsen/logrus" -) - -func init() { - // Log as JSON instead of the default ASCII formatter. - log.SetFormatter(&log.JSONFormatter{}) - - // Output to stderr instead of stdout, could also be a file. - log.SetOutput(os.Stderr) - - // Only log the warning severity or above. - log.SetLevel(log.WarnLevel) -} - -func main() { - log.WithFields(log.Fields{ - "animal": "walrus", - "size": 10, - }).Info("A group of walrus emerges from the ocean") - - log.WithFields(log.Fields{ - "omg": true, - "number": 122, - }).Warn("The group's number increased tremendously!") - - log.WithFields(log.Fields{ - "omg": true, - "number": 100, - }).Fatal("The ice breaks!") - - // A common pattern is to re-use fields between logging statements by re-using - // the logrus.Entry returned from WithFields() - contextLogger := log.WithFields(log.Fields{ - "common": "this is a common field", - "other": "I also should be logged always", - }) - - contextLogger.Info("I'll be logged with common and other field") - contextLogger.Info("Me too") -} -``` - -For more advanced usage such as logging to multiple locations from the same -application, you can also create an instance of the `logrus` Logger: - -```go -package main - -import ( - "github.com/Sirupsen/logrus" -) - -// Create a new instance of the logger. You can have any number of instances. -var log = logrus.New() - -func main() { - // The API for setting attributes is a little different than the package level - // exported logger. See Godoc. - log.Out = os.Stderr - - log.WithFields(logrus.Fields{ - "animal": "walrus", - "size": 10, - }).Info("A group of walrus emerges from the ocean") -} -``` - -#### Fields - -Logrus encourages careful, structured logging though logging fields instead of -long, unparseable error messages. For example, instead of: `log.Fatalf("Failed -to send event %s to topic %s with key %d")`, you should log the much more -discoverable: - -```go -log.WithFields(log.Fields{ - "event": event, - "topic": topic, - "key": key, -}).Fatal("Failed to send event") -``` - -We've found this API forces you to think about logging in a way that produces -much more useful logging messages. We've been in countless situations where just -a single added field to a log statement that was already there would've saved us -hours. The `WithFields` call is optional. - -In general, with Logrus using any of the `printf`-family functions should be -seen as a hint you should add a field, however, you can still use the -`printf`-family functions with Logrus. - -#### Hooks - -You can add hooks for logging levels. For example to send errors to an exception -tracking service on `Error`, `Fatal` and `Panic`, info to StatsD or log to -multiple places simultaneously, e.g. syslog. - -Logrus comes with [built-in hooks](hooks/). Add those, or your custom hook, in -`init`: - -```go -import ( - log "github.com/Sirupsen/logrus" - "gopkg.in/gemnasium/logrus-airbrake-hook.v2" // the package is named "aibrake" - logrus_syslog "github.com/Sirupsen/logrus/hooks/syslog" - "log/syslog" -) - -func init() { - - // Use the Airbrake hook to report errors that have Error severity or above to - // an exception tracker. You can create custom hooks, see the Hooks section. - log.AddHook(airbrake.NewHook(123, "xyz", "production")) - - hook, err := logrus_syslog.NewSyslogHook("udp", "localhost:514", syslog.LOG_INFO, "") - if err != nil { - log.Error("Unable to connect to local syslog daemon") - } else { - log.AddHook(hook) - } -} -``` -Note: Syslog hook also support connecting to local syslog (Ex. "/dev/log" or "/var/run/syslog" or "/var/run/log"). For the detail, please check the [syslog hook README](hooks/syslog/README.md). - -| Hook | Description | -| ----- | ----------- | -| [Airbrake](https://github.com/gemnasium/logrus-airbrake-hook) | Send errors to the Airbrake API V3. Uses the official [`gobrake`](https://github.com/airbrake/gobrake) behind the scenes. | -| [Airbrake "legacy"](https://github.com/gemnasium/logrus-airbrake-legacy-hook) | Send errors to an exception tracking service compatible with the Airbrake API V2. Uses [`airbrake-go`](https://github.com/tobi/airbrake-go) behind the scenes. | -| [Papertrail](https://github.com/polds/logrus-papertrail-hook) | Send errors to the [Papertrail](https://papertrailapp.com) hosted logging service via UDP. | -| [Syslog](https://github.com/Sirupsen/logrus/blob/master/hooks/syslog/syslog.go) | Send errors to remote syslog server. Uses standard library `log/syslog` behind the scenes. | -| [Bugsnag](https://github.com/Shopify/logrus-bugsnag/blob/master/bugsnag.go) | Send errors to the Bugsnag exception tracking service. | -| [Sentry](https://github.com/evalphobia/logrus_sentry) | Send errors to the Sentry error logging and aggregation service. | -| [Hiprus](https://github.com/nubo/hiprus) | Send errors to a channel in hipchat. | -| [Logrusly](https://github.com/sebest/logrusly) | Send logs to [Loggly](https://www.loggly.com/) | -| [Slackrus](https://github.com/johntdyer/slackrus) | Hook for Slack chat. | -| [Journalhook](https://github.com/wercker/journalhook) | Hook for logging to `systemd-journald` | -| [Graylog](https://github.com/gemnasium/logrus-graylog-hook) | Hook for logging to [Graylog](http://graylog2.org/) | -| [Raygun](https://github.com/squirkle/logrus-raygun-hook) | Hook for logging to [Raygun.io](http://raygun.io/) | -| [LFShook](https://github.com/rifflock/lfshook) | Hook for logging to the local filesystem | -| [Honeybadger](https://github.com/agonzalezro/logrus_honeybadger) | Hook for sending exceptions to Honeybadger | -| [Mail](https://github.com/zbindenren/logrus_mail) | Hook for sending exceptions via mail | -| [Rollrus](https://github.com/heroku/rollrus) | Hook for sending errors to rollbar | -| [Fluentd](https://github.com/evalphobia/logrus_fluent) | Hook for logging to fluentd | -| [Mongodb](https://github.com/weekface/mgorus) | Hook for logging to mongodb | -| [Influxus] (http://github.com/vlad-doru/influxus) | Hook for concurrently logging to [InfluxDB] (http://influxdata.com/) | -| [InfluxDB](https://github.com/Abramovic/logrus_influxdb) | Hook for logging to influxdb | -| [Octokit](https://github.com/dorajistyle/logrus-octokit-hook) | Hook for logging to github via octokit | -| [DeferPanic](https://github.com/deferpanic/dp-logrus) | Hook for logging to DeferPanic | -| [Redis-Hook](https://github.com/rogierlommers/logrus-redis-hook) | Hook for logging to a ELK stack (through Redis) | -| [Amqp-Hook](https://github.com/vladoatanasov/logrus_amqp) | Hook for logging to Amqp broker (Like RabbitMQ) | -| [KafkaLogrus](https://github.com/goibibo/KafkaLogrus) | Hook for logging to kafka | -| [Typetalk](https://github.com/dragon3/logrus-typetalk-hook) | Hook for logging to [Typetalk](https://www.typetalk.in/) | -| [ElasticSearch](https://github.com/sohlich/elogrus) | Hook for logging to ElasticSearch| -| [Sumorus](https://github.com/doublefree/sumorus) | Hook for logging to [SumoLogic](https://www.sumologic.com/)| -| [Scribe](https://github.com/sagar8192/logrus-scribe-hook) | Hook for logging to [Scribe](https://github.com/facebookarchive/scribe)| -| [Logstash](https://github.com/bshuster-repo/logrus-logstash-hook) | Hook for logging to [Logstash](https://www.elastic.co/products/logstash) | -| [logz.io](https://github.com/ripcurld00d/logrus-logzio-hook) | Hook for logging to [logz.io](https://logz.io), a Log as a Service using Logstash | -| [Logmatic.io](https://github.com/logmatic/logmatic-go) | Hook for logging to [Logmatic.io](http://logmatic.io/) | -| [Pushover](https://github.com/toorop/logrus_pushover) | Send error via [Pushover](https://pushover.net) | -| [PostgreSQL](https://github.com/gemnasium/logrus-postgresql-hook) | Send logs to [PostgreSQL](http://postgresql.org) | - - -#### Level logging - -Logrus has six logging levels: Debug, Info, Warning, Error, Fatal and Panic. - -```go -log.Debug("Useful debugging information.") -log.Info("Something noteworthy happened!") -log.Warn("You should probably take a look at this.") -log.Error("Something failed but I'm not quitting.") -// Calls os.Exit(1) after logging -log.Fatal("Bye.") -// Calls panic() after logging -log.Panic("I'm bailing.") -``` - -You can set the logging level on a `Logger`, then it will only log entries with -that severity or anything above it: - -```go -// Will log anything that is info or above (warn, error, fatal, panic). Default. -log.SetLevel(log.InfoLevel) -``` - -It may be useful to set `log.Level = logrus.DebugLevel` in a debug or verbose -environment if your application has that. - -#### Entries - -Besides the fields added with `WithField` or `WithFields` some fields are -automatically added to all logging events: - -1. `time`. The timestamp when the entry was created. -2. `msg`. The logging message passed to `{Info,Warn,Error,Fatal,Panic}` after - the `AddFields` call. E.g. `Failed to send event.` -3. `level`. The logging level. E.g. `info`. - -#### Environments - -Logrus has no notion of environment. - -If you wish for hooks and formatters to only be used in specific environments, -you should handle that yourself. For example, if your application has a global -variable `Environment`, which is a string representation of the environment you -could do: - -```go -import ( - log "github.com/Sirupsen/logrus" -) - -init() { - // do something here to set environment depending on an environment variable - // or command-line flag - if Environment == "production" { - log.SetFormatter(&log.JSONFormatter{}) - } else { - // The TextFormatter is default, you don't actually have to do this. - log.SetFormatter(&log.TextFormatter{}) - } -} -``` - -This configuration is how `logrus` was intended to be used, but JSON in -production is mostly only useful if you do log aggregation with tools like -Splunk or Logstash. - -#### Formatters - -The built-in logging formatters are: - -* `logrus.TextFormatter`. Logs the event in colors if stdout is a tty, otherwise - without colors. - * *Note:* to force colored output when there is no TTY, set the `ForceColors` - field to `true`. To force no colored output even if there is a TTY set the - `DisableColors` field to `true` -* `logrus.JSONFormatter`. Logs fields as JSON. - -Third party logging formatters: - -* [`logstash`](https://github.com/bshuster-repo/logrus-logstash-hook). Logs fields as [Logstash](http://logstash.net) Events. -* [`prefixed`](https://github.com/x-cray/logrus-prefixed-formatter). Displays log entry source along with alternative layout. -* [`zalgo`](https://github.com/aybabtme/logzalgo). Invoking the P͉̫o̳̼̊w̖͈̰͎e̬͔̭͂r͚̼̹̲ ̫͓͉̳͈ō̠͕͖̚f̝͍̠ ͕̲̞͖͑Z̖̫̤̫ͪa͉̬͈̗l͖͎g̳̥o̰̥̅!̣͔̲̻͊̄ ̙̘̦̹̦. - -You can define your formatter by implementing the `Formatter` interface, -requiring a `Format` method. `Format` takes an `*Entry`. `entry.Data` is a -`Fields` type (`map[string]interface{}`) with all your fields as well as the -default ones (see Entries section above): - -```go -type MyJSONFormatter struct { -} - -log.SetFormatter(new(MyJSONFormatter)) - -func (f *MyJSONFormatter) Format(entry *Entry) ([]byte, error) { - // Note this doesn't include Time, Level and Message which are available on - // the Entry. Consult `godoc` on information about those fields or read the - // source of the official loggers. - serialized, err := json.Marshal(entry.Data) - if err != nil { - return nil, fmt.Errorf("Failed to marshal fields to JSON, %v", err) - } - return append(serialized, '\n'), nil -} -``` - -#### Logger as an `io.Writer` - -Logrus can be transformed into an `io.Writer`. That writer is the end of an `io.Pipe` and it is your responsibility to close it. - -```go -w := logger.Writer() -defer w.Close() - -srv := http.Server{ - // create a stdlib log.Logger that writes to - // logrus.Logger. - ErrorLog: log.New(w, "", 0), -} -``` - -Each line written to that writer will be printed the usual way, using formatters -and hooks. The level for those entries is `info`. - -#### Rotation - -Log rotation is not provided with Logrus. Log rotation should be done by an -external program (like `logrotate(8)`) that can compress and delete old log -entries. It should not be a feature of the application-level logger. - -#### Tools - -| Tool | Description | -| ---- | ----------- | -|[Logrus Mate](https://github.com/gogap/logrus_mate)|Logrus mate is a tool for Logrus to manage loggers, you can initial logger's level, hook and formatter by config file, the logger will generated with different config at different environment.| -|[Logrus Viper Helper](https://github.com/heirko/go-contrib/tree/master/logrusHelper)|An Helper arround Logrus to wrap with spf13/Viper to load configuration with fangs! And to simplify Logrus configuration use some behavior of [Logrus Mate](https://github.com/gogap/logrus_mate). [sample](https://github.com/heirko/iris-contrib/blob/master/middleware/logrus-logger/example) | - -#### Testing - -Logrus has a built in facility for asserting the presence of log messages. This is implemented through the `test` hook and provides: - -* decorators for existing logger (`test.NewLocal` and `test.NewGlobal`) which basically just add the `test` hook -* a test logger (`test.NewNullLogger`) that just records log messages (and does not output any): - -```go -logger, hook := NewNullLogger() -logger.Error("Hello error") - -assert.Equal(1, len(hook.Entries)) -assert.Equal(logrus.ErrorLevel, hook.LastEntry().Level) -assert.Equal("Hello error", hook.LastEntry().Message) - -hook.Reset() -assert.Nil(hook.LastEntry()) -``` - -#### Fatal handlers - -Logrus can register one or more functions that will be called when any `fatal` -level message is logged. The registered handlers will be executed before -logrus performs a `os.Exit(1)`. This behavior may be helpful if callers need -to gracefully shutdown. Unlike a `panic("Something went wrong...")` call which can be intercepted with a deferred `recover` a call to `os.Exit(1)` can not be intercepted. - -``` -... -handler := func() { - // gracefully shutdown something... -} -logrus.RegisterExitHandler(handler) -... -``` - -#### Thread safety - -By default Logger is protected by mutex for concurrent writes, this mutex is invoked when calling hooks and writing logs. -If you are sure such locking is not needed, you can call logger.SetNoLock() to disable the locking. - -Situation when locking is not needed includes: - -* You have no hooks registered, or hooks calling is already thread-safe. - -* Writing to logger.Out is already thread-safe, for example: - - 1) logger.Out is protected by locks. - - 2) logger.Out is a os.File handler opened with `O_APPEND` flag, and every write is smaller than 4k. (This allow multi-thread/multi-process writing) - - (Refer to http://www.notthewizard.com/2014/06/17/are-files-appends-really-atomic/) diff --git a/vendor/github.com/Sirupsen/logrus/alt_exit.go b/vendor/github.com/Sirupsen/logrus/alt_exit.go deleted file mode 100644 index b4c9e84..0000000 --- a/vendor/github.com/Sirupsen/logrus/alt_exit.go +++ /dev/null @@ -1,64 +0,0 @@ -package logrus - -// The following code was sourced and modified from the -// https://bitbucket.org/tebeka/atexit package governed by the following license: -// -// Copyright (c) 2012 Miki Tebeka . -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -import ( - "fmt" - "os" -) - -var handlers = []func(){} - -func runHandler(handler func()) { - defer func() { - if err := recover(); err != nil { - fmt.Fprintln(os.Stderr, "Error: Logrus exit handler error:", err) - } - }() - - handler() -} - -func runHandlers() { - for _, handler := range handlers { - runHandler(handler) - } -} - -// Exit runs all the Logrus atexit handlers and then terminates the program using os.Exit(code) -func Exit(code int) { - runHandlers() - os.Exit(code) -} - -// RegisterExitHandler adds a Logrus Exit handler, call logrus.Exit to invoke -// all handlers. The handlers will also be invoked when any Fatal log entry is -// made. -// -// This method is useful when a caller wishes to use logrus to log a fatal -// message but also needs to gracefully shutdown. An example usecase could be -// closing database connections, or sending a alert that the application is -// closing. -func RegisterExitHandler(handler func()) { - handlers = append(handlers, handler) -} diff --git a/vendor/github.com/Sirupsen/logrus/doc.go b/vendor/github.com/Sirupsen/logrus/doc.go deleted file mode 100644 index dddd5f8..0000000 --- a/vendor/github.com/Sirupsen/logrus/doc.go +++ /dev/null @@ -1,26 +0,0 @@ -/* -Package logrus is a structured logger for Go, completely API compatible with the standard library logger. - - -The simplest way to use Logrus is simply the package-level exported logger: - - package main - - import ( - log "github.com/Sirupsen/logrus" - ) - - func main() { - log.WithFields(log.Fields{ - "animal": "walrus", - "number": 1, - "size": 10, - }).Info("A walrus appears") - } - -Output: - time="2015-09-07T08:48:33Z" level=info msg="A walrus appears" animal=walrus number=1 size=10 - -For a full guide visit https://github.com/Sirupsen/logrus -*/ -package logrus diff --git a/vendor/github.com/Sirupsen/logrus/entry.go b/vendor/github.com/Sirupsen/logrus/entry.go deleted file mode 100644 index 4edbe7a..0000000 --- a/vendor/github.com/Sirupsen/logrus/entry.go +++ /dev/null @@ -1,275 +0,0 @@ -package logrus - -import ( - "bytes" - "fmt" - "os" - "sync" - "time" -) - -var bufferPool *sync.Pool - -func init() { - bufferPool = &sync.Pool{ - New: func() interface{} { - return new(bytes.Buffer) - }, - } -} - -// Defines the key when adding errors using WithError. -var ErrorKey = "error" - -// An entry is the final or intermediate Logrus logging entry. It contains all -// the fields passed with WithField{,s}. It's finally logged when Debug, Info, -// Warn, Error, Fatal or Panic is called on it. These objects can be reused and -// passed around as much as you wish to avoid field duplication. -type Entry struct { - Logger *Logger - - // Contains all the fields set by the user. - Data Fields - - // Time at which the log entry was created - Time time.Time - - // Level the log entry was logged at: Debug, Info, Warn, Error, Fatal or Panic - Level Level - - // Message passed to Debug, Info, Warn, Error, Fatal or Panic - Message string - - // When formatter is called in entry.log(), an Buffer may be set to entry - Buffer *bytes.Buffer -} - -func NewEntry(logger *Logger) *Entry { - return &Entry{ - Logger: logger, - // Default is three fields, give a little extra room - Data: make(Fields, 5), - } -} - -// Returns the string representation from the reader and ultimately the -// formatter. -func (entry *Entry) String() (string, error) { - serialized, err := entry.Logger.Formatter.Format(entry) - if err != nil { - return "", err - } - str := string(serialized) - return str, nil -} - -// Add an error as single field (using the key defined in ErrorKey) to the Entry. -func (entry *Entry) WithError(err error) *Entry { - return entry.WithField(ErrorKey, err) -} - -// Add a single field to the Entry. -func (entry *Entry) WithField(key string, value interface{}) *Entry { - return entry.WithFields(Fields{key: value}) -} - -// Add a map of fields to the Entry. -func (entry *Entry) WithFields(fields Fields) *Entry { - data := make(Fields, len(entry.Data)+len(fields)) - for k, v := range entry.Data { - data[k] = v - } - for k, v := range fields { - data[k] = v - } - return &Entry{Logger: entry.Logger, Data: data} -} - -// This function is not declared with a pointer value because otherwise -// race conditions will occur when using multiple goroutines -func (entry Entry) log(level Level, msg string) { - var buffer *bytes.Buffer - entry.Time = time.Now() - entry.Level = level - entry.Message = msg - - if err := entry.Logger.Hooks.Fire(level, &entry); err != nil { - entry.Logger.mu.Lock() - fmt.Fprintf(os.Stderr, "Failed to fire hook: %v\n", err) - entry.Logger.mu.Unlock() - } - buffer = bufferPool.Get().(*bytes.Buffer) - buffer.Reset() - defer bufferPool.Put(buffer) - entry.Buffer = buffer - serialized, err := entry.Logger.Formatter.Format(&entry) - entry.Buffer = nil - if err != nil { - entry.Logger.mu.Lock() - fmt.Fprintf(os.Stderr, "Failed to obtain reader, %v\n", err) - entry.Logger.mu.Unlock() - } else { - entry.Logger.mu.Lock() - _, err = entry.Logger.Out.Write(serialized) - if err != nil { - fmt.Fprintf(os.Stderr, "Failed to write to log, %v\n", err) - } - entry.Logger.mu.Unlock() - } - - // To avoid Entry#log() returning a value that only would make sense for - // panic() to use in Entry#Panic(), we avoid the allocation by checking - // directly here. - if level <= PanicLevel { - panic(&entry) - } -} - -func (entry *Entry) Debug(args ...interface{}) { - if entry.Logger.Level >= DebugLevel { - entry.log(DebugLevel, fmt.Sprint(args...)) - } -} - -func (entry *Entry) Print(args ...interface{}) { - entry.Info(args...) -} - -func (entry *Entry) Info(args ...interface{}) { - if entry.Logger.Level >= InfoLevel { - entry.log(InfoLevel, fmt.Sprint(args...)) - } -} - -func (entry *Entry) Warn(args ...interface{}) { - if entry.Logger.Level >= WarnLevel { - entry.log(WarnLevel, fmt.Sprint(args...)) - } -} - -func (entry *Entry) Warning(args ...interface{}) { - entry.Warn(args...) -} - -func (entry *Entry) Error(args ...interface{}) { - if entry.Logger.Level >= ErrorLevel { - entry.log(ErrorLevel, fmt.Sprint(args...)) - } -} - -func (entry *Entry) Fatal(args ...interface{}) { - if entry.Logger.Level >= FatalLevel { - entry.log(FatalLevel, fmt.Sprint(args...)) - } - Exit(1) -} - -func (entry *Entry) Panic(args ...interface{}) { - if entry.Logger.Level >= PanicLevel { - entry.log(PanicLevel, fmt.Sprint(args...)) - } - panic(fmt.Sprint(args...)) -} - -// Entry Printf family functions - -func (entry *Entry) Debugf(format string, args ...interface{}) { - if entry.Logger.Level >= DebugLevel { - entry.Debug(fmt.Sprintf(format, args...)) - } -} - -func (entry *Entry) Infof(format string, args ...interface{}) { - if entry.Logger.Level >= InfoLevel { - entry.Info(fmt.Sprintf(format, args...)) - } -} - -func (entry *Entry) Printf(format string, args ...interface{}) { - entry.Infof(format, args...) -} - -func (entry *Entry) Warnf(format string, args ...interface{}) { - if entry.Logger.Level >= WarnLevel { - entry.Warn(fmt.Sprintf(format, args...)) - } -} - -func (entry *Entry) Warningf(format string, args ...interface{}) { - entry.Warnf(format, args...) -} - -func (entry *Entry) Errorf(format string, args ...interface{}) { - if entry.Logger.Level >= ErrorLevel { - entry.Error(fmt.Sprintf(format, args...)) - } -} - -func (entry *Entry) Fatalf(format string, args ...interface{}) { - if entry.Logger.Level >= FatalLevel { - entry.Fatal(fmt.Sprintf(format, args...)) - } - Exit(1) -} - -func (entry *Entry) Panicf(format string, args ...interface{}) { - if entry.Logger.Level >= PanicLevel { - entry.Panic(fmt.Sprintf(format, args...)) - } -} - -// Entry Println family functions - -func (entry *Entry) Debugln(args ...interface{}) { - if entry.Logger.Level >= DebugLevel { - entry.Debug(entry.sprintlnn(args...)) - } -} - -func (entry *Entry) Infoln(args ...interface{}) { - if entry.Logger.Level >= InfoLevel { - entry.Info(entry.sprintlnn(args...)) - } -} - -func (entry *Entry) Println(args ...interface{}) { - entry.Infoln(args...) -} - -func (entry *Entry) Warnln(args ...interface{}) { - if entry.Logger.Level >= WarnLevel { - entry.Warn(entry.sprintlnn(args...)) - } -} - -func (entry *Entry) Warningln(args ...interface{}) { - entry.Warnln(args...) -} - -func (entry *Entry) Errorln(args ...interface{}) { - if entry.Logger.Level >= ErrorLevel { - entry.Error(entry.sprintlnn(args...)) - } -} - -func (entry *Entry) Fatalln(args ...interface{}) { - if entry.Logger.Level >= FatalLevel { - entry.Fatal(entry.sprintlnn(args...)) - } - Exit(1) -} - -func (entry *Entry) Panicln(args ...interface{}) { - if entry.Logger.Level >= PanicLevel { - entry.Panic(entry.sprintlnn(args...)) - } -} - -// Sprintlnn => Sprint no newline. This is to get the behavior of how -// fmt.Sprintln where spaces are always added between operands, regardless of -// their type. Instead of vendoring the Sprintln implementation to spare a -// string allocation, we do the simplest thing. -func (entry *Entry) sprintlnn(args ...interface{}) string { - msg := fmt.Sprintln(args...) - return msg[:len(msg)-1] -} diff --git a/vendor/github.com/Sirupsen/logrus/exported.go b/vendor/github.com/Sirupsen/logrus/exported.go deleted file mode 100644 index 9a0120a..0000000 --- a/vendor/github.com/Sirupsen/logrus/exported.go +++ /dev/null @@ -1,193 +0,0 @@ -package logrus - -import ( - "io" -) - -var ( - // std is the name of the standard logger in stdlib `log` - std = New() -) - -func StandardLogger() *Logger { - return std -} - -// SetOutput sets the standard logger output. -func SetOutput(out io.Writer) { - std.mu.Lock() - defer std.mu.Unlock() - std.Out = out -} - -// SetFormatter sets the standard logger formatter. -func SetFormatter(formatter Formatter) { - std.mu.Lock() - defer std.mu.Unlock() - std.Formatter = formatter -} - -// SetLevel sets the standard logger level. -func SetLevel(level Level) { - std.mu.Lock() - defer std.mu.Unlock() - std.Level = level -} - -// GetLevel returns the standard logger level. -func GetLevel() Level { - std.mu.Lock() - defer std.mu.Unlock() - return std.Level -} - -// AddHook adds a hook to the standard logger hooks. -func AddHook(hook Hook) { - std.mu.Lock() - defer std.mu.Unlock() - std.Hooks.Add(hook) -} - -// WithError creates an entry from the standard logger and adds an error to it, using the value defined in ErrorKey as key. -func WithError(err error) *Entry { - return std.WithField(ErrorKey, err) -} - -// WithField creates an entry from the standard logger and adds a field to -// it. If you want multiple fields, use `WithFields`. -// -// Note that it doesn't log until you call Debug, Print, Info, Warn, Fatal -// or Panic on the Entry it returns. -func WithField(key string, value interface{}) *Entry { - return std.WithField(key, value) -} - -// WithFields creates an entry from the standard logger and adds multiple -// fields to it. This is simply a helper for `WithField`, invoking it -// once for each field. -// -// Note that it doesn't log until you call Debug, Print, Info, Warn, Fatal -// or Panic on the Entry it returns. -func WithFields(fields Fields) *Entry { - return std.WithFields(fields) -} - -// Debug logs a message at level Debug on the standard logger. -func Debug(args ...interface{}) { - std.Debug(args...) -} - -// Print logs a message at level Info on the standard logger. -func Print(args ...interface{}) { - std.Print(args...) -} - -// Info logs a message at level Info on the standard logger. -func Info(args ...interface{}) { - std.Info(args...) -} - -// Warn logs a message at level Warn on the standard logger. -func Warn(args ...interface{}) { - std.Warn(args...) -} - -// Warning logs a message at level Warn on the standard logger. -func Warning(args ...interface{}) { - std.Warning(args...) -} - -// Error logs a message at level Error on the standard logger. -func Error(args ...interface{}) { - std.Error(args...) -} - -// Panic logs a message at level Panic on the standard logger. -func Panic(args ...interface{}) { - std.Panic(args...) -} - -// Fatal logs a message at level Fatal on the standard logger. -func Fatal(args ...interface{}) { - std.Fatal(args...) -} - -// Debugf logs a message at level Debug on the standard logger. -func Debugf(format string, args ...interface{}) { - std.Debugf(format, args...) -} - -// Printf logs a message at level Info on the standard logger. -func Printf(format string, args ...interface{}) { - std.Printf(format, args...) -} - -// Infof logs a message at level Info on the standard logger. -func Infof(format string, args ...interface{}) { - std.Infof(format, args...) -} - -// Warnf logs a message at level Warn on the standard logger. -func Warnf(format string, args ...interface{}) { - std.Warnf(format, args...) -} - -// Warningf logs a message at level Warn on the standard logger. -func Warningf(format string, args ...interface{}) { - std.Warningf(format, args...) -} - -// Errorf logs a message at level Error on the standard logger. -func Errorf(format string, args ...interface{}) { - std.Errorf(format, args...) -} - -// Panicf logs a message at level Panic on the standard logger. -func Panicf(format string, args ...interface{}) { - std.Panicf(format, args...) -} - -// Fatalf logs a message at level Fatal on the standard logger. -func Fatalf(format string, args ...interface{}) { - std.Fatalf(format, args...) -} - -// Debugln logs a message at level Debug on the standard logger. -func Debugln(args ...interface{}) { - std.Debugln(args...) -} - -// Println logs a message at level Info on the standard logger. -func Println(args ...interface{}) { - std.Println(args...) -} - -// Infoln logs a message at level Info on the standard logger. -func Infoln(args ...interface{}) { - std.Infoln(args...) -} - -// Warnln logs a message at level Warn on the standard logger. -func Warnln(args ...interface{}) { - std.Warnln(args...) -} - -// Warningln logs a message at level Warn on the standard logger. -func Warningln(args ...interface{}) { - std.Warningln(args...) -} - -// Errorln logs a message at level Error on the standard logger. -func Errorln(args ...interface{}) { - std.Errorln(args...) -} - -// Panicln logs a message at level Panic on the standard logger. -func Panicln(args ...interface{}) { - std.Panicln(args...) -} - -// Fatalln logs a message at level Fatal on the standard logger. -func Fatalln(args ...interface{}) { - std.Fatalln(args...) -} diff --git a/vendor/github.com/Sirupsen/logrus/formatter.go b/vendor/github.com/Sirupsen/logrus/formatter.go deleted file mode 100644 index b5fbe93..0000000 --- a/vendor/github.com/Sirupsen/logrus/formatter.go +++ /dev/null @@ -1,45 +0,0 @@ -package logrus - -import "time" - -const DefaultTimestampFormat = time.RFC3339 - -// The Formatter interface is used to implement a custom Formatter. It takes an -// `Entry`. It exposes all the fields, including the default ones: -// -// * `entry.Data["msg"]`. The message passed from Info, Warn, Error .. -// * `entry.Data["time"]`. The timestamp. -// * `entry.Data["level"]. The level the entry was logged at. -// -// Any additional fields added with `WithField` or `WithFields` are also in -// `entry.Data`. Format is expected to return an array of bytes which are then -// logged to `logger.Out`. -type Formatter interface { - Format(*Entry) ([]byte, error) -} - -// This is to not silently overwrite `time`, `msg` and `level` fields when -// dumping it. If this code wasn't there doing: -// -// logrus.WithField("level", 1).Info("hello") -// -// Would just silently drop the user provided level. Instead with this code -// it'll logged as: -// -// {"level": "info", "fields.level": 1, "msg": "hello", "time": "..."} -// -// It's not exported because it's still using Data in an opinionated way. It's to -// avoid code duplication between the two default formatters. -func prefixFieldClashes(data Fields) { - if t, ok := data["time"]; ok { - data["fields.time"] = t - } - - if m, ok := data["msg"]; ok { - data["fields.msg"] = m - } - - if l, ok := data["level"]; ok { - data["fields.level"] = l - } -} diff --git a/vendor/github.com/Sirupsen/logrus/hooks.go b/vendor/github.com/Sirupsen/logrus/hooks.go deleted file mode 100644 index 3f151cd..0000000 --- a/vendor/github.com/Sirupsen/logrus/hooks.go +++ /dev/null @@ -1,34 +0,0 @@ -package logrus - -// A hook to be fired when logging on the logging levels returned from -// `Levels()` on your implementation of the interface. Note that this is not -// fired in a goroutine or a channel with workers, you should handle such -// functionality yourself if your call is non-blocking and you don't wish for -// the logging calls for levels returned from `Levels()` to block. -type Hook interface { - Levels() []Level - Fire(*Entry) error -} - -// Internal type for storing the hooks on a logger instance. -type LevelHooks map[Level][]Hook - -// Add a hook to an instance of logger. This is called with -// `log.Hooks.Add(new(MyHook))` where `MyHook` implements the `Hook` interface. -func (hooks LevelHooks) Add(hook Hook) { - for _, level := range hook.Levels() { - hooks[level] = append(hooks[level], hook) - } -} - -// Fire all the hooks for the passed level. Used by `entry.log` to fire -// appropriate hooks for a log entry. -func (hooks LevelHooks) Fire(level Level, entry *Entry) error { - for _, hook := range hooks[level] { - if err := hook.Fire(entry); err != nil { - return err - } - } - - return nil -} diff --git a/vendor/github.com/Sirupsen/logrus/json_formatter.go b/vendor/github.com/Sirupsen/logrus/json_formatter.go deleted file mode 100644 index 266554e..0000000 --- a/vendor/github.com/Sirupsen/logrus/json_formatter.go +++ /dev/null @@ -1,74 +0,0 @@ -package logrus - -import ( - "encoding/json" - "fmt" -) - -type fieldKey string -type FieldMap map[fieldKey]string - -const ( - FieldKeyMsg = "msg" - FieldKeyLevel = "level" - FieldKeyTime = "time" -) - -func (f FieldMap) resolve(key fieldKey) string { - if k, ok := f[key]; ok { - return k - } - - return string(key) -} - -type JSONFormatter struct { - // TimestampFormat sets the format used for marshaling timestamps. - TimestampFormat string - - // DisableTimestamp allows disabling automatic timestamps in output - DisableTimestamp bool - - // FieldMap allows users to customize the names of keys for various fields. - // As an example: - // formatter := &JSONFormatter{ - // FieldMap: FieldMap{ - // FieldKeyTime: "@timestamp", - // FieldKeyLevel: "@level", - // FieldKeyLevel: "@message", - // }, - // } - FieldMap FieldMap -} - -func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) { - data := make(Fields, len(entry.Data)+3) - for k, v := range entry.Data { - switch v := v.(type) { - case error: - // Otherwise errors are ignored by `encoding/json` - // https://github.com/Sirupsen/logrus/issues/137 - data[k] = v.Error() - default: - data[k] = v - } - } - prefixFieldClashes(data) - - timestampFormat := f.TimestampFormat - if timestampFormat == "" { - timestampFormat = DefaultTimestampFormat - } - - if !f.DisableTimestamp { - data[f.FieldMap.resolve(FieldKeyTime)] = entry.Time.Format(timestampFormat) - } - data[f.FieldMap.resolve(FieldKeyMsg)] = entry.Message - data[f.FieldMap.resolve(FieldKeyLevel)] = entry.Level.String() - - serialized, err := json.Marshal(data) - if err != nil { - return nil, fmt.Errorf("Failed to marshal fields to JSON, %v", err) - } - return append(serialized, '\n'), nil -} diff --git a/vendor/github.com/Sirupsen/logrus/logger.go b/vendor/github.com/Sirupsen/logrus/logger.go deleted file mode 100644 index b769f3d..0000000 --- a/vendor/github.com/Sirupsen/logrus/logger.go +++ /dev/null @@ -1,308 +0,0 @@ -package logrus - -import ( - "io" - "os" - "sync" -) - -type Logger struct { - // The logs are `io.Copy`'d to this in a mutex. It's common to set this to a - // file, or leave it default which is `os.Stderr`. You can also set this to - // something more adventorous, such as logging to Kafka. - Out io.Writer - // Hooks for the logger instance. These allow firing events based on logging - // levels and log entries. For example, to send errors to an error tracking - // service, log to StatsD or dump the core on fatal errors. - Hooks LevelHooks - // All log entries pass through the formatter before logged to Out. The - // included formatters are `TextFormatter` and `JSONFormatter` for which - // TextFormatter is the default. In development (when a TTY is attached) it - // logs with colors, but to a file it wouldn't. You can easily implement your - // own that implements the `Formatter` interface, see the `README` or included - // formatters for examples. - Formatter Formatter - // The logging level the logger should log at. This is typically (and defaults - // to) `logrus.Info`, which allows Info(), Warn(), Error() and Fatal() to be - // logged. `logrus.Debug` is useful in - Level Level - // Used to sync writing to the log. Locking is enabled by Default - mu MutexWrap - // Reusable empty entry - entryPool sync.Pool -} - -type MutexWrap struct { - lock sync.Mutex - disabled bool -} - -func (mw *MutexWrap) Lock() { - if !mw.disabled { - mw.lock.Lock() - } -} - -func (mw *MutexWrap) Unlock() { - if !mw.disabled { - mw.lock.Unlock() - } -} - -func (mw *MutexWrap) Disable() { - mw.disabled = true -} - -// Creates a new logger. Configuration should be set by changing `Formatter`, -// `Out` and `Hooks` directly on the default logger instance. You can also just -// instantiate your own: -// -// var log = &Logger{ -// Out: os.Stderr, -// Formatter: new(JSONFormatter), -// Hooks: make(LevelHooks), -// Level: logrus.DebugLevel, -// } -// -// It's recommended to make this a global instance called `log`. -func New() *Logger { - return &Logger{ - Out: os.Stderr, - Formatter: new(TextFormatter), - Hooks: make(LevelHooks), - Level: InfoLevel, - } -} - -func (logger *Logger) newEntry() *Entry { - entry, ok := logger.entryPool.Get().(*Entry) - if ok { - return entry - } - return NewEntry(logger) -} - -func (logger *Logger) releaseEntry(entry *Entry) { - logger.entryPool.Put(entry) -} - -// Adds a field to the log entry, note that it doesn't log until you call -// Debug, Print, Info, Warn, Fatal or Panic. It only creates a log entry. -// If you want multiple fields, use `WithFields`. -func (logger *Logger) WithField(key string, value interface{}) *Entry { - entry := logger.newEntry() - defer logger.releaseEntry(entry) - return entry.WithField(key, value) -} - -// Adds a struct of fields to the log entry. All it does is call `WithField` for -// each `Field`. -func (logger *Logger) WithFields(fields Fields) *Entry { - entry := logger.newEntry() - defer logger.releaseEntry(entry) - return entry.WithFields(fields) -} - -// Add an error as single field to the log entry. All it does is call -// `WithError` for the given `error`. -func (logger *Logger) WithError(err error) *Entry { - entry := logger.newEntry() - defer logger.releaseEntry(entry) - return entry.WithError(err) -} - -func (logger *Logger) Debugf(format string, args ...interface{}) { - if logger.Level >= DebugLevel { - entry := logger.newEntry() - entry.Debugf(format, args...) - logger.releaseEntry(entry) - } -} - -func (logger *Logger) Infof(format string, args ...interface{}) { - if logger.Level >= InfoLevel { - entry := logger.newEntry() - entry.Infof(format, args...) - logger.releaseEntry(entry) - } -} - -func (logger *Logger) Printf(format string, args ...interface{}) { - entry := logger.newEntry() - entry.Printf(format, args...) - logger.releaseEntry(entry) -} - -func (logger *Logger) Warnf(format string, args ...interface{}) { - if logger.Level >= WarnLevel { - entry := logger.newEntry() - entry.Warnf(format, args...) - logger.releaseEntry(entry) - } -} - -func (logger *Logger) Warningf(format string, args ...interface{}) { - if logger.Level >= WarnLevel { - entry := logger.newEntry() - entry.Warnf(format, args...) - logger.releaseEntry(entry) - } -} - -func (logger *Logger) Errorf(format string, args ...interface{}) { - if logger.Level >= ErrorLevel { - entry := logger.newEntry() - entry.Errorf(format, args...) - logger.releaseEntry(entry) - } -} - -func (logger *Logger) Fatalf(format string, args ...interface{}) { - if logger.Level >= FatalLevel { - entry := logger.newEntry() - entry.Fatalf(format, args...) - logger.releaseEntry(entry) - } - Exit(1) -} - -func (logger *Logger) Panicf(format string, args ...interface{}) { - if logger.Level >= PanicLevel { - entry := logger.newEntry() - entry.Panicf(format, args...) - logger.releaseEntry(entry) - } -} - -func (logger *Logger) Debug(args ...interface{}) { - if logger.Level >= DebugLevel { - entry := logger.newEntry() - entry.Debug(args...) - logger.releaseEntry(entry) - } -} - -func (logger *Logger) Info(args ...interface{}) { - if logger.Level >= InfoLevel { - entry := logger.newEntry() - entry.Info(args...) - logger.releaseEntry(entry) - } -} - -func (logger *Logger) Print(args ...interface{}) { - entry := logger.newEntry() - entry.Info(args...) - logger.releaseEntry(entry) -} - -func (logger *Logger) Warn(args ...interface{}) { - if logger.Level >= WarnLevel { - entry := logger.newEntry() - entry.Warn(args...) - logger.releaseEntry(entry) - } -} - -func (logger *Logger) Warning(args ...interface{}) { - if logger.Level >= WarnLevel { - entry := logger.newEntry() - entry.Warn(args...) - logger.releaseEntry(entry) - } -} - -func (logger *Logger) Error(args ...interface{}) { - if logger.Level >= ErrorLevel { - entry := logger.newEntry() - entry.Error(args...) - logger.releaseEntry(entry) - } -} - -func (logger *Logger) Fatal(args ...interface{}) { - if logger.Level >= FatalLevel { - entry := logger.newEntry() - entry.Fatal(args...) - logger.releaseEntry(entry) - } - Exit(1) -} - -func (logger *Logger) Panic(args ...interface{}) { - if logger.Level >= PanicLevel { - entry := logger.newEntry() - entry.Panic(args...) - logger.releaseEntry(entry) - } -} - -func (logger *Logger) Debugln(args ...interface{}) { - if logger.Level >= DebugLevel { - entry := logger.newEntry() - entry.Debugln(args...) - logger.releaseEntry(entry) - } -} - -func (logger *Logger) Infoln(args ...interface{}) { - if logger.Level >= InfoLevel { - entry := logger.newEntry() - entry.Infoln(args...) - logger.releaseEntry(entry) - } -} - -func (logger *Logger) Println(args ...interface{}) { - entry := logger.newEntry() - entry.Println(args...) - logger.releaseEntry(entry) -} - -func (logger *Logger) Warnln(args ...interface{}) { - if logger.Level >= WarnLevel { - entry := logger.newEntry() - entry.Warnln(args...) - logger.releaseEntry(entry) - } -} - -func (logger *Logger) Warningln(args ...interface{}) { - if logger.Level >= WarnLevel { - entry := logger.newEntry() - entry.Warnln(args...) - logger.releaseEntry(entry) - } -} - -func (logger *Logger) Errorln(args ...interface{}) { - if logger.Level >= ErrorLevel { - entry := logger.newEntry() - entry.Errorln(args...) - logger.releaseEntry(entry) - } -} - -func (logger *Logger) Fatalln(args ...interface{}) { - if logger.Level >= FatalLevel { - entry := logger.newEntry() - entry.Fatalln(args...) - logger.releaseEntry(entry) - } - Exit(1) -} - -func (logger *Logger) Panicln(args ...interface{}) { - if logger.Level >= PanicLevel { - entry := logger.newEntry() - entry.Panicln(args...) - logger.releaseEntry(entry) - } -} - -//When file is opened with appending mode, it's safe to -//write concurrently to a file (within 4k message on Linux). -//In these cases user can choose to disable the lock. -func (logger *Logger) SetNoLock() { - logger.mu.Disable() -} diff --git a/vendor/github.com/Sirupsen/logrus/logrus.go b/vendor/github.com/Sirupsen/logrus/logrus.go deleted file mode 100644 index e596691..0000000 --- a/vendor/github.com/Sirupsen/logrus/logrus.go +++ /dev/null @@ -1,143 +0,0 @@ -package logrus - -import ( - "fmt" - "log" - "strings" -) - -// Fields type, used to pass to `WithFields`. -type Fields map[string]interface{} - -// Level type -type Level uint8 - -// Convert the Level to a string. E.g. PanicLevel becomes "panic". -func (level Level) String() string { - switch level { - case DebugLevel: - return "debug" - case InfoLevel: - return "info" - case WarnLevel: - return "warning" - case ErrorLevel: - return "error" - case FatalLevel: - return "fatal" - case PanicLevel: - return "panic" - } - - return "unknown" -} - -// ParseLevel takes a string level and returns the Logrus log level constant. -func ParseLevel(lvl string) (Level, error) { - switch strings.ToLower(lvl) { - case "panic": - return PanicLevel, nil - case "fatal": - return FatalLevel, nil - case "error": - return ErrorLevel, nil - case "warn", "warning": - return WarnLevel, nil - case "info": - return InfoLevel, nil - case "debug": - return DebugLevel, nil - } - - var l Level - return l, fmt.Errorf("not a valid logrus Level: %q", lvl) -} - -// A constant exposing all logging levels -var AllLevels = []Level{ - PanicLevel, - FatalLevel, - ErrorLevel, - WarnLevel, - InfoLevel, - DebugLevel, -} - -// These are the different logging levels. You can set the logging level to log -// on your instance of logger, obtained with `logrus.New()`. -const ( - // PanicLevel level, highest level of severity. Logs and then calls panic with the - // message passed to Debug, Info, ... - PanicLevel Level = iota - // FatalLevel level. Logs and then calls `os.Exit(1)`. It will exit even if the - // logging level is set to Panic. - FatalLevel - // ErrorLevel level. Logs. Used for errors that should definitely be noted. - // Commonly used for hooks to send errors to an error tracking service. - ErrorLevel - // WarnLevel level. Non-critical entries that deserve eyes. - WarnLevel - // InfoLevel level. General operational entries about what's going on inside the - // application. - InfoLevel - // DebugLevel level. Usually only enabled when debugging. Very verbose logging. - DebugLevel -) - -// Won't compile if StdLogger can't be realized by a log.Logger -var ( - _ StdLogger = &log.Logger{} - _ StdLogger = &Entry{} - _ StdLogger = &Logger{} -) - -// StdLogger is what your logrus-enabled library should take, that way -// it'll accept a stdlib logger and a logrus logger. There's no standard -// interface, this is the closest we get, unfortunately. -type StdLogger interface { - Print(...interface{}) - Printf(string, ...interface{}) - Println(...interface{}) - - Fatal(...interface{}) - Fatalf(string, ...interface{}) - Fatalln(...interface{}) - - Panic(...interface{}) - Panicf(string, ...interface{}) - Panicln(...interface{}) -} - -// The FieldLogger interface generalizes the Entry and Logger types -type FieldLogger interface { - WithField(key string, value interface{}) *Entry - WithFields(fields Fields) *Entry - WithError(err error) *Entry - - Debugf(format string, args ...interface{}) - Infof(format string, args ...interface{}) - Printf(format string, args ...interface{}) - Warnf(format string, args ...interface{}) - Warningf(format string, args ...interface{}) - Errorf(format string, args ...interface{}) - Fatalf(format string, args ...interface{}) - Panicf(format string, args ...interface{}) - - Debug(args ...interface{}) - Info(args ...interface{}) - Print(args ...interface{}) - Warn(args ...interface{}) - Warning(args ...interface{}) - Error(args ...interface{}) - Fatal(args ...interface{}) - Panic(args ...interface{}) - - Debugln(args ...interface{}) - Infoln(args ...interface{}) - Println(args ...interface{}) - Warnln(args ...interface{}) - Warningln(args ...interface{}) - Errorln(args ...interface{}) - Fatalln(args ...interface{}) - Panicln(args ...interface{}) -} diff --git a/vendor/github.com/Sirupsen/logrus/terminal_appengine.go b/vendor/github.com/Sirupsen/logrus/terminal_appengine.go deleted file mode 100644 index 1960169..0000000 --- a/vendor/github.com/Sirupsen/logrus/terminal_appengine.go +++ /dev/null @@ -1,8 +0,0 @@ -// +build appengine - -package logrus - -// IsTerminal returns true if stderr's file descriptor is a terminal. -func IsTerminal() bool { - return true -} diff --git a/vendor/github.com/Sirupsen/logrus/terminal_bsd.go b/vendor/github.com/Sirupsen/logrus/terminal_bsd.go deleted file mode 100644 index 5f6be4d..0000000 --- a/vendor/github.com/Sirupsen/logrus/terminal_bsd.go +++ /dev/null @@ -1,10 +0,0 @@ -// +build darwin freebsd openbsd netbsd dragonfly -// +build !appengine - -package logrus - -import "syscall" - -const ioctlReadTermios = syscall.TIOCGETA - -type Termios syscall.Termios diff --git a/vendor/github.com/Sirupsen/logrus/terminal_linux.go b/vendor/github.com/Sirupsen/logrus/terminal_linux.go deleted file mode 100644 index 308160c..0000000 --- a/vendor/github.com/Sirupsen/logrus/terminal_linux.go +++ /dev/null @@ -1,14 +0,0 @@ -// Based on ssh/terminal: -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build !appengine - -package logrus - -import "syscall" - -const ioctlReadTermios = syscall.TCGETS - -type Termios syscall.Termios diff --git a/vendor/github.com/Sirupsen/logrus/terminal_notwindows.go b/vendor/github.com/Sirupsen/logrus/terminal_notwindows.go deleted file mode 100644 index 329038f..0000000 --- a/vendor/github.com/Sirupsen/logrus/terminal_notwindows.go +++ /dev/null @@ -1,22 +0,0 @@ -// Based on ssh/terminal: -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build linux darwin freebsd openbsd netbsd dragonfly -// +build !appengine - -package logrus - -import ( - "syscall" - "unsafe" -) - -// IsTerminal returns true if stderr's file descriptor is a terminal. -func IsTerminal() bool { - fd := syscall.Stderr - var termios Termios - _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0) - return err == 0 -} diff --git a/vendor/github.com/Sirupsen/logrus/terminal_solaris.go b/vendor/github.com/Sirupsen/logrus/terminal_solaris.go deleted file mode 100644 index a3c6f6e..0000000 --- a/vendor/github.com/Sirupsen/logrus/terminal_solaris.go +++ /dev/null @@ -1,15 +0,0 @@ -// +build solaris,!appengine - -package logrus - -import ( - "os" - - "golang.org/x/sys/unix" -) - -// IsTerminal returns true if the given file descriptor is a terminal. -func IsTerminal() bool { - _, err := unix.IoctlGetTermios(int(os.Stdout.Fd()), unix.TCGETA) - return err == nil -} diff --git a/vendor/github.com/Sirupsen/logrus/terminal_windows.go b/vendor/github.com/Sirupsen/logrus/terminal_windows.go deleted file mode 100644 index 3727e8a..0000000 --- a/vendor/github.com/Sirupsen/logrus/terminal_windows.go +++ /dev/null @@ -1,27 +0,0 @@ -// Based on ssh/terminal: -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build windows,!appengine - -package logrus - -import ( - "syscall" - "unsafe" -) - -var kernel32 = syscall.NewLazyDLL("kernel32.dll") - -var ( - procGetConsoleMode = kernel32.NewProc("GetConsoleMode") -) - -// IsTerminal returns true if stderr's file descriptor is a terminal. -func IsTerminal() bool { - fd := syscall.Stderr - var st uint32 - r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(fd), uintptr(unsafe.Pointer(&st)), 0) - return r != 0 && e == 0 -} diff --git a/vendor/github.com/Sirupsen/logrus/text_formatter.go b/vendor/github.com/Sirupsen/logrus/text_formatter.go deleted file mode 100644 index 9114b3c..0000000 --- a/vendor/github.com/Sirupsen/logrus/text_formatter.go +++ /dev/null @@ -1,168 +0,0 @@ -package logrus - -import ( - "bytes" - "fmt" - "runtime" - "sort" - "strings" - "time" -) - -const ( - nocolor = 0 - red = 31 - green = 32 - yellow = 33 - blue = 34 - gray = 37 -) - -var ( - baseTimestamp time.Time - isTerminal bool -) - -func init() { - baseTimestamp = time.Now() - isTerminal = IsTerminal() -} - -func miniTS() int { - return int(time.Since(baseTimestamp) / time.Second) -} - -type TextFormatter struct { - // Set to true to bypass checking for a TTY before outputting colors. - ForceColors bool - - // Force disabling colors. - DisableColors bool - - // Disable timestamp logging. useful when output is redirected to logging - // system that already adds timestamps. - DisableTimestamp bool - - // Enable logging the full timestamp when a TTY is attached instead of just - // the time passed since beginning of execution. - FullTimestamp bool - - // TimestampFormat to use for display when a full timestamp is printed - TimestampFormat string - - // The fields are sorted by default for a consistent output. For applications - // that log extremely frequently and don't use the JSON formatter this may not - // be desired. - DisableSorting bool -} - -func (f *TextFormatter) Format(entry *Entry) ([]byte, error) { - var b *bytes.Buffer - var keys []string = make([]string, 0, len(entry.Data)) - for k := range entry.Data { - keys = append(keys, k) - } - - if !f.DisableSorting { - sort.Strings(keys) - } - if entry.Buffer != nil { - b = entry.Buffer - } else { - b = &bytes.Buffer{} - } - - prefixFieldClashes(entry.Data) - - isColorTerminal := isTerminal && (runtime.GOOS != "windows") - isColored := (f.ForceColors || isColorTerminal) && !f.DisableColors - - timestampFormat := f.TimestampFormat - if timestampFormat == "" { - timestampFormat = DefaultTimestampFormat - } - if isColored { - f.printColored(b, entry, keys, timestampFormat) - } else { - if !f.DisableTimestamp { - f.appendKeyValue(b, "time", entry.Time.Format(timestampFormat)) - } - f.appendKeyValue(b, "level", entry.Level.String()) - if entry.Message != "" { - f.appendKeyValue(b, "msg", entry.Message) - } - for _, key := range keys { - f.appendKeyValue(b, key, entry.Data[key]) - } - } - - b.WriteByte('\n') - return b.Bytes(), nil -} - -func (f *TextFormatter) printColored(b *bytes.Buffer, entry *Entry, keys []string, timestampFormat string) { - var levelColor int - switch entry.Level { - case DebugLevel: - levelColor = gray - case WarnLevel: - levelColor = yellow - case ErrorLevel, FatalLevel, PanicLevel: - levelColor = red - default: - levelColor = blue - } - - levelText := strings.ToUpper(entry.Level.String())[0:4] - - if !f.FullTimestamp { - fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%04d] %-44s ", levelColor, levelText, miniTS(), entry.Message) - } else { - fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%s] %-44s ", levelColor, levelText, entry.Time.Format(timestampFormat), entry.Message) - } - for _, k := range keys { - v := entry.Data[k] - fmt.Fprintf(b, " \x1b[%dm%s\x1b[0m=", levelColor, k) - f.appendValue(b, v) - } -} - -func needsQuoting(text string) bool { - for _, ch := range text { - if !((ch >= 'a' && ch <= 'z') || - (ch >= 'A' && ch <= 'Z') || - (ch >= '0' && ch <= '9') || - ch == '-' || ch == '.') { - return true - } - } - return false -} - -func (f *TextFormatter) appendKeyValue(b *bytes.Buffer, key string, value interface{}) { - - b.WriteString(key) - b.WriteByte('=') - f.appendValue(b, value) - b.WriteByte(' ') -} - -func (f *TextFormatter) appendValue(b *bytes.Buffer, value interface{}) { - switch value := value.(type) { - case string: - if !needsQuoting(value) { - b.WriteString(value) - } else { - fmt.Fprintf(b, "%q", value) - } - case error: - errmsg := value.Error() - if !needsQuoting(errmsg) { - b.WriteString(errmsg) - } else { - fmt.Fprintf(b, "%q", errmsg) - } - default: - fmt.Fprint(b, value) - } -} diff --git a/vendor/github.com/Sirupsen/logrus/writer.go b/vendor/github.com/Sirupsen/logrus/writer.go deleted file mode 100644 index f74d2aa..0000000 --- a/vendor/github.com/Sirupsen/logrus/writer.go +++ /dev/null @@ -1,53 +0,0 @@ -package logrus - -import ( - "bufio" - "io" - "runtime" -) - -func (logger *Logger) Writer() *io.PipeWriter { - return logger.WriterLevel(InfoLevel) -} - -func (logger *Logger) WriterLevel(level Level) *io.PipeWriter { - reader, writer := io.Pipe() - - var printFunc func(args ...interface{}) - switch level { - case DebugLevel: - printFunc = logger.Debug - case InfoLevel: - printFunc = logger.Info - case WarnLevel: - printFunc = logger.Warn - case ErrorLevel: - printFunc = logger.Error - case FatalLevel: - printFunc = logger.Fatal - case PanicLevel: - printFunc = logger.Panic - default: - printFunc = logger.Print - } - - go logger.writerScanner(reader, printFunc) - runtime.SetFinalizer(writer, writerFinalizer) - - return writer -} - -func (logger *Logger) writerScanner(reader *io.PipeReader, printFunc func(args ...interface{})) { - scanner := bufio.NewScanner(reader) - for scanner.Scan() { - printFunc(scanner.Text()) - } - if err := scanner.Err(); err != nil { - logger.Errorf("Error while reading from Writer: %s", err) - } - reader.Close() -} - -func writerFinalizer(writer *io.PipeWriter) { - writer.Close() -} diff --git a/vendor/github.com/andybalholm/cascadia/.travis.yml b/vendor/github.com/andybalholm/cascadia/.travis.yml deleted file mode 100644 index 6f22751..0000000 --- a/vendor/github.com/andybalholm/cascadia/.travis.yml +++ /dev/null @@ -1,14 +0,0 @@ -language: go - -go: - - 1.3 - - 1.4 - -install: - - go get github.com/andybalholm/cascadia - -script: - - go test -v - -notifications: - email: false diff --git a/vendor/github.com/andybalholm/cascadia/LICENSE b/vendor/github.com/andybalholm/cascadia/LICENSE deleted file mode 100644 index ee5ad35..0000000 --- a/vendor/github.com/andybalholm/cascadia/LICENSE +++ /dev/null @@ -1,24 +0,0 @@ -Copyright (c) 2011 Andy Balholm. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/andybalholm/cascadia/README.md b/vendor/github.com/andybalholm/cascadia/README.md deleted file mode 100644 index 9021cb9..0000000 --- a/vendor/github.com/andybalholm/cascadia/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# cascadia - -[![](https://travis-ci.org/andybalholm/cascadia.svg)](https://travis-ci.org/andybalholm/cascadia) - -The Cascadia package implements CSS selectors for use with the parse trees produced by the html package. - -To test CSS selectors without writing Go code, check out [cascadia](https://github.com/suntong/cascadia) the command line tool, a thin wrapper around this package. diff --git a/vendor/github.com/andybalholm/cascadia/parser.go b/vendor/github.com/andybalholm/cascadia/parser.go deleted file mode 100644 index 495db9c..0000000 --- a/vendor/github.com/andybalholm/cascadia/parser.go +++ /dev/null @@ -1,835 +0,0 @@ -// Package cascadia is an implementation of CSS selectors. -package cascadia - -import ( - "errors" - "fmt" - "regexp" - "strconv" - "strings" - - "golang.org/x/net/html" -) - -// a parser for CSS selectors -type parser struct { - s string // the source text - i int // the current position -} - -// parseEscape parses a backslash escape. -func (p *parser) parseEscape() (result string, err error) { - if len(p.s) < p.i+2 || p.s[p.i] != '\\' { - return "", errors.New("invalid escape sequence") - } - - start := p.i + 1 - c := p.s[start] - switch { - case c == '\r' || c == '\n' || c == '\f': - return "", errors.New("escaped line ending outside string") - case hexDigit(c): - // unicode escape (hex) - var i int - for i = start; i < p.i+6 && i < len(p.s) && hexDigit(p.s[i]); i++ { - // empty - } - v, _ := strconv.ParseUint(p.s[start:i], 16, 21) - if len(p.s) > i { - switch p.s[i] { - case '\r': - i++ - if len(p.s) > i && p.s[i] == '\n' { - i++ - } - case ' ', '\t', '\n', '\f': - i++ - } - } - p.i = i - return string(rune(v)), nil - } - - // Return the literal character after the backslash. - result = p.s[start : start+1] - p.i += 2 - return result, nil -} - -func hexDigit(c byte) bool { - return '0' <= c && c <= '9' || 'a' <= c && c <= 'f' || 'A' <= c && c <= 'F' -} - -// nameStart returns whether c can be the first character of an identifier -// (not counting an initial hyphen, or an escape sequence). -func nameStart(c byte) bool { - return 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' || c == '_' || c > 127 -} - -// nameChar returns whether c can be a character within an identifier -// (not counting an escape sequence). -func nameChar(c byte) bool { - return 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' || c == '_' || c > 127 || - c == '-' || '0' <= c && c <= '9' -} - -// parseIdentifier parses an identifier. -func (p *parser) parseIdentifier() (result string, err error) { - startingDash := false - if len(p.s) > p.i && p.s[p.i] == '-' { - startingDash = true - p.i++ - } - - if len(p.s) <= p.i { - return "", errors.New("expected identifier, found EOF instead") - } - - if c := p.s[p.i]; !(nameStart(c) || c == '\\') { - return "", fmt.Errorf("expected identifier, found %c instead", c) - } - - result, err = p.parseName() - if startingDash && err == nil { - result = "-" + result - } - return -} - -// parseName parses a name (which is like an identifier, but doesn't have -// extra restrictions on the first character). -func (p *parser) parseName() (result string, err error) { - i := p.i -loop: - for i < len(p.s) { - c := p.s[i] - switch { - case nameChar(c): - start := i - for i < len(p.s) && nameChar(p.s[i]) { - i++ - } - result += p.s[start:i] - case c == '\\': - p.i = i - val, err := p.parseEscape() - if err != nil { - return "", err - } - i = p.i - result += val - default: - break loop - } - } - - if result == "" { - return "", errors.New("expected name, found EOF instead") - } - - p.i = i - return result, nil -} - -// parseString parses a single- or double-quoted string. -func (p *parser) parseString() (result string, err error) { - i := p.i - if len(p.s) < i+2 { - return "", errors.New("expected string, found EOF instead") - } - - quote := p.s[i] - i++ - -loop: - for i < len(p.s) { - switch p.s[i] { - case '\\': - if len(p.s) > i+1 { - switch c := p.s[i+1]; c { - case '\r': - if len(p.s) > i+2 && p.s[i+2] == '\n' { - i += 3 - continue loop - } - fallthrough - case '\n', '\f': - i += 2 - continue loop - } - } - p.i = i - val, err := p.parseEscape() - if err != nil { - return "", err - } - i = p.i - result += val - case quote: - break loop - case '\r', '\n', '\f': - return "", errors.New("unexpected end of line in string") - default: - start := i - for i < len(p.s) { - if c := p.s[i]; c == quote || c == '\\' || c == '\r' || c == '\n' || c == '\f' { - break - } - i++ - } - result += p.s[start:i] - } - } - - if i >= len(p.s) { - return "", errors.New("EOF in string") - } - - // Consume the final quote. - i++ - - p.i = i - return result, nil -} - -// parseRegex parses a regular expression; the end is defined by encountering an -// unmatched closing ')' or ']' which is not consumed -func (p *parser) parseRegex() (rx *regexp.Regexp, err error) { - i := p.i - if len(p.s) < i+2 { - return nil, errors.New("expected regular expression, found EOF instead") - } - - // number of open parens or brackets; - // when it becomes negative, finished parsing regex - open := 0 - -loop: - for i < len(p.s) { - switch p.s[i] { - case '(', '[': - open++ - case ')', ']': - open-- - if open < 0 { - break loop - } - } - i++ - } - - if i >= len(p.s) { - return nil, errors.New("EOF in regular expression") - } - rx, err = regexp.Compile(p.s[p.i:i]) - p.i = i - return rx, err -} - -// skipWhitespace consumes whitespace characters and comments. -// It returns true if there was actually anything to skip. -func (p *parser) skipWhitespace() bool { - i := p.i - for i < len(p.s) { - switch p.s[i] { - case ' ', '\t', '\r', '\n', '\f': - i++ - continue - case '/': - if strings.HasPrefix(p.s[i:], "/*") { - end := strings.Index(p.s[i+len("/*"):], "*/") - if end != -1 { - i += end + len("/**/") - continue - } - } - } - break - } - - if i > p.i { - p.i = i - return true - } - - return false -} - -// consumeParenthesis consumes an opening parenthesis and any following -// whitespace. It returns true if there was actually a parenthesis to skip. -func (p *parser) consumeParenthesis() bool { - if p.i < len(p.s) && p.s[p.i] == '(' { - p.i++ - p.skipWhitespace() - return true - } - return false -} - -// consumeClosingParenthesis consumes a closing parenthesis and any preceding -// whitespace. It returns true if there was actually a parenthesis to skip. -func (p *parser) consumeClosingParenthesis() bool { - i := p.i - p.skipWhitespace() - if p.i < len(p.s) && p.s[p.i] == ')' { - p.i++ - return true - } - p.i = i - return false -} - -// parseTypeSelector parses a type selector (one that matches by tag name). -func (p *parser) parseTypeSelector() (result Selector, err error) { - tag, err := p.parseIdentifier() - if err != nil { - return nil, err - } - - return typeSelector(tag), nil -} - -// parseIDSelector parses a selector that matches by id attribute. -func (p *parser) parseIDSelector() (Selector, error) { - if p.i >= len(p.s) { - return nil, fmt.Errorf("expected id selector (#id), found EOF instead") - } - if p.s[p.i] != '#' { - return nil, fmt.Errorf("expected id selector (#id), found '%c' instead", p.s[p.i]) - } - - p.i++ - id, err := p.parseName() - if err != nil { - return nil, err - } - - return attributeEqualsSelector("id", id), nil -} - -// parseClassSelector parses a selector that matches by class attribute. -func (p *parser) parseClassSelector() (Selector, error) { - if p.i >= len(p.s) { - return nil, fmt.Errorf("expected class selector (.class), found EOF instead") - } - if p.s[p.i] != '.' { - return nil, fmt.Errorf("expected class selector (.class), found '%c' instead", p.s[p.i]) - } - - p.i++ - class, err := p.parseIdentifier() - if err != nil { - return nil, err - } - - return attributeIncludesSelector("class", class), nil -} - -// parseAttributeSelector parses a selector that matches by attribute value. -func (p *parser) parseAttributeSelector() (Selector, error) { - if p.i >= len(p.s) { - return nil, fmt.Errorf("expected attribute selector ([attribute]), found EOF instead") - } - if p.s[p.i] != '[' { - return nil, fmt.Errorf("expected attribute selector ([attribute]), found '%c' instead", p.s[p.i]) - } - - p.i++ - p.skipWhitespace() - key, err := p.parseIdentifier() - if err != nil { - return nil, err - } - - p.skipWhitespace() - if p.i >= len(p.s) { - return nil, errors.New("unexpected EOF in attribute selector") - } - - if p.s[p.i] == ']' { - p.i++ - return attributeExistsSelector(key), nil - } - - if p.i+2 >= len(p.s) { - return nil, errors.New("unexpected EOF in attribute selector") - } - - op := p.s[p.i : p.i+2] - if op[0] == '=' { - op = "=" - } else if op[1] != '=' { - return nil, fmt.Errorf(`expected equality operator, found "%s" instead`, op) - } - p.i += len(op) - - p.skipWhitespace() - if p.i >= len(p.s) { - return nil, errors.New("unexpected EOF in attribute selector") - } - var val string - var rx *regexp.Regexp - if op == "#=" { - rx, err = p.parseRegex() - } else { - switch p.s[p.i] { - case '\'', '"': - val, err = p.parseString() - default: - val, err = p.parseIdentifier() - } - } - if err != nil { - return nil, err - } - - p.skipWhitespace() - if p.i >= len(p.s) { - return nil, errors.New("unexpected EOF in attribute selector") - } - if p.s[p.i] != ']' { - return nil, fmt.Errorf("expected ']', found '%c' instead", p.s[p.i]) - } - p.i++ - - switch op { - case "=": - return attributeEqualsSelector(key, val), nil - case "!=": - return attributeNotEqualSelector(key, val), nil - case "~=": - return attributeIncludesSelector(key, val), nil - case "|=": - return attributeDashmatchSelector(key, val), nil - case "^=": - return attributePrefixSelector(key, val), nil - case "$=": - return attributeSuffixSelector(key, val), nil - case "*=": - return attributeSubstringSelector(key, val), nil - case "#=": - return attributeRegexSelector(key, rx), nil - } - - return nil, fmt.Errorf("attribute operator %q is not supported", op) -} - -var errExpectedParenthesis = errors.New("expected '(' but didn't find it") -var errExpectedClosingParenthesis = errors.New("expected ')' but didn't find it") -var errUnmatchedParenthesis = errors.New("unmatched '('") - -// parsePseudoclassSelector parses a pseudoclass selector like :not(p). -func (p *parser) parsePseudoclassSelector() (Selector, error) { - if p.i >= len(p.s) { - return nil, fmt.Errorf("expected pseudoclass selector (:pseudoclass), found EOF instead") - } - if p.s[p.i] != ':' { - return nil, fmt.Errorf("expected attribute selector (:pseudoclass), found '%c' instead", p.s[p.i]) - } - - p.i++ - name, err := p.parseIdentifier() - if err != nil { - return nil, err - } - name = toLowerASCII(name) - - switch name { - case "not", "has", "haschild": - if !p.consumeParenthesis() { - return nil, errExpectedParenthesis - } - sel, parseErr := p.parseSelectorGroup() - if parseErr != nil { - return nil, parseErr - } - if !p.consumeClosingParenthesis() { - return nil, errExpectedClosingParenthesis - } - - switch name { - case "not": - return negatedSelector(sel), nil - case "has": - return hasDescendantSelector(sel), nil - case "haschild": - return hasChildSelector(sel), nil - } - - case "contains", "containsown": - if !p.consumeParenthesis() { - return nil, errExpectedParenthesis - } - if p.i == len(p.s) { - return nil, errUnmatchedParenthesis - } - var val string - switch p.s[p.i] { - case '\'', '"': - val, err = p.parseString() - default: - val, err = p.parseIdentifier() - } - if err != nil { - return nil, err - } - val = strings.ToLower(val) - p.skipWhitespace() - if p.i >= len(p.s) { - return nil, errors.New("unexpected EOF in pseudo selector") - } - if !p.consumeClosingParenthesis() { - return nil, errExpectedClosingParenthesis - } - - switch name { - case "contains": - return textSubstrSelector(val), nil - case "containsown": - return ownTextSubstrSelector(val), nil - } - - case "matches", "matchesown": - if !p.consumeParenthesis() { - return nil, errExpectedParenthesis - } - rx, err := p.parseRegex() - if err != nil { - return nil, err - } - if p.i >= len(p.s) { - return nil, errors.New("unexpected EOF in pseudo selector") - } - if !p.consumeClosingParenthesis() { - return nil, errExpectedClosingParenthesis - } - - switch name { - case "matches": - return textRegexSelector(rx), nil - case "matchesown": - return ownTextRegexSelector(rx), nil - } - - case "nth-child", "nth-last-child", "nth-of-type", "nth-last-of-type": - if !p.consumeParenthesis() { - return nil, errExpectedParenthesis - } - a, b, err := p.parseNth() - if err != nil { - return nil, err - } - if !p.consumeClosingParenthesis() { - return nil, errExpectedClosingParenthesis - } - if a == 0 { - switch name { - case "nth-child": - return simpleNthChildSelector(b, false), nil - case "nth-of-type": - return simpleNthChildSelector(b, true), nil - case "nth-last-child": - return simpleNthLastChildSelector(b, false), nil - case "nth-last-of-type": - return simpleNthLastChildSelector(b, true), nil - } - } - return nthChildSelector(a, b, - name == "nth-last-child" || name == "nth-last-of-type", - name == "nth-of-type" || name == "nth-last-of-type"), - nil - - case "first-child": - return simpleNthChildSelector(1, false), nil - case "last-child": - return simpleNthLastChildSelector(1, false), nil - case "first-of-type": - return simpleNthChildSelector(1, true), nil - case "last-of-type": - return simpleNthLastChildSelector(1, true), nil - case "only-child": - return onlyChildSelector(false), nil - case "only-of-type": - return onlyChildSelector(true), nil - case "input": - return inputSelector, nil - case "empty": - return emptyElementSelector, nil - case "root": - return rootSelector, nil - } - - return nil, fmt.Errorf("unknown pseudoclass :%s", name) -} - -// parseInteger parses a decimal integer. -func (p *parser) parseInteger() (int, error) { - i := p.i - start := i - for i < len(p.s) && '0' <= p.s[i] && p.s[i] <= '9' { - i++ - } - if i == start { - return 0, errors.New("expected integer, but didn't find it") - } - p.i = i - - val, err := strconv.Atoi(p.s[start:i]) - if err != nil { - return 0, err - } - - return val, nil -} - -// parseNth parses the argument for :nth-child (normally of the form an+b). -func (p *parser) parseNth() (a, b int, err error) { - // initial state - if p.i >= len(p.s) { - goto eof - } - switch p.s[p.i] { - case '-': - p.i++ - goto negativeA - case '+': - p.i++ - goto positiveA - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - goto positiveA - case 'n', 'N': - a = 1 - p.i++ - goto readN - case 'o', 'O', 'e', 'E': - id, nameErr := p.parseName() - if nameErr != nil { - return 0, 0, nameErr - } - id = toLowerASCII(id) - if id == "odd" { - return 2, 1, nil - } - if id == "even" { - return 2, 0, nil - } - return 0, 0, fmt.Errorf("expected 'odd' or 'even', but found '%s' instead", id) - default: - goto invalid - } - -positiveA: - if p.i >= len(p.s) { - goto eof - } - switch p.s[p.i] { - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - a, err = p.parseInteger() - if err != nil { - return 0, 0, err - } - goto readA - case 'n', 'N': - a = 1 - p.i++ - goto readN - default: - goto invalid - } - -negativeA: - if p.i >= len(p.s) { - goto eof - } - switch p.s[p.i] { - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - a, err = p.parseInteger() - if err != nil { - return 0, 0, err - } - a = -a - goto readA - case 'n', 'N': - a = -1 - p.i++ - goto readN - default: - goto invalid - } - -readA: - if p.i >= len(p.s) { - goto eof - } - switch p.s[p.i] { - case 'n', 'N': - p.i++ - goto readN - default: - // The number we read as a is actually b. - return 0, a, nil - } - -readN: - p.skipWhitespace() - if p.i >= len(p.s) { - goto eof - } - switch p.s[p.i] { - case '+': - p.i++ - p.skipWhitespace() - b, err = p.parseInteger() - if err != nil { - return 0, 0, err - } - return a, b, nil - case '-': - p.i++ - p.skipWhitespace() - b, err = p.parseInteger() - if err != nil { - return 0, 0, err - } - return a, -b, nil - default: - return a, 0, nil - } - -eof: - return 0, 0, errors.New("unexpected EOF while attempting to parse expression of form an+b") - -invalid: - return 0, 0, errors.New("unexpected character while attempting to parse expression of form an+b") -} - -// parseSimpleSelectorSequence parses a selector sequence that applies to -// a single element. -func (p *parser) parseSimpleSelectorSequence() (Selector, error) { - var result Selector - - if p.i >= len(p.s) { - return nil, errors.New("expected selector, found EOF instead") - } - - switch p.s[p.i] { - case '*': - // It's the universal selector. Just skip over it, since it doesn't affect the meaning. - p.i++ - case '#', '.', '[', ':': - // There's no type selector. Wait to process the other till the main loop. - default: - r, err := p.parseTypeSelector() - if err != nil { - return nil, err - } - result = r - } - -loop: - for p.i < len(p.s) { - var ns Selector - var err error - switch p.s[p.i] { - case '#': - ns, err = p.parseIDSelector() - case '.': - ns, err = p.parseClassSelector() - case '[': - ns, err = p.parseAttributeSelector() - case ':': - ns, err = p.parsePseudoclassSelector() - default: - break loop - } - if err != nil { - return nil, err - } - if result == nil { - result = ns - } else { - result = intersectionSelector(result, ns) - } - } - - if result == nil { - result = func(n *html.Node) bool { - return n.Type == html.ElementNode - } - } - - return result, nil -} - -// parseSelector parses a selector that may include combinators. -func (p *parser) parseSelector() (result Selector, err error) { - p.skipWhitespace() - result, err = p.parseSimpleSelectorSequence() - if err != nil { - return - } - - for { - var combinator byte - if p.skipWhitespace() { - combinator = ' ' - } - if p.i >= len(p.s) { - return - } - - switch p.s[p.i] { - case '+', '>', '~': - combinator = p.s[p.i] - p.i++ - p.skipWhitespace() - case ',', ')': - // These characters can't begin a selector, but they can legally occur after one. - return - } - - if combinator == 0 { - return - } - - c, err := p.parseSimpleSelectorSequence() - if err != nil { - return nil, err - } - - switch combinator { - case ' ': - result = descendantSelector(result, c) - case '>': - result = childSelector(result, c) - case '+': - result = siblingSelector(result, c, true) - case '~': - result = siblingSelector(result, c, false) - } - } - - panic("unreachable") -} - -// parseSelectorGroup parses a group of selectors, separated by commas. -func (p *parser) parseSelectorGroup() (result Selector, err error) { - result, err = p.parseSelector() - if err != nil { - return - } - - for p.i < len(p.s) { - if p.s[p.i] != ',' { - return result, nil - } - p.i++ - c, err := p.parseSelector() - if err != nil { - return nil, err - } - result = unionSelector(result, c) - } - - return -} diff --git a/vendor/github.com/andybalholm/cascadia/selector.go b/vendor/github.com/andybalholm/cascadia/selector.go deleted file mode 100644 index 9fb05cc..0000000 --- a/vendor/github.com/andybalholm/cascadia/selector.go +++ /dev/null @@ -1,622 +0,0 @@ -package cascadia - -import ( - "bytes" - "fmt" - "regexp" - "strings" - - "golang.org/x/net/html" -) - -// the Selector type, and functions for creating them - -// A Selector is a function which tells whether a node matches or not. -type Selector func(*html.Node) bool - -// hasChildMatch returns whether n has any child that matches a. -func hasChildMatch(n *html.Node, a Selector) bool { - for c := n.FirstChild; c != nil; c = c.NextSibling { - if a(c) { - return true - } - } - return false -} - -// hasDescendantMatch performs a depth-first search of n's descendants, -// testing whether any of them match a. It returns true as soon as a match is -// found, or false if no match is found. -func hasDescendantMatch(n *html.Node, a Selector) bool { - for c := n.FirstChild; c != nil; c = c.NextSibling { - if a(c) || (c.Type == html.ElementNode && hasDescendantMatch(c, a)) { - return true - } - } - return false -} - -// Compile parses a selector and returns, if successful, a Selector object -// that can be used to match against html.Node objects. -func Compile(sel string) (Selector, error) { - p := &parser{s: sel} - compiled, err := p.parseSelectorGroup() - if err != nil { - return nil, err - } - - if p.i < len(sel) { - return nil, fmt.Errorf("parsing %q: %d bytes left over", sel, len(sel)-p.i) - } - - return compiled, nil -} - -// MustCompile is like Compile, but panics instead of returning an error. -func MustCompile(sel string) Selector { - compiled, err := Compile(sel) - if err != nil { - panic(err) - } - return compiled -} - -// MatchAll returns a slice of the nodes that match the selector, -// from n and its children. -func (s Selector) MatchAll(n *html.Node) []*html.Node { - return s.matchAllInto(n, nil) -} - -func (s Selector) matchAllInto(n *html.Node, storage []*html.Node) []*html.Node { - if s(n) { - storage = append(storage, n) - } - - for child := n.FirstChild; child != nil; child = child.NextSibling { - storage = s.matchAllInto(child, storage) - } - - return storage -} - -// Match returns true if the node matches the selector. -func (s Selector) Match(n *html.Node) bool { - return s(n) -} - -// MatchFirst returns the first node that matches s, from n and its children. -func (s Selector) MatchFirst(n *html.Node) *html.Node { - if s.Match(n) { - return n - } - - for c := n.FirstChild; c != nil; c = c.NextSibling { - m := s.MatchFirst(c) - if m != nil { - return m - } - } - return nil -} - -// Filter returns the nodes in nodes that match the selector. -func (s Selector) Filter(nodes []*html.Node) (result []*html.Node) { - for _, n := range nodes { - if s(n) { - result = append(result, n) - } - } - return result -} - -// typeSelector returns a Selector that matches elements with a given tag name. -func typeSelector(tag string) Selector { - tag = toLowerASCII(tag) - return func(n *html.Node) bool { - return n.Type == html.ElementNode && n.Data == tag - } -} - -// toLowerASCII returns s with all ASCII capital letters lowercased. -func toLowerASCII(s string) string { - var b []byte - for i := 0; i < len(s); i++ { - if c := s[i]; 'A' <= c && c <= 'Z' { - if b == nil { - b = make([]byte, len(s)) - copy(b, s) - } - b[i] = s[i] + ('a' - 'A') - } - } - - if b == nil { - return s - } - - return string(b) -} - -// attributeSelector returns a Selector that matches elements -// where the attribute named key satisifes the function f. -func attributeSelector(key string, f func(string) bool) Selector { - key = toLowerASCII(key) - return func(n *html.Node) bool { - if n.Type != html.ElementNode { - return false - } - for _, a := range n.Attr { - if a.Key == key && f(a.Val) { - return true - } - } - return false - } -} - -// attributeExistsSelector returns a Selector that matches elements that have -// an attribute named key. -func attributeExistsSelector(key string) Selector { - return attributeSelector(key, func(string) bool { return true }) -} - -// attributeEqualsSelector returns a Selector that matches elements where -// the attribute named key has the value val. -func attributeEqualsSelector(key, val string) Selector { - return attributeSelector(key, - func(s string) bool { - return s == val - }) -} - -// attributeNotEqualSelector returns a Selector that matches elements where -// the attribute named key does not have the value val. -func attributeNotEqualSelector(key, val string) Selector { - key = toLowerASCII(key) - return func(n *html.Node) bool { - if n.Type != html.ElementNode { - return false - } - for _, a := range n.Attr { - if a.Key == key && a.Val == val { - return false - } - } - return true - } -} - -// attributeIncludesSelector returns a Selector that matches elements where -// the attribute named key is a whitespace-separated list that includes val. -func attributeIncludesSelector(key, val string) Selector { - return attributeSelector(key, - func(s string) bool { - for s != "" { - i := strings.IndexAny(s, " \t\r\n\f") - if i == -1 { - return s == val - } - if s[:i] == val { - return true - } - s = s[i+1:] - } - return false - }) -} - -// attributeDashmatchSelector returns a Selector that matches elements where -// the attribute named key equals val or starts with val plus a hyphen. -func attributeDashmatchSelector(key, val string) Selector { - return attributeSelector(key, - func(s string) bool { - if s == val { - return true - } - if len(s) <= len(val) { - return false - } - if s[:len(val)] == val && s[len(val)] == '-' { - return true - } - return false - }) -} - -// attributePrefixSelector returns a Selector that matches elements where -// the attribute named key starts with val. -func attributePrefixSelector(key, val string) Selector { - return attributeSelector(key, - func(s string) bool { - if strings.TrimSpace(s) == "" { - return false - } - return strings.HasPrefix(s, val) - }) -} - -// attributeSuffixSelector returns a Selector that matches elements where -// the attribute named key ends with val. -func attributeSuffixSelector(key, val string) Selector { - return attributeSelector(key, - func(s string) bool { - if strings.TrimSpace(s) == "" { - return false - } - return strings.HasSuffix(s, val) - }) -} - -// attributeSubstringSelector returns a Selector that matches nodes where -// the attribute named key contains val. -func attributeSubstringSelector(key, val string) Selector { - return attributeSelector(key, - func(s string) bool { - if strings.TrimSpace(s) == "" { - return false - } - return strings.Contains(s, val) - }) -} - -// attributeRegexSelector returns a Selector that matches nodes where -// the attribute named key matches the regular expression rx -func attributeRegexSelector(key string, rx *regexp.Regexp) Selector { - return attributeSelector(key, - func(s string) bool { - return rx.MatchString(s) - }) -} - -// intersectionSelector returns a selector that matches nodes that match -// both a and b. -func intersectionSelector(a, b Selector) Selector { - return func(n *html.Node) bool { - return a(n) && b(n) - } -} - -// unionSelector returns a selector that matches elements that match -// either a or b. -func unionSelector(a, b Selector) Selector { - return func(n *html.Node) bool { - return a(n) || b(n) - } -} - -// negatedSelector returns a selector that matches elements that do not match a. -func negatedSelector(a Selector) Selector { - return func(n *html.Node) bool { - if n.Type != html.ElementNode { - return false - } - return !a(n) - } -} - -// writeNodeText writes the text contained in n and its descendants to b. -func writeNodeText(n *html.Node, b *bytes.Buffer) { - switch n.Type { - case html.TextNode: - b.WriteString(n.Data) - case html.ElementNode: - for c := n.FirstChild; c != nil; c = c.NextSibling { - writeNodeText(c, b) - } - } -} - -// nodeText returns the text contained in n and its descendants. -func nodeText(n *html.Node) string { - var b bytes.Buffer - writeNodeText(n, &b) - return b.String() -} - -// nodeOwnText returns the contents of the text nodes that are direct -// children of n. -func nodeOwnText(n *html.Node) string { - var b bytes.Buffer - for c := n.FirstChild; c != nil; c = c.NextSibling { - if c.Type == html.TextNode { - b.WriteString(c.Data) - } - } - return b.String() -} - -// textSubstrSelector returns a selector that matches nodes that -// contain the given text. -func textSubstrSelector(val string) Selector { - return func(n *html.Node) bool { - text := strings.ToLower(nodeText(n)) - return strings.Contains(text, val) - } -} - -// ownTextSubstrSelector returns a selector that matches nodes that -// directly contain the given text -func ownTextSubstrSelector(val string) Selector { - return func(n *html.Node) bool { - text := strings.ToLower(nodeOwnText(n)) - return strings.Contains(text, val) - } -} - -// textRegexSelector returns a selector that matches nodes whose text matches -// the specified regular expression -func textRegexSelector(rx *regexp.Regexp) Selector { - return func(n *html.Node) bool { - return rx.MatchString(nodeText(n)) - } -} - -// ownTextRegexSelector returns a selector that matches nodes whose text -// directly matches the specified regular expression -func ownTextRegexSelector(rx *regexp.Regexp) Selector { - return func(n *html.Node) bool { - return rx.MatchString(nodeOwnText(n)) - } -} - -// hasChildSelector returns a selector that matches elements -// with a child that matches a. -func hasChildSelector(a Selector) Selector { - return func(n *html.Node) bool { - if n.Type != html.ElementNode { - return false - } - return hasChildMatch(n, a) - } -} - -// hasDescendantSelector returns a selector that matches elements -// with any descendant that matches a. -func hasDescendantSelector(a Selector) Selector { - return func(n *html.Node) bool { - if n.Type != html.ElementNode { - return false - } - return hasDescendantMatch(n, a) - } -} - -// nthChildSelector returns a selector that implements :nth-child(an+b). -// If last is true, implements :nth-last-child instead. -// If ofType is true, implements :nth-of-type instead. -func nthChildSelector(a, b int, last, ofType bool) Selector { - return func(n *html.Node) bool { - if n.Type != html.ElementNode { - return false - } - - parent := n.Parent - if parent == nil { - return false - } - - if parent.Type == html.DocumentNode { - return false - } - - i := -1 - count := 0 - for c := parent.FirstChild; c != nil; c = c.NextSibling { - if (c.Type != html.ElementNode) || (ofType && c.Data != n.Data) { - continue - } - count++ - if c == n { - i = count - if !last { - break - } - } - } - - if i == -1 { - // This shouldn't happen, since n should always be one of its parent's children. - return false - } - - if last { - i = count - i + 1 - } - - i -= b - if a == 0 { - return i == 0 - } - - return i%a == 0 && i/a >= 0 - } -} - -// simpleNthChildSelector returns a selector that implements :nth-child(b). -// If ofType is true, implements :nth-of-type instead. -func simpleNthChildSelector(b int, ofType bool) Selector { - return func(n *html.Node) bool { - if n.Type != html.ElementNode { - return false - } - - parent := n.Parent - if parent == nil { - return false - } - - if parent.Type == html.DocumentNode { - return false - } - - count := 0 - for c := parent.FirstChild; c != nil; c = c.NextSibling { - if c.Type != html.ElementNode || (ofType && c.Data != n.Data) { - continue - } - count++ - if c == n { - return count == b - } - if count >= b { - return false - } - } - return false - } -} - -// simpleNthLastChildSelector returns a selector that implements -// :nth-last-child(b). If ofType is true, implements :nth-last-of-type -// instead. -func simpleNthLastChildSelector(b int, ofType bool) Selector { - return func(n *html.Node) bool { - if n.Type != html.ElementNode { - return false - } - - parent := n.Parent - if parent == nil { - return false - } - - if parent.Type == html.DocumentNode { - return false - } - - count := 0 - for c := parent.LastChild; c != nil; c = c.PrevSibling { - if c.Type != html.ElementNode || (ofType && c.Data != n.Data) { - continue - } - count++ - if c == n { - return count == b - } - if count >= b { - return false - } - } - return false - } -} - -// onlyChildSelector returns a selector that implements :only-child. -// If ofType is true, it implements :only-of-type instead. -func onlyChildSelector(ofType bool) Selector { - return func(n *html.Node) bool { - if n.Type != html.ElementNode { - return false - } - - parent := n.Parent - if parent == nil { - return false - } - - if parent.Type == html.DocumentNode { - return false - } - - count := 0 - for c := parent.FirstChild; c != nil; c = c.NextSibling { - if (c.Type != html.ElementNode) || (ofType && c.Data != n.Data) { - continue - } - count++ - if count > 1 { - return false - } - } - - return count == 1 - } -} - -// inputSelector is a Selector that matches input, select, textarea and button elements. -func inputSelector(n *html.Node) bool { - return n.Type == html.ElementNode && (n.Data == "input" || n.Data == "select" || n.Data == "textarea" || n.Data == "button") -} - -// emptyElementSelector is a Selector that matches empty elements. -func emptyElementSelector(n *html.Node) bool { - if n.Type != html.ElementNode { - return false - } - - for c := n.FirstChild; c != nil; c = c.NextSibling { - switch c.Type { - case html.ElementNode, html.TextNode: - return false - } - } - - return true -} - -// descendantSelector returns a Selector that matches an element if -// it matches d and has an ancestor that matches a. -func descendantSelector(a, d Selector) Selector { - return func(n *html.Node) bool { - if !d(n) { - return false - } - - for p := n.Parent; p != nil; p = p.Parent { - if a(p) { - return true - } - } - - return false - } -} - -// childSelector returns a Selector that matches an element if -// it matches d and its parent matches a. -func childSelector(a, d Selector) Selector { - return func(n *html.Node) bool { - return d(n) && n.Parent != nil && a(n.Parent) - } -} - -// siblingSelector returns a Selector that matches an element -// if it matches s2 and in is preceded by an element that matches s1. -// If adjacent is true, the sibling must be immediately before the element. -func siblingSelector(s1, s2 Selector, adjacent bool) Selector { - return func(n *html.Node) bool { - if !s2(n) { - return false - } - - if adjacent { - for n = n.PrevSibling; n != nil; n = n.PrevSibling { - if n.Type == html.TextNode || n.Type == html.CommentNode { - continue - } - return s1(n) - } - return false - } - - // Walk backwards looking for element that matches s1 - for c := n.PrevSibling; c != nil; c = c.PrevSibling { - if s1(c) { - return true - } - } - - return false - } -} - -// rootSelector implements :root -func rootSelector(n *html.Node) bool { - if n.Type != html.ElementNode { - return false - } - if n.Parent == nil { - return false - } - return n.Parent.Type == html.DocumentNode -} diff --git a/vendor/github.com/antonmedv/expr/.gitignore b/vendor/github.com/antonmedv/expr/.gitignore deleted file mode 100644 index 39b3c48..0000000 --- a/vendor/github.com/antonmedv/expr/.gitignore +++ /dev/null @@ -1,7 +0,0 @@ -*.exe -*.exe~ -*.dll -*.so -*.dylib -*.test -*.out diff --git a/vendor/github.com/antonmedv/expr/.travis.yml b/vendor/github.com/antonmedv/expr/.travis.yml deleted file mode 100644 index 745b115..0000000 --- a/vendor/github.com/antonmedv/expr/.travis.yml +++ /dev/null @@ -1,3 +0,0 @@ -language: go -go: - - 1.13.x diff --git a/vendor/github.com/antonmedv/expr/LICENSE b/vendor/github.com/antonmedv/expr/LICENSE deleted file mode 100644 index 7d058f8..0000000 --- a/vendor/github.com/antonmedv/expr/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2019 Anton Medvedev - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/antonmedv/expr/README.md b/vendor/github.com/antonmedv/expr/README.md deleted file mode 100644 index 00a644f..0000000 --- a/vendor/github.com/antonmedv/expr/README.md +++ /dev/null @@ -1,163 +0,0 @@ -# Expr -[![Build Status](https://travis-ci.org/antonmedv/expr.svg?branch=master)](https://travis-ci.org/antonmedv/expr) -[![Go Report Card](https://goreportcard.com/badge/github.com/antonmedv/expr)](https://goreportcard.com/report/github.com/antonmedv/expr) -[![GoDoc](https://godoc.org/github.com/antonmedv/expr?status.svg)](https://godoc.org/github.com/antonmedv/expr) - -expr logo - -**Expr** package provides an engine that can compile and evaluate expressions. -An expression is a one-liner that returns a value (mostly, but not limited to, booleans). -It is designed for simplicity, speed and safety. - -The purpose of the package is to allow users to use expressions inside configuration for more complex logic. -It is a perfect candidate for the foundation of a _business rule engine_. -The idea is to let configure things in a dynamic way without recompile of a program: - -```coffeescript -# Get the special price if -user.Group in ["good_customers", "collaborator"] - -# Promote article to the homepage when -len(article.Comments) > 100 and article.Category not in ["misc"] - -# Send an alert when -product.Stock < 15 -``` - -## Features - -* Seamless integration with Go (no need to redefine types) -* Static typing ([example](https://godoc.org/github.com/antonmedv/expr#example-Env)). - ```go - out, err := expr.Compile(`name + age`) - // err: invalid operation + (mismatched types string and int) - // | name + age - // | .....^ - ``` -* User-friendly error messages. -* Reasonable set of basic operators. -* Builtins `all`, `none`, `any`, `one`, `filter`, `map`. - ```coffeescript - all(Tweets, {.Size <= 280}) - ``` -* Fast ([benchmarks](https://github.com/antonmedv/golang-expression-evaluation-comparison#readme)): uses bytecode virtual machine and optimizing compiler. - -## Install - -``` -go get github.com/antonmedv/expr -``` - -## Documentation - -* See [Getting Started](docs/Getting-Started.md) page for developer documentation. -* See [Language Definition](docs/Language-Definition.md) page to learn the syntax. - -## Expr Code Editor - - - Expr Code Editor - - -Also, I have an embeddable code editor written in JavaScript which allows editing expressions with syntax highlighting and autocomplete based on your types declaration. - -[Learn more →](https://antonmedv.github.io/expr/) - -## Examples - -[Play Online](https://play.golang.org/p/z7T8ytJ1T1d) - -```go -package main - -import ( - "fmt" - "github.com/antonmedv/expr" -) - -func main() { - env := map[string]interface{}{ - "greet": "Hello, %v!", - "names": []string{"world", "you"}, - "sprintf": fmt.Sprintf, - } - - code := `sprintf(greet, names[0])` - - program, err := expr.Compile(code, expr.Env(env)) - if err != nil { - panic(err) - } - - output, err := expr.Run(program, env) - if err != nil { - panic(err) - } - - fmt.Println(output) -} -``` - -[Play Online](https://play.golang.org/p/4S4brsIvU4i) - -```go -package main - -import ( - "fmt" - "github.com/antonmedv/expr" -) - -type Tweet struct { - Len int -} - -type Env struct { - Tweets []Tweet -} - -func main() { - code := `all(Tweets, {.Len <= 240})` - - program, err := expr.Compile(code, expr.Env(Env{})) - if err != nil { - panic(err) - } - - env := Env{ - Tweets: []Tweet{{42}, {98}, {69}}, - } - output, err := expr.Run(program, env) - if err != nil { - panic(err) - } - - fmt.Println(output) -} -``` - -## Contributing - -**Expr** consist of a few packages for parsing source code to AST, type checking AST, compiling to bytecode and VM for running bytecode program. - -Also expr provides powerful tool [exe](cmd/exe) for debugging. It has interactive terminal debugger for our bytecode virtual machine. - -

- debugger -

- - -## Who is using Expr? - -* Aviasales [Aviasales](https://aviasales.ru) are actively using Expr for different parts of the search engine. -* Argo [Argo Rollouts](https://argoproj.github.io/argo-rollouts/) - Progressive Delivery for Kubernetes. -* Argo [Argo Workflows](https://argoproj.github.io/argo/) - The workflow engine for KubernetesOverview. -* CrowdSec [Crowdsec](https://crowdsec.net/) - A security automation tool. -* [Mystery Minds](https://www.mysteryminds.com/en/) uses Expr to allow easy yet powerful customization of its matching algorithm. -* [qiniu](https://www.qiniu.com/) qiniu cloud use Expr in trade systems. - -[Add your company too](https://github.com/antonmedv/expr/edit/master/README.md) - -## License - -[MIT](LICENSE) diff --git a/vendor/github.com/antonmedv/expr/ast/node.go b/vendor/github.com/antonmedv/expr/ast/node.go deleted file mode 100644 index 4b2b5c2..0000000 --- a/vendor/github.com/antonmedv/expr/ast/node.go +++ /dev/null @@ -1,171 +0,0 @@ -package ast - -import ( - "reflect" - "regexp" - - "github.com/antonmedv/expr/file" -) - -// Node represents items of abstract syntax tree. -type Node interface { - Location() file.Location - SetLocation(file.Location) - Type() reflect.Type - SetType(reflect.Type) -} - -func Patch(node *Node, newNode Node) { - newNode.SetType((*node).Type()) - newNode.SetLocation((*node).Location()) - *node = newNode -} - -type base struct { - loc file.Location - nodeType reflect.Type -} - -func (n *base) Location() file.Location { - return n.loc -} - -func (n *base) SetLocation(loc file.Location) { - n.loc = loc -} - -func (n *base) Type() reflect.Type { - return n.nodeType -} - -func (n *base) SetType(t reflect.Type) { - n.nodeType = t -} - -type NilNode struct { - base -} - -type IdentifierNode struct { - base - Value string - NilSafe bool -} - -type IntegerNode struct { - base - Value int -} - -type FloatNode struct { - base - Value float64 -} - -type BoolNode struct { - base - Value bool -} - -type StringNode struct { - base - Value string -} - -type ConstantNode struct { - base - Value interface{} -} - -type UnaryNode struct { - base - Operator string - Node Node -} - -type BinaryNode struct { - base - Operator string - Left Node - Right Node -} - -type MatchesNode struct { - base - Regexp *regexp.Regexp - Left Node - Right Node -} - -type PropertyNode struct { - base - Node Node - Property string - NilSafe bool -} - -type IndexNode struct { - base - Node Node - Index Node -} - -type SliceNode struct { - base - Node Node - From Node - To Node -} - -type MethodNode struct { - base - Node Node - Method string - Arguments []Node - NilSafe bool -} - -type FunctionNode struct { - base - Name string - Arguments []Node - Fast bool -} - -type BuiltinNode struct { - base - Name string - Arguments []Node -} - -type ClosureNode struct { - base - Node Node -} - -type PointerNode struct { - base -} - -type ConditionalNode struct { - base - Cond Node - Exp1 Node - Exp2 Node -} - -type ArrayNode struct { - base - Nodes []Node -} - -type MapNode struct { - base - Pairs []Node -} - -type PairNode struct { - base - Key Node - Value Node -} diff --git a/vendor/github.com/antonmedv/expr/ast/print.go b/vendor/github.com/antonmedv/expr/ast/print.go deleted file mode 100644 index 285984b..0000000 --- a/vendor/github.com/antonmedv/expr/ast/print.go +++ /dev/null @@ -1,59 +0,0 @@ -package ast - -import ( - "fmt" - "reflect" - "regexp" -) - -func Dump(node Node) string { - return dump(reflect.ValueOf(node), "") -} - -func dump(v reflect.Value, ident string) string { - if !v.IsValid() { - return "nil" - } - t := v.Type() - switch t.Kind() { - case reflect.Struct: - out := t.Name() + "{\n" - for i := 0; i < t.NumField(); i++ { - f := t.Field(i) - if isPrivate(f.Name) { - continue - } - s := v.Field(i) - out += fmt.Sprintf("%v%v: %v,\n", ident+"\t", f.Name, dump(s, ident+"\t")) - } - return out + ident + "}" - case reflect.Slice: - if v.Len() == 0 { - return "[]" - } - out := "[\n" - for i := 0; i < v.Len(); i++ { - s := v.Index(i) - out += fmt.Sprintf("%v%v,", ident+"\t", dump(s, ident+"\t")) - if i+1 < v.Len() { - out += "\n" - } - } - return out + "\n" + ident + "]" - case reflect.Ptr: - return dump(v.Elem(), ident) - case reflect.Interface: - return dump(reflect.ValueOf(v.Interface()), ident) - - case reflect.String: - return fmt.Sprintf("%q", v) - default: - return fmt.Sprintf("%v", v) - } -} - -var isCapital = regexp.MustCompile("^[A-Z]") - -func isPrivate(s string) bool { - return !isCapital.Match([]byte(s)) -} diff --git a/vendor/github.com/antonmedv/expr/ast/visitor.go b/vendor/github.com/antonmedv/expr/ast/visitor.go deleted file mode 100644 index a3e270e..0000000 --- a/vendor/github.com/antonmedv/expr/ast/visitor.go +++ /dev/null @@ -1,108 +0,0 @@ -package ast - -import "fmt" - -type Visitor interface { - Enter(node *Node) - Exit(node *Node) -} - -type walker struct { - visitor Visitor -} - -func Walk(node *Node, visitor Visitor) { - w := walker{ - visitor: visitor, - } - w.walk(node) -} - -func (w *walker) walk(node *Node) { - w.visitor.Enter(node) - - switch n := (*node).(type) { - case *NilNode: - w.visitor.Exit(node) - case *IdentifierNode: - w.visitor.Exit(node) - case *IntegerNode: - w.visitor.Exit(node) - case *FloatNode: - w.visitor.Exit(node) - case *BoolNode: - w.visitor.Exit(node) - case *StringNode: - w.visitor.Exit(node) - case *ConstantNode: - w.visitor.Exit(node) - case *UnaryNode: - w.walk(&n.Node) - w.visitor.Exit(node) - case *BinaryNode: - w.walk(&n.Left) - w.walk(&n.Right) - w.visitor.Exit(node) - case *MatchesNode: - w.walk(&n.Left) - w.walk(&n.Right) - w.visitor.Exit(node) - case *PropertyNode: - w.walk(&n.Node) - w.visitor.Exit(node) - case *IndexNode: - w.walk(&n.Node) - w.walk(&n.Index) - w.visitor.Exit(node) - case *SliceNode: - if n.From != nil { - w.walk(&n.From) - } - if n.To != nil { - w.walk(&n.To) - } - w.visitor.Exit(node) - case *MethodNode: - w.walk(&n.Node) - for i := range n.Arguments { - w.walk(&n.Arguments[i]) - } - w.visitor.Exit(node) - case *FunctionNode: - for i := range n.Arguments { - w.walk(&n.Arguments[i]) - } - w.visitor.Exit(node) - case *BuiltinNode: - for i := range n.Arguments { - w.walk(&n.Arguments[i]) - } - w.visitor.Exit(node) - case *ClosureNode: - w.walk(&n.Node) - w.visitor.Exit(node) - case *PointerNode: - w.visitor.Exit(node) - case *ConditionalNode: - w.walk(&n.Cond) - w.walk(&n.Exp1) - w.walk(&n.Exp2) - w.visitor.Exit(node) - case *ArrayNode: - for i := range n.Nodes { - w.walk(&n.Nodes[i]) - } - w.visitor.Exit(node) - case *MapNode: - for i := range n.Pairs { - w.walk(&n.Pairs[i]) - } - w.visitor.Exit(node) - case *PairNode: - w.walk(&n.Key) - w.walk(&n.Value) - w.visitor.Exit(node) - default: - panic(fmt.Sprintf("undefined node type (%T)", node)) - } -} diff --git a/vendor/github.com/antonmedv/expr/checker/checker.go b/vendor/github.com/antonmedv/expr/checker/checker.go deleted file mode 100644 index 282031a..0000000 --- a/vendor/github.com/antonmedv/expr/checker/checker.go +++ /dev/null @@ -1,615 +0,0 @@ -package checker - -import ( - "fmt" - "reflect" - - "github.com/antonmedv/expr/ast" - "github.com/antonmedv/expr/conf" - "github.com/antonmedv/expr/file" - "github.com/antonmedv/expr/parser" -) - -var errorType = reflect.TypeOf((*error)(nil)).Elem() - -func Check(tree *parser.Tree, config *conf.Config) (reflect.Type, error) { - v := &visitor{ - collections: make([]reflect.Type, 0), - } - if config != nil { - v.types = config.Types - v.operators = config.Operators - v.expect = config.Expect - v.strict = config.Strict - v.defaultType = config.DefaultType - } - - t := v.visit(tree.Node) - - if v.expect != reflect.Invalid { - switch v.expect { - case reflect.Int64, reflect.Float64: - if !isNumber(t) { - return nil, fmt.Errorf("expected %v, but got %v", v.expect, t) - } - default: - if t.Kind() != v.expect { - return nil, fmt.Errorf("expected %v, but got %v", v.expect, t) - } - } - } - - if v.err != nil { - return t, v.err.Bind(tree.Source) - } - - return t, nil -} - -type visitor struct { - types conf.TypesTable - operators conf.OperatorsTable - expect reflect.Kind - collections []reflect.Type - strict bool - defaultType reflect.Type - err *file.Error -} - -func (v *visitor) visit(node ast.Node) reflect.Type { - var t reflect.Type - switch n := node.(type) { - case *ast.NilNode: - t = v.NilNode(n) - case *ast.IdentifierNode: - t = v.IdentifierNode(n) - case *ast.IntegerNode: - t = v.IntegerNode(n) - case *ast.FloatNode: - t = v.FloatNode(n) - case *ast.BoolNode: - t = v.BoolNode(n) - case *ast.StringNode: - t = v.StringNode(n) - case *ast.ConstantNode: - t = v.ConstantNode(n) - case *ast.UnaryNode: - t = v.UnaryNode(n) - case *ast.BinaryNode: - t = v.BinaryNode(n) - case *ast.MatchesNode: - t = v.MatchesNode(n) - case *ast.PropertyNode: - t = v.PropertyNode(n) - case *ast.IndexNode: - t = v.IndexNode(n) - case *ast.SliceNode: - t = v.SliceNode(n) - case *ast.MethodNode: - t = v.MethodNode(n) - case *ast.FunctionNode: - t = v.FunctionNode(n) - case *ast.BuiltinNode: - t = v.BuiltinNode(n) - case *ast.ClosureNode: - t = v.ClosureNode(n) - case *ast.PointerNode: - t = v.PointerNode(n) - case *ast.ConditionalNode: - t = v.ConditionalNode(n) - case *ast.ArrayNode: - t = v.ArrayNode(n) - case *ast.MapNode: - t = v.MapNode(n) - case *ast.PairNode: - t = v.PairNode(n) - default: - panic(fmt.Sprintf("undefined node type (%T)", node)) - } - node.SetType(t) - return t -} - -func (v *visitor) error(node ast.Node, format string, args ...interface{}) reflect.Type { - if v.err == nil { // show first error - v.err = &file.Error{ - Location: node.Location(), - Message: fmt.Sprintf(format, args...), - } - } - return interfaceType // interface represent undefined type -} - -func (v *visitor) NilNode(*ast.NilNode) reflect.Type { - return nilType -} - -func (v *visitor) IdentifierNode(node *ast.IdentifierNode) reflect.Type { - if v.types == nil { - return interfaceType - } - if t, ok := v.types[node.Value]; ok { - if t.Ambiguous { - return v.error(node, "ambiguous identifier %v", node.Value) - } - return t.Type - } - if !v.strict { - if v.defaultType != nil { - return v.defaultType - } - return interfaceType - } - if !node.NilSafe { - return v.error(node, "unknown name %v", node.Value) - } - return nilType -} - -func (v *visitor) IntegerNode(*ast.IntegerNode) reflect.Type { - return integerType -} - -func (v *visitor) FloatNode(*ast.FloatNode) reflect.Type { - return floatType -} - -func (v *visitor) BoolNode(*ast.BoolNode) reflect.Type { - return boolType -} - -func (v *visitor) StringNode(*ast.StringNode) reflect.Type { - return stringType -} - -func (v *visitor) ConstantNode(node *ast.ConstantNode) reflect.Type { - return reflect.TypeOf(node.Value) -} - -func (v *visitor) UnaryNode(node *ast.UnaryNode) reflect.Type { - t := v.visit(node.Node) - - switch node.Operator { - - case "!", "not": - if isBool(t) { - return boolType - } - - case "+", "-": - if isNumber(t) { - return t - } - - default: - return v.error(node, "unknown operator (%v)", node.Operator) - } - - return v.error(node, `invalid operation: %v (mismatched type %v)`, node.Operator, t) -} - -func (v *visitor) BinaryNode(node *ast.BinaryNode) reflect.Type { - l := v.visit(node.Left) - r := v.visit(node.Right) - - // check operator overloading - if fns, ok := v.operators[node.Operator]; ok { - t, _, ok := conf.FindSuitableOperatorOverload(fns, v.types, l, r) - if ok { - return t - } - } - - switch node.Operator { - case "==", "!=": - if isNumber(l) && isNumber(r) { - return boolType - } - if isComparable(l, r) { - return boolType - } - - case "or", "||", "and", "&&": - if isBool(l) && isBool(r) { - return boolType - } - - case "in", "not in": - if isString(l) && isStruct(r) { - return boolType - } - if isMap(r) { - return boolType - } - if isArray(r) { - return boolType - } - - case "<", ">", ">=", "<=": - if isNumber(l) && isNumber(r) { - return boolType - } - if isString(l) && isString(r) { - return boolType - } - - case "/", "-", "*": - if isNumber(l) && isNumber(r) { - return combined(l, r) - } - - case "**": - if isNumber(l) && isNumber(r) { - return floatType - } - - case "%": - if isInteger(l) && isInteger(r) { - return combined(l, r) - } - - case "+": - if isNumber(l) && isNumber(r) { - return combined(l, r) - } - if isString(l) && isString(r) { - return stringType - } - - case "contains", "startsWith", "endsWith": - if isString(l) && isString(r) { - return boolType - } - - case "..": - if isInteger(l) && isInteger(r) { - return reflect.SliceOf(integerType) - } - - default: - return v.error(node, "unknown operator (%v)", node.Operator) - - } - - return v.error(node, `invalid operation: %v (mismatched types %v and %v)`, node.Operator, l, r) -} - -func (v *visitor) MatchesNode(node *ast.MatchesNode) reflect.Type { - l := v.visit(node.Left) - r := v.visit(node.Right) - - if isString(l) && isString(r) { - return boolType - } - - return v.error(node, `invalid operation: matches (mismatched types %v and %v)`, l, r) -} - -func (v *visitor) PropertyNode(node *ast.PropertyNode) reflect.Type { - t := v.visit(node.Node) - if t, ok := fieldType(t, node.Property); ok { - return t - } - if !node.NilSafe { - return v.error(node, "type %v has no field %v", t, node.Property) - } - return nil -} - -func (v *visitor) IndexNode(node *ast.IndexNode) reflect.Type { - t := v.visit(node.Node) - i := v.visit(node.Index) - - if t, ok := indexType(t); ok { - if !isInteger(i) && !isString(i) { - return v.error(node, "invalid operation: cannot use %v as index to %v", i, t) - } - return t - } - - return v.error(node, "invalid operation: type %v does not support indexing", t) -} - -func (v *visitor) SliceNode(node *ast.SliceNode) reflect.Type { - t := v.visit(node.Node) - - _, isIndex := indexType(t) - - if isIndex || isString(t) { - if node.From != nil { - from := v.visit(node.From) - if !isInteger(from) { - return v.error(node.From, "invalid operation: non-integer slice index %v", from) - } - } - if node.To != nil { - to := v.visit(node.To) - if !isInteger(to) { - return v.error(node.To, "invalid operation: non-integer slice index %v", to) - } - } - return t - } - - return v.error(node, "invalid operation: cannot slice %v", t) -} - -func (v *visitor) FunctionNode(node *ast.FunctionNode) reflect.Type { - if f, ok := v.types[node.Name]; ok { - if fn, ok := isFuncType(f.Type); ok { - - inputParamsCount := 1 // for functions - if f.Method { - inputParamsCount = 2 // for methods - } - - if !isInterface(fn) && - fn.IsVariadic() && - fn.NumIn() == inputParamsCount && - ((fn.NumOut() == 1 && // Function with one return value - fn.Out(0).Kind() == reflect.Interface) || - (fn.NumOut() == 2 && // Function with one return value and an error - fn.Out(0).Kind() == reflect.Interface && - fn.Out(1) == errorType)) { - rest := fn.In(fn.NumIn() - 1) // function has only one param for functions and two for methods - if rest.Kind() == reflect.Slice && rest.Elem().Kind() == reflect.Interface { - node.Fast = true - } - } - - return v.checkFunc(fn, f.Method, node, node.Name, node.Arguments) - } - } - if !v.strict { - if v.defaultType != nil { - return v.defaultType - } - return interfaceType - } - return v.error(node, "unknown func %v", node.Name) -} - -func (v *visitor) MethodNode(node *ast.MethodNode) reflect.Type { - t := v.visit(node.Node) - if f, method, ok := methodType(t, node.Method); ok { - if fn, ok := isFuncType(f); ok { - return v.checkFunc(fn, method, node, node.Method, node.Arguments) - } - } - if !node.NilSafe { - return v.error(node, "type %v has no method %v", t, node.Method) - } - return nil -} - -// checkFunc checks func arguments and returns "return type" of func or method. -func (v *visitor) checkFunc(fn reflect.Type, method bool, node ast.Node, name string, arguments []ast.Node) reflect.Type { - if isInterface(fn) { - return interfaceType - } - - if fn.NumOut() == 0 { - return v.error(node, "func %v doesn't return value", name) - } - if numOut := fn.NumOut(); numOut > 2 { - return v.error(node, "func %v returns more then two values", name) - } - - numIn := fn.NumIn() - - // If func is method on an env, first argument should be a receiver, - // and actual arguments less then numIn by one. - if method { - numIn-- - } - - if fn.IsVariadic() { - if len(arguments) < numIn-1 { - return v.error(node, "not enough arguments to call %v", name) - } - } else { - if len(arguments) > numIn { - return v.error(node, "too many arguments to call %v", name) - } - if len(arguments) < numIn { - return v.error(node, "not enough arguments to call %v", name) - } - } - - offset := 0 - - // Skip first argument in case of the receiver. - if method { - offset = 1 - } - - for i, arg := range arguments { - t := v.visit(arg) - - var in reflect.Type - if fn.IsVariadic() && i >= numIn-1 { - // For variadic arguments fn(xs ...int), go replaces type of xs (int) with ([]int). - // As we compare arguments one by one, we need underling type. - in = fn.In(fn.NumIn() - 1) - in, _ = indexType(in) - } else { - in = fn.In(i + offset) - } - - if isIntegerOrArithmeticOperation(arg) { - t = in - setTypeForIntegers(arg, t) - } - - if t == nil { - continue - } - - if !t.AssignableTo(in) && t.Kind() != reflect.Interface { - return v.error(arg, "cannot use %v as argument (type %v) to call %v ", t, in, name) - } - } - - return fn.Out(0) -} - -func (v *visitor) BuiltinNode(node *ast.BuiltinNode) reflect.Type { - switch node.Name { - - case "len": - param := v.visit(node.Arguments[0]) - if isArray(param) || isMap(param) || isString(param) { - return integerType - } - return v.error(node, "invalid argument for len (type %v)", param) - - case "all", "none", "any", "one": - collection := v.visit(node.Arguments[0]) - if !isArray(collection) { - return v.error(node.Arguments[0], "builtin %v takes only array (got %v)", node.Name, collection) - } - - v.collections = append(v.collections, collection) - closure := v.visit(node.Arguments[1]) - v.collections = v.collections[:len(v.collections)-1] - - if isFunc(closure) && - closure.NumOut() == 1 && - closure.NumIn() == 1 && isInterface(closure.In(0)) { - - if !isBool(closure.Out(0)) { - return v.error(node.Arguments[1], "closure should return boolean (got %v)", closure.Out(0).String()) - } - return boolType - } - return v.error(node.Arguments[1], "closure should has one input and one output param") - - case "filter": - collection := v.visit(node.Arguments[0]) - if !isArray(collection) { - return v.error(node.Arguments[0], "builtin %v takes only array (got %v)", node.Name, collection) - } - - v.collections = append(v.collections, collection) - closure := v.visit(node.Arguments[1]) - v.collections = v.collections[:len(v.collections)-1] - - if isFunc(closure) && - closure.NumOut() == 1 && - closure.NumIn() == 1 && isInterface(closure.In(0)) { - - if !isBool(closure.Out(0)) { - return v.error(node.Arguments[1], "closure should return boolean (got %v)", closure.Out(0).String()) - } - if isInterface(collection) { - return arrayType - } - return reflect.SliceOf(collection.Elem()) - } - return v.error(node.Arguments[1], "closure should has one input and one output param") - - case "map": - collection := v.visit(node.Arguments[0]) - if !isArray(collection) { - return v.error(node.Arguments[0], "builtin %v takes only array (got %v)", node.Name, collection) - } - - v.collections = append(v.collections, collection) - closure := v.visit(node.Arguments[1]) - v.collections = v.collections[:len(v.collections)-1] - - if isFunc(closure) && - closure.NumOut() == 1 && - closure.NumIn() == 1 && isInterface(closure.In(0)) { - - return reflect.SliceOf(closure.Out(0)) - } - return v.error(node.Arguments[1], "closure should has one input and one output param") - - case "count": - collection := v.visit(node.Arguments[0]) - if !isArray(collection) { - return v.error(node.Arguments[0], "builtin %v takes only array (got %v)", node.Name, collection) - } - - v.collections = append(v.collections, collection) - closure := v.visit(node.Arguments[1]) - v.collections = v.collections[:len(v.collections)-1] - - if isFunc(closure) && - closure.NumOut() == 1 && - closure.NumIn() == 1 && isInterface(closure.In(0)) { - if !isBool(closure.Out(0)) { - return v.error(node.Arguments[1], "closure should return boolean (got %v)", closure.Out(0).String()) - } - - return integerType - } - return v.error(node.Arguments[1], "closure should has one input and one output param") - - default: - return v.error(node, "unknown builtin %v", node.Name) - } -} - -func (v *visitor) ClosureNode(node *ast.ClosureNode) reflect.Type { - t := v.visit(node.Node) - return reflect.FuncOf([]reflect.Type{interfaceType}, []reflect.Type{t}, false) -} - -func (v *visitor) PointerNode(node *ast.PointerNode) reflect.Type { - if len(v.collections) == 0 { - return v.error(node, "cannot use pointer accessor outside closure") - } - - collection := v.collections[len(v.collections)-1] - - if t, ok := indexType(collection); ok { - return t - } - return v.error(node, "cannot use %v as array", collection) -} - -func (v *visitor) ConditionalNode(node *ast.ConditionalNode) reflect.Type { - c := v.visit(node.Cond) - if !isBool(c) { - return v.error(node.Cond, "non-bool expression (type %v) used as condition", c) - } - - t1 := v.visit(node.Exp1) - t2 := v.visit(node.Exp2) - - if t1 == nil && t2 != nil { - return t2 - } - if t1 != nil && t2 == nil { - return t1 - } - if t1 == nil && t2 == nil { - return nilType - } - if t1.AssignableTo(t2) { - return t1 - } - return interfaceType -} - -func (v *visitor) ArrayNode(node *ast.ArrayNode) reflect.Type { - for _, node := range node.Nodes { - _ = v.visit(node) - } - return arrayType -} - -func (v *visitor) MapNode(node *ast.MapNode) reflect.Type { - for _, pair := range node.Pairs { - v.visit(pair) - } - return mapType -} - -func (v *visitor) PairNode(node *ast.PairNode) reflect.Type { - v.visit(node.Key) - v.visit(node.Value) - return nilType -} diff --git a/vendor/github.com/antonmedv/expr/checker/types.go b/vendor/github.com/antonmedv/expr/checker/types.go deleted file mode 100644 index 756ed8f..0000000 --- a/vendor/github.com/antonmedv/expr/checker/types.go +++ /dev/null @@ -1,349 +0,0 @@ -package checker - -import ( - "reflect" - - "github.com/antonmedv/expr/ast" -) - -var ( - nilType = reflect.TypeOf(nil) - boolType = reflect.TypeOf(true) - integerType = reflect.TypeOf(int(0)) - floatType = reflect.TypeOf(float64(0)) - stringType = reflect.TypeOf("") - arrayType = reflect.TypeOf([]interface{}{}) - mapType = reflect.TypeOf(map[string]interface{}{}) - interfaceType = reflect.TypeOf(new(interface{})).Elem() -) - -func typeWeight(t reflect.Type) int { - switch t.Kind() { - case reflect.Uint: - return 1 - case reflect.Uint8: - return 2 - case reflect.Uint16: - return 3 - case reflect.Uint32: - return 4 - case reflect.Uint64: - return 5 - case reflect.Int: - return 6 - case reflect.Int8: - return 7 - case reflect.Int16: - return 8 - case reflect.Int32: - return 9 - case reflect.Int64: - return 10 - case reflect.Float32: - return 11 - case reflect.Float64: - return 12 - default: - return 0 - } -} - -func combined(a, b reflect.Type) reflect.Type { - if typeWeight(a) > typeWeight(b) { - return a - } else { - return b - } -} - -func dereference(t reflect.Type) reflect.Type { - if t == nil { - return nil - } - if t.Kind() == reflect.Ptr { - t = dereference(t.Elem()) - } - return t -} - -func isComparable(l, r reflect.Type) bool { - l = dereference(l) - r = dereference(r) - - if l == nil || r == nil { // It is possible to compare with nil. - return true - } - if l.Kind() == r.Kind() { - return true - } - if isInterface(l) || isInterface(r) { - return true - } - return false -} - -func isInterface(t reflect.Type) bool { - t = dereference(t) - if t != nil { - switch t.Kind() { - case reflect.Interface: - return true - } - } - return false -} - -func isInteger(t reflect.Type) bool { - t = dereference(t) - if t != nil { - switch t.Kind() { - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - fallthrough - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: - return true - case reflect.Interface: - return true - } - } - return false -} - -func isFloat(t reflect.Type) bool { - t = dereference(t) - if t != nil { - switch t.Kind() { - case reflect.Float32, reflect.Float64: - return true - case reflect.Interface: - return true - } - } - return false -} - -func isNumber(t reflect.Type) bool { - return isInteger(t) || isFloat(t) -} - -func isBool(t reflect.Type) bool { - t = dereference(t) - if t != nil { - switch t.Kind() { - case reflect.Bool: - return true - case reflect.Interface: - return true - } - } - return false -} - -func isString(t reflect.Type) bool { - t = dereference(t) - if t != nil { - switch t.Kind() { - case reflect.String: - return true - case reflect.Interface: - return true - } - } - return false -} - -func isArray(t reflect.Type) bool { - t = dereference(t) - if t != nil { - switch t.Kind() { - case reflect.Slice, reflect.Array: - return true - case reflect.Interface: - return true - } - } - return false -} - -func isMap(t reflect.Type) bool { - t = dereference(t) - if t != nil { - switch t.Kind() { - case reflect.Map: - return true - case reflect.Interface: - return true - } - } - return false -} - -func isStruct(t reflect.Type) bool { - t = dereference(t) - if t != nil { - switch t.Kind() { - case reflect.Struct: - return true - } - } - return false -} - -func isFunc(t reflect.Type) bool { - t = dereference(t) - if t != nil { - switch t.Kind() { - case reflect.Func: - return true - } - } - return false -} - -func fieldType(ntype reflect.Type, name string) (reflect.Type, bool) { - ntype = dereference(ntype) - if ntype != nil { - switch ntype.Kind() { - case reflect.Interface: - return interfaceType, true - case reflect.Struct: - // First check all struct's fields. - for i := 0; i < ntype.NumField(); i++ { - f := ntype.Field(i) - if f.Name == name { - return f.Type, true - } - } - - // Second check fields of embedded structs. - for i := 0; i < ntype.NumField(); i++ { - f := ntype.Field(i) - if f.Anonymous { - if t, ok := fieldType(f.Type, name); ok { - return t, true - } - } - } - case reflect.Map: - return ntype.Elem(), true - } - } - - return nil, false -} - -func methodType(t reflect.Type, name string) (reflect.Type, bool, bool) { - if t != nil { - // First, check methods defined on type itself, - // independent of which type it is. - if m, ok := t.MethodByName(name); ok { - if t.Kind() == reflect.Interface { - // In case of interface type method will not have a receiver, - // and to prevent checker decreasing numbers of in arguments - // return method type as not method (second argument is false). - return m.Type, false, true - } else { - return m.Type, true, true - } - } - - d := t - if t.Kind() == reflect.Ptr { - d = t.Elem() - } - - switch d.Kind() { - case reflect.Interface: - return interfaceType, false, true - case reflect.Struct: - // First, check all struct's fields. - for i := 0; i < d.NumField(); i++ { - f := d.Field(i) - if !f.Anonymous && f.Name == name { - return f.Type, false, true - } - } - - // Second, check fields of embedded structs. - for i := 0; i < d.NumField(); i++ { - f := d.Field(i) - if f.Anonymous { - if t, method, ok := methodType(f.Type, name); ok { - return t, method, true - } - } - } - - case reflect.Map: - return d.Elem(), false, true - } - } - return nil, false, false -} - -func indexType(ntype reflect.Type) (reflect.Type, bool) { - ntype = dereference(ntype) - if ntype == nil { - return nil, false - } - - switch ntype.Kind() { - case reflect.Interface: - return interfaceType, true - case reflect.Map, reflect.Array, reflect.Slice: - return ntype.Elem(), true - } - - return nil, false -} - -func isFuncType(ntype reflect.Type) (reflect.Type, bool) { - ntype = dereference(ntype) - if ntype == nil { - return nil, false - } - - switch ntype.Kind() { - case reflect.Interface: - return interfaceType, true - case reflect.Func: - return ntype, true - } - - return nil, false -} - -func isIntegerOrArithmeticOperation(node ast.Node) bool { - switch n := node.(type) { - case *ast.IntegerNode: - return true - case *ast.UnaryNode: - switch n.Operator { - case "+", "-": - return true - } - case *ast.BinaryNode: - switch n.Operator { - case "+", "/", "-", "*": - return true - } - } - return false -} - -func setTypeForIntegers(node ast.Node, t reflect.Type) { - switch n := node.(type) { - case *ast.IntegerNode: - n.SetType(t) - case *ast.UnaryNode: - switch n.Operator { - case "+", "-": - setTypeForIntegers(n.Node, t) - } - case *ast.BinaryNode: - switch n.Operator { - case "+", "/", "-", "*": - setTypeForIntegers(n.Left, t) - setTypeForIntegers(n.Right, t) - } - } -} diff --git a/vendor/github.com/antonmedv/expr/compiler/compiler.go b/vendor/github.com/antonmedv/expr/compiler/compiler.go deleted file mode 100644 index 36ac92f..0000000 --- a/vendor/github.com/antonmedv/expr/compiler/compiler.go +++ /dev/null @@ -1,673 +0,0 @@ -package compiler - -import ( - "encoding/binary" - "fmt" - "math" - "reflect" - - "github.com/antonmedv/expr/ast" - "github.com/antonmedv/expr/conf" - "github.com/antonmedv/expr/file" - "github.com/antonmedv/expr/parser" - . "github.com/antonmedv/expr/vm" -) - -func Compile(tree *parser.Tree, config *conf.Config) (program *Program, err error) { - defer func() { - if r := recover(); r != nil { - err = fmt.Errorf("%v", r) - } - }() - - c := &compiler{ - index: make(map[interface{}]uint16), - locations: make(map[int]file.Location), - } - - if config != nil { - c.mapEnv = config.MapEnv - c.cast = config.Expect - } - - c.compile(tree.Node) - - switch c.cast { - case reflect.Int64: - c.emit(OpCast, encode(0)...) - case reflect.Float64: - c.emit(OpCast, encode(1)...) - } - - program = &Program{ - Source: tree.Source, - Locations: c.locations, - Constants: c.constants, - Bytecode: c.bytecode, - } - return -} - -type compiler struct { - locations map[int]file.Location - constants []interface{} - bytecode []byte - index map[interface{}]uint16 - mapEnv bool - cast reflect.Kind - nodes []ast.Node -} - -func (c *compiler) emit(op byte, b ...byte) int { - c.bytecode = append(c.bytecode, op) - current := len(c.bytecode) - c.bytecode = append(c.bytecode, b...) - - var loc file.Location - if len(c.nodes) > 0 { - loc = c.nodes[len(c.nodes)-1].Location() - } - c.locations[current-1] = loc - - return current -} - -func (c *compiler) emitPush(value interface{}) int { - return c.emit(OpPush, c.makeConstant(value)...) -} - -func (c *compiler) makeConstant(i interface{}) []byte { - hashable := true - switch reflect.TypeOf(i).Kind() { - case reflect.Slice, reflect.Map: - hashable = false - } - - if hashable { - if p, ok := c.index[i]; ok { - return encode(p) - } - } - - c.constants = append(c.constants, i) - if len(c.constants) > math.MaxUint16 { - panic("exceeded constants max space limit") - } - - p := uint16(len(c.constants) - 1) - if hashable { - c.index[i] = p - } - return encode(p) -} - -func (c *compiler) placeholder() []byte { - return []byte{0xFF, 0xFF} -} - -func (c *compiler) patchJump(placeholder int) { - offset := len(c.bytecode) - 2 - placeholder - b := encode(uint16(offset)) - c.bytecode[placeholder] = b[0] - c.bytecode[placeholder+1] = b[1] -} - -func (c *compiler) calcBackwardJump(to int) []byte { - return encode(uint16(len(c.bytecode) + 1 + 2 - to)) -} - -func (c *compiler) compile(node ast.Node) { - c.nodes = append(c.nodes, node) - defer func() { - c.nodes = c.nodes[:len(c.nodes)-1] - }() - - switch n := node.(type) { - case *ast.NilNode: - c.NilNode(n) - case *ast.IdentifierNode: - c.IdentifierNode(n) - case *ast.IntegerNode: - c.IntegerNode(n) - case *ast.FloatNode: - c.FloatNode(n) - case *ast.BoolNode: - c.BoolNode(n) - case *ast.StringNode: - c.StringNode(n) - case *ast.ConstantNode: - c.ConstantNode(n) - case *ast.UnaryNode: - c.UnaryNode(n) - case *ast.BinaryNode: - c.BinaryNode(n) - case *ast.MatchesNode: - c.MatchesNode(n) - case *ast.PropertyNode: - c.PropertyNode(n) - case *ast.IndexNode: - c.IndexNode(n) - case *ast.SliceNode: - c.SliceNode(n) - case *ast.MethodNode: - c.MethodNode(n) - case *ast.FunctionNode: - c.FunctionNode(n) - case *ast.BuiltinNode: - c.BuiltinNode(n) - case *ast.ClosureNode: - c.ClosureNode(n) - case *ast.PointerNode: - c.PointerNode(n) - case *ast.ConditionalNode: - c.ConditionalNode(n) - case *ast.ArrayNode: - c.ArrayNode(n) - case *ast.MapNode: - c.MapNode(n) - case *ast.PairNode: - c.PairNode(n) - default: - panic(fmt.Sprintf("undefined node type (%T)", node)) - } -} - -func (c *compiler) NilNode(node *ast.NilNode) { - c.emit(OpNil) -} - -func (c *compiler) IdentifierNode(node *ast.IdentifierNode) { - v := c.makeConstant(node.Value) - if c.mapEnv { - c.emit(OpFetchMap, v...) - } else if node.NilSafe { - c.emit(OpFetchNilSafe, v...) - } else { - c.emit(OpFetch, v...) - } -} - -func (c *compiler) IntegerNode(node *ast.IntegerNode) { - t := node.Type() - if t == nil { - c.emitPush(node.Value) - return - } - - switch t.Kind() { - case reflect.Float32: - c.emitPush(float32(node.Value)) - case reflect.Float64: - c.emitPush(float64(node.Value)) - - case reflect.Int: - c.emitPush(int(node.Value)) - case reflect.Int8: - c.emitPush(int8(node.Value)) - case reflect.Int16: - c.emitPush(int16(node.Value)) - case reflect.Int32: - c.emitPush(int32(node.Value)) - case reflect.Int64: - c.emitPush(int64(node.Value)) - - case reflect.Uint: - c.emitPush(uint(node.Value)) - case reflect.Uint8: - c.emitPush(uint8(node.Value)) - case reflect.Uint16: - c.emitPush(uint16(node.Value)) - case reflect.Uint32: - c.emitPush(uint32(node.Value)) - case reflect.Uint64: - c.emitPush(uint64(node.Value)) - - default: - c.emitPush(node.Value) - } -} - -func (c *compiler) FloatNode(node *ast.FloatNode) { - c.emitPush(node.Value) -} - -func (c *compiler) BoolNode(node *ast.BoolNode) { - if node.Value { - c.emit(OpTrue) - } else { - c.emit(OpFalse) - } -} - -func (c *compiler) StringNode(node *ast.StringNode) { - c.emitPush(node.Value) -} - -func (c *compiler) ConstantNode(node *ast.ConstantNode) { - c.emitPush(node.Value) -} - -func (c *compiler) UnaryNode(node *ast.UnaryNode) { - c.compile(node.Node) - - switch node.Operator { - - case "!", "not": - c.emit(OpNot) - - case "+": - // Do nothing - - case "-": - c.emit(OpNegate) - - default: - panic(fmt.Sprintf("unknown operator (%v)", node.Operator)) - } -} - -func (c *compiler) BinaryNode(node *ast.BinaryNode) { - l := kind(node.Left) - r := kind(node.Right) - - switch node.Operator { - case "==": - c.compile(node.Left) - c.compile(node.Right) - - if l == r && l == reflect.Int { - c.emit(OpEqualInt) - } else if l == r && l == reflect.String { - c.emit(OpEqualString) - } else { - c.emit(OpEqual) - } - - case "!=": - c.compile(node.Left) - c.compile(node.Right) - c.emit(OpEqual) - c.emit(OpNot) - - case "or", "||": - c.compile(node.Left) - end := c.emit(OpJumpIfTrue, c.placeholder()...) - c.emit(OpPop) - c.compile(node.Right) - c.patchJump(end) - - case "and", "&&": - c.compile(node.Left) - end := c.emit(OpJumpIfFalse, c.placeholder()...) - c.emit(OpPop) - c.compile(node.Right) - c.patchJump(end) - - case "in": - c.compile(node.Left) - c.compile(node.Right) - c.emit(OpIn) - - case "not in": - c.compile(node.Left) - c.compile(node.Right) - c.emit(OpIn) - c.emit(OpNot) - - case "<": - c.compile(node.Left) - c.compile(node.Right) - c.emit(OpLess) - - case ">": - c.compile(node.Left) - c.compile(node.Right) - c.emit(OpMore) - - case "<=": - c.compile(node.Left) - c.compile(node.Right) - c.emit(OpLessOrEqual) - - case ">=": - c.compile(node.Left) - c.compile(node.Right) - c.emit(OpMoreOrEqual) - - case "+": - c.compile(node.Left) - c.compile(node.Right) - c.emit(OpAdd) - - case "-": - c.compile(node.Left) - c.compile(node.Right) - c.emit(OpSubtract) - - case "*": - c.compile(node.Left) - c.compile(node.Right) - c.emit(OpMultiply) - - case "/": - c.compile(node.Left) - c.compile(node.Right) - c.emit(OpDivide) - - case "%": - c.compile(node.Left) - c.compile(node.Right) - c.emit(OpModulo) - - case "**": - c.compile(node.Left) - c.compile(node.Right) - c.emit(OpExponent) - - case "contains": - c.compile(node.Left) - c.compile(node.Right) - c.emit(OpContains) - - case "startsWith": - c.compile(node.Left) - c.compile(node.Right) - c.emit(OpStartsWith) - - case "endsWith": - c.compile(node.Left) - c.compile(node.Right) - c.emit(OpEndsWith) - - case "..": - c.compile(node.Left) - c.compile(node.Right) - c.emit(OpRange) - - default: - panic(fmt.Sprintf("unknown operator (%v)", node.Operator)) - - } -} - -func (c *compiler) MatchesNode(node *ast.MatchesNode) { - if node.Regexp != nil { - c.compile(node.Left) - c.emit(OpMatchesConst, c.makeConstant(node.Regexp)...) - return - } - c.compile(node.Left) - c.compile(node.Right) - c.emit(OpMatches) -} - -func (c *compiler) PropertyNode(node *ast.PropertyNode) { - c.compile(node.Node) - if !node.NilSafe { - c.emit(OpProperty, c.makeConstant(node.Property)...) - } else { - c.emit(OpPropertyNilSafe, c.makeConstant(node.Property)...) - } -} - -func (c *compiler) IndexNode(node *ast.IndexNode) { - c.compile(node.Node) - c.compile(node.Index) - c.emit(OpIndex) -} - -func (c *compiler) SliceNode(node *ast.SliceNode) { - c.compile(node.Node) - if node.To != nil { - c.compile(node.To) - } else { - c.emit(OpLen) - } - if node.From != nil { - c.compile(node.From) - } else { - c.emitPush(0) - } - c.emit(OpSlice) -} - -func (c *compiler) MethodNode(node *ast.MethodNode) { - c.compile(node.Node) - for _, arg := range node.Arguments { - c.compile(arg) - } - if !node.NilSafe { - c.emit(OpMethod, c.makeConstant(Call{Name: node.Method, Size: len(node.Arguments)})...) - } else { - c.emit(OpMethodNilSafe, c.makeConstant(Call{Name: node.Method, Size: len(node.Arguments)})...) - } -} - -func (c *compiler) FunctionNode(node *ast.FunctionNode) { - for _, arg := range node.Arguments { - c.compile(arg) - } - op := OpCall - if node.Fast { - op = OpCallFast - } - c.emit(op, c.makeConstant(Call{Name: node.Name, Size: len(node.Arguments)})...) -} - -func (c *compiler) BuiltinNode(node *ast.BuiltinNode) { - switch node.Name { - case "len": - c.compile(node.Arguments[0]) - c.emit(OpLen) - c.emit(OpRot) - c.emit(OpPop) - - case "all": - c.compile(node.Arguments[0]) - c.emit(OpBegin) - var loopBreak int - c.emitLoop(func() { - c.compile(node.Arguments[1]) - loopBreak = c.emit(OpJumpIfFalse, c.placeholder()...) - c.emit(OpPop) - }) - c.emit(OpTrue) - c.patchJump(loopBreak) - c.emit(OpEnd) - - case "none": - c.compile(node.Arguments[0]) - c.emit(OpBegin) - var loopBreak int - c.emitLoop(func() { - c.compile(node.Arguments[1]) - c.emit(OpNot) - loopBreak = c.emit(OpJumpIfFalse, c.placeholder()...) - c.emit(OpPop) - }) - c.emit(OpTrue) - c.patchJump(loopBreak) - c.emit(OpEnd) - - case "any": - c.compile(node.Arguments[0]) - c.emit(OpBegin) - var loopBreak int - c.emitLoop(func() { - c.compile(node.Arguments[1]) - loopBreak = c.emit(OpJumpIfTrue, c.placeholder()...) - c.emit(OpPop) - }) - c.emit(OpFalse) - c.patchJump(loopBreak) - c.emit(OpEnd) - - case "one": - count := c.makeConstant("count") - c.compile(node.Arguments[0]) - c.emit(OpBegin) - c.emitPush(0) - c.emit(OpStore, count...) - c.emitLoop(func() { - c.compile(node.Arguments[1]) - c.emitCond(func() { - c.emit(OpInc, count...) - }) - }) - c.emit(OpLoad, count...) - c.emitPush(1) - c.emit(OpEqual) - c.emit(OpEnd) - - case "filter": - count := c.makeConstant("count") - c.compile(node.Arguments[0]) - c.emit(OpBegin) - c.emitPush(0) - c.emit(OpStore, count...) - c.emitLoop(func() { - c.compile(node.Arguments[1]) - c.emitCond(func() { - c.emit(OpInc, count...) - - c.emit(OpLoad, c.makeConstant("array")...) - c.emit(OpLoad, c.makeConstant("i")...) - c.emit(OpIndex) - }) - }) - c.emit(OpLoad, count...) - c.emit(OpEnd) - c.emit(OpArray) - - case "map": - c.compile(node.Arguments[0]) - c.emit(OpBegin) - size := c.emitLoop(func() { - c.compile(node.Arguments[1]) - }) - c.emit(OpLoad, size...) - c.emit(OpEnd) - c.emit(OpArray) - - case "count": - count := c.makeConstant("count") - c.compile(node.Arguments[0]) - c.emit(OpBegin) - c.emitPush(0) - c.emit(OpStore, count...) - c.emitLoop(func() { - c.compile(node.Arguments[1]) - c.emitCond(func() { - c.emit(OpInc, count...) - }) - }) - c.emit(OpLoad, count...) - c.emit(OpEnd) - - default: - panic(fmt.Sprintf("unknown builtin %v", node.Name)) - } -} - -func (c *compiler) emitCond(body func()) { - noop := c.emit(OpJumpIfFalse, c.placeholder()...) - c.emit(OpPop) - - body() - - jmp := c.emit(OpJump, c.placeholder()...) - c.patchJump(noop) - c.emit(OpPop) - c.patchJump(jmp) -} - -func (c *compiler) emitLoop(body func()) []byte { - i := c.makeConstant("i") - size := c.makeConstant("size") - array := c.makeConstant("array") - - c.emit(OpLen) - c.emit(OpStore, size...) - c.emit(OpStore, array...) - c.emitPush(0) - c.emit(OpStore, i...) - - cond := len(c.bytecode) - c.emit(OpLoad, i...) - c.emit(OpLoad, size...) - c.emit(OpLess) - end := c.emit(OpJumpIfFalse, c.placeholder()...) - c.emit(OpPop) - - body() - - c.emit(OpInc, i...) - c.emit(OpJumpBackward, c.calcBackwardJump(cond)...) - - c.patchJump(end) - c.emit(OpPop) - - return size -} - -func (c *compiler) ClosureNode(node *ast.ClosureNode) { - c.compile(node.Node) -} - -func (c *compiler) PointerNode(node *ast.PointerNode) { - c.emit(OpLoad, c.makeConstant("array")...) - c.emit(OpLoad, c.makeConstant("i")...) - c.emit(OpIndex) -} - -func (c *compiler) ConditionalNode(node *ast.ConditionalNode) { - c.compile(node.Cond) - otherwise := c.emit(OpJumpIfFalse, c.placeholder()...) - - c.emit(OpPop) - c.compile(node.Exp1) - end := c.emit(OpJump, c.placeholder()...) - - c.patchJump(otherwise) - c.emit(OpPop) - c.compile(node.Exp2) - - c.patchJump(end) -} - -func (c *compiler) ArrayNode(node *ast.ArrayNode) { - for _, node := range node.Nodes { - c.compile(node) - } - - c.emitPush(len(node.Nodes)) - c.emit(OpArray) -} - -func (c *compiler) MapNode(node *ast.MapNode) { - for _, pair := range node.Pairs { - c.compile(pair) - } - - c.emitPush(len(node.Pairs)) - c.emit(OpMap) -} - -func (c *compiler) PairNode(node *ast.PairNode) { - c.compile(node.Key) - c.compile(node.Value) -} - -func encode(i uint16) []byte { - b := make([]byte, 2) - binary.LittleEndian.PutUint16(b, i) - return b -} - -func kind(node ast.Node) reflect.Kind { - t := node.Type() - if t == nil { - return reflect.Invalid - } - return t.Kind() -} diff --git a/vendor/github.com/antonmedv/expr/compiler/patcher.go b/vendor/github.com/antonmedv/expr/compiler/patcher.go deleted file mode 100644 index 2491dec..0000000 --- a/vendor/github.com/antonmedv/expr/compiler/patcher.go +++ /dev/null @@ -1,44 +0,0 @@ -package compiler - -import ( - "github.com/antonmedv/expr/ast" - "github.com/antonmedv/expr/conf" -) - -type operatorPatcher struct { - ops map[string][]string - types conf.TypesTable -} - -func (p *operatorPatcher) Enter(node *ast.Node) {} -func (p *operatorPatcher) Exit(node *ast.Node) { - binaryNode, ok := (*node).(*ast.BinaryNode) - if !ok { - return - } - - fns, ok := p.ops[binaryNode.Operator] - if !ok { - return - } - - leftType := binaryNode.Left.Type() - rightType := binaryNode.Right.Type() - - _, fn, ok := conf.FindSuitableOperatorOverload(fns, p.types, leftType, rightType) - if ok { - newNode := &ast.FunctionNode{ - Name: fn, - Arguments: []ast.Node{binaryNode.Left, binaryNode.Right}, - } - ast.Patch(node, newNode) - } -} - -func PatchOperators(node *ast.Node, config *conf.Config) { - if len(config.Operators) == 0 { - return - } - patcher := &operatorPatcher{ops: config.Operators, types: config.Types} - ast.Walk(node, patcher) -} diff --git a/vendor/github.com/antonmedv/expr/conf/config.go b/vendor/github.com/antonmedv/expr/conf/config.go deleted file mode 100644 index 7ba07fe..0000000 --- a/vendor/github.com/antonmedv/expr/conf/config.go +++ /dev/null @@ -1,89 +0,0 @@ -package conf - -import ( - "fmt" - "reflect" - - "github.com/antonmedv/expr/ast" - "github.com/antonmedv/expr/vm" -) - -type Config struct { - Env interface{} - MapEnv bool - Types TypesTable - Operators OperatorsTable - Expect reflect.Kind - Optimize bool - Strict bool - DefaultType reflect.Type - ConstExprFns map[string]reflect.Value - Visitors []ast.Visitor - err error -} - -func New(env interface{}) *Config { - var mapEnv bool - var mapValueType reflect.Type - if _, ok := env.(map[string]interface{}); ok { - mapEnv = true - } else { - if reflect.ValueOf(env).Kind() == reflect.Map { - mapValueType = reflect.TypeOf(env).Elem() - } - } - - return &Config{ - Env: env, - MapEnv: mapEnv, - Types: CreateTypesTable(env), - Optimize: true, - Strict: true, - DefaultType: mapValueType, - ConstExprFns: make(map[string]reflect.Value), - } -} - -// Check validates the compiler configuration. -func (c *Config) Check() error { - // Check that all functions that define operator overloading - // exist in environment and have correct signatures. - for op, fns := range c.Operators { - for _, fn := range fns { - fnType, ok := c.Types[fn] - if !ok || fnType.Type.Kind() != reflect.Func { - return fmt.Errorf("function %s for %s operator does not exist in environment", fn, op) - } - requiredNumIn := 2 - if fnType.Method { - requiredNumIn = 3 // As first argument of method is receiver. - } - if fnType.Type.NumIn() != requiredNumIn || fnType.Type.NumOut() != 1 { - return fmt.Errorf("function %s for %s operator does not have a correct signature", fn, op) - } - } - } - - // Check that all ConstExprFns are functions. - for name, fn := range c.ConstExprFns { - if fn.Kind() != reflect.Func { - return fmt.Errorf("const expression %q must be a function", name) - } - } - - return c.err -} - -func (c *Config) ConstExpr(name string) { - if c.Env == nil { - c.Error(fmt.Errorf("no environment for const expression: %v", name)) - return - } - c.ConstExprFns[name] = vm.FetchFn(c.Env, name) -} - -func (c *Config) Error(err error) { - if c.err == nil { - c.err = err - } -} diff --git a/vendor/github.com/antonmedv/expr/conf/operators_table.go b/vendor/github.com/antonmedv/expr/conf/operators_table.go deleted file mode 100644 index 0ceb844..0000000 --- a/vendor/github.com/antonmedv/expr/conf/operators_table.go +++ /dev/null @@ -1,26 +0,0 @@ -package conf - -import "reflect" - -// OperatorsTable maps binary operators to corresponding list of functions. -// Functions should be provided in the environment to allow operator overloading. -type OperatorsTable map[string][]string - -func FindSuitableOperatorOverload(fns []string, types TypesTable, l, r reflect.Type) (reflect.Type, string, bool) { - for _, fn := range fns { - fnType := types[fn] - firstInIndex := 0 - if fnType.Method { - firstInIndex = 1 // As first argument to method is receiver. - } - firstArgType := fnType.Type.In(firstInIndex) - secondArgType := fnType.Type.In(firstInIndex + 1) - - firstArgumentFit := l == firstArgType || (firstArgType.Kind() == reflect.Interface && (l == nil || l.Implements(firstArgType))) - secondArgumentFit := r == secondArgType || (secondArgType.Kind() == reflect.Interface && (r == nil || r.Implements(secondArgType))) - if firstArgumentFit && secondArgumentFit { - return fnType.Type.Out(0), fn, true - } - } - return nil, "", false -} diff --git a/vendor/github.com/antonmedv/expr/conf/types_table.go b/vendor/github.com/antonmedv/expr/conf/types_table.go deleted file mode 100644 index d5539da..0000000 --- a/vendor/github.com/antonmedv/expr/conf/types_table.go +++ /dev/null @@ -1,100 +0,0 @@ -package conf - -import "reflect" - -type Tag struct { - Type reflect.Type - Method bool - Ambiguous bool -} - -type TypesTable map[string]Tag - -// CreateTypesTable creates types table for type checks during parsing. -// If struct is passed, all fields will be treated as variables, -// as well as all fields of embedded structs and struct itself. -// -// If map is passed, all items will be treated as variables -// (key as name, value as type). -func CreateTypesTable(i interface{}) TypesTable { - if i == nil { - return nil - } - - types := make(TypesTable) - v := reflect.ValueOf(i) - t := reflect.TypeOf(i) - - d := t - if t.Kind() == reflect.Ptr { - d = t.Elem() - } - - switch d.Kind() { - case reflect.Struct: - types = FieldsFromStruct(d) - - // Methods of struct should be gathered from original struct with pointer, - // as methods maybe declared on pointer receiver. Also this method retrieves - // all embedded structs methods as well, no need to recursion. - for i := 0; i < t.NumMethod(); i++ { - m := t.Method(i) - types[m.Name] = Tag{Type: m.Type, Method: true} - } - - case reflect.Map: - for _, key := range v.MapKeys() { - value := v.MapIndex(key) - if key.Kind() == reflect.String && value.IsValid() && value.CanInterface() { - types[key.String()] = Tag{Type: reflect.TypeOf(value.Interface())} - } - } - - // A map may have method too. - for i := 0; i < t.NumMethod(); i++ { - m := t.Method(i) - types[m.Name] = Tag{Type: m.Type, Method: true} - } - } - - return types -} - -func FieldsFromStruct(t reflect.Type) TypesTable { - types := make(TypesTable) - t = dereference(t) - if t == nil { - return types - } - - switch t.Kind() { - case reflect.Struct: - for i := 0; i < t.NumField(); i++ { - f := t.Field(i) - - if f.Anonymous { - for name, typ := range FieldsFromStruct(f.Type) { - if _, ok := types[name]; ok { - types[name] = Tag{Ambiguous: true} - } else { - types[name] = typ - } - } - } - - types[f.Name] = Tag{Type: f.Type} - } - } - - return types -} - -func dereference(t reflect.Type) reflect.Type { - if t == nil { - return nil - } - if t.Kind() == reflect.Ptr { - t = dereference(t.Elem()) - } - return t -} diff --git a/vendor/github.com/antonmedv/expr/expr.go b/vendor/github.com/antonmedv/expr/expr.go deleted file mode 100644 index 05c54ad..0000000 --- a/vendor/github.com/antonmedv/expr/expr.go +++ /dev/null @@ -1,187 +0,0 @@ -package expr - -import ( - "fmt" - "github.com/antonmedv/expr/ast" - "github.com/antonmedv/expr/file" - "reflect" - - "github.com/antonmedv/expr/checker" - "github.com/antonmedv/expr/compiler" - "github.com/antonmedv/expr/conf" - "github.com/antonmedv/expr/optimizer" - "github.com/antonmedv/expr/parser" - "github.com/antonmedv/expr/vm" -) - -// Option for configuring config. -type Option func(c *conf.Config) - -// Eval parses, compiles and runs given input. -func Eval(input string, env interface{}) (interface{}, error) { - if _, ok := env.(Option); ok { - return nil, fmt.Errorf("misused expr.Eval: second argument (env) should be passed without expr.Env") - } - - tree, err := parser.Parse(input) - if err != nil { - return nil, err - } - - program, err := compiler.Compile(tree, nil) - if err != nil { - return nil, err - } - - output, err := vm.Run(program, env) - if err != nil { - return nil, err - } - - return output, nil -} - -// Env specifies expected input of env for type checks. -// If struct is passed, all fields will be treated as variables, -// as well as all fields of embedded structs and struct itself. -// If map is passed, all items will be treated as variables. -// Methods defined on this type will be available as functions. -func Env(env interface{}) Option { - return func(c *conf.Config) { - if _, ok := env.(map[string]interface{}); ok { - c.MapEnv = true - } else { - if reflect.ValueOf(env).Kind() == reflect.Map { - c.DefaultType = reflect.TypeOf(env).Elem() - } - } - c.Strict = true - c.Types = conf.CreateTypesTable(env) - c.Env = env - } -} - -// AllowUndefinedVariables allows to use undefined variables inside expressions. -// This can be used with expr.Env option to partially define a few variables. -// Note what this option is only works in map environment are used, otherwise -// runtime.fetch will panic as there is no way to get missing field zero value. -func AllowUndefinedVariables() Option { - return func(c *conf.Config) { - c.Strict = false - } -} - -// Operator allows to override binary operator with function. -func Operator(operator string, fn ...string) Option { - return func(c *conf.Config) { - c.Operators[operator] = append(c.Operators[operator], fn...) - } -} - -// ConstExpr defines func expression as constant. If all argument to this function is constants, -// then it can be replaced by result of this func call on compile step. -func ConstExpr(fn string) Option { - return func(c *conf.Config) { - c.ConstExpr(fn) - } -} - -// AsBool tells the compiler to expect boolean result. -func AsBool() Option { - return func(c *conf.Config) { - c.Expect = reflect.Bool - } -} - -// AsInt64 tells the compiler to expect int64 result. -func AsInt64() Option { - return func(c *conf.Config) { - c.Expect = reflect.Int64 - } -} - -// AsFloat64 tells the compiler to expect float64 result. -func AsFloat64() Option { - return func(c *conf.Config) { - c.Expect = reflect.Float64 - } -} - -// Optimize turns optimizations on or off. -func Optimize(b bool) Option { - return func(c *conf.Config) { - c.Optimize = b - } -} - -// Patch adds visitor to list of visitors what will be applied before compiling AST to bytecode. -func Patch(visitor ast.Visitor) Option { - return func(c *conf.Config) { - c.Visitors = append(c.Visitors, visitor) - } -} - -// Compile parses and compiles given input expression to bytecode program. -func Compile(input string, ops ...Option) (*vm.Program, error) { - config := &conf.Config{ - Operators: make(map[string][]string), - ConstExprFns: make(map[string]reflect.Value), - Optimize: true, - } - - for _, op := range ops { - op(config) - } - - if err := config.Check(); err != nil { - return nil, err - } - - tree, err := parser.Parse(input) - if err != nil { - return nil, err - } - - _, err = checker.Check(tree, config) - - // If we have a patch to apply, it may fix out error and - // second type check is needed. Otherwise it is an error. - if err != nil && len(config.Visitors) == 0 { - return nil, err - } - - // Patch operators before Optimize, as we may also mark it as ConstExpr. - compiler.PatchOperators(&tree.Node, config) - - if len(config.Visitors) >= 0 { - for _, v := range config.Visitors { - ast.Walk(&tree.Node, v) - } - _, err = checker.Check(tree, config) - if err != nil { - return nil, err - } - } - - if config.Optimize { - err = optimizer.Optimize(&tree.Node, config) - if err != nil { - if fileError, ok := err.(*file.Error); ok { - return nil, fileError.Bind(tree.Source) - } - return nil, err - } - } - - program, err := compiler.Compile(tree, config) - if err != nil { - return nil, err - } - - return program, nil -} - -// Run evaluates given bytecode program. -func Run(program *vm.Program, env interface{}) (interface{}, error) { - return vm.Run(program, env) -} diff --git a/vendor/github.com/antonmedv/expr/file/error.go b/vendor/github.com/antonmedv/expr/file/error.go deleted file mode 100644 index b7af3e6..0000000 --- a/vendor/github.com/antonmedv/expr/file/error.go +++ /dev/null @@ -1,58 +0,0 @@ -package file - -import ( - "fmt" - "strings" - "unicode/utf8" -) - -type Error struct { - Location - Message string - Snippet string -} - -func (e *Error) Error() string { - return e.format() -} - -func (e *Error) Bind(source *Source) *Error { - if snippet, found := source.Snippet(e.Location.Line); found { - snippet := strings.Replace(snippet, "\t", " ", -1) - srcLine := "\n | " + snippet - var bytes = []byte(snippet) - var indLine = "\n | " - for i := 0; i < e.Location.Column && len(bytes) > 0; i++ { - _, sz := utf8.DecodeRune(bytes) - bytes = bytes[sz:] - if sz > 1 { - goto noind - } else { - indLine += "." - } - } - if _, sz := utf8.DecodeRune(bytes); sz > 1 { - goto noind - } else { - indLine += "^" - } - srcLine += indLine - - noind: - e.Snippet = srcLine - } - return e -} - -func (e *Error) format() string { - if e.Location.Empty() { - return e.Message - } - return fmt.Sprintf( - "%s (%d:%d)%s", - e.Message, - e.Line, - e.Column+1, // add one to the 0-based column for display - e.Snippet, - ) -} diff --git a/vendor/github.com/antonmedv/expr/file/location.go b/vendor/github.com/antonmedv/expr/file/location.go deleted file mode 100644 index a92e27f..0000000 --- a/vendor/github.com/antonmedv/expr/file/location.go +++ /dev/null @@ -1,10 +0,0 @@ -package file - -type Location struct { - Line int // The 1-based line of the location. - Column int // The 0-based column number of the location. -} - -func (l Location) Empty() bool { - return l.Column == 0 && l.Line == 0 -} diff --git a/vendor/github.com/antonmedv/expr/file/source.go b/vendor/github.com/antonmedv/expr/file/source.go deleted file mode 100644 index 185d156..0000000 --- a/vendor/github.com/antonmedv/expr/file/source.go +++ /dev/null @@ -1,95 +0,0 @@ -package file - -import ( - "encoding/json" - "strings" - "unicode/utf8" -) - -type Source struct { - contents []rune - lineOffsets []int32 -} - -func NewSource(contents string) *Source { - s := &Source{ - contents: []rune(contents), - } - s.updateOffsets() - return s -} - -func (s *Source) MarshalJSON() ([]byte, error) { - return json.Marshal(s.contents) -} - -func (s *Source) UnmarshalJSON(b []byte) error { - contents := make([]rune, 0) - err := json.Unmarshal(b, &contents) - if err != nil { - return err - } - - s.contents = contents - s.updateOffsets() - return nil -} - -func (s *Source) Content() string { - return string(s.contents) -} - -func (s *Source) Snippet(line int) (string, bool) { - charStart, found := s.findLineOffset(line) - if !found || len(s.contents) == 0 { - return "", false - } - charEnd, found := s.findLineOffset(line + 1) - if found { - return string(s.contents[charStart : charEnd-1]), true - } - return string(s.contents[charStart:]), true -} - -// updateOffsets compute line offsets up front as they are referred to frequently. -func (s *Source) updateOffsets() { - lines := strings.Split(string(s.contents), "\n") - offsets := make([]int32, len(lines)) - var offset int32 - for i, line := range lines { - offset = offset + int32(utf8.RuneCountInString(line)) + 1 - offsets[int32(i)] = offset - } - s.lineOffsets = offsets -} - -// findLineOffset returns the offset where the (1-indexed) line begins, -// or false if line doesn't exist. -func (s *Source) findLineOffset(line int) (int32, bool) { - if line == 1 { - return 0, true - } else if line > 1 && line <= len(s.lineOffsets) { - offset := s.lineOffsets[line-2] - return offset, true - } - return -1, false -} - -// findLine finds the line that contains the given character offset and -// returns the line number and offset of the beginning of that line. -// Note that the last line is treated as if it contains all offsets -// beyond the end of the actual source. -func (s *Source) findLine(characterOffset int32) (int32, int32) { - var line int32 = 1 - for _, lineOffset := range s.lineOffsets { - if lineOffset > characterOffset { - break - } else { - line++ - } - } - if line == 1 { - return line, 0 - } - return line, s.lineOffsets[line-2] -} diff --git a/vendor/github.com/antonmedv/expr/optimizer/const_expr.go b/vendor/github.com/antonmedv/expr/optimizer/const_expr.go deleted file mode 100644 index 85fcc33..0000000 --- a/vendor/github.com/antonmedv/expr/optimizer/const_expr.go +++ /dev/null @@ -1,77 +0,0 @@ -package optimizer - -import ( - "fmt" - . "github.com/antonmedv/expr/ast" - "github.com/antonmedv/expr/file" - "reflect" - "strings" -) - -type constExpr struct { - applied bool - err error - fns map[string]reflect.Value -} - -func (*constExpr) Enter(*Node) {} -func (c *constExpr) Exit(node *Node) { - defer func() { - if r := recover(); r != nil { - msg := fmt.Sprintf("%v", r) - // Make message more actual, it's a runtime error, but at compile step. - msg = strings.Replace(msg, "runtime error:", "compile error:", 1) - c.err = &file.Error{ - Location: (*node).Location(), - Message: msg, - } - } - }() - - patch := func(newNode Node) { - c.applied = true - Patch(node, newNode) - } - - switch n := (*node).(type) { - case *FunctionNode: - fn, ok := c.fns[n.Name] - if ok { - in := make([]reflect.Value, len(n.Arguments)) - for i := 0; i < len(n.Arguments); i++ { - arg := n.Arguments[i] - var param interface{} - - switch a := arg.(type) { - case *NilNode: - param = nil - case *IntegerNode: - param = a.Value - case *FloatNode: - param = a.Value - case *BoolNode: - param = a.Value - case *StringNode: - param = a.Value - case *ConstantNode: - param = a.Value - - default: - return // Const expr optimization not applicable. - } - - if param == nil && reflect.TypeOf(param) == nil { - // In case of nil value and nil type use this hack, - // otherwise reflect.Call will panic on zero value. - in[i] = reflect.ValueOf(¶m).Elem() - } else { - in[i] = reflect.ValueOf(param) - } - } - - out := fn.Call(in) - constNode := &ConstantNode{Value: out[0].Interface()} - patch(constNode) - } - } -} diff --git a/vendor/github.com/antonmedv/expr/optimizer/const_range.go b/vendor/github.com/antonmedv/expr/optimizer/const_range.go deleted file mode 100644 index 5205aa1..0000000 --- a/vendor/github.com/antonmedv/expr/optimizer/const_range.go +++ /dev/null @@ -1,41 +0,0 @@ -package optimizer - -import ( - . "github.com/antonmedv/expr/ast" -) - -type constRange struct{} - -func (*constRange) Enter(*Node) {} -func (*constRange) Exit(node *Node) { - switch n := (*node).(type) { - case *BinaryNode: - if n.Operator == ".." { - if min, ok := n.Left.(*IntegerNode); ok { - if max, ok := n.Right.(*IntegerNode); ok { - size := max.Value - min.Value + 1 - // In case the max < min, patch empty slice - // as max must be greater than equal to min. - if size < 1 { - Patch(node, &ConstantNode{ - Value: make([]int, 0), - }) - return - } - // In this case array is too big. Skip generation, - // and wait for memory budget detection on runtime. - if size > 1e6 { - return - } - value := make([]int, size) - for i := range value { - value[i] = min.Value + i - } - Patch(node, &ConstantNode{ - Value: value, - }) - } - } - } - } -} diff --git a/vendor/github.com/antonmedv/expr/optimizer/fold.go b/vendor/github.com/antonmedv/expr/optimizer/fold.go deleted file mode 100644 index 6669125..0000000 --- a/vendor/github.com/antonmedv/expr/optimizer/fold.go +++ /dev/null @@ -1,133 +0,0 @@ -package optimizer - -import ( - "math" - "reflect" - - . "github.com/antonmedv/expr/ast" - "github.com/antonmedv/expr/file" -) - -type fold struct { - applied bool - err *file.Error -} - -func (*fold) Enter(*Node) {} -func (fold *fold) Exit(node *Node) { - patch := func(newNode Node) { - fold.applied = true - Patch(node, newNode) - } - // for IntegerNode the type may have been changed from int->float - // preserve this information by setting the type after the Patch - patchWithType := func(newNode Node, leafType reflect.Type) { - patch(newNode) - newNode.SetType(leafType) - } - - switch n := (*node).(type) { - case *UnaryNode: - switch n.Operator { - case "-": - if i, ok := n.Node.(*IntegerNode); ok { - patchWithType(&IntegerNode{Value: -i.Value}, n.Node.Type()) - } - case "+": - if i, ok := n.Node.(*IntegerNode); ok { - patchWithType(&IntegerNode{Value: i.Value}, n.Node.Type()) - } - } - - case *BinaryNode: - switch n.Operator { - case "+": - if a, ok := n.Left.(*IntegerNode); ok { - if b, ok := n.Right.(*IntegerNode); ok { - patchWithType(&IntegerNode{Value: a.Value + b.Value}, a.Type()) - } - } - if a, ok := n.Left.(*StringNode); ok { - if b, ok := n.Right.(*StringNode); ok { - patch(&StringNode{Value: a.Value + b.Value}) - } - } - case "-": - if a, ok := n.Left.(*IntegerNode); ok { - if b, ok := n.Right.(*IntegerNode); ok { - patchWithType(&IntegerNode{Value: a.Value - b.Value}, a.Type()) - } - } - case "*": - if a, ok := n.Left.(*IntegerNode); ok { - if b, ok := n.Right.(*IntegerNode); ok { - patchWithType(&IntegerNode{Value: a.Value * b.Value}, a.Type()) - } - } - case "/": - if a, ok := n.Left.(*IntegerNode); ok { - if b, ok := n.Right.(*IntegerNode); ok { - if b.Value == 0 { - fold.err = &file.Error{ - Location: (*node).Location(), - Message: "integer divide by zero", - } - return - } - patchWithType(&IntegerNode{Value: a.Value / b.Value}, a.Type()) - } - } - case "%": - if a, ok := n.Left.(*IntegerNode); ok { - if b, ok := n.Right.(*IntegerNode); ok { - if b.Value == 0 { - fold.err = &file.Error{ - Location: (*node).Location(), - Message: "integer divide by zero", - } - return - } - patch(&IntegerNode{Value: a.Value % b.Value}) - } - } - case "**": - if a, ok := n.Left.(*IntegerNode); ok { - if b, ok := n.Right.(*IntegerNode); ok { - patch(&FloatNode{Value: math.Pow(float64(a.Value), float64(b.Value))}) - } - } - } - - case *ArrayNode: - if len(n.Nodes) > 0 { - - for _, a := range n.Nodes { - if _, ok := a.(*IntegerNode); !ok { - goto string - } - } - { - value := make([]int, len(n.Nodes)) - for i, a := range n.Nodes { - value[i] = a.(*IntegerNode).Value - } - patch(&ConstantNode{Value: value}) - } - - string: - for _, a := range n.Nodes { - if _, ok := a.(*StringNode); !ok { - return - } - } - { - value := make([]string, len(n.Nodes)) - for i, a := range n.Nodes { - value[i] = a.(*StringNode).Value - } - patch(&ConstantNode{Value: value}) - } - - } - } -} diff --git a/vendor/github.com/antonmedv/expr/optimizer/in_array.go b/vendor/github.com/antonmedv/expr/optimizer/in_array.go deleted file mode 100644 index 8156faa..0000000 --- a/vendor/github.com/antonmedv/expr/optimizer/in_array.go +++ /dev/null @@ -1,65 +0,0 @@ -package optimizer - -import ( - "reflect" - - . "github.com/antonmedv/expr/ast" -) - -type inArray struct{} - -func (*inArray) Enter(*Node) {} -func (*inArray) Exit(node *Node) { - switch n := (*node).(type) { - case *BinaryNode: - if n.Operator == "in" || n.Operator == "not in" { - if array, ok := n.Right.(*ArrayNode); ok { - if len(array.Nodes) > 0 { - t := n.Left.Type() - if t == nil || t.Kind() != reflect.Int { - // This optimization can be only performed if left side is int type, - // as runtime.in func uses reflect.Map.MapIndex and keys of map must, - // be same as checked value type. - goto string - } - - for _, a := range array.Nodes { - if _, ok := a.(*IntegerNode); !ok { - goto string - } - } - { - value := make(map[int]struct{}) - for _, a := range array.Nodes { - value[a.(*IntegerNode).Value] = struct{}{} - } - Patch(node, &BinaryNode{ - Operator: n.Operator, - Left: n.Left, - Right: &ConstantNode{Value: value}, - }) - } - - string: - for _, a := range array.Nodes { - if _, ok := a.(*StringNode); !ok { - return - } - } - { - value := make(map[string]struct{}) - for _, a := range array.Nodes { - value[a.(*StringNode).Value] = struct{}{} - } - Patch(node, &BinaryNode{ - Operator: n.Operator, - Left: n.Left, - Right: &ConstantNode{Value: value}, - }) - } - - } - } - } - } -} diff --git a/vendor/github.com/antonmedv/expr/optimizer/in_range.go b/vendor/github.com/antonmedv/expr/optimizer/in_range.go deleted file mode 100644 index 177c919..0000000 --- a/vendor/github.com/antonmedv/expr/optimizer/in_range.go +++ /dev/null @@ -1,41 +0,0 @@ -package optimizer - -import ( - . "github.com/antonmedv/expr/ast" -) - -type inRange struct{} - -func (*inRange) Enter(*Node) {} -func (*inRange) Exit(node *Node) { - switch n := (*node).(type) { - case *BinaryNode: - if n.Operator == "in" || n.Operator == "not in" { - if rng, ok := n.Right.(*BinaryNode); ok && rng.Operator == ".." { - if from, ok := rng.Left.(*IntegerNode); ok { - if to, ok := rng.Right.(*IntegerNode); ok { - Patch(node, &BinaryNode{ - Operator: "and", - Left: &BinaryNode{ - Operator: ">=", - Left: n.Left, - Right: from, - }, - Right: &BinaryNode{ - Operator: "<=", - Left: n.Left, - Right: to, - }, - }) - if n.Operator == "not in" { - Patch(node, &UnaryNode{ - Operator: "not", - Node: *node, - }) - } - } - } - } - } - } -} diff --git a/vendor/github.com/antonmedv/expr/optimizer/optimizer.go b/vendor/github.com/antonmedv/expr/optimizer/optimizer.go deleted file mode 100644 index 738348d..0000000 --- a/vendor/github.com/antonmedv/expr/optimizer/optimizer.go +++ /dev/null @@ -1,37 +0,0 @@ -package optimizer - -import ( - . "github.com/antonmedv/expr/ast" - "github.com/antonmedv/expr/conf" -) - -func Optimize(node *Node, config *conf.Config) error { - Walk(node, &inArray{}) - for limit := 1000; limit >= 0; limit-- { - fold := &fold{} - Walk(node, fold) - if fold.err != nil { - return fold.err - } - if !fold.applied { - break - } - } - if config != nil && len(config.ConstExprFns) > 0 { - for limit := 100; limit >= 0; limit-- { - constExpr := &constExpr{ - fns: config.ConstExprFns, - } - Walk(node, constExpr) - if constExpr.err != nil { - return constExpr.err - } - if !constExpr.applied { - break - } - } - } - Walk(node, &inRange{}) - Walk(node, &constRange{}) - return nil -} diff --git a/vendor/github.com/antonmedv/expr/parser/lexer/lexer.go b/vendor/github.com/antonmedv/expr/parser/lexer/lexer.go deleted file mode 100644 index 6e4848a..0000000 --- a/vendor/github.com/antonmedv/expr/parser/lexer/lexer.go +++ /dev/null @@ -1,212 +0,0 @@ -package lexer - -import ( - "fmt" - "strings" - "unicode/utf8" - - "github.com/antonmedv/expr/file" -) - -func Lex(source *file.Source) ([]Token, error) { - l := &lexer{ - input: source.Content(), - tokens: make([]Token, 0), - } - - l.loc = file.Location{Line: 1, Column: 0} - l.prev = l.loc - l.startLoc = l.loc - - for state := root; state != nil; { - state = state(l) - } - - if l.err != nil { - return nil, l.err.Bind(source) - } - - return l.tokens, nil -} - -type lexer struct { - input string - tokens []Token - start, end int // current position in input - width int // last rune width - startLoc file.Location // start location - prev, loc file.Location // prev location of end location, end location - err *file.Error -} - -const eof rune = -1 - -func (l *lexer) next() rune { - if l.end >= len(l.input) { - l.width = 0 - return eof - } - r, w := utf8.DecodeRuneInString(l.input[l.end:]) - l.width = w - l.end += w - - l.prev = l.loc - if r == '\n' { - l.loc.Line++ - l.loc.Column = 0 - } else { - l.loc.Column++ - } - - return r -} - -func (l *lexer) peek() rune { - r := l.next() - l.backup() - return r -} - -func (l *lexer) backup() { - l.end -= l.width - l.loc = l.prev -} - -func (l *lexer) emit(t Kind) { - l.emitValue(t, l.word()) -} - -func (l *lexer) emitValue(t Kind, value string) { - l.tokens = append(l.tokens, Token{ - Location: l.startLoc, - Kind: t, - Value: value, - }) - l.start = l.end - l.startLoc = l.loc -} - -func (l *lexer) emitEOF() { - l.tokens = append(l.tokens, Token{ - Location: l.prev, // Point to previous position for better error messages. - Kind: EOF, - }) - l.start = l.end - l.startLoc = l.loc -} - -func (l *lexer) word() string { - return l.input[l.start:l.end] -} - -func (l *lexer) ignore() { - l.start = l.end - l.startLoc = l.loc -} - -func (l *lexer) accept(valid string) bool { - if strings.ContainsRune(valid, l.next()) { - return true - } - l.backup() - return false -} - -func (l *lexer) acceptRun(valid string) { - for strings.ContainsRune(valid, l.next()) { - } - l.backup() -} - -func (l *lexer) acceptWord(word string) bool { - pos, loc, prev := l.end, l.loc, l.prev - - // Skip spaces (U+0020) if any - r := l.peek() - for ; r == ' '; r = l.peek() { - l.next() - } - - for _, ch := range word { - if l.next() != ch { - l.end, l.loc, l.prev = pos, loc, prev - return false - } - } - if r = l.peek(); r != ' ' && r != eof { - l.end, l.loc, l.prev = pos, loc, prev - return false - } - - return true -} - -func (l *lexer) error(format string, args ...interface{}) stateFn { - if l.err == nil { // show first error - l.err = &file.Error{ - Location: l.loc, - Message: fmt.Sprintf(format, args...), - } - } - return nil -} - -func digitVal(ch rune) int { - switch { - case '0' <= ch && ch <= '9': - return int(ch - '0') - case 'a' <= lower(ch) && lower(ch) <= 'f': - return int(lower(ch) - 'a' + 10) - } - return 16 // larger than any legal digit val -} - -func lower(ch rune) rune { return ('a' - 'A') | ch } // returns lower-case ch iff ch is ASCII letter - -func (l *lexer) scanDigits(ch rune, base, n int) rune { - for n > 0 && digitVal(ch) < base { - ch = l.next() - n-- - } - if n > 0 { - l.error("invalid char escape") - } - return ch -} - -func (l *lexer) scanEscape(quote rune) rune { - ch := l.next() // read character after '/' - switch ch { - case 'a', 'b', 'f', 'n', 'r', 't', 'v', '\\', quote: - // nothing to do - ch = l.next() - case '0', '1', '2', '3', '4', '5', '6', '7': - ch = l.scanDigits(ch, 8, 3) - case 'x': - ch = l.scanDigits(l.next(), 16, 2) - case 'u': - ch = l.scanDigits(l.next(), 16, 4) - case 'U': - ch = l.scanDigits(l.next(), 16, 8) - default: - l.error("invalid char escape") - } - return ch -} - -func (l *lexer) scanString(quote rune) (n int) { - ch := l.next() // read character after quote - for ch != quote { - if ch == '\n' || ch == eof { - l.error("literal not terminated") - return - } - if ch == '\\' { - ch = l.scanEscape(quote) - } else { - ch = l.next() - } - n++ - } - return -} diff --git a/vendor/github.com/antonmedv/expr/parser/lexer/state.go b/vendor/github.com/antonmedv/expr/parser/lexer/state.go deleted file mode 100644 index 0d4bece..0000000 --- a/vendor/github.com/antonmedv/expr/parser/lexer/state.go +++ /dev/null @@ -1,148 +0,0 @@ -package lexer - -import ( - "strings" -) - -type stateFn func(*lexer) stateFn - -func root(l *lexer) stateFn { - switch r := l.next(); { - case r == eof: - l.emitEOF() - return nil - case IsSpace(r): - l.ignore() - return root - case r == '\'' || r == '"': - l.scanString(r) - str, err := unescape(l.word()) - if err != nil { - l.error("%v", err) - } - l.emitValue(String, str) - case '0' <= r && r <= '9': - l.backup() - return number - case r == '?': - if l.peek() == '.' { - return nilsafe - } - l.emit(Operator) - case strings.ContainsRune("([{", r): - l.emit(Bracket) - case strings.ContainsRune(")]}", r): - l.emit(Bracket) - case strings.ContainsRune("#,?:%+-/", r): // single rune operator - l.emit(Operator) - case strings.ContainsRune("&|!=*<>", r): // possible double rune operator - l.accept("&|=*") - l.emit(Operator) - case r == '.': - l.backup() - return dot - case IsAlphaNumeric(r): - l.backup() - return identifier - default: - return l.error("unrecognized character: %#U", r) - } - return root -} - -func number(l *lexer) stateFn { - if !l.scanNumber() { - return l.error("bad number syntax: %q", l.word()) - } - l.emit(Number) - return root -} - -func (l *lexer) scanNumber() bool { - digits := "0123456789_" - // Is it hex? - if l.accept("0") { - // Note: Leading 0 does not mean octal in floats. - if l.accept("xX") { - digits = "0123456789abcdefABCDEF_" - } else if l.accept("oO") { - digits = "01234567_" - } else if l.accept("bB") { - digits = "01_" - } - } - l.acceptRun(digits) - loc, prev, end := l.loc, l.prev, l.end - if l.accept(".") { - // Lookup for .. operator: if after dot there is another dot (1..2), it maybe a range operator. - if l.peek() == '.' { - // We can't backup() here, as it would require two backups, - // and backup() func supports only one for now. So, save and - // restore it here. - l.loc, l.prev, l.end = loc, prev, end - return true - } - l.acceptRun(digits) - } - if l.accept("eE") { - l.accept("+-") - l.acceptRun(digits) - } - // Next thing mustn't be alphanumeric. - if IsAlphaNumeric(l.peek()) { - l.next() - return false - } - return true -} - -func dot(l *lexer) stateFn { - l.next() - if l.accept("0123456789") { - l.backup() - return number - } - l.accept(".") - l.emit(Operator) - return root -} - -func nilsafe(l *lexer) stateFn { - l.next() - l.accept("?.") - l.emit(Operator) - return root -} - -func identifier(l *lexer) stateFn { -loop: - for { - switch r := l.next(); { - case IsAlphaNumeric(r): - // absorb - default: - l.backup() - switch l.word() { - case "not": - return not - case "in", "or", "and", "matches", "contains", "startsWith", "endsWith": - l.emit(Operator) - default: - l.emit(Identifier) - } - break loop - } - } - return root -} - -func not(l *lexer) stateFn { - switch l.acceptWord("in") { - case true: - l.emitValue(Operator, "not in") - case false: - l.emitValue(Operator, "not") - } - - return root -} diff --git a/vendor/github.com/antonmedv/expr/parser/lexer/token.go b/vendor/github.com/antonmedv/expr/parser/lexer/token.go deleted file mode 100644 index 8917b26..0000000 --- a/vendor/github.com/antonmedv/expr/parser/lexer/token.go +++ /dev/null @@ -1,47 +0,0 @@ -package lexer - -import ( - "fmt" - - "github.com/antonmedv/expr/file" -) - -type Kind string - -const ( - Identifier Kind = "Identifier" - Number Kind = "Number" - String Kind = "String" - Operator Kind = "Operator" - Bracket Kind = "Bracket" - EOF Kind = "EOF" -) - -type Token struct { - file.Location - Kind Kind - Value string -} - -func (t Token) String() string { - if t.Value == "" { - return string(t.Kind) - } - return fmt.Sprintf("%s(%#v)", t.Kind, t.Value) -} - -func (t Token) Is(kind Kind, values ...string) bool { - if len(values) == 0 { - return kind == t.Kind - } - - for _, v := range values { - if v == t.Value { - goto found - } - } - return false - -found: - return kind == t.Kind -} diff --git a/vendor/github.com/antonmedv/expr/parser/lexer/utils.go b/vendor/github.com/antonmedv/expr/parser/lexer/utils.go deleted file mode 100644 index 72e3cf2..0000000 --- a/vendor/github.com/antonmedv/expr/parser/lexer/utils.go +++ /dev/null @@ -1,194 +0,0 @@ -package lexer - -import ( - "fmt" - "strings" - "unicode" - "unicode/utf8" -) - -func IsSpace(r rune) bool { - return unicode.IsSpace(r) -} - -func IsAlphaNumeric(r rune) bool { - return IsAlphabetic(r) || unicode.IsDigit(r) -} - -func IsAlphabetic(r rune) bool { - return r == '_' || r == '$' || unicode.IsLetter(r) -} - -var ( - newlineNormalizer = strings.NewReplacer("\r\n", "\n", "\r", "\n") -) - -// Unescape takes a quoted string, unquotes, and unescapes it. -func unescape(value string) (string, error) { - // All strings normalize newlines to the \n representation. - value = newlineNormalizer.Replace(value) - n := len(value) - - // Nothing to unescape / decode. - if n < 2 { - return value, fmt.Errorf("unable to unescape string") - } - - // Quoted string of some form, must have same first and last char. - if value[0] != value[n-1] || (value[0] != '"' && value[0] != '\'') { - return value, fmt.Errorf("unable to unescape string") - } - - value = value[1 : n-1] - - // The string contains escape characters. - // The following logic is adapted from `strconv/quote.go` - var runeTmp [utf8.UTFMax]byte - buf := make([]byte, 0, 3*n/2) - for len(value) > 0 { - c, multibyte, rest, err := unescapeChar(value) - if err != nil { - return "", err - } - value = rest - if c < utf8.RuneSelf || !multibyte { - buf = append(buf, byte(c)) - } else { - n := utf8.EncodeRune(runeTmp[:], c) - buf = append(buf, runeTmp[:n]...) - } - } - return string(buf), nil -} - -// unescapeChar takes a string input and returns the following info: -// -// value - the escaped unicode rune at the front of the string. -// multibyte - whether the rune value might require multiple bytes to represent. -// tail - the remainder of the input string. -// err - error value, if the character could not be unescaped. -// -// When multibyte is true the return value may still fit within a single byte, -// but a multibyte conversion is attempted which is more expensive than when the -// value is known to fit within one byte. -func unescapeChar(s string) (value rune, multibyte bool, tail string, err error) { - // 1. Character is not an escape sequence. - switch c := s[0]; { - case c >= utf8.RuneSelf: - r, size := utf8.DecodeRuneInString(s) - return r, true, s[size:], nil - case c != '\\': - return rune(s[0]), false, s[1:], nil - } - - // 2. Last character is the start of an escape sequence. - if len(s) <= 1 { - err = fmt.Errorf("unable to unescape string, found '\\' as last character") - return - } - - c := s[1] - s = s[2:] - // 3. Common escape sequences shared with Google SQL - switch c { - case 'a': - value = '\a' - case 'b': - value = '\b' - case 'f': - value = '\f' - case 'n': - value = '\n' - case 'r': - value = '\r' - case 't': - value = '\t' - case 'v': - value = '\v' - case '\\': - value = '\\' - case '\'': - value = '\'' - case '"': - value = '"' - case '`': - value = '`' - case '?': - value = '?' - - // 4. Unicode escape sequences, reproduced from `strconv/quote.go` - case 'x', 'X', 'u', 'U': - n := 0 - switch c { - case 'x', 'X': - n = 2 - case 'u': - n = 4 - case 'U': - n = 8 - } - var v rune - if len(s) < n { - err = fmt.Errorf("unable to unescape string") - return - } - for j := 0; j < n; j++ { - x, ok := unhex(s[j]) - if !ok { - err = fmt.Errorf("unable to unescape string") - return - } - v = v<<4 | x - } - s = s[n:] - if v > utf8.MaxRune { - err = fmt.Errorf("unable to unescape string") - return - } - value = v - multibyte = true - - // 5. Octal escape sequences, must be three digits \[0-3][0-7][0-7] - case '0', '1', '2', '3': - if len(s) < 2 { - err = fmt.Errorf("unable to unescape octal sequence in string") - return - } - v := rune(c - '0') - for j := 0; j < 2; j++ { - x := s[j] - if x < '0' || x > '7' { - err = fmt.Errorf("unable to unescape octal sequence in string") - return - } - v = v*8 + rune(x-'0') - } - if v > utf8.MaxRune { - err = fmt.Errorf("unable to unescape string") - return - } - value = v - s = s[2:] - multibyte = true - - // Unknown escape sequence. - default: - err = fmt.Errorf("unable to unescape string") - } - - tail = s - return -} - -func unhex(b byte) (rune, bool) { - c := rune(b) - switch { - case '0' <= c && c <= '9': - return c - '0', true - case 'a' <= c && c <= 'f': - return c - 'a' + 10, true - case 'A' <= c && c <= 'F': - return c - 'A' + 10, true - } - return 0, false -} diff --git a/vendor/github.com/antonmedv/expr/parser/parser.go b/vendor/github.com/antonmedv/expr/parser/parser.go deleted file mode 100644 index 821de9d..0000000 --- a/vendor/github.com/antonmedv/expr/parser/parser.go +++ /dev/null @@ -1,588 +0,0 @@ -package parser - -import ( - "fmt" - "regexp" - "strconv" - "strings" - "unicode/utf8" - - . "github.com/antonmedv/expr/ast" - "github.com/antonmedv/expr/file" - . "github.com/antonmedv/expr/parser/lexer" -) - -type associativity int - -const ( - left associativity = iota + 1 - right -) - -type operator struct { - precedence int - associativity associativity -} - -type builtin struct { - arity int -} - -var unaryOperators = map[string]operator{ - "not": {50, left}, - "!": {50, left}, - "-": {500, left}, - "+": {500, left}, -} - -var binaryOperators = map[string]operator{ - "or": {10, left}, - "||": {10, left}, - "and": {15, left}, - "&&": {15, left}, - "==": {20, left}, - "!=": {20, left}, - "<": {20, left}, - ">": {20, left}, - ">=": {20, left}, - "<=": {20, left}, - "not in": {20, left}, - "in": {20, left}, - "matches": {20, left}, - "contains": {20, left}, - "startsWith": {20, left}, - "endsWith": {20, left}, - "..": {25, left}, - "+": {30, left}, - "-": {30, left}, - "*": {60, left}, - "/": {60, left}, - "%": {60, left}, - "**": {70, right}, -} - -var builtins = map[string]builtin{ - "len": {1}, - "all": {2}, - "none": {2}, - "any": {2}, - "one": {2}, - "filter": {2}, - "map": {2}, - "count": {2}, -} - -type parser struct { - tokens []Token - current Token - pos int - err *file.Error - depth int // closure call depth -} - -type Tree struct { - Node Node - Source *file.Source -} - -func Parse(input string) (*Tree, error) { - source := file.NewSource(input) - - tokens, err := Lex(source) - if err != nil { - return nil, err - } - - p := &parser{ - tokens: tokens, - current: tokens[0], - } - - node := p.parseExpression(0) - - if !p.current.Is(EOF) { - p.error("unexpected token %v", p.current) - } - - if p.err != nil { - return nil, p.err.Bind(source) - } - - return &Tree{ - Node: node, - Source: source, - }, nil -} - -func (p *parser) error(format string, args ...interface{}) { - if p.err == nil { // show first error - p.err = &file.Error{ - Location: p.current.Location, - Message: fmt.Sprintf(format, args...), - } - } -} - -func (p *parser) next() { - p.pos++ - if p.pos >= len(p.tokens) { - p.error("unexpected end of expression") - return - } - p.current = p.tokens[p.pos] -} - -func (p *parser) expect(kind Kind, values ...string) { - if p.current.Is(kind, values...) { - p.next() - return - } - p.error("unexpected token %v", p.current) -} - -// parse functions - -func (p *parser) parseExpression(precedence int) Node { - nodeLeft := p.parsePrimary() - - token := p.current - for token.Is(Operator) && p.err == nil { - if op, ok := binaryOperators[token.Value]; ok { - if op.precedence >= precedence { - p.next() - - var nodeRight Node - if op.associativity == left { - nodeRight = p.parseExpression(op.precedence + 1) - } else { - nodeRight = p.parseExpression(op.precedence) - } - - if token.Is(Operator, "matches") { - var r *regexp.Regexp - var err error - - if s, ok := nodeRight.(*StringNode); ok { - r, err = regexp.Compile(s.Value) - if err != nil { - p.error("%v", err) - } - } - nodeLeft = &MatchesNode{ - Regexp: r, - Left: nodeLeft, - Right: nodeRight, - } - nodeLeft.SetLocation(token.Location) - } else { - nodeLeft = &BinaryNode{ - Operator: token.Value, - Left: nodeLeft, - Right: nodeRight, - } - nodeLeft.SetLocation(token.Location) - } - token = p.current - continue - } - } - break - } - - if precedence == 0 { - nodeLeft = p.parseConditionalExpression(nodeLeft) - } - - return nodeLeft -} - -func (p *parser) parsePrimary() Node { - token := p.current - - if token.Is(Operator) { - if op, ok := unaryOperators[token.Value]; ok { - p.next() - expr := p.parseExpression(op.precedence) - node := &UnaryNode{ - Operator: token.Value, - Node: expr, - } - node.SetLocation(token.Location) - return p.parsePostfixExpression(node) - } - } - - if token.Is(Bracket, "(") { - p.next() - expr := p.parseExpression(0) - p.expect(Bracket, ")") // "an opened parenthesis is not properly closed" - return p.parsePostfixExpression(expr) - } - - if p.depth > 0 { - if token.Is(Operator, "#") || token.Is(Operator, ".") { - if token.Is(Operator, "#") { - p.next() - } - node := &PointerNode{} - node.SetLocation(token.Location) - return p.parsePostfixExpression(node) - } - } else { - if token.Is(Operator, "#") || token.Is(Operator, ".") { - p.error("cannot use pointer accessor outside closure") - } - } - - return p.parsePrimaryExpression() -} - -func (p *parser) parseConditionalExpression(node Node) Node { - var expr1, expr2 Node - for p.current.Is(Operator, "?") && p.err == nil { - p.next() - - if !p.current.Is(Operator, ":") { - expr1 = p.parseExpression(0) - p.expect(Operator, ":") - expr2 = p.parseExpression(0) - } else { - p.next() - expr1 = node - expr2 = p.parseExpression(0) - } - - node = &ConditionalNode{ - Cond: node, - Exp1: expr1, - Exp2: expr2, - } - } - return node -} - -func (p *parser) parsePrimaryExpression() Node { - var node Node - token := p.current - - switch token.Kind { - - case Identifier: - p.next() - switch token.Value { - case "true": - node := &BoolNode{Value: true} - node.SetLocation(token.Location) - return node - case "false": - node := &BoolNode{Value: false} - node.SetLocation(token.Location) - return node - case "nil": - node := &NilNode{} - node.SetLocation(token.Location) - return node - default: - node = p.parseIdentifierExpression(token, p.current) - } - - case Number: - p.next() - value := strings.Replace(token.Value, "_", "", -1) - if strings.ContainsAny(value, ".eE") { - number, err := strconv.ParseFloat(value, 64) - if err != nil { - p.error("invalid float literal: %v", err) - } - node := &FloatNode{Value: number} - node.SetLocation(token.Location) - return node - } else if strings.Contains(value, "x") { - number, err := strconv.ParseInt(value, 0, 64) - if err != nil { - p.error("invalid hex literal: %v", err) - } - node := &IntegerNode{Value: int(number)} - node.SetLocation(token.Location) - return node - } else { - number, err := strconv.ParseInt(value, 10, 64) - if err != nil { - p.error("invalid integer literal: %v", err) - } - node := &IntegerNode{Value: int(number)} - node.SetLocation(token.Location) - return node - } - - case String: - p.next() - node := &StringNode{Value: token.Value} - node.SetLocation(token.Location) - return node - - default: - if token.Is(Bracket, "[") { - node = p.parseArrayExpression(token) - } else if token.Is(Bracket, "{") { - node = p.parseMapExpression(token) - } else { - p.error("unexpected token %v", token) - } - } - - return p.parsePostfixExpression(node) -} - -func (p *parser) parseIdentifierExpression(token, next Token) Node { - var node Node - if p.current.Is(Bracket, "(") { - var arguments []Node - - if b, ok := builtins[token.Value]; ok { - p.expect(Bracket, "(") - // TODO: Add builtins signatures. - if b.arity == 1 { - arguments = make([]Node, 1) - arguments[0] = p.parseExpression(0) - } else if b.arity == 2 { - arguments = make([]Node, 2) - arguments[0] = p.parseExpression(0) - p.expect(Operator, ",") - arguments[1] = p.parseClosure() - } - p.expect(Bracket, ")") - - node = &BuiltinNode{ - Name: token.Value, - Arguments: arguments, - } - node.SetLocation(token.Location) - } else { - arguments = p.parseArguments() - node = &FunctionNode{ - Name: token.Value, - Arguments: arguments, - } - node.SetLocation(token.Location) - } - } else { - var nilsafe bool - if next.Value == "?." { - nilsafe = true - } - node = &IdentifierNode{Value: token.Value, NilSafe: nilsafe} - node.SetLocation(token.Location) - } - return node -} - -func (p *parser) parseClosure() Node { - token := p.current - p.expect(Bracket, "{") - - p.depth++ - node := p.parseExpression(0) - p.depth-- - - p.expect(Bracket, "}") - closure := &ClosureNode{ - Node: node, - } - closure.SetLocation(token.Location) - return closure -} - -func (p *parser) parseArrayExpression(token Token) Node { - nodes := make([]Node, 0) - - p.expect(Bracket, "[") - for !p.current.Is(Bracket, "]") && p.err == nil { - if len(nodes) > 0 { - p.expect(Operator, ",") - if p.current.Is(Bracket, "]") { - goto end - } - } - node := p.parseExpression(0) - nodes = append(nodes, node) - } -end: - p.expect(Bracket, "]") - - node := &ArrayNode{Nodes: nodes} - node.SetLocation(token.Location) - return node -} - -func (p *parser) parseMapExpression(token Token) Node { - p.expect(Bracket, "{") - - nodes := make([]Node, 0) - for !p.current.Is(Bracket, "}") && p.err == nil { - if len(nodes) > 0 { - p.expect(Operator, ",") - if p.current.Is(Bracket, "}") { - goto end - } - if p.current.Is(Operator, ",") { - p.error("unexpected token %v", p.current) - } - } - - var key Node - // a map key can be: - // * a number - // * a string - // * a identifier, which is equivalent to a string - // * an expression, which must be enclosed in parentheses -- (1 + 2) - if p.current.Is(Number) || p.current.Is(String) || p.current.Is(Identifier) { - key = &StringNode{Value: p.current.Value} - key.SetLocation(token.Location) - p.next() - } else if p.current.Is(Bracket, "(") { - key = p.parseExpression(0) - } else { - p.error("a map key must be a quoted string, a number, a identifier, or an expression enclosed in parentheses (unexpected token %v)", p.current) - } - - p.expect(Operator, ":") - - node := p.parseExpression(0) - pair := &PairNode{Key: key, Value: node} - pair.SetLocation(token.Location) - nodes = append(nodes, pair) - } - -end: - p.expect(Bracket, "}") - - node := &MapNode{Pairs: nodes} - node.SetLocation(token.Location) - return node -} - -func (p *parser) parsePostfixExpression(node Node) Node { - token := p.current - var nilsafe bool - for (token.Is(Operator) || token.Is(Bracket)) && p.err == nil { - if token.Value == "." || token.Value == "?." { - if token.Value == "?." { - nilsafe = true - } - p.next() - - token = p.current - p.next() - - if token.Kind != Identifier && - // Operators like "not" and "matches" are valid methods or property names. - (token.Kind != Operator || !isValidIdentifier(token.Value)) { - p.error("expected name") - } - - if p.current.Is(Bracket, "(") { - arguments := p.parseArguments() - node = &MethodNode{ - Node: node, - Method: token.Value, - Arguments: arguments, - NilSafe: nilsafe, - } - node.SetLocation(token.Location) - } else { - node = &PropertyNode{ - Node: node, - Property: token.Value, - NilSafe: nilsafe, - } - node.SetLocation(token.Location) - } - - } else if token.Value == "[" { - p.next() - var from, to Node - - if p.current.Is(Operator, ":") { // slice without from [:1] - p.next() - - if !p.current.Is(Bracket, "]") { // slice without from and to [:] - to = p.parseExpression(0) - } - - node = &SliceNode{ - Node: node, - To: to, - } - node.SetLocation(token.Location) - p.expect(Bracket, "]") - - } else { - - from = p.parseExpression(0) - - if p.current.Is(Operator, ":") { - p.next() - - if !p.current.Is(Bracket, "]") { // slice without to [1:] - to = p.parseExpression(0) - } - - node = &SliceNode{ - Node: node, - From: from, - To: to, - } - node.SetLocation(token.Location) - p.expect(Bracket, "]") - - } else { - // Slice operator [:] was not found, it should by just index node. - - node = &IndexNode{ - Node: node, - Index: from, - } - node.SetLocation(token.Location) - p.expect(Bracket, "]") - } - } - } else { - break - } - - token = p.current - } - return node -} - -func isValidIdentifier(str string) bool { - if len(str) == 0 { - return false - } - h, w := utf8.DecodeRuneInString(str) - if !IsAlphabetic(h) { - return false - } - for _, r := range str[w:] { - if !IsAlphaNumeric(r) { - return false - } - } - return true -} - -func (p *parser) parseArguments() []Node { - p.expect(Bracket, "(") - nodes := make([]Node, 0) - for !p.current.Is(Bracket, ")") && p.err == nil { - if len(nodes) > 0 { - p.expect(Operator, ",") - } - node := p.parseExpression(0) - nodes = append(nodes, node) - } - p.expect(Bracket, ")") - - return nodes -} diff --git a/vendor/github.com/antonmedv/expr/vm/helpers.go b/vendor/github.com/antonmedv/expr/vm/helpers.go deleted file mode 100644 index 775b0e7..0000000 --- a/vendor/github.com/antonmedv/expr/vm/helpers.go +++ /dev/null @@ -1,3247 +0,0 @@ -// Code generated by vm/generate/main.go. DO NOT EDIT. - -package vm - -import ( - "fmt" - "reflect" -) - -func equal(a, b interface{}) interface{} { - switch x := a.(type) { - case uint: - switch y := b.(type) { - case uint: - return x == y - case uint8: - return uint8(x) == y - case uint16: - return uint16(x) == y - case uint32: - return uint32(x) == y - case uint64: - return uint64(x) == y - case int: - return int(x) == y - case int8: - return int8(x) == y - case int16: - return int16(x) == y - case int32: - return int32(x) == y - case int64: - return int64(x) == y - case float32: - return float32(x) == y - case float64: - return float64(x) == y - } - case uint8: - switch y := b.(type) { - case uint: - return x == uint8(y) - case uint8: - return x == y - case uint16: - return uint16(x) == y - case uint32: - return uint32(x) == y - case uint64: - return uint64(x) == y - case int: - return int(x) == y - case int8: - return int8(x) == y - case int16: - return int16(x) == y - case int32: - return int32(x) == y - case int64: - return int64(x) == y - case float32: - return float32(x) == y - case float64: - return float64(x) == y - } - case uint16: - switch y := b.(type) { - case uint: - return x == uint16(y) - case uint8: - return x == uint16(y) - case uint16: - return x == y - case uint32: - return uint32(x) == y - case uint64: - return uint64(x) == y - case int: - return int(x) == y - case int8: - return int8(x) == y - case int16: - return int16(x) == y - case int32: - return int32(x) == y - case int64: - return int64(x) == y - case float32: - return float32(x) == y - case float64: - return float64(x) == y - } - case uint32: - switch y := b.(type) { - case uint: - return x == uint32(y) - case uint8: - return x == uint32(y) - case uint16: - return x == uint32(y) - case uint32: - return x == y - case uint64: - return uint64(x) == y - case int: - return int(x) == y - case int8: - return int8(x) == y - case int16: - return int16(x) == y - case int32: - return int32(x) == y - case int64: - return int64(x) == y - case float32: - return float32(x) == y - case float64: - return float64(x) == y - } - case uint64: - switch y := b.(type) { - case uint: - return x == uint64(y) - case uint8: - return x == uint64(y) - case uint16: - return x == uint64(y) - case uint32: - return x == uint64(y) - case uint64: - return x == y - case int: - return int(x) == y - case int8: - return int8(x) == y - case int16: - return int16(x) == y - case int32: - return int32(x) == y - case int64: - return int64(x) == y - case float32: - return float32(x) == y - case float64: - return float64(x) == y - } - case int: - switch y := b.(type) { - case uint: - return x == int(y) - case uint8: - return x == int(y) - case uint16: - return x == int(y) - case uint32: - return x == int(y) - case uint64: - return x == int(y) - case int: - return x == y - case int8: - return int8(x) == y - case int16: - return int16(x) == y - case int32: - return int32(x) == y - case int64: - return int64(x) == y - case float32: - return float32(x) == y - case float64: - return float64(x) == y - } - case int8: - switch y := b.(type) { - case uint: - return x == int8(y) - case uint8: - return x == int8(y) - case uint16: - return x == int8(y) - case uint32: - return x == int8(y) - case uint64: - return x == int8(y) - case int: - return x == int8(y) - case int8: - return x == y - case int16: - return int16(x) == y - case int32: - return int32(x) == y - case int64: - return int64(x) == y - case float32: - return float32(x) == y - case float64: - return float64(x) == y - } - case int16: - switch y := b.(type) { - case uint: - return x == int16(y) - case uint8: - return x == int16(y) - case uint16: - return x == int16(y) - case uint32: - return x == int16(y) - case uint64: - return x == int16(y) - case int: - return x == int16(y) - case int8: - return x == int16(y) - case int16: - return x == y - case int32: - return int32(x) == y - case int64: - return int64(x) == y - case float32: - return float32(x) == y - case float64: - return float64(x) == y - } - case int32: - switch y := b.(type) { - case uint: - return x == int32(y) - case uint8: - return x == int32(y) - case uint16: - return x == int32(y) - case uint32: - return x == int32(y) - case uint64: - return x == int32(y) - case int: - return x == int32(y) - case int8: - return x == int32(y) - case int16: - return x == int32(y) - case int32: - return x == y - case int64: - return int64(x) == y - case float32: - return float32(x) == y - case float64: - return float64(x) == y - } - case int64: - switch y := b.(type) { - case uint: - return x == int64(y) - case uint8: - return x == int64(y) - case uint16: - return x == int64(y) - case uint32: - return x == int64(y) - case uint64: - return x == int64(y) - case int: - return x == int64(y) - case int8: - return x == int64(y) - case int16: - return x == int64(y) - case int32: - return x == int64(y) - case int64: - return x == y - case float32: - return float32(x) == y - case float64: - return float64(x) == y - } - case float32: - switch y := b.(type) { - case uint: - return x == float32(y) - case uint8: - return x == float32(y) - case uint16: - return x == float32(y) - case uint32: - return x == float32(y) - case uint64: - return x == float32(y) - case int: - return x == float32(y) - case int8: - return x == float32(y) - case int16: - return x == float32(y) - case int32: - return x == float32(y) - case int64: - return x == float32(y) - case float32: - return x == y - case float64: - return float64(x) == y - } - case float64: - switch y := b.(type) { - case uint: - return x == float64(y) - case uint8: - return x == float64(y) - case uint16: - return x == float64(y) - case uint32: - return x == float64(y) - case uint64: - return x == float64(y) - case int: - return x == float64(y) - case int8: - return x == float64(y) - case int16: - return x == float64(y) - case int32: - return x == float64(y) - case int64: - return x == float64(y) - case float32: - return x == float64(y) - case float64: - return x == y - } - case string: - switch y := b.(type) { - case string: - return x == y - } - } - if isNil(a) && isNil(b) { - return true - } - return reflect.DeepEqual(a, b) -} - -func less(a, b interface{}) interface{} { - switch x := a.(type) { - case uint: - switch y := b.(type) { - case uint: - return x < y - case uint8: - return uint8(x) < y - case uint16: - return uint16(x) < y - case uint32: - return uint32(x) < y - case uint64: - return uint64(x) < y - case int: - return int(x) < y - case int8: - return int8(x) < y - case int16: - return int16(x) < y - case int32: - return int32(x) < y - case int64: - return int64(x) < y - case float32: - return float32(x) < y - case float64: - return float64(x) < y - } - case uint8: - switch y := b.(type) { - case uint: - return x < uint8(y) - case uint8: - return x < y - case uint16: - return uint16(x) < y - case uint32: - return uint32(x) < y - case uint64: - return uint64(x) < y - case int: - return int(x) < y - case int8: - return int8(x) < y - case int16: - return int16(x) < y - case int32: - return int32(x) < y - case int64: - return int64(x) < y - case float32: - return float32(x) < y - case float64: - return float64(x) < y - } - case uint16: - switch y := b.(type) { - case uint: - return x < uint16(y) - case uint8: - return x < uint16(y) - case uint16: - return x < y - case uint32: - return uint32(x) < y - case uint64: - return uint64(x) < y - case int: - return int(x) < y - case int8: - return int8(x) < y - case int16: - return int16(x) < y - case int32: - return int32(x) < y - case int64: - return int64(x) < y - case float32: - return float32(x) < y - case float64: - return float64(x) < y - } - case uint32: - switch y := b.(type) { - case uint: - return x < uint32(y) - case uint8: - return x < uint32(y) - case uint16: - return x < uint32(y) - case uint32: - return x < y - case uint64: - return uint64(x) < y - case int: - return int(x) < y - case int8: - return int8(x) < y - case int16: - return int16(x) < y - case int32: - return int32(x) < y - case int64: - return int64(x) < y - case float32: - return float32(x) < y - case float64: - return float64(x) < y - } - case uint64: - switch y := b.(type) { - case uint: - return x < uint64(y) - case uint8: - return x < uint64(y) - case uint16: - return x < uint64(y) - case uint32: - return x < uint64(y) - case uint64: - return x < y - case int: - return int(x) < y - case int8: - return int8(x) < y - case int16: - return int16(x) < y - case int32: - return int32(x) < y - case int64: - return int64(x) < y - case float32: - return float32(x) < y - case float64: - return float64(x) < y - } - case int: - switch y := b.(type) { - case uint: - return x < int(y) - case uint8: - return x < int(y) - case uint16: - return x < int(y) - case uint32: - return x < int(y) - case uint64: - return x < int(y) - case int: - return x < y - case int8: - return int8(x) < y - case int16: - return int16(x) < y - case int32: - return int32(x) < y - case int64: - return int64(x) < y - case float32: - return float32(x) < y - case float64: - return float64(x) < y - } - case int8: - switch y := b.(type) { - case uint: - return x < int8(y) - case uint8: - return x < int8(y) - case uint16: - return x < int8(y) - case uint32: - return x < int8(y) - case uint64: - return x < int8(y) - case int: - return x < int8(y) - case int8: - return x < y - case int16: - return int16(x) < y - case int32: - return int32(x) < y - case int64: - return int64(x) < y - case float32: - return float32(x) < y - case float64: - return float64(x) < y - } - case int16: - switch y := b.(type) { - case uint: - return x < int16(y) - case uint8: - return x < int16(y) - case uint16: - return x < int16(y) - case uint32: - return x < int16(y) - case uint64: - return x < int16(y) - case int: - return x < int16(y) - case int8: - return x < int16(y) - case int16: - return x < y - case int32: - return int32(x) < y - case int64: - return int64(x) < y - case float32: - return float32(x) < y - case float64: - return float64(x) < y - } - case int32: - switch y := b.(type) { - case uint: - return x < int32(y) - case uint8: - return x < int32(y) - case uint16: - return x < int32(y) - case uint32: - return x < int32(y) - case uint64: - return x < int32(y) - case int: - return x < int32(y) - case int8: - return x < int32(y) - case int16: - return x < int32(y) - case int32: - return x < y - case int64: - return int64(x) < y - case float32: - return float32(x) < y - case float64: - return float64(x) < y - } - case int64: - switch y := b.(type) { - case uint: - return x < int64(y) - case uint8: - return x < int64(y) - case uint16: - return x < int64(y) - case uint32: - return x < int64(y) - case uint64: - return x < int64(y) - case int: - return x < int64(y) - case int8: - return x < int64(y) - case int16: - return x < int64(y) - case int32: - return x < int64(y) - case int64: - return x < y - case float32: - return float32(x) < y - case float64: - return float64(x) < y - } - case float32: - switch y := b.(type) { - case uint: - return x < float32(y) - case uint8: - return x < float32(y) - case uint16: - return x < float32(y) - case uint32: - return x < float32(y) - case uint64: - return x < float32(y) - case int: - return x < float32(y) - case int8: - return x < float32(y) - case int16: - return x < float32(y) - case int32: - return x < float32(y) - case int64: - return x < float32(y) - case float32: - return x < y - case float64: - return float64(x) < y - } - case float64: - switch y := b.(type) { - case uint: - return x < float64(y) - case uint8: - return x < float64(y) - case uint16: - return x < float64(y) - case uint32: - return x < float64(y) - case uint64: - return x < float64(y) - case int: - return x < float64(y) - case int8: - return x < float64(y) - case int16: - return x < float64(y) - case int32: - return x < float64(y) - case int64: - return x < float64(y) - case float32: - return x < float64(y) - case float64: - return x < y - } - case string: - switch y := b.(type) { - case string: - return x < y - } - } - panic(fmt.Sprintf("invalid operation: %T %v %T", a, "<", b)) -} - -func more(a, b interface{}) interface{} { - switch x := a.(type) { - case uint: - switch y := b.(type) { - case uint: - return x > y - case uint8: - return uint8(x) > y - case uint16: - return uint16(x) > y - case uint32: - return uint32(x) > y - case uint64: - return uint64(x) > y - case int: - return int(x) > y - case int8: - return int8(x) > y - case int16: - return int16(x) > y - case int32: - return int32(x) > y - case int64: - return int64(x) > y - case float32: - return float32(x) > y - case float64: - return float64(x) > y - } - case uint8: - switch y := b.(type) { - case uint: - return x > uint8(y) - case uint8: - return x > y - case uint16: - return uint16(x) > y - case uint32: - return uint32(x) > y - case uint64: - return uint64(x) > y - case int: - return int(x) > y - case int8: - return int8(x) > y - case int16: - return int16(x) > y - case int32: - return int32(x) > y - case int64: - return int64(x) > y - case float32: - return float32(x) > y - case float64: - return float64(x) > y - } - case uint16: - switch y := b.(type) { - case uint: - return x > uint16(y) - case uint8: - return x > uint16(y) - case uint16: - return x > y - case uint32: - return uint32(x) > y - case uint64: - return uint64(x) > y - case int: - return int(x) > y - case int8: - return int8(x) > y - case int16: - return int16(x) > y - case int32: - return int32(x) > y - case int64: - return int64(x) > y - case float32: - return float32(x) > y - case float64: - return float64(x) > y - } - case uint32: - switch y := b.(type) { - case uint: - return x > uint32(y) - case uint8: - return x > uint32(y) - case uint16: - return x > uint32(y) - case uint32: - return x > y - case uint64: - return uint64(x) > y - case int: - return int(x) > y - case int8: - return int8(x) > y - case int16: - return int16(x) > y - case int32: - return int32(x) > y - case int64: - return int64(x) > y - case float32: - return float32(x) > y - case float64: - return float64(x) > y - } - case uint64: - switch y := b.(type) { - case uint: - return x > uint64(y) - case uint8: - return x > uint64(y) - case uint16: - return x > uint64(y) - case uint32: - return x > uint64(y) - case uint64: - return x > y - case int: - return int(x) > y - case int8: - return int8(x) > y - case int16: - return int16(x) > y - case int32: - return int32(x) > y - case int64: - return int64(x) > y - case float32: - return float32(x) > y - case float64: - return float64(x) > y - } - case int: - switch y := b.(type) { - case uint: - return x > int(y) - case uint8: - return x > int(y) - case uint16: - return x > int(y) - case uint32: - return x > int(y) - case uint64: - return x > int(y) - case int: - return x > y - case int8: - return int8(x) > y - case int16: - return int16(x) > y - case int32: - return int32(x) > y - case int64: - return int64(x) > y - case float32: - return float32(x) > y - case float64: - return float64(x) > y - } - case int8: - switch y := b.(type) { - case uint: - return x > int8(y) - case uint8: - return x > int8(y) - case uint16: - return x > int8(y) - case uint32: - return x > int8(y) - case uint64: - return x > int8(y) - case int: - return x > int8(y) - case int8: - return x > y - case int16: - return int16(x) > y - case int32: - return int32(x) > y - case int64: - return int64(x) > y - case float32: - return float32(x) > y - case float64: - return float64(x) > y - } - case int16: - switch y := b.(type) { - case uint: - return x > int16(y) - case uint8: - return x > int16(y) - case uint16: - return x > int16(y) - case uint32: - return x > int16(y) - case uint64: - return x > int16(y) - case int: - return x > int16(y) - case int8: - return x > int16(y) - case int16: - return x > y - case int32: - return int32(x) > y - case int64: - return int64(x) > y - case float32: - return float32(x) > y - case float64: - return float64(x) > y - } - case int32: - switch y := b.(type) { - case uint: - return x > int32(y) - case uint8: - return x > int32(y) - case uint16: - return x > int32(y) - case uint32: - return x > int32(y) - case uint64: - return x > int32(y) - case int: - return x > int32(y) - case int8: - return x > int32(y) - case int16: - return x > int32(y) - case int32: - return x > y - case int64: - return int64(x) > y - case float32: - return float32(x) > y - case float64: - return float64(x) > y - } - case int64: - switch y := b.(type) { - case uint: - return x > int64(y) - case uint8: - return x > int64(y) - case uint16: - return x > int64(y) - case uint32: - return x > int64(y) - case uint64: - return x > int64(y) - case int: - return x > int64(y) - case int8: - return x > int64(y) - case int16: - return x > int64(y) - case int32: - return x > int64(y) - case int64: - return x > y - case float32: - return float32(x) > y - case float64: - return float64(x) > y - } - case float32: - switch y := b.(type) { - case uint: - return x > float32(y) - case uint8: - return x > float32(y) - case uint16: - return x > float32(y) - case uint32: - return x > float32(y) - case uint64: - return x > float32(y) - case int: - return x > float32(y) - case int8: - return x > float32(y) - case int16: - return x > float32(y) - case int32: - return x > float32(y) - case int64: - return x > float32(y) - case float32: - return x > y - case float64: - return float64(x) > y - } - case float64: - switch y := b.(type) { - case uint: - return x > float64(y) - case uint8: - return x > float64(y) - case uint16: - return x > float64(y) - case uint32: - return x > float64(y) - case uint64: - return x > float64(y) - case int: - return x > float64(y) - case int8: - return x > float64(y) - case int16: - return x > float64(y) - case int32: - return x > float64(y) - case int64: - return x > float64(y) - case float32: - return x > float64(y) - case float64: - return x > y - } - case string: - switch y := b.(type) { - case string: - return x > y - } - } - panic(fmt.Sprintf("invalid operation: %T %v %T", a, ">", b)) -} - -func lessOrEqual(a, b interface{}) interface{} { - switch x := a.(type) { - case uint: - switch y := b.(type) { - case uint: - return x <= y - case uint8: - return uint8(x) <= y - case uint16: - return uint16(x) <= y - case uint32: - return uint32(x) <= y - case uint64: - return uint64(x) <= y - case int: - return int(x) <= y - case int8: - return int8(x) <= y - case int16: - return int16(x) <= y - case int32: - return int32(x) <= y - case int64: - return int64(x) <= y - case float32: - return float32(x) <= y - case float64: - return float64(x) <= y - } - case uint8: - switch y := b.(type) { - case uint: - return x <= uint8(y) - case uint8: - return x <= y - case uint16: - return uint16(x) <= y - case uint32: - return uint32(x) <= y - case uint64: - return uint64(x) <= y - case int: - return int(x) <= y - case int8: - return int8(x) <= y - case int16: - return int16(x) <= y - case int32: - return int32(x) <= y - case int64: - return int64(x) <= y - case float32: - return float32(x) <= y - case float64: - return float64(x) <= y - } - case uint16: - switch y := b.(type) { - case uint: - return x <= uint16(y) - case uint8: - return x <= uint16(y) - case uint16: - return x <= y - case uint32: - return uint32(x) <= y - case uint64: - return uint64(x) <= y - case int: - return int(x) <= y - case int8: - return int8(x) <= y - case int16: - return int16(x) <= y - case int32: - return int32(x) <= y - case int64: - return int64(x) <= y - case float32: - return float32(x) <= y - case float64: - return float64(x) <= y - } - case uint32: - switch y := b.(type) { - case uint: - return x <= uint32(y) - case uint8: - return x <= uint32(y) - case uint16: - return x <= uint32(y) - case uint32: - return x <= y - case uint64: - return uint64(x) <= y - case int: - return int(x) <= y - case int8: - return int8(x) <= y - case int16: - return int16(x) <= y - case int32: - return int32(x) <= y - case int64: - return int64(x) <= y - case float32: - return float32(x) <= y - case float64: - return float64(x) <= y - } - case uint64: - switch y := b.(type) { - case uint: - return x <= uint64(y) - case uint8: - return x <= uint64(y) - case uint16: - return x <= uint64(y) - case uint32: - return x <= uint64(y) - case uint64: - return x <= y - case int: - return int(x) <= y - case int8: - return int8(x) <= y - case int16: - return int16(x) <= y - case int32: - return int32(x) <= y - case int64: - return int64(x) <= y - case float32: - return float32(x) <= y - case float64: - return float64(x) <= y - } - case int: - switch y := b.(type) { - case uint: - return x <= int(y) - case uint8: - return x <= int(y) - case uint16: - return x <= int(y) - case uint32: - return x <= int(y) - case uint64: - return x <= int(y) - case int: - return x <= y - case int8: - return int8(x) <= y - case int16: - return int16(x) <= y - case int32: - return int32(x) <= y - case int64: - return int64(x) <= y - case float32: - return float32(x) <= y - case float64: - return float64(x) <= y - } - case int8: - switch y := b.(type) { - case uint: - return x <= int8(y) - case uint8: - return x <= int8(y) - case uint16: - return x <= int8(y) - case uint32: - return x <= int8(y) - case uint64: - return x <= int8(y) - case int: - return x <= int8(y) - case int8: - return x <= y - case int16: - return int16(x) <= y - case int32: - return int32(x) <= y - case int64: - return int64(x) <= y - case float32: - return float32(x) <= y - case float64: - return float64(x) <= y - } - case int16: - switch y := b.(type) { - case uint: - return x <= int16(y) - case uint8: - return x <= int16(y) - case uint16: - return x <= int16(y) - case uint32: - return x <= int16(y) - case uint64: - return x <= int16(y) - case int: - return x <= int16(y) - case int8: - return x <= int16(y) - case int16: - return x <= y - case int32: - return int32(x) <= y - case int64: - return int64(x) <= y - case float32: - return float32(x) <= y - case float64: - return float64(x) <= y - } - case int32: - switch y := b.(type) { - case uint: - return x <= int32(y) - case uint8: - return x <= int32(y) - case uint16: - return x <= int32(y) - case uint32: - return x <= int32(y) - case uint64: - return x <= int32(y) - case int: - return x <= int32(y) - case int8: - return x <= int32(y) - case int16: - return x <= int32(y) - case int32: - return x <= y - case int64: - return int64(x) <= y - case float32: - return float32(x) <= y - case float64: - return float64(x) <= y - } - case int64: - switch y := b.(type) { - case uint: - return x <= int64(y) - case uint8: - return x <= int64(y) - case uint16: - return x <= int64(y) - case uint32: - return x <= int64(y) - case uint64: - return x <= int64(y) - case int: - return x <= int64(y) - case int8: - return x <= int64(y) - case int16: - return x <= int64(y) - case int32: - return x <= int64(y) - case int64: - return x <= y - case float32: - return float32(x) <= y - case float64: - return float64(x) <= y - } - case float32: - switch y := b.(type) { - case uint: - return x <= float32(y) - case uint8: - return x <= float32(y) - case uint16: - return x <= float32(y) - case uint32: - return x <= float32(y) - case uint64: - return x <= float32(y) - case int: - return x <= float32(y) - case int8: - return x <= float32(y) - case int16: - return x <= float32(y) - case int32: - return x <= float32(y) - case int64: - return x <= float32(y) - case float32: - return x <= y - case float64: - return float64(x) <= y - } - case float64: - switch y := b.(type) { - case uint: - return x <= float64(y) - case uint8: - return x <= float64(y) - case uint16: - return x <= float64(y) - case uint32: - return x <= float64(y) - case uint64: - return x <= float64(y) - case int: - return x <= float64(y) - case int8: - return x <= float64(y) - case int16: - return x <= float64(y) - case int32: - return x <= float64(y) - case int64: - return x <= float64(y) - case float32: - return x <= float64(y) - case float64: - return x <= y - } - case string: - switch y := b.(type) { - case string: - return x <= y - } - } - panic(fmt.Sprintf("invalid operation: %T %v %T", a, "<=", b)) -} - -func moreOrEqual(a, b interface{}) interface{} { - switch x := a.(type) { - case uint: - switch y := b.(type) { - case uint: - return x >= y - case uint8: - return uint8(x) >= y - case uint16: - return uint16(x) >= y - case uint32: - return uint32(x) >= y - case uint64: - return uint64(x) >= y - case int: - return int(x) >= y - case int8: - return int8(x) >= y - case int16: - return int16(x) >= y - case int32: - return int32(x) >= y - case int64: - return int64(x) >= y - case float32: - return float32(x) >= y - case float64: - return float64(x) >= y - } - case uint8: - switch y := b.(type) { - case uint: - return x >= uint8(y) - case uint8: - return x >= y - case uint16: - return uint16(x) >= y - case uint32: - return uint32(x) >= y - case uint64: - return uint64(x) >= y - case int: - return int(x) >= y - case int8: - return int8(x) >= y - case int16: - return int16(x) >= y - case int32: - return int32(x) >= y - case int64: - return int64(x) >= y - case float32: - return float32(x) >= y - case float64: - return float64(x) >= y - } - case uint16: - switch y := b.(type) { - case uint: - return x >= uint16(y) - case uint8: - return x >= uint16(y) - case uint16: - return x >= y - case uint32: - return uint32(x) >= y - case uint64: - return uint64(x) >= y - case int: - return int(x) >= y - case int8: - return int8(x) >= y - case int16: - return int16(x) >= y - case int32: - return int32(x) >= y - case int64: - return int64(x) >= y - case float32: - return float32(x) >= y - case float64: - return float64(x) >= y - } - case uint32: - switch y := b.(type) { - case uint: - return x >= uint32(y) - case uint8: - return x >= uint32(y) - case uint16: - return x >= uint32(y) - case uint32: - return x >= y - case uint64: - return uint64(x) >= y - case int: - return int(x) >= y - case int8: - return int8(x) >= y - case int16: - return int16(x) >= y - case int32: - return int32(x) >= y - case int64: - return int64(x) >= y - case float32: - return float32(x) >= y - case float64: - return float64(x) >= y - } - case uint64: - switch y := b.(type) { - case uint: - return x >= uint64(y) - case uint8: - return x >= uint64(y) - case uint16: - return x >= uint64(y) - case uint32: - return x >= uint64(y) - case uint64: - return x >= y - case int: - return int(x) >= y - case int8: - return int8(x) >= y - case int16: - return int16(x) >= y - case int32: - return int32(x) >= y - case int64: - return int64(x) >= y - case float32: - return float32(x) >= y - case float64: - return float64(x) >= y - } - case int: - switch y := b.(type) { - case uint: - return x >= int(y) - case uint8: - return x >= int(y) - case uint16: - return x >= int(y) - case uint32: - return x >= int(y) - case uint64: - return x >= int(y) - case int: - return x >= y - case int8: - return int8(x) >= y - case int16: - return int16(x) >= y - case int32: - return int32(x) >= y - case int64: - return int64(x) >= y - case float32: - return float32(x) >= y - case float64: - return float64(x) >= y - } - case int8: - switch y := b.(type) { - case uint: - return x >= int8(y) - case uint8: - return x >= int8(y) - case uint16: - return x >= int8(y) - case uint32: - return x >= int8(y) - case uint64: - return x >= int8(y) - case int: - return x >= int8(y) - case int8: - return x >= y - case int16: - return int16(x) >= y - case int32: - return int32(x) >= y - case int64: - return int64(x) >= y - case float32: - return float32(x) >= y - case float64: - return float64(x) >= y - } - case int16: - switch y := b.(type) { - case uint: - return x >= int16(y) - case uint8: - return x >= int16(y) - case uint16: - return x >= int16(y) - case uint32: - return x >= int16(y) - case uint64: - return x >= int16(y) - case int: - return x >= int16(y) - case int8: - return x >= int16(y) - case int16: - return x >= y - case int32: - return int32(x) >= y - case int64: - return int64(x) >= y - case float32: - return float32(x) >= y - case float64: - return float64(x) >= y - } - case int32: - switch y := b.(type) { - case uint: - return x >= int32(y) - case uint8: - return x >= int32(y) - case uint16: - return x >= int32(y) - case uint32: - return x >= int32(y) - case uint64: - return x >= int32(y) - case int: - return x >= int32(y) - case int8: - return x >= int32(y) - case int16: - return x >= int32(y) - case int32: - return x >= y - case int64: - return int64(x) >= y - case float32: - return float32(x) >= y - case float64: - return float64(x) >= y - } - case int64: - switch y := b.(type) { - case uint: - return x >= int64(y) - case uint8: - return x >= int64(y) - case uint16: - return x >= int64(y) - case uint32: - return x >= int64(y) - case uint64: - return x >= int64(y) - case int: - return x >= int64(y) - case int8: - return x >= int64(y) - case int16: - return x >= int64(y) - case int32: - return x >= int64(y) - case int64: - return x >= y - case float32: - return float32(x) >= y - case float64: - return float64(x) >= y - } - case float32: - switch y := b.(type) { - case uint: - return x >= float32(y) - case uint8: - return x >= float32(y) - case uint16: - return x >= float32(y) - case uint32: - return x >= float32(y) - case uint64: - return x >= float32(y) - case int: - return x >= float32(y) - case int8: - return x >= float32(y) - case int16: - return x >= float32(y) - case int32: - return x >= float32(y) - case int64: - return x >= float32(y) - case float32: - return x >= y - case float64: - return float64(x) >= y - } - case float64: - switch y := b.(type) { - case uint: - return x >= float64(y) - case uint8: - return x >= float64(y) - case uint16: - return x >= float64(y) - case uint32: - return x >= float64(y) - case uint64: - return x >= float64(y) - case int: - return x >= float64(y) - case int8: - return x >= float64(y) - case int16: - return x >= float64(y) - case int32: - return x >= float64(y) - case int64: - return x >= float64(y) - case float32: - return x >= float64(y) - case float64: - return x >= y - } - case string: - switch y := b.(type) { - case string: - return x >= y - } - } - panic(fmt.Sprintf("invalid operation: %T %v %T", a, ">=", b)) -} - -func add(a, b interface{}) interface{} { - switch x := a.(type) { - case uint: - switch y := b.(type) { - case uint: - return x + y - case uint8: - return uint8(x) + y - case uint16: - return uint16(x) + y - case uint32: - return uint32(x) + y - case uint64: - return uint64(x) + y - case int: - return int(x) + y - case int8: - return int8(x) + y - case int16: - return int16(x) + y - case int32: - return int32(x) + y - case int64: - return int64(x) + y - case float32: - return float32(x) + y - case float64: - return float64(x) + y - } - case uint8: - switch y := b.(type) { - case uint: - return x + uint8(y) - case uint8: - return x + y - case uint16: - return uint16(x) + y - case uint32: - return uint32(x) + y - case uint64: - return uint64(x) + y - case int: - return int(x) + y - case int8: - return int8(x) + y - case int16: - return int16(x) + y - case int32: - return int32(x) + y - case int64: - return int64(x) + y - case float32: - return float32(x) + y - case float64: - return float64(x) + y - } - case uint16: - switch y := b.(type) { - case uint: - return x + uint16(y) - case uint8: - return x + uint16(y) - case uint16: - return x + y - case uint32: - return uint32(x) + y - case uint64: - return uint64(x) + y - case int: - return int(x) + y - case int8: - return int8(x) + y - case int16: - return int16(x) + y - case int32: - return int32(x) + y - case int64: - return int64(x) + y - case float32: - return float32(x) + y - case float64: - return float64(x) + y - } - case uint32: - switch y := b.(type) { - case uint: - return x + uint32(y) - case uint8: - return x + uint32(y) - case uint16: - return x + uint32(y) - case uint32: - return x + y - case uint64: - return uint64(x) + y - case int: - return int(x) + y - case int8: - return int8(x) + y - case int16: - return int16(x) + y - case int32: - return int32(x) + y - case int64: - return int64(x) + y - case float32: - return float32(x) + y - case float64: - return float64(x) + y - } - case uint64: - switch y := b.(type) { - case uint: - return x + uint64(y) - case uint8: - return x + uint64(y) - case uint16: - return x + uint64(y) - case uint32: - return x + uint64(y) - case uint64: - return x + y - case int: - return int(x) + y - case int8: - return int8(x) + y - case int16: - return int16(x) + y - case int32: - return int32(x) + y - case int64: - return int64(x) + y - case float32: - return float32(x) + y - case float64: - return float64(x) + y - } - case int: - switch y := b.(type) { - case uint: - return x + int(y) - case uint8: - return x + int(y) - case uint16: - return x + int(y) - case uint32: - return x + int(y) - case uint64: - return x + int(y) - case int: - return x + y - case int8: - return int8(x) + y - case int16: - return int16(x) + y - case int32: - return int32(x) + y - case int64: - return int64(x) + y - case float32: - return float32(x) + y - case float64: - return float64(x) + y - } - case int8: - switch y := b.(type) { - case uint: - return x + int8(y) - case uint8: - return x + int8(y) - case uint16: - return x + int8(y) - case uint32: - return x + int8(y) - case uint64: - return x + int8(y) - case int: - return x + int8(y) - case int8: - return x + y - case int16: - return int16(x) + y - case int32: - return int32(x) + y - case int64: - return int64(x) + y - case float32: - return float32(x) + y - case float64: - return float64(x) + y - } - case int16: - switch y := b.(type) { - case uint: - return x + int16(y) - case uint8: - return x + int16(y) - case uint16: - return x + int16(y) - case uint32: - return x + int16(y) - case uint64: - return x + int16(y) - case int: - return x + int16(y) - case int8: - return x + int16(y) - case int16: - return x + y - case int32: - return int32(x) + y - case int64: - return int64(x) + y - case float32: - return float32(x) + y - case float64: - return float64(x) + y - } - case int32: - switch y := b.(type) { - case uint: - return x + int32(y) - case uint8: - return x + int32(y) - case uint16: - return x + int32(y) - case uint32: - return x + int32(y) - case uint64: - return x + int32(y) - case int: - return x + int32(y) - case int8: - return x + int32(y) - case int16: - return x + int32(y) - case int32: - return x + y - case int64: - return int64(x) + y - case float32: - return float32(x) + y - case float64: - return float64(x) + y - } - case int64: - switch y := b.(type) { - case uint: - return x + int64(y) - case uint8: - return x + int64(y) - case uint16: - return x + int64(y) - case uint32: - return x + int64(y) - case uint64: - return x + int64(y) - case int: - return x + int64(y) - case int8: - return x + int64(y) - case int16: - return x + int64(y) - case int32: - return x + int64(y) - case int64: - return x + y - case float32: - return float32(x) + y - case float64: - return float64(x) + y - } - case float32: - switch y := b.(type) { - case uint: - return x + float32(y) - case uint8: - return x + float32(y) - case uint16: - return x + float32(y) - case uint32: - return x + float32(y) - case uint64: - return x + float32(y) - case int: - return x + float32(y) - case int8: - return x + float32(y) - case int16: - return x + float32(y) - case int32: - return x + float32(y) - case int64: - return x + float32(y) - case float32: - return x + y - case float64: - return float64(x) + y - } - case float64: - switch y := b.(type) { - case uint: - return x + float64(y) - case uint8: - return x + float64(y) - case uint16: - return x + float64(y) - case uint32: - return x + float64(y) - case uint64: - return x + float64(y) - case int: - return x + float64(y) - case int8: - return x + float64(y) - case int16: - return x + float64(y) - case int32: - return x + float64(y) - case int64: - return x + float64(y) - case float32: - return x + float64(y) - case float64: - return x + y - } - case string: - switch y := b.(type) { - case string: - return x + y - } - } - panic(fmt.Sprintf("invalid operation: %T %v %T", a, "+", b)) -} - -func subtract(a, b interface{}) interface{} { - switch x := a.(type) { - case uint: - switch y := b.(type) { - case uint: - return x - y - case uint8: - return uint8(x) - y - case uint16: - return uint16(x) - y - case uint32: - return uint32(x) - y - case uint64: - return uint64(x) - y - case int: - return int(x) - y - case int8: - return int8(x) - y - case int16: - return int16(x) - y - case int32: - return int32(x) - y - case int64: - return int64(x) - y - case float32: - return float32(x) - y - case float64: - return float64(x) - y - } - case uint8: - switch y := b.(type) { - case uint: - return x - uint8(y) - case uint8: - return x - y - case uint16: - return uint16(x) - y - case uint32: - return uint32(x) - y - case uint64: - return uint64(x) - y - case int: - return int(x) - y - case int8: - return int8(x) - y - case int16: - return int16(x) - y - case int32: - return int32(x) - y - case int64: - return int64(x) - y - case float32: - return float32(x) - y - case float64: - return float64(x) - y - } - case uint16: - switch y := b.(type) { - case uint: - return x - uint16(y) - case uint8: - return x - uint16(y) - case uint16: - return x - y - case uint32: - return uint32(x) - y - case uint64: - return uint64(x) - y - case int: - return int(x) - y - case int8: - return int8(x) - y - case int16: - return int16(x) - y - case int32: - return int32(x) - y - case int64: - return int64(x) - y - case float32: - return float32(x) - y - case float64: - return float64(x) - y - } - case uint32: - switch y := b.(type) { - case uint: - return x - uint32(y) - case uint8: - return x - uint32(y) - case uint16: - return x - uint32(y) - case uint32: - return x - y - case uint64: - return uint64(x) - y - case int: - return int(x) - y - case int8: - return int8(x) - y - case int16: - return int16(x) - y - case int32: - return int32(x) - y - case int64: - return int64(x) - y - case float32: - return float32(x) - y - case float64: - return float64(x) - y - } - case uint64: - switch y := b.(type) { - case uint: - return x - uint64(y) - case uint8: - return x - uint64(y) - case uint16: - return x - uint64(y) - case uint32: - return x - uint64(y) - case uint64: - return x - y - case int: - return int(x) - y - case int8: - return int8(x) - y - case int16: - return int16(x) - y - case int32: - return int32(x) - y - case int64: - return int64(x) - y - case float32: - return float32(x) - y - case float64: - return float64(x) - y - } - case int: - switch y := b.(type) { - case uint: - return x - int(y) - case uint8: - return x - int(y) - case uint16: - return x - int(y) - case uint32: - return x - int(y) - case uint64: - return x - int(y) - case int: - return x - y - case int8: - return int8(x) - y - case int16: - return int16(x) - y - case int32: - return int32(x) - y - case int64: - return int64(x) - y - case float32: - return float32(x) - y - case float64: - return float64(x) - y - } - case int8: - switch y := b.(type) { - case uint: - return x - int8(y) - case uint8: - return x - int8(y) - case uint16: - return x - int8(y) - case uint32: - return x - int8(y) - case uint64: - return x - int8(y) - case int: - return x - int8(y) - case int8: - return x - y - case int16: - return int16(x) - y - case int32: - return int32(x) - y - case int64: - return int64(x) - y - case float32: - return float32(x) - y - case float64: - return float64(x) - y - } - case int16: - switch y := b.(type) { - case uint: - return x - int16(y) - case uint8: - return x - int16(y) - case uint16: - return x - int16(y) - case uint32: - return x - int16(y) - case uint64: - return x - int16(y) - case int: - return x - int16(y) - case int8: - return x - int16(y) - case int16: - return x - y - case int32: - return int32(x) - y - case int64: - return int64(x) - y - case float32: - return float32(x) - y - case float64: - return float64(x) - y - } - case int32: - switch y := b.(type) { - case uint: - return x - int32(y) - case uint8: - return x - int32(y) - case uint16: - return x - int32(y) - case uint32: - return x - int32(y) - case uint64: - return x - int32(y) - case int: - return x - int32(y) - case int8: - return x - int32(y) - case int16: - return x - int32(y) - case int32: - return x - y - case int64: - return int64(x) - y - case float32: - return float32(x) - y - case float64: - return float64(x) - y - } - case int64: - switch y := b.(type) { - case uint: - return x - int64(y) - case uint8: - return x - int64(y) - case uint16: - return x - int64(y) - case uint32: - return x - int64(y) - case uint64: - return x - int64(y) - case int: - return x - int64(y) - case int8: - return x - int64(y) - case int16: - return x - int64(y) - case int32: - return x - int64(y) - case int64: - return x - y - case float32: - return float32(x) - y - case float64: - return float64(x) - y - } - case float32: - switch y := b.(type) { - case uint: - return x - float32(y) - case uint8: - return x - float32(y) - case uint16: - return x - float32(y) - case uint32: - return x - float32(y) - case uint64: - return x - float32(y) - case int: - return x - float32(y) - case int8: - return x - float32(y) - case int16: - return x - float32(y) - case int32: - return x - float32(y) - case int64: - return x - float32(y) - case float32: - return x - y - case float64: - return float64(x) - y - } - case float64: - switch y := b.(type) { - case uint: - return x - float64(y) - case uint8: - return x - float64(y) - case uint16: - return x - float64(y) - case uint32: - return x - float64(y) - case uint64: - return x - float64(y) - case int: - return x - float64(y) - case int8: - return x - float64(y) - case int16: - return x - float64(y) - case int32: - return x - float64(y) - case int64: - return x - float64(y) - case float32: - return x - float64(y) - case float64: - return x - y - } - } - panic(fmt.Sprintf("invalid operation: %T %v %T", a, "-", b)) -} - -func multiply(a, b interface{}) interface{} { - switch x := a.(type) { - case uint: - switch y := b.(type) { - case uint: - return x * y - case uint8: - return uint8(x) * y - case uint16: - return uint16(x) * y - case uint32: - return uint32(x) * y - case uint64: - return uint64(x) * y - case int: - return int(x) * y - case int8: - return int8(x) * y - case int16: - return int16(x) * y - case int32: - return int32(x) * y - case int64: - return int64(x) * y - case float32: - return float32(x) * y - case float64: - return float64(x) * y - } - case uint8: - switch y := b.(type) { - case uint: - return x * uint8(y) - case uint8: - return x * y - case uint16: - return uint16(x) * y - case uint32: - return uint32(x) * y - case uint64: - return uint64(x) * y - case int: - return int(x) * y - case int8: - return int8(x) * y - case int16: - return int16(x) * y - case int32: - return int32(x) * y - case int64: - return int64(x) * y - case float32: - return float32(x) * y - case float64: - return float64(x) * y - } - case uint16: - switch y := b.(type) { - case uint: - return x * uint16(y) - case uint8: - return x * uint16(y) - case uint16: - return x * y - case uint32: - return uint32(x) * y - case uint64: - return uint64(x) * y - case int: - return int(x) * y - case int8: - return int8(x) * y - case int16: - return int16(x) * y - case int32: - return int32(x) * y - case int64: - return int64(x) * y - case float32: - return float32(x) * y - case float64: - return float64(x) * y - } - case uint32: - switch y := b.(type) { - case uint: - return x * uint32(y) - case uint8: - return x * uint32(y) - case uint16: - return x * uint32(y) - case uint32: - return x * y - case uint64: - return uint64(x) * y - case int: - return int(x) * y - case int8: - return int8(x) * y - case int16: - return int16(x) * y - case int32: - return int32(x) * y - case int64: - return int64(x) * y - case float32: - return float32(x) * y - case float64: - return float64(x) * y - } - case uint64: - switch y := b.(type) { - case uint: - return x * uint64(y) - case uint8: - return x * uint64(y) - case uint16: - return x * uint64(y) - case uint32: - return x * uint64(y) - case uint64: - return x * y - case int: - return int(x) * y - case int8: - return int8(x) * y - case int16: - return int16(x) * y - case int32: - return int32(x) * y - case int64: - return int64(x) * y - case float32: - return float32(x) * y - case float64: - return float64(x) * y - } - case int: - switch y := b.(type) { - case uint: - return x * int(y) - case uint8: - return x * int(y) - case uint16: - return x * int(y) - case uint32: - return x * int(y) - case uint64: - return x * int(y) - case int: - return x * y - case int8: - return int8(x) * y - case int16: - return int16(x) * y - case int32: - return int32(x) * y - case int64: - return int64(x) * y - case float32: - return float32(x) * y - case float64: - return float64(x) * y - } - case int8: - switch y := b.(type) { - case uint: - return x * int8(y) - case uint8: - return x * int8(y) - case uint16: - return x * int8(y) - case uint32: - return x * int8(y) - case uint64: - return x * int8(y) - case int: - return x * int8(y) - case int8: - return x * y - case int16: - return int16(x) * y - case int32: - return int32(x) * y - case int64: - return int64(x) * y - case float32: - return float32(x) * y - case float64: - return float64(x) * y - } - case int16: - switch y := b.(type) { - case uint: - return x * int16(y) - case uint8: - return x * int16(y) - case uint16: - return x * int16(y) - case uint32: - return x * int16(y) - case uint64: - return x * int16(y) - case int: - return x * int16(y) - case int8: - return x * int16(y) - case int16: - return x * y - case int32: - return int32(x) * y - case int64: - return int64(x) * y - case float32: - return float32(x) * y - case float64: - return float64(x) * y - } - case int32: - switch y := b.(type) { - case uint: - return x * int32(y) - case uint8: - return x * int32(y) - case uint16: - return x * int32(y) - case uint32: - return x * int32(y) - case uint64: - return x * int32(y) - case int: - return x * int32(y) - case int8: - return x * int32(y) - case int16: - return x * int32(y) - case int32: - return x * y - case int64: - return int64(x) * y - case float32: - return float32(x) * y - case float64: - return float64(x) * y - } - case int64: - switch y := b.(type) { - case uint: - return x * int64(y) - case uint8: - return x * int64(y) - case uint16: - return x * int64(y) - case uint32: - return x * int64(y) - case uint64: - return x * int64(y) - case int: - return x * int64(y) - case int8: - return x * int64(y) - case int16: - return x * int64(y) - case int32: - return x * int64(y) - case int64: - return x * y - case float32: - return float32(x) * y - case float64: - return float64(x) * y - } - case float32: - switch y := b.(type) { - case uint: - return x * float32(y) - case uint8: - return x * float32(y) - case uint16: - return x * float32(y) - case uint32: - return x * float32(y) - case uint64: - return x * float32(y) - case int: - return x * float32(y) - case int8: - return x * float32(y) - case int16: - return x * float32(y) - case int32: - return x * float32(y) - case int64: - return x * float32(y) - case float32: - return x * y - case float64: - return float64(x) * y - } - case float64: - switch y := b.(type) { - case uint: - return x * float64(y) - case uint8: - return x * float64(y) - case uint16: - return x * float64(y) - case uint32: - return x * float64(y) - case uint64: - return x * float64(y) - case int: - return x * float64(y) - case int8: - return x * float64(y) - case int16: - return x * float64(y) - case int32: - return x * float64(y) - case int64: - return x * float64(y) - case float32: - return x * float64(y) - case float64: - return x * y - } - } - panic(fmt.Sprintf("invalid operation: %T %v %T", a, "*", b)) -} - -func divide(a, b interface{}) interface{} { - switch x := a.(type) { - case uint: - switch y := b.(type) { - case uint: - return x / y - case uint8: - return uint8(x) / y - case uint16: - return uint16(x) / y - case uint32: - return uint32(x) / y - case uint64: - return uint64(x) / y - case int: - return int(x) / y - case int8: - return int8(x) / y - case int16: - return int16(x) / y - case int32: - return int32(x) / y - case int64: - return int64(x) / y - case float32: - return float32(x) / y - case float64: - return float64(x) / y - } - case uint8: - switch y := b.(type) { - case uint: - return x / uint8(y) - case uint8: - return x / y - case uint16: - return uint16(x) / y - case uint32: - return uint32(x) / y - case uint64: - return uint64(x) / y - case int: - return int(x) / y - case int8: - return int8(x) / y - case int16: - return int16(x) / y - case int32: - return int32(x) / y - case int64: - return int64(x) / y - case float32: - return float32(x) / y - case float64: - return float64(x) / y - } - case uint16: - switch y := b.(type) { - case uint: - return x / uint16(y) - case uint8: - return x / uint16(y) - case uint16: - return x / y - case uint32: - return uint32(x) / y - case uint64: - return uint64(x) / y - case int: - return int(x) / y - case int8: - return int8(x) / y - case int16: - return int16(x) / y - case int32: - return int32(x) / y - case int64: - return int64(x) / y - case float32: - return float32(x) / y - case float64: - return float64(x) / y - } - case uint32: - switch y := b.(type) { - case uint: - return x / uint32(y) - case uint8: - return x / uint32(y) - case uint16: - return x / uint32(y) - case uint32: - return x / y - case uint64: - return uint64(x) / y - case int: - return int(x) / y - case int8: - return int8(x) / y - case int16: - return int16(x) / y - case int32: - return int32(x) / y - case int64: - return int64(x) / y - case float32: - return float32(x) / y - case float64: - return float64(x) / y - } - case uint64: - switch y := b.(type) { - case uint: - return x / uint64(y) - case uint8: - return x / uint64(y) - case uint16: - return x / uint64(y) - case uint32: - return x / uint64(y) - case uint64: - return x / y - case int: - return int(x) / y - case int8: - return int8(x) / y - case int16: - return int16(x) / y - case int32: - return int32(x) / y - case int64: - return int64(x) / y - case float32: - return float32(x) / y - case float64: - return float64(x) / y - } - case int: - switch y := b.(type) { - case uint: - return x / int(y) - case uint8: - return x / int(y) - case uint16: - return x / int(y) - case uint32: - return x / int(y) - case uint64: - return x / int(y) - case int: - return x / y - case int8: - return int8(x) / y - case int16: - return int16(x) / y - case int32: - return int32(x) / y - case int64: - return int64(x) / y - case float32: - return float32(x) / y - case float64: - return float64(x) / y - } - case int8: - switch y := b.(type) { - case uint: - return x / int8(y) - case uint8: - return x / int8(y) - case uint16: - return x / int8(y) - case uint32: - return x / int8(y) - case uint64: - return x / int8(y) - case int: - return x / int8(y) - case int8: - return x / y - case int16: - return int16(x) / y - case int32: - return int32(x) / y - case int64: - return int64(x) / y - case float32: - return float32(x) / y - case float64: - return float64(x) / y - } - case int16: - switch y := b.(type) { - case uint: - return x / int16(y) - case uint8: - return x / int16(y) - case uint16: - return x / int16(y) - case uint32: - return x / int16(y) - case uint64: - return x / int16(y) - case int: - return x / int16(y) - case int8: - return x / int16(y) - case int16: - return x / y - case int32: - return int32(x) / y - case int64: - return int64(x) / y - case float32: - return float32(x) / y - case float64: - return float64(x) / y - } - case int32: - switch y := b.(type) { - case uint: - return x / int32(y) - case uint8: - return x / int32(y) - case uint16: - return x / int32(y) - case uint32: - return x / int32(y) - case uint64: - return x / int32(y) - case int: - return x / int32(y) - case int8: - return x / int32(y) - case int16: - return x / int32(y) - case int32: - return x / y - case int64: - return int64(x) / y - case float32: - return float32(x) / y - case float64: - return float64(x) / y - } - case int64: - switch y := b.(type) { - case uint: - return x / int64(y) - case uint8: - return x / int64(y) - case uint16: - return x / int64(y) - case uint32: - return x / int64(y) - case uint64: - return x / int64(y) - case int: - return x / int64(y) - case int8: - return x / int64(y) - case int16: - return x / int64(y) - case int32: - return x / int64(y) - case int64: - return x / y - case float32: - return float32(x) / y - case float64: - return float64(x) / y - } - case float32: - switch y := b.(type) { - case uint: - return x / float32(y) - case uint8: - return x / float32(y) - case uint16: - return x / float32(y) - case uint32: - return x / float32(y) - case uint64: - return x / float32(y) - case int: - return x / float32(y) - case int8: - return x / float32(y) - case int16: - return x / float32(y) - case int32: - return x / float32(y) - case int64: - return x / float32(y) - case float32: - return x / y - case float64: - return float64(x) / y - } - case float64: - switch y := b.(type) { - case uint: - return x / float64(y) - case uint8: - return x / float64(y) - case uint16: - return x / float64(y) - case uint32: - return x / float64(y) - case uint64: - return x / float64(y) - case int: - return x / float64(y) - case int8: - return x / float64(y) - case int16: - return x / float64(y) - case int32: - return x / float64(y) - case int64: - return x / float64(y) - case float32: - return x / float64(y) - case float64: - return x / y - } - } - panic(fmt.Sprintf("invalid operation: %T %v %T", a, "/", b)) -} - -func modulo(a, b interface{}) interface{} { - switch x := a.(type) { - case uint: - switch y := b.(type) { - case uint: - return x % y - case uint8: - return uint8(x) % y - case uint16: - return uint16(x) % y - case uint32: - return uint32(x) % y - case uint64: - return uint64(x) % y - case int: - return int(x) % y - case int8: - return int8(x) % y - case int16: - return int16(x) % y - case int32: - return int32(x) % y - case int64: - return int64(x) % y - } - case uint8: - switch y := b.(type) { - case uint: - return x % uint8(y) - case uint8: - return x % y - case uint16: - return uint16(x) % y - case uint32: - return uint32(x) % y - case uint64: - return uint64(x) % y - case int: - return int(x) % y - case int8: - return int8(x) % y - case int16: - return int16(x) % y - case int32: - return int32(x) % y - case int64: - return int64(x) % y - } - case uint16: - switch y := b.(type) { - case uint: - return x % uint16(y) - case uint8: - return x % uint16(y) - case uint16: - return x % y - case uint32: - return uint32(x) % y - case uint64: - return uint64(x) % y - case int: - return int(x) % y - case int8: - return int8(x) % y - case int16: - return int16(x) % y - case int32: - return int32(x) % y - case int64: - return int64(x) % y - } - case uint32: - switch y := b.(type) { - case uint: - return x % uint32(y) - case uint8: - return x % uint32(y) - case uint16: - return x % uint32(y) - case uint32: - return x % y - case uint64: - return uint64(x) % y - case int: - return int(x) % y - case int8: - return int8(x) % y - case int16: - return int16(x) % y - case int32: - return int32(x) % y - case int64: - return int64(x) % y - } - case uint64: - switch y := b.(type) { - case uint: - return x % uint64(y) - case uint8: - return x % uint64(y) - case uint16: - return x % uint64(y) - case uint32: - return x % uint64(y) - case uint64: - return x % y - case int: - return int(x) % y - case int8: - return int8(x) % y - case int16: - return int16(x) % y - case int32: - return int32(x) % y - case int64: - return int64(x) % y - } - case int: - switch y := b.(type) { - case uint: - return x % int(y) - case uint8: - return x % int(y) - case uint16: - return x % int(y) - case uint32: - return x % int(y) - case uint64: - return x % int(y) - case int: - return x % y - case int8: - return int8(x) % y - case int16: - return int16(x) % y - case int32: - return int32(x) % y - case int64: - return int64(x) % y - } - case int8: - switch y := b.(type) { - case uint: - return x % int8(y) - case uint8: - return x % int8(y) - case uint16: - return x % int8(y) - case uint32: - return x % int8(y) - case uint64: - return x % int8(y) - case int: - return x % int8(y) - case int8: - return x % y - case int16: - return int16(x) % y - case int32: - return int32(x) % y - case int64: - return int64(x) % y - } - case int16: - switch y := b.(type) { - case uint: - return x % int16(y) - case uint8: - return x % int16(y) - case uint16: - return x % int16(y) - case uint32: - return x % int16(y) - case uint64: - return x % int16(y) - case int: - return x % int16(y) - case int8: - return x % int16(y) - case int16: - return x % y - case int32: - return int32(x) % y - case int64: - return int64(x) % y - } - case int32: - switch y := b.(type) { - case uint: - return x % int32(y) - case uint8: - return x % int32(y) - case uint16: - return x % int32(y) - case uint32: - return x % int32(y) - case uint64: - return x % int32(y) - case int: - return x % int32(y) - case int8: - return x % int32(y) - case int16: - return x % int32(y) - case int32: - return x % y - case int64: - return int64(x) % y - } - case int64: - switch y := b.(type) { - case uint: - return x % int64(y) - case uint8: - return x % int64(y) - case uint16: - return x % int64(y) - case uint32: - return x % int64(y) - case uint64: - return x % int64(y) - case int: - return x % int64(y) - case int8: - return x % int64(y) - case int16: - return x % int64(y) - case int32: - return x % int64(y) - case int64: - return x % y - } - } - panic(fmt.Sprintf("invalid operation: %T %v %T", a, "%", b)) -} diff --git a/vendor/github.com/antonmedv/expr/vm/opcodes.go b/vendor/github.com/antonmedv/expr/vm/opcodes.go deleted file mode 100644 index 7f2dd37..0000000 --- a/vendor/github.com/antonmedv/expr/vm/opcodes.go +++ /dev/null @@ -1,56 +0,0 @@ -package vm - -const ( - OpPush byte = iota - OpPop - OpRot - OpFetch - OpFetchNilSafe - OpFetchMap - OpTrue - OpFalse - OpNil - OpNegate - OpNot - OpEqual - OpEqualInt - OpEqualString - OpJump - OpJumpIfTrue - OpJumpIfFalse - OpJumpBackward - OpIn - OpLess - OpMore - OpLessOrEqual - OpMoreOrEqual - OpAdd - OpSubtract - OpMultiply - OpDivide - OpModulo - OpExponent - OpRange - OpMatches - OpMatchesConst - OpContains - OpStartsWith - OpEndsWith - OpIndex - OpSlice - OpProperty - OpPropertyNilSafe - OpCall - OpCallFast - OpMethod - OpMethodNilSafe - OpArray - OpMap - OpLen - OpCast - OpStore - OpLoad - OpInc - OpBegin - OpEnd // This opcode must be at the end of this list. -) diff --git a/vendor/github.com/antonmedv/expr/vm/program.go b/vendor/github.com/antonmedv/expr/vm/program.go deleted file mode 100644 index 5a41f8a..0000000 --- a/vendor/github.com/antonmedv/expr/vm/program.go +++ /dev/null @@ -1,225 +0,0 @@ -package vm - -import ( - "encoding/binary" - "fmt" - "regexp" - - "github.com/antonmedv/expr/file" -) - -type Program struct { - Source *file.Source - Locations map[int]file.Location - Constants []interface{} - Bytecode []byte -} - -func (program *Program) Disassemble() string { - out := "" - ip := 0 - for ip < len(program.Bytecode) { - pp := ip - op := program.Bytecode[ip] - ip++ - - readArg := func() uint16 { - if ip+1 >= len(program.Bytecode) { - return 0 - } - - i := binary.LittleEndian.Uint16([]byte{program.Bytecode[ip], program.Bytecode[ip+1]}) - ip += 2 - return i - } - - code := func(label string) { - out += fmt.Sprintf("%v\t%v\n", pp, label) - } - jump := func(label string) { - a := readArg() - out += fmt.Sprintf("%v\t%v\t%v\t(%v)\n", pp, label, a, ip+int(a)) - } - back := func(label string) { - a := readArg() - out += fmt.Sprintf("%v\t%v\t%v\t(%v)\n", pp, label, a, ip-int(a)) - } - argument := func(label string) { - a := readArg() - out += fmt.Sprintf("%v\t%v\t%v\n", pp, label, a) - } - constant := func(label string) { - a := readArg() - var c interface{} - if int(a) < len(program.Constants) { - c = program.Constants[a] - } - if r, ok := c.(*regexp.Regexp); ok { - c = r.String() - } - out += fmt.Sprintf("%v\t%v\t%v\t%#v\n", pp, label, a, c) - } - - switch op { - case OpPush: - constant("OpPush") - - case OpPop: - code("OpPop") - - case OpRot: - code("OpRot") - - case OpFetch: - constant("OpFetch") - - case OpFetchNilSafe: - constant("OpFetchNilSafe") - - case OpFetchMap: - constant("OpFetchMap") - - case OpTrue: - code("OpTrue") - - case OpFalse: - code("OpFalse") - - case OpNil: - code("OpNil") - - case OpNegate: - code("OpNegate") - - case OpNot: - code("OpNot") - - case OpEqual: - code("OpEqual") - - case OpEqualInt: - code("OpEqualInt") - - case OpEqualString: - code("OpEqualString") - - case OpJump: - jump("OpJump") - - case OpJumpIfTrue: - jump("OpJumpIfTrue") - - case OpJumpIfFalse: - jump("OpJumpIfFalse") - - case OpJumpBackward: - back("OpJumpBackward") - - case OpIn: - code("OpIn") - - case OpLess: - code("OpLess") - - case OpMore: - code("OpMore") - - case OpLessOrEqual: - code("OpLessOrEqual") - - case OpMoreOrEqual: - code("OpMoreOrEqual") - - case OpAdd: - code("OpAdd") - - case OpSubtract: - code("OpSubtract") - - case OpMultiply: - code("OpMultiply") - - case OpDivide: - code("OpDivide") - - case OpModulo: - code("OpModulo") - - case OpExponent: - code("OpExponent") - - case OpRange: - code("OpRange") - - case OpMatches: - code("OpMatches") - - case OpMatchesConst: - constant("OpMatchesConst") - - case OpContains: - code("OpContains") - - case OpStartsWith: - code("OpStartsWith") - - case OpEndsWith: - code("OpEndsWith") - - case OpIndex: - code("OpIndex") - - case OpSlice: - code("OpSlice") - - case OpProperty: - constant("OpProperty") - - case OpPropertyNilSafe: - constant("OpPropertyNilSafe") - - case OpCall: - constant("OpCall") - - case OpCallFast: - constant("OpCallFast") - - case OpMethod: - constant("OpMethod") - - case OpMethodNilSafe: - constant("OpMethodNilSafe") - - case OpArray: - code("OpArray") - - case OpMap: - code("OpMap") - - case OpLen: - code("OpLen") - - case OpCast: - argument("OpCast") - - case OpStore: - constant("OpStore") - - case OpLoad: - constant("OpLoad") - - case OpInc: - constant("OpInc") - - case OpBegin: - code("OpBegin") - - case OpEnd: - code("OpEnd") - - default: - out += fmt.Sprintf("%v\t%#x\n", pp, op) - } - } - return out -} diff --git a/vendor/github.com/antonmedv/expr/vm/runtime.go b/vendor/github.com/antonmedv/expr/vm/runtime.go deleted file mode 100644 index 2e00913..0000000 --- a/vendor/github.com/antonmedv/expr/vm/runtime.go +++ /dev/null @@ -1,370 +0,0 @@ -package vm - -//go:generate go run ./generate - -import ( - "fmt" - "math" - "reflect" -) - -type Call struct { - Name string - Size int -} - -type Scope map[string]interface{} - -type Fetcher interface { - Fetch(interface{}) interface{} -} - -func fetch(from, i interface{}, nilsafe bool) interface{} { - if fetcher, ok := from.(Fetcher); ok { - value := fetcher.Fetch(i) - if value != nil { - return value - } - if !nilsafe { - panic(fmt.Sprintf("cannot fetch %v from %T", i, from)) - } - return nil - } - - v := reflect.ValueOf(from) - kind := v.Kind() - - // Structures can be access through a pointer or through a value, when they - // are accessed through a pointer we don't want to copy them to a value. - if kind == reflect.Ptr && reflect.Indirect(v).Kind() == reflect.Struct { - v = reflect.Indirect(v) - kind = v.Kind() - } - - switch kind { - - case reflect.Array, reflect.Slice, reflect.String: - value := v.Index(toInt(i)) - if value.IsValid() && value.CanInterface() { - return value.Interface() - } - - case reflect.Map: - value := v.MapIndex(reflect.ValueOf(i)) - if value.IsValid() { - if value.CanInterface() { - return value.Interface() - } - } else { - elem := reflect.TypeOf(from).Elem() - return reflect.Zero(elem).Interface() - } - - case reflect.Struct: - value := v.FieldByName(reflect.ValueOf(i).String()) - if value.IsValid() && value.CanInterface() { - return value.Interface() - } - } - if !nilsafe { - panic(fmt.Sprintf("cannot fetch %v from %T", i, from)) - } - return nil -} - -func slice(array, from, to interface{}) interface{} { - v := reflect.ValueOf(array) - - switch v.Kind() { - case reflect.Array, reflect.Slice, reflect.String: - length := v.Len() - a, b := toInt(from), toInt(to) - - if b > length { - b = length - } - if a > b { - a = b - } - - value := v.Slice(a, b) - if value.IsValid() && value.CanInterface() { - return value.Interface() - } - - case reflect.Ptr: - value := v.Elem() - if value.IsValid() && value.CanInterface() { - return slice(value.Interface(), from, to) - } - - } - panic(fmt.Sprintf("cannot slice %v", from)) -} - -func FetchFn(from interface{}, name string) reflect.Value { - v := reflect.ValueOf(from) - - // Methods can be defined on any type. - if v.NumMethod() > 0 { - method := v.MethodByName(name) - if method.IsValid() { - return method - } - } - - d := v - if v.Kind() == reflect.Ptr { - d = v.Elem() - } - - switch d.Kind() { - case reflect.Map: - value := d.MapIndex(reflect.ValueOf(name)) - if value.IsValid() && value.CanInterface() { - return value.Elem() - } - case reflect.Struct: - // If struct has not method, maybe it has func field. - // To access this field we need dereference value. - value := d.FieldByName(name) - if value.IsValid() { - return value - } - } - panic(fmt.Sprintf(`cannot get "%v" from %T`, name, from)) -} - -func FetchFnNil(from interface{}, name string) reflect.Value { - if v := reflect.ValueOf(from); !v.IsValid() { - return v - } - return FetchFn(from, name) -} - -func in(needle interface{}, array interface{}) bool { - if array == nil { - return false - } - v := reflect.ValueOf(array) - - switch v.Kind() { - - case reflect.Array, reflect.Slice: - for i := 0; i < v.Len(); i++ { - value := v.Index(i) - if value.IsValid() && value.CanInterface() { - if equal(value.Interface(), needle).(bool) { - return true - } - } - } - return false - - case reflect.Map: - n := reflect.ValueOf(needle) - if !n.IsValid() { - panic(fmt.Sprintf("cannot use %T as index to %T", needle, array)) - } - value := v.MapIndex(n) - if value.IsValid() { - return true - } - return false - - case reflect.Struct: - n := reflect.ValueOf(needle) - if !n.IsValid() || n.Kind() != reflect.String { - panic(fmt.Sprintf("cannot use %T as field name of %T", needle, array)) - } - value := v.FieldByName(n.String()) - if value.IsValid() { - return true - } - return false - - case reflect.Ptr: - value := v.Elem() - if value.IsValid() && value.CanInterface() { - return in(needle, value.Interface()) - } - return false - } - - panic(fmt.Sprintf(`operator "in"" not defined on %T`, array)) -} - -func length(a interface{}) int { - v := reflect.ValueOf(a) - switch v.Kind() { - case reflect.Array, reflect.Slice, reflect.Map, reflect.String: - return v.Len() - default: - panic(fmt.Sprintf("invalid argument for len (type %T)", a)) - } -} - -func negate(i interface{}) interface{} { - switch v := i.(type) { - case float32: - return -v - case float64: - return -v - - case int: - return -v - case int8: - return -v - case int16: - return -v - case int32: - return -v - case int64: - return -v - - case uint: - return -v - case uint8: - return -v - case uint16: - return -v - case uint32: - return -v - case uint64: - return -v - - default: - panic(fmt.Sprintf("invalid operation: - %T", v)) - } -} - -func exponent(a, b interface{}) float64 { - return math.Pow(toFloat64(a), toFloat64(b)) -} - -func makeRange(min, max int) []int { - size := max - min + 1 - if size <= 0 { - return []int{} - } - rng := make([]int, size) - for i := range rng { - rng[i] = min + i - } - return rng -} - -func toInt(a interface{}) int { - switch x := a.(type) { - case float32: - return int(x) - case float64: - return int(x) - - case int: - return x - case int8: - return int(x) - case int16: - return int(x) - case int32: - return int(x) - case int64: - return int(x) - - case uint: - return int(x) - case uint8: - return int(x) - case uint16: - return int(x) - case uint32: - return int(x) - case uint64: - return int(x) - - default: - panic(fmt.Sprintf("invalid operation: int(%T)", x)) - } -} - -func toInt64(a interface{}) int64 { - switch x := a.(type) { - case float32: - return int64(x) - case float64: - return int64(x) - - case int: - return int64(x) - case int8: - return int64(x) - case int16: - return int64(x) - case int32: - return int64(x) - case int64: - return x - - case uint: - return int64(x) - case uint8: - return int64(x) - case uint16: - return int64(x) - case uint32: - return int64(x) - case uint64: - return int64(x) - - default: - panic(fmt.Sprintf("invalid operation: int64(%T)", x)) - } -} - -func toFloat64(a interface{}) float64 { - switch x := a.(type) { - case float32: - return float64(x) - case float64: - return x - - case int: - return float64(x) - case int8: - return float64(x) - case int16: - return float64(x) - case int32: - return float64(x) - case int64: - return float64(x) - - case uint: - return float64(x) - case uint8: - return float64(x) - case uint16: - return float64(x) - case uint32: - return float64(x) - case uint64: - return float64(x) - - default: - panic(fmt.Sprintf("invalid operation: float64(%T)", x)) - } -} - -func isNil(v interface{}) bool { - if v == nil { - return true - } - r := reflect.ValueOf(v) - switch r.Kind() { - case reflect.Chan, reflect.Func, reflect.Map, reflect.Ptr, reflect.Interface, reflect.Slice: - return r.IsNil() - default: - return false - } -} diff --git a/vendor/github.com/antonmedv/expr/vm/vm.go b/vendor/github.com/antonmedv/expr/vm/vm.go deleted file mode 100644 index 6957dfa..0000000 --- a/vendor/github.com/antonmedv/expr/vm/vm.go +++ /dev/null @@ -1,484 +0,0 @@ -package vm - -import ( - "fmt" - "reflect" - "regexp" - "strings" - - "github.com/antonmedv/expr/file" -) - -var errorType = reflect.TypeOf((*error)(nil)).Elem() - -var ( - MemoryBudget int = 1e6 -) - -func Run(program *Program, env interface{}) (interface{}, error) { - if program == nil { - return nil, fmt.Errorf("program is nil") - } - - vm := VM{} - return vm.Run(program, env) -} - -type VM struct { - stack []interface{} - constants []interface{} - bytecode []byte - ip int - pp int - scopes []Scope - debug bool - step chan struct{} - curr chan int - memory int - limit int -} - -func Debug() *VM { - vm := &VM{ - debug: true, - step: make(chan struct{}, 0), - curr: make(chan int, 0), - } - return vm -} - -func (vm *VM) Run(program *Program, env interface{}) (out interface{}, err error) { - defer func() { - if r := recover(); r != nil { - f := &file.Error{ - Location: program.Locations[vm.pp], - Message: fmt.Sprintf("%v", r), - } - err = f.Bind(program.Source) - } - }() - - vm.limit = MemoryBudget - vm.ip = 0 - vm.pp = 0 - - if vm.stack == nil { - vm.stack = make([]interface{}, 0, 2) - } else { - vm.stack = vm.stack[0:0] - } - - if vm.scopes != nil { - vm.scopes = vm.scopes[0:0] - } - - vm.bytecode = program.Bytecode - vm.constants = program.Constants - - for vm.ip < len(vm.bytecode) { - - if vm.debug { - <-vm.step - } - - vm.pp = vm.ip - vm.ip++ - op := vm.bytecode[vm.pp] - - switch op { - - case OpPush: - vm.push(vm.constant()) - - case OpPop: - vm.pop() - - case OpRot: - b := vm.pop() - a := vm.pop() - vm.push(b) - vm.push(a) - - case OpFetch: - vm.push(fetch(env, vm.constant(), false)) - - case OpFetchNilSafe: - vm.push(fetch(env, vm.constant(), true)) - - case OpFetchMap: - vm.push(env.(map[string]interface{})[vm.constant().(string)]) - - case OpTrue: - vm.push(true) - - case OpFalse: - vm.push(false) - - case OpNil: - vm.push(nil) - - case OpNegate: - v := negate(vm.pop()) - vm.push(v) - - case OpNot: - v := vm.pop().(bool) - vm.push(!v) - - case OpEqual: - b := vm.pop() - a := vm.pop() - vm.push(equal(a, b)) - - case OpEqualInt: - b := vm.pop() - a := vm.pop() - vm.push(a.(int) == b.(int)) - - case OpEqualString: - b := vm.pop() - a := vm.pop() - vm.push(a.(string) == b.(string)) - - case OpJump: - offset := vm.arg() - vm.ip += int(offset) - - case OpJumpIfTrue: - offset := vm.arg() - if vm.current().(bool) { - vm.ip += int(offset) - } - - case OpJumpIfFalse: - offset := vm.arg() - if !vm.current().(bool) { - vm.ip += int(offset) - } - - case OpJumpBackward: - offset := vm.arg() - vm.ip -= int(offset) - - case OpIn: - b := vm.pop() - a := vm.pop() - vm.push(in(a, b)) - - case OpLess: - b := vm.pop() - a := vm.pop() - vm.push(less(a, b)) - - case OpMore: - b := vm.pop() - a := vm.pop() - vm.push(more(a, b)) - - case OpLessOrEqual: - b := vm.pop() - a := vm.pop() - vm.push(lessOrEqual(a, b)) - - case OpMoreOrEqual: - b := vm.pop() - a := vm.pop() - vm.push(moreOrEqual(a, b)) - - case OpAdd: - b := vm.pop() - a := vm.pop() - vm.push(add(a, b)) - - case OpSubtract: - b := vm.pop() - a := vm.pop() - vm.push(subtract(a, b)) - - case OpMultiply: - b := vm.pop() - a := vm.pop() - vm.push(multiply(a, b)) - - case OpDivide: - b := vm.pop() - a := vm.pop() - vm.push(divide(a, b)) - - case OpModulo: - b := vm.pop() - a := vm.pop() - vm.push(modulo(a, b)) - - case OpExponent: - b := vm.pop() - a := vm.pop() - vm.push(exponent(a, b)) - - case OpRange: - b := vm.pop() - a := vm.pop() - min := toInt(a) - max := toInt(b) - size := max - min + 1 - if vm.memory+size >= vm.limit { - panic("memory budget exceeded") - } - vm.push(makeRange(min, max)) - vm.memory += size - - case OpMatches: - b := vm.pop() - a := vm.pop() - match, err := regexp.MatchString(b.(string), a.(string)) - if err != nil { - panic(err) - } - - vm.push(match) - - case OpMatchesConst: - a := vm.pop() - r := vm.constant().(*regexp.Regexp) - vm.push(r.MatchString(a.(string))) - - case OpContains: - b := vm.pop() - a := vm.pop() - vm.push(strings.Contains(a.(string), b.(string))) - - case OpStartsWith: - b := vm.pop() - a := vm.pop() - vm.push(strings.HasPrefix(a.(string), b.(string))) - - case OpEndsWith: - b := vm.pop() - a := vm.pop() - vm.push(strings.HasSuffix(a.(string), b.(string))) - - case OpIndex: - b := vm.pop() - a := vm.pop() - vm.push(fetch(a, b, false)) - - case OpSlice: - from := vm.pop() - to := vm.pop() - node := vm.pop() - vm.push(slice(node, from, to)) - - case OpProperty: - a := vm.pop() - b := vm.constant() - vm.push(fetch(a, b, false)) - - case OpPropertyNilSafe: - a := vm.pop() - b := vm.constant() - vm.push(fetch(a, b, true)) - - case OpCall: - call := vm.constant().(Call) - in := make([]reflect.Value, call.Size) - for i := call.Size - 1; i >= 0; i-- { - param := vm.pop() - if param == nil && reflect.TypeOf(param) == nil { - // In case of nil value and nil type use this hack, - // otherwise reflect.Call will panic on zero value. - in[i] = reflect.ValueOf(¶m).Elem() - } else { - in[i] = reflect.ValueOf(param) - } - } - out := FetchFn(env, call.Name).Call(in) - if len(out) == 2 && out[1].Type() == errorType && !out[1].IsNil() { - return nil, out[1].Interface().(error) - } - vm.push(out[0].Interface()) - - case OpCallFast: - call := vm.constant().(Call) - in := make([]interface{}, call.Size) - for i := call.Size - 1; i >= 0; i-- { - in[i] = vm.pop() - } - fn := FetchFn(env, call.Name).Interface() - if typed, ok := fn.(func(...interface{}) interface{}); ok { - vm.push(typed(in...)) - } else if typed, ok := fn.(func(...interface{}) (interface{}, error)); ok { - res, err := typed(in...) - if err != nil { - return nil, err - } - vm.push(res) - } - - case OpMethod: - call := vm.constants[vm.arg()].(Call) - in := make([]reflect.Value, call.Size) - for i := call.Size - 1; i >= 0; i-- { - param := vm.pop() - if param == nil && reflect.TypeOf(param) == nil { - // In case of nil value and nil type use this hack, - // otherwise reflect.Call will panic on zero value. - in[i] = reflect.ValueOf(¶m).Elem() - } else { - in[i] = reflect.ValueOf(param) - } - } - out := FetchFn(vm.pop(), call.Name).Call(in) - if len(out) == 2 && out[1].Type() == errorType && !out[1].IsNil() { - return nil, out[1].Interface().(error) - } - vm.push(out[0].Interface()) - - case OpMethodNilSafe: - call := vm.constants[vm.arg()].(Call) - in := make([]reflect.Value, call.Size) - for i := call.Size - 1; i >= 0; i-- { - param := vm.pop() - if param == nil && reflect.TypeOf(param) == nil { - // In case of nil value and nil type use this hack, - // otherwise reflect.Call will panic on zero value. - in[i] = reflect.ValueOf(¶m).Elem() - } else { - in[i] = reflect.ValueOf(param) - } - } - fn := FetchFnNil(vm.pop(), call.Name) - if !fn.IsValid() { - vm.push(nil) - } else { - out := fn.Call(in) - vm.push(out[0].Interface()) - } - - case OpArray: - size := vm.pop().(int) - array := make([]interface{}, size) - for i := size - 1; i >= 0; i-- { - array[i] = vm.pop() - } - vm.push(array) - vm.memory += size - if vm.memory >= vm.limit { - panic("memory budget exceeded") - } - - case OpMap: - size := vm.pop().(int) - m := make(map[string]interface{}) - for i := size - 1; i >= 0; i-- { - value := vm.pop() - key := vm.pop() - m[key.(string)] = value - } - vm.push(m) - vm.memory += size - if vm.memory >= vm.limit { - panic("memory budget exceeded") - } - - case OpLen: - vm.push(length(vm.current())) - - case OpCast: - t := vm.arg() - switch t { - case 0: - vm.push(toInt64(vm.pop())) - case 1: - vm.push(toFloat64(vm.pop())) - } - - case OpStore: - scope := vm.Scope() - key := vm.constant().(string) - value := vm.pop() - scope[key] = value - - case OpLoad: - scope := vm.Scope() - key := vm.constant().(string) - vm.push(scope[key]) - - case OpInc: - scope := vm.Scope() - key := vm.constant().(string) - i := scope[key].(int) - i++ - scope[key] = i - - case OpBegin: - scope := make(Scope) - vm.scopes = append(vm.scopes, scope) - - case OpEnd: - vm.scopes = vm.scopes[:len(vm.scopes)-1] - - default: - panic(fmt.Sprintf("unknown bytecode %#x", op)) - } - - if vm.debug { - vm.curr <- vm.ip - } - } - - if vm.debug { - close(vm.curr) - close(vm.step) - } - - if len(vm.stack) > 0 { - return vm.pop(), nil - } - - return nil, nil -} - -func (vm *VM) push(value interface{}) { - vm.stack = append(vm.stack, value) -} - -func (vm *VM) current() interface{} { - return vm.stack[len(vm.stack)-1] -} - -func (vm *VM) pop() interface{} { - value := vm.stack[len(vm.stack)-1] - vm.stack = vm.stack[:len(vm.stack)-1] - return value -} - -func (vm *VM) arg() uint16 { - b0, b1 := vm.bytecode[vm.ip], vm.bytecode[vm.ip+1] - vm.ip += 2 - return uint16(b0) | uint16(b1)<<8 -} - -func (vm *VM) constant() interface{} { - return vm.constants[vm.arg()] -} - -func (vm *VM) Stack() []interface{} { - return vm.stack -} - -func (vm *VM) Scope() Scope { - if len(vm.scopes) > 0 { - return vm.scopes[len(vm.scopes)-1] - } - return nil -} - -func (vm *VM) Step() { - if vm.ip < len(vm.bytecode) { - vm.step <- struct{}{} - } -} - -func (vm *VM) Position() chan int { - return vm.curr -} diff --git a/vendor/github.com/aymerick/douceur/LICENSE b/vendor/github.com/aymerick/douceur/LICENSE deleted file mode 100644 index 6ce87cd..0000000 --- a/vendor/github.com/aymerick/douceur/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2015 Aymerick JEHANNE - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - diff --git a/vendor/github.com/aymerick/douceur/css/declaration.go b/vendor/github.com/aymerick/douceur/css/declaration.go deleted file mode 100644 index 61d29d3..0000000 --- a/vendor/github.com/aymerick/douceur/css/declaration.go +++ /dev/null @@ -1,60 +0,0 @@ -package css - -import "fmt" - -// Declaration represents a parsed style property -type Declaration struct { - Property string - Value string - Important bool -} - -// NewDeclaration instanciates a new Declaration -func NewDeclaration() *Declaration { - return &Declaration{} -} - -// Returns string representation of the Declaration -func (decl *Declaration) String() string { - return decl.StringWithImportant(true) -} - -// StringWithImportant returns string representation with optional !important part -func (decl *Declaration) StringWithImportant(option bool) string { - result := fmt.Sprintf("%s: %s", decl.Property, decl.Value) - - if option && decl.Important { - result += " !important" - } - - result += ";" - - return result -} - -// Equal returns true if both Declarations are equals -func (decl *Declaration) Equal(other *Declaration) bool { - return (decl.Property == other.Property) && (decl.Value == other.Value) && (decl.Important == other.Important) -} - -// -// DeclarationsByProperty -// - -// DeclarationsByProperty represents sortable style declarations -type DeclarationsByProperty []*Declaration - -// Implements sort.Interface -func (declarations DeclarationsByProperty) Len() int { - return len(declarations) -} - -// Implements sort.Interface -func (declarations DeclarationsByProperty) Swap(i, j int) { - declarations[i], declarations[j] = declarations[j], declarations[i] -} - -// Implements sort.Interface -func (declarations DeclarationsByProperty) Less(i, j int) bool { - return declarations[i].Property < declarations[j].Property -} diff --git a/vendor/github.com/aymerick/douceur/css/rule.go b/vendor/github.com/aymerick/douceur/css/rule.go deleted file mode 100644 index b5a44b5..0000000 --- a/vendor/github.com/aymerick/douceur/css/rule.go +++ /dev/null @@ -1,230 +0,0 @@ -package css - -import ( - "fmt" - "strings" -) - -const ( - indentSpace = 2 -) - -// RuleKind represents a Rule kind -type RuleKind int - -// Rule kinds -const ( - QualifiedRule RuleKind = iota - AtRule -) - -// At Rules than have Rules inside their block instead of Declarations -var atRulesWithRulesBlock = []string{ - "@document", "@font-feature-values", "@keyframes", "@media", "@supports", -} - -// Rule represents a parsed CSS rule -type Rule struct { - Kind RuleKind - - // At Rule name (eg: "@media") - Name string - - // Raw prelude - Prelude string - - // Qualified Rule selectors parsed from prelude - Selectors []string - - // Style properties - Declarations []*Declaration - - // At Rule embedded rules - Rules []*Rule - - // Current rule embedding level - EmbedLevel int -} - -// NewRule instanciates a new Rule -func NewRule(kind RuleKind) *Rule { - return &Rule{ - Kind: kind, - } -} - -// Returns string representation of rule kind -func (kind RuleKind) String() string { - switch kind { - case QualifiedRule: - return "Qualified Rule" - case AtRule: - return "At Rule" - default: - return "WAT" - } -} - -// EmbedsRules returns true if this rule embeds another rules -func (rule *Rule) EmbedsRules() bool { - if rule.Kind == AtRule { - for _, atRuleName := range atRulesWithRulesBlock { - if rule.Name == atRuleName { - return true - } - } - } - - return false -} - -// Equal returns true if both rules are equals -func (rule *Rule) Equal(other *Rule) bool { - if (rule.Kind != other.Kind) || - (rule.Prelude != other.Prelude) || - (rule.Name != other.Name) { - return false - } - - if (len(rule.Selectors) != len(other.Selectors)) || - (len(rule.Declarations) != len(other.Declarations)) || - (len(rule.Rules) != len(other.Rules)) { - return false - } - - for i, sel := range rule.Selectors { - if sel != other.Selectors[i] { - return false - } - } - - for i, decl := range rule.Declarations { - if !decl.Equal(other.Declarations[i]) { - return false - } - } - - for i, rule := range rule.Rules { - if !rule.Equal(other.Rules[i]) { - return false - } - } - - return true -} - -// Diff returns a string representation of rules differences -func (rule *Rule) Diff(other *Rule) []string { - result := []string{} - - if rule.Kind != other.Kind { - result = append(result, fmt.Sprintf("Kind: %s | %s", rule.Kind.String(), other.Kind.String())) - } - - if rule.Prelude != other.Prelude { - result = append(result, fmt.Sprintf("Prelude: \"%s\" | \"%s\"", rule.Prelude, other.Prelude)) - } - - if rule.Name != other.Name { - result = append(result, fmt.Sprintf("Name: \"%s\" | \"%s\"", rule.Name, other.Name)) - } - - if len(rule.Selectors) != len(other.Selectors) { - result = append(result, fmt.Sprintf("Selectors: %v | %v", strings.Join(rule.Selectors, ", "), strings.Join(other.Selectors, ", "))) - } else { - for i, sel := range rule.Selectors { - if sel != other.Selectors[i] { - result = append(result, fmt.Sprintf("Selector: \"%s\" | \"%s\"", sel, other.Selectors[i])) - } - } - } - - if len(rule.Declarations) != len(other.Declarations) { - result = append(result, fmt.Sprintf("Declarations Nb: %d | %d", len(rule.Declarations), len(other.Declarations))) - } else { - for i, decl := range rule.Declarations { - if !decl.Equal(other.Declarations[i]) { - result = append(result, fmt.Sprintf("Declaration: \"%s\" | \"%s\"", decl.String(), other.Declarations[i].String())) - } - } - } - - if len(rule.Rules) != len(other.Rules) { - result = append(result, fmt.Sprintf("Rules Nb: %d | %d", len(rule.Rules), len(other.Rules))) - } else { - - for i, rule := range rule.Rules { - if !rule.Equal(other.Rules[i]) { - result = append(result, fmt.Sprintf("Rule: \"%s\" | \"%s\"", rule.String(), other.Rules[i].String())) - } - } - } - - return result -} - -// Returns the string representation of a rule -func (rule *Rule) String() string { - result := "" - - if rule.Kind == QualifiedRule { - for i, sel := range rule.Selectors { - if i != 0 { - result += ", " - } - result += sel - } - } else { - // AtRule - result += fmt.Sprintf("%s", rule.Name) - - if rule.Prelude != "" { - if result != "" { - result += " " - } - result += fmt.Sprintf("%s", rule.Prelude) - } - } - - if (len(rule.Declarations) == 0) && (len(rule.Rules) == 0) { - result += ";" - } else { - result += " {\n" - - if rule.EmbedsRules() { - for _, subRule := range rule.Rules { - result += fmt.Sprintf("%s%s\n", rule.indent(), subRule.String()) - } - } else { - for _, decl := range rule.Declarations { - result += fmt.Sprintf("%s%s\n", rule.indent(), decl.String()) - } - } - - result += fmt.Sprintf("%s}", rule.indentEndBlock()) - } - - return result -} - -// Returns identation spaces for declarations and rules -func (rule *Rule) indent() string { - result := "" - - for i := 0; i < ((rule.EmbedLevel + 1) * indentSpace); i++ { - result += " " - } - - return result -} - -// Returns identation spaces for end of block character -func (rule *Rule) indentEndBlock() string { - result := "" - - for i := 0; i < (rule.EmbedLevel * indentSpace); i++ { - result += " " - } - - return result -} diff --git a/vendor/github.com/aymerick/douceur/css/stylesheet.go b/vendor/github.com/aymerick/douceur/css/stylesheet.go deleted file mode 100644 index 6b32c2e..0000000 --- a/vendor/github.com/aymerick/douceur/css/stylesheet.go +++ /dev/null @@ -1,25 +0,0 @@ -package css - -// Stylesheet represents a parsed stylesheet -type Stylesheet struct { - Rules []*Rule -} - -// NewStylesheet instanciate a new Stylesheet -func NewStylesheet() *Stylesheet { - return &Stylesheet{} -} - -// Returns string representation of the Stylesheet -func (sheet *Stylesheet) String() string { - result := "" - - for _, rule := range sheet.Rules { - if result != "" { - result += "\n" - } - result += rule.String() - } - - return result -} diff --git a/vendor/github.com/aymerick/douceur/inliner/element.go b/vendor/github.com/aymerick/douceur/inliner/element.go deleted file mode 100644 index cd96a6f..0000000 --- a/vendor/github.com/aymerick/douceur/inliner/element.go +++ /dev/null @@ -1,181 +0,0 @@ -package inliner - -import ( - "sort" - - "github.com/PuerkitoBio/goquery" - - "github.com/aymerick/douceur/css" - "github.com/aymerick/douceur/parser" -) - -// Element represents a HTML element with matching CSS rules -type Element struct { - // The goquery handler - elt *goquery.Selection - - // The style rules to apply on that element - styleRules []*StyleRule -} - -// ElementAttr represents a HTML element attribute -type ElementAttr struct { - attr string - elements []string -} - -// Index is style property name -var styleToAttr map[string]*ElementAttr - -func init() { - // Borrowed from premailer: - // https://github.com/premailer/premailer/blob/master/lib/premailer/premailer.rb - styleToAttr = map[string]*ElementAttr{ - "text-align": { - "align", - []string{"h1", "h2", "h3", "h4", "h5", "h6", "p", "div", "blockquote", "tr", "th", "td"}, - }, - "background-color": { - "bgcolor", - []string{"body", "table", "tr", "th", "td"}, - }, - "background-image": { - "background", - []string{"table"}, - }, - "vertical-align": { - "valign", - []string{"th", "td"}, - }, - "float": { - "align", - []string{"img"}, - }, - // @todo width and height ? - } -} - -// NewElement instanciates a new element -func NewElement(elt *goquery.Selection) *Element { - return &Element{ - elt: elt, - } -} - -// Add a Style Rule to Element -func (element *Element) addStyleRule(styleRule *StyleRule) { - element.styleRules = append(element.styleRules, styleRule) -} - -// Inline styles on element -func (element *Element) inline() error { - // compute declarations - declarations, err := element.computeDeclarations() - if err != nil { - return err - } - - // set style attribute - styleValue := computeStyleValue(declarations) - if styleValue != "" { - element.elt.SetAttr("style", styleValue) - } - - // set additionnal attributes - element.setAttributesFromStyle(declarations) - - return nil -} - -// Compute css declarations -func (element *Element) computeDeclarations() ([]*css.Declaration, error) { - result := []*css.Declaration{} - - styles := make(map[string]*StyleDeclaration) - - // First: parsed stylesheets rules - mergeStyleDeclarations(element.styleRules, styles) - - // Then: inline rules - inlineRules, err := element.parseInlineStyle() - if err != nil { - return result, err - } - - mergeStyleDeclarations(inlineRules, styles) - - // map to array - for _, styleDecl := range styles { - result = append(result, styleDecl.Declaration) - } - - // sort declarations by property name - sort.Sort(css.DeclarationsByProperty(result)) - - return result, nil -} - -// Parse inline style rules -func (element *Element) parseInlineStyle() ([]*StyleRule, error) { - result := []*StyleRule{} - - styleValue, exists := element.elt.Attr("style") - if (styleValue == "") || !exists { - return result, nil - } - - declarations, err := parser.ParseDeclarations(styleValue) - if err != nil { - return result, err - } - - result = append(result, NewStyleRule(inlineFakeSelector, declarations)) - - return result, nil -} - -// Set additional attributes from style declarations -func (element *Element) setAttributesFromStyle(declarations []*css.Declaration) { - // for each style declarations - for _, declaration := range declarations { - if eltAttr := styleToAttr[declaration.Property]; eltAttr != nil { - // check if element is allowed for that attribute - for _, eltAllowed := range eltAttr.elements { - if element.elt.Nodes[0].Data == eltAllowed { - element.elt.SetAttr(eltAttr.attr, declaration.Value) - - break - } - } - } - } -} - -// helper -func computeStyleValue(declarations []*css.Declaration) string { - result := "" - - // set style attribute value - for _, declaration := range declarations { - if result != "" { - result += " " - } - - result += declaration.StringWithImportant(false) - } - - return result -} - -// helper -func mergeStyleDeclarations(styleRules []*StyleRule, output map[string]*StyleDeclaration) { - for _, styleRule := range styleRules { - for _, declaration := range styleRule.Declarations { - styleDecl := NewStyleDeclaration(styleRule, declaration) - - if (output[declaration.Property] == nil) || (styleDecl.Specificity() >= output[declaration.Property].Specificity()) { - output[declaration.Property] = styleDecl - } - } - } -} diff --git a/vendor/github.com/aymerick/douceur/inliner/inliner.go b/vendor/github.com/aymerick/douceur/inliner/inliner.go deleted file mode 100644 index 842a92d..0000000 --- a/vendor/github.com/aymerick/douceur/inliner/inliner.go +++ /dev/null @@ -1,243 +0,0 @@ -package inliner - -import ( - "fmt" - "strconv" - "strings" - - "github.com/PuerkitoBio/goquery" - "github.com/aymerick/douceur/css" - "github.com/aymerick/douceur/parser" - "golang.org/x/net/html" -) - -const ( - eltMarkerAttr = "douceur-mark" -) - -var unsupportedSelectors = []string{ - ":active", ":after", ":before", ":checked", ":disabled", ":enabled", - ":first-line", ":first-letter", ":focus", ":hover", ":invalid", ":in-range", - ":lang", ":link", ":root", ":selection", ":target", ":valid", ":visited"} - -// Inliner presents a CSS Inliner -type Inliner struct { - // Raw HTML - html string - - // Parsed HTML document - doc *goquery.Document - - // Parsed stylesheets - stylesheets []*css.Stylesheet - - // Collected inlinable style rules - rules []*StyleRule - - // HTML elements matching collected inlinable style rules - elements map[string]*Element - - // CSS rules that are not inlinable but that must be inserted in output document - rawRules []fmt.Stringer - - // current element marker value - eltMarker int -} - -// NewInliner instanciates a new Inliner -func NewInliner(html string) *Inliner { - return &Inliner{ - html: html, - elements: make(map[string]*Element), - } -} - -// Inline inlines css into html document -func Inline(html string) (string, error) { - result, err := NewInliner(html).Inline() - if err != nil { - return "", err - } - - return result, nil -} - -// Inline inlines CSS and returns HTML -func (inliner *Inliner) Inline() (string, error) { - // parse HTML document - if err := inliner.parseHTML(); err != nil { - return "", err - } - - // parse stylesheets - if err := inliner.parseStylesheets(); err != nil { - return "", err - } - - // collect elements and style rules - inliner.collectElementsAndRules() - - // inline css - if err := inliner.inlineStyleRules(); err != nil { - return "", err - } - - // insert raw stylesheet - inliner.insertRawStylesheet() - - // generate HTML document - return inliner.genHTML() -} - -// Parses raw html -func (inliner *Inliner) parseHTML() error { - doc, err := goquery.NewDocumentFromReader(strings.NewReader(inliner.html)) - if err != nil { - return err - } - - inliner.doc = doc - - return nil -} - -// Parses and removes stylesheets from HTML document -func (inliner *Inliner) parseStylesheets() error { - var result error - - inliner.doc.Find("style").EachWithBreak(func(i int, s *goquery.Selection) bool { - stylesheet, err := parser.Parse(s.Text()) - if err != nil { - result = err - return false - } - - inliner.stylesheets = append(inliner.stylesheets, stylesheet) - - // removes parsed stylesheet - s.Remove() - - return true - }) - - return result -} - -// Collects HTML elements matching parsed stylesheets, and thus collect used style rules -func (inliner *Inliner) collectElementsAndRules() { - for _, stylesheet := range inliner.stylesheets { - for _, rule := range stylesheet.Rules { - if rule.Kind == css.QualifiedRule { - // Let's go! - inliner.handleQualifiedRule(rule) - } else { - // Keep it 'as is' - inliner.rawRules = append(inliner.rawRules, rule) - } - } - } -} - -// Handles parsed qualified rule -func (inliner *Inliner) handleQualifiedRule(rule *css.Rule) { - for _, selector := range rule.Selectors { - if Inlinable(selector) { - inliner.doc.Find(selector).Each(func(i int, s *goquery.Selection) { - // get marker - eltMarker, exists := s.Attr(eltMarkerAttr) - if !exists { - // mark element - eltMarker = strconv.Itoa(inliner.eltMarker) - s.SetAttr(eltMarkerAttr, eltMarker) - inliner.eltMarker++ - - // add new element - inliner.elements[eltMarker] = NewElement(s) - } - - // add style rule for element - inliner.elements[eltMarker].addStyleRule(NewStyleRule(selector, rule.Declarations)) - }) - } else { - // Keep it 'as is' - inliner.rawRules = append(inliner.rawRules, NewStyleRule(selector, rule.Declarations)) - } - } -} - -// Inline style rules in HTML document -func (inliner *Inliner) inlineStyleRules() error { - for _, element := range inliner.elements { - // remove marker - element.elt.RemoveAttr(eltMarkerAttr) - - // inline element - err := element.inline() - if err != nil { - return err - } - } - - return nil -} - -// Computes raw CSS rules -func (inliner *Inliner) computeRawCSS() string { - result := "" - - for _, rawRule := range inliner.rawRules { - result += rawRule.String() - result += "\n" - } - - return result -} - -// Insert raw CSS rules into HTML document -func (inliner *Inliner) insertRawStylesheet() { - rawCSS := inliner.computeRawCSS() - if rawCSS != "" { - // create - - - - - -

Welcome to your new account on my service!

- -

- Here is some more information: - -

-

- - - ` - - text, err := html2text.FromString(inputHtml) - if err != nil { - panic(err) - } - fmt.Println(text) -} -``` - -Output: -``` -Mega Service ( http://mymegaservice.com/ ) - -****************************************** -Welcome to your new account on my service! -****************************************** - -Here is some more information: - -* Link 1: Example.com ( https://example.com ) -* Link 2: Example2.com ( https://example2.com ) -* Something else -``` - - -## Unit-tests - -Running the unit-tests is straightforward and standard: - -```bash -go test -``` - - -# License - -Permissive MIT license. - - -## Contact - -You are more than welcome to open issues and send pull requests if you find a bug or want a new feature. - -If you appreciate this library please feel free to drop me a line and tell me! It's always nice to hear from people who have benefitted from my work. - -Email: jay at (my github username).com - -Twitter: [@jtaylor](https://twitter.com/jtaylor) - diff --git a/vendor/github.com/jaytaylor/html2text/html2text.go b/vendor/github.com/jaytaylor/html2text/html2text.go deleted file mode 100644 index 66454cf..0000000 --- a/vendor/github.com/jaytaylor/html2text/html2text.go +++ /dev/null @@ -1,300 +0,0 @@ -package html2text - -import ( - "bytes" - "io" - "regexp" - "strings" - "unicode" - - "golang.org/x/net/html" - "golang.org/x/net/html/atom" -) - -var ( - spacingRe = regexp.MustCompile(`[ \r\n\t]+`) - newlineRe = regexp.MustCompile(`\n\n+`) -) - -type textifyTraverseCtx struct { - Buf bytes.Buffer - - prefix string - blockquoteLevel int - lineLength int - endsWithSpace bool - endsWithNewline bool - justClosedDiv bool -} - -func (ctx *textifyTraverseCtx) traverse(node *html.Node) error { - switch node.Type { - - default: - return ctx.traverseChildren(node) - - case html.TextNode: - data := strings.Trim(spacingRe.ReplaceAllString(node.Data, " "), " ") - return ctx.emit(data) - - case html.ElementNode: - - ctx.justClosedDiv = false - switch node.DataAtom { - case atom.Br: - return ctx.emit("\n") - - case atom.H1, atom.H2, atom.H3: - subCtx := textifyTraverseCtx{} - if err := subCtx.traverseChildren(node); err != nil { - return err - } - - str := subCtx.Buf.String() - dividerLen := 0 - for _, line := range strings.Split(str, "\n") { - if lineLen := len([]rune(line)); lineLen-1 > dividerLen { - dividerLen = lineLen - 1 - } - } - divider := "" - if node.DataAtom == atom.H1 { - divider = strings.Repeat("*", dividerLen) - } else { - divider = strings.Repeat("-", dividerLen) - } - - if node.DataAtom == atom.H3 { - return ctx.emit("\n\n" + str + "\n" + divider + "\n\n") - } - return ctx.emit("\n\n" + divider + "\n" + str + "\n" + divider + "\n\n") - - case atom.Blockquote: - ctx.blockquoteLevel++ - ctx.prefix = strings.Repeat(">", ctx.blockquoteLevel) + " " - if err := ctx.emit("\n"); err != nil { - return err - } - if ctx.blockquoteLevel == 1 { - if err := ctx.emit("\n"); err != nil { - return err - } - } - if err := ctx.traverseChildren(node); err != nil { - return err - } - ctx.blockquoteLevel-- - ctx.prefix = strings.Repeat(">", ctx.blockquoteLevel) - if ctx.blockquoteLevel > 0 { - ctx.prefix += " " - } - return ctx.emit("\n\n") - - case atom.Div: - if ctx.lineLength > 0 { - if err := ctx.emit("\n"); err != nil { - return err - } - } - if err := ctx.traverseChildren(node); err != nil { - return err - } - var err error - if ctx.justClosedDiv == false { - err = ctx.emit("\n") - } - ctx.justClosedDiv = true - return err - - case atom.Li: - if err := ctx.emit("* "); err != nil { - return err - } - - if err := ctx.traverseChildren(node); err != nil { - return err - } - - return ctx.emit("\n") - - case atom.B, atom.Strong: - subCtx := textifyTraverseCtx{} - subCtx.endsWithSpace = true - if err := subCtx.traverseChildren(node); err != nil { - return err - } - str := subCtx.Buf.String() - return ctx.emit("*" + str + "*") - - case atom.A: - // If image is the only child, take its alt text as the link text - if img := node.FirstChild; img != nil && node.LastChild == img && img.DataAtom == atom.Img { - if altText := getAttrVal(img, "alt"); altText != "" { - ctx.emit(altText) - } - } else if err := ctx.traverseChildren(node); err != nil { - return err - } - - hrefLink := "" - if attrVal := getAttrVal(node, "href"); attrVal != "" { - attrVal = ctx.normalizeHrefLink(attrVal) - if attrVal != "" { - hrefLink = "( " + attrVal + " )" - } - } - - return ctx.emit(hrefLink) - - case atom.P, atom.Ul, atom.Table: - if err := ctx.emit("\n\n"); err != nil { - return err - } - - if err := ctx.traverseChildren(node); err != nil { - return err - } - - return ctx.emit("\n\n") - - case atom.Tr: - if err := ctx.traverseChildren(node); err != nil { - return err - } - - return ctx.emit("\n") - - case atom.Style, atom.Script, atom.Head: - // Ignore the subtree - return nil - - default: - return ctx.traverseChildren(node) - } - } -} - -func (ctx *textifyTraverseCtx) traverseChildren(node *html.Node) error { - for c := node.FirstChild; c != nil; c = c.NextSibling { - if err := ctx.traverse(c); err != nil { - return err - } - } - - return nil -} - -func (ctx *textifyTraverseCtx) emit(data string) error { - if len(data) == 0 { - return nil - } - lines := ctx.breakLongLines(data) - var err error - for _, line := range lines { - runes := []rune(line) - startsWithSpace := unicode.IsSpace(runes[0]) - if !startsWithSpace && !ctx.endsWithSpace { - ctx.Buf.WriteByte(' ') - ctx.lineLength++ - } - ctx.endsWithSpace = unicode.IsSpace(runes[len(runes)-1]) - for _, c := range line { - _, err = ctx.Buf.WriteString(string(c)) - if err != nil { - return err - } - ctx.lineLength++ - if c == '\n' { - ctx.lineLength = 0 - if ctx.prefix != "" { - _, err = ctx.Buf.WriteString(ctx.prefix) - if err != nil { - return err - } - } - } - } - } - return nil -} - -func (ctx *textifyTraverseCtx) breakLongLines(data string) []string { - // only break lines when we are in blockquotes - if ctx.blockquoteLevel == 0 { - return []string{data} - } - var ret []string - runes := []rune(data) - l := len(runes) - existing := ctx.lineLength - if existing >= 74 { - ret = append(ret, "\n") - existing = 0 - } - for l+existing > 74 { - i := 74 - existing - for i >= 0 && !unicode.IsSpace(runes[i]) { - i-- - } - if i == -1 { - // no spaces, so go the other way - i = 74 - existing - for i < l && !unicode.IsSpace(runes[i]) { - i++ - } - } - ret = append(ret, string(runes[:i])+"\n") - for i < l && unicode.IsSpace(runes[i]) { - i++ - } - runes = runes[i:] - l = len(runes) - existing = 0 - } - if len(runes) > 0 { - ret = append(ret, string(runes)) - } - return ret -} - -func (ctx *textifyTraverseCtx) normalizeHrefLink(link string) string { - link = strings.TrimSpace(link) - link = strings.TrimPrefix(link, "mailto:") - return link -} - -func getAttrVal(node *html.Node, attrName string) string { - for _, attr := range node.Attr { - if attr.Key == attrName { - return attr.Val - } - } - - return "" -} - -func FromReader(reader io.Reader) (string, error) { - doc, err := html.Parse(reader) - if err != nil { - return "", err - } - - ctx := textifyTraverseCtx{ - Buf: bytes.Buffer{}, - } - if err = ctx.traverse(doc); err != nil { - return "", err - } - - text := strings.TrimSpace(newlineRe.ReplaceAllString( - strings.Replace(ctx.Buf.String(), "\n ", "\n", -1), "\n\n")) - return text, nil -} - -func FromString(input string) (string, error) { - text, err := FromReader(strings.NewReader(input)) - if err != nil { - return "", err - } - return text, nil -} diff --git a/vendor/github.com/joho/godotenv/.gitignore b/vendor/github.com/joho/godotenv/.gitignore deleted file mode 100644 index e43b0f9..0000000 --- a/vendor/github.com/joho/godotenv/.gitignore +++ /dev/null @@ -1 +0,0 @@ -.DS_Store diff --git a/vendor/github.com/joho/godotenv/LICENCE b/vendor/github.com/joho/godotenv/LICENCE deleted file mode 100644 index e7ddd51..0000000 --- a/vendor/github.com/joho/godotenv/LICENCE +++ /dev/null @@ -1,23 +0,0 @@ -Copyright (c) 2013 John Barton - -MIT License - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - diff --git a/vendor/github.com/joho/godotenv/README.md b/vendor/github.com/joho/godotenv/README.md deleted file mode 100644 index 05c47e6..0000000 --- a/vendor/github.com/joho/godotenv/README.md +++ /dev/null @@ -1,127 +0,0 @@ -# GoDotEnv [![wercker status](https://app.wercker.com/status/507594c2ec7e60f19403a568dfea0f78 "wercker status")](https://app.wercker.com/project/bykey/507594c2ec7e60f19403a568dfea0f78) - -A Go (golang) port of the Ruby dotenv project (which loads env vars from a .env file) - -From the original Library: - -> Storing configuration in the environment is one of the tenets of a twelve-factor app. Anything that is likely to change between deployment environments–such as resource handles for databases or credentials for external services–should be extracted from the code into environment variables. -> -> But it is not always practical to set environment variables on development machines or continuous integration servers where multiple projects are run. Dotenv load variables from a .env file into ENV when the environment is bootstrapped. - -It can be used as a library (for loading in env for your own daemons etc) or as a bin command. - -There is test coverage and CI for both linuxish and windows environments, but I make no guarantees about the bin version working on windows. - -## Installation - -As a library - -```shell -go get github.com/joho/godotenv -``` - -or if you want to use it as a bin command -```shell -go get github.com/joho/godotenv/cmd/godotenv -``` - -## Usage - -Add your application configuration to your `.env` file in the root of your project: - -```shell -S3_BUCKET=YOURS3BUCKET -SECRET_KEY=YOURSECRETKEYGOESHERE -``` - -Then in your Go app you can do something like - -```go -package main - -import ( - "github.com/joho/godotenv" - "log" - "os" -) - -func main() { - err := godotenv.Load() - if err != nil { - log.Fatal("Error loading .env file") - } - - s3Bucket := os.Getenv("S3_BUCKET") - secretKey := os.Getenv("SECRET_KEY") - - // now do something with s3 or whatever -} -``` - -If you're even lazier than that, you can just take advantage of the autoload package which will read in `.env` on import - -```go -import _ "github.com/joho/godotenv/autoload" -``` - -While `.env` in the project root is the default, you don't have to be constrained, both examples below are 100% legit - -```go -_ = godotenv.Load("somerandomfile") -_ = godotenv.Load("filenumberone.env", "filenumbertwo.env") -``` - -If you want to be really fancy with your env file you can do comments and exports (below is a valid env file) - -```shell -# I am a comment and that is OK -SOME_VAR=someval -FOO=BAR # comments at line end are OK too -export BAR=BAZ -``` - -Or finally you can do YAML(ish) style - -```yaml -FOO: bar -BAR: baz -``` - -as a final aside, if you don't want godotenv munging your env you can just get a map back instead - -```go -var myEnv map[string]string -myEnv, err := godotenv.Read() - -s3Bucket := myEnv["S3_BUCKET"] -``` - -### Command Mode - -Assuming you've installed the command as above and you've got `$GOPATH/bin` in your `$PATH` - -``` -godotenv -f /some/path/to/.env some_command with some args -``` - -If you don't specify `-f` it will fall back on the default of loading `.env` in `PWD` - -## Contributing - -Contributions are most welcome! The parser itself is pretty stupidly naive and I wouldn't be surprised if it breaks with edge cases. - -*code changes without tests will not be accepted* - -1. Fork it -2. Create your feature branch (`git checkout -b my-new-feature`) -3. Commit your changes (`git commit -am 'Added some feature'`) -4. Push to the branch (`git push origin my-new-feature`) -5. Create new Pull Request - -## CI - -Linux: [![wercker status](https://app.wercker.com/status/507594c2ec7e60f19403a568dfea0f78/m "wercker status")](https://app.wercker.com/project/bykey/507594c2ec7e60f19403a568dfea0f78) Windows: [![Build status](https://ci.appveyor.com/api/projects/status/9v40vnfvvgde64u4)](https://ci.appveyor.com/project/joho/godotenv) - -## Who? - -The original library [dotenv](https://github.com/bkeepers/dotenv) was written by [Brandon Keepers](http://opensoul.org/), and this port was done by [John Barton](http://whoisjohnbarton.com) based off the tests/fixtures in the original library. diff --git a/vendor/github.com/joho/godotenv/godotenv.go b/vendor/github.com/joho/godotenv/godotenv.go deleted file mode 100644 index a098dd2..0000000 --- a/vendor/github.com/joho/godotenv/godotenv.go +++ /dev/null @@ -1,235 +0,0 @@ -// Package godotenv is a go port of the ruby dotenv library (https://github.com/bkeepers/dotenv) -// -// Examples/readme can be found on the github page at https://github.com/joho/godotenv -// -// The TL;DR is that you make a .env file that looks something like -// -// SOME_ENV_VAR=somevalue -// -// and then in your go code you can call -// -// godotenv.Load() -// -// and all the env vars declared in .env will be avaiable through os.Getenv("SOME_ENV_VAR") -package godotenv - -import ( - "bufio" - "errors" - "os" - "os/exec" - "strings" -) - -// Load will read your env file(s) and load them into ENV for this process. -// -// Call this function as close as possible to the start of your program (ideally in main) -// -// If you call Load without any args it will default to loading .env in the current path -// -// You can otherwise tell it which files to load (there can be more than one) like -// -// godotenv.Load("fileone", "filetwo") -// -// It's important to note that it WILL NOT OVERRIDE an env variable that already exists - consider the .env file to set dev vars or sensible defaults -func Load(filenames ...string) (err error) { - filenames = filenamesOrDefault(filenames) - - for _, filename := range filenames { - err = loadFile(filename, false) - if err != nil { - return // return early on a spazout - } - } - return -} - -// Overload will read your env file(s) and load them into ENV for this process. -// -// Call this function as close as possible to the start of your program (ideally in main) -// -// If you call Overload without any args it will default to loading .env in the current path -// -// You can otherwise tell it which files to load (there can be more than one) like -// -// godotenv.Overload("fileone", "filetwo") -// -// It's important to note this WILL OVERRIDE an env variable that already exists - consider the .env file to forcefilly set all vars. -func Overload(filenames ...string) (err error) { - filenames = filenamesOrDefault(filenames) - - for _, filename := range filenames { - err = loadFile(filename, true) - if err != nil { - return // return early on a spazout - } - } - return -} - -// Read all env (with same file loading semantics as Load) but return values as -// a map rather than automatically writing values into env -func Read(filenames ...string) (envMap map[string]string, err error) { - filenames = filenamesOrDefault(filenames) - envMap = make(map[string]string) - - for _, filename := range filenames { - individualEnvMap, individualErr := readFile(filename) - - if individualErr != nil { - err = individualErr - return // return early on a spazout - } - - for key, value := range individualEnvMap { - envMap[key] = value - } - } - - return -} - -// Exec loads env vars from the specified filenames (empty map falls back to default) -// then executes the cmd specified. -// -// Simply hooks up os.Stdin/err/out to the command and calls Run() -// -// If you want more fine grained control over your command it's recommended -// that you use `Load()` or `Read()` and the `os/exec` package yourself. -func Exec(filenames []string, cmd string, cmdArgs []string) error { - Load(filenames...) - - command := exec.Command(cmd, cmdArgs...) - command.Stdin = os.Stdin - command.Stdout = os.Stdout - command.Stderr = os.Stderr - return command.Run() -} - -func filenamesOrDefault(filenames []string) []string { - if len(filenames) == 0 { - return []string{".env"} - } - return filenames -} - -func loadFile(filename string, overload bool) error { - envMap, err := readFile(filename) - if err != nil { - return err - } - - for key, value := range envMap { - if os.Getenv(key) == "" || overload { - os.Setenv(key, value) - } - } - - return nil -} - -func readFile(filename string) (envMap map[string]string, err error) { - file, err := os.Open(filename) - if err != nil { - return - } - defer file.Close() - - envMap = make(map[string]string) - - var lines []string - scanner := bufio.NewScanner(file) - for scanner.Scan() { - lines = append(lines, scanner.Text()) - } - - if err = scanner.Err(); err != nil { - return - } - - for _, fullLine := range lines { - if !isIgnoredLine(fullLine) { - var key, value string - key, value, err = parseLine(fullLine) - - if err != nil { - return - } - envMap[key] = value - } - } - return -} - -func parseLine(line string) (key string, value string, err error) { - if len(line) == 0 { - err = errors.New("zero length string") - return - } - - // ditch the comments (but keep quoted hashes) - if strings.Contains(line, "#") { - segmentsBetweenHashes := strings.Split(line, "#") - quotesAreOpen := false - var segmentsToKeep []string - for _, segment := range segmentsBetweenHashes { - if strings.Count(segment, "\"") == 1 || strings.Count(segment, "'") == 1 { - if quotesAreOpen { - quotesAreOpen = false - segmentsToKeep = append(segmentsToKeep, segment) - } else { - quotesAreOpen = true - } - } - - if len(segmentsToKeep) == 0 || quotesAreOpen { - segmentsToKeep = append(segmentsToKeep, segment) - } - } - - line = strings.Join(segmentsToKeep, "#") - } - - // now split key from value - splitString := strings.SplitN(line, "=", 2) - - if len(splitString) != 2 { - // try yaml mode! - splitString = strings.SplitN(line, ":", 2) - } - - if len(splitString) != 2 { - err = errors.New("Can't separate key from value") - return - } - - // Parse the key - key = splitString[0] - if strings.HasPrefix(key, "export") { - key = strings.TrimPrefix(key, "export") - } - key = strings.Trim(key, " ") - - // Parse the value - value = splitString[1] - // trim - value = strings.Trim(value, " ") - - // check if we've got quoted values - if strings.Count(value, "\"") == 2 || strings.Count(value, "'") == 2 { - // pull the quotes off the edges - value = strings.Trim(value, "\"'") - - // expand quotes - value = strings.Replace(value, "\\\"", "\"", -1) - // expand newlines - value = strings.Replace(value, "\\n", "\n", -1) - } - - return -} - -func isIgnoredLine(line string) bool { - trimmedLine := strings.Trim(line, " \n\t") - return len(trimmedLine) == 0 || strings.HasPrefix(trimmedLine, "#") -} diff --git a/vendor/github.com/joho/godotenv/wercker.yml b/vendor/github.com/joho/godotenv/wercker.yml deleted file mode 100644 index c716ac9..0000000 --- a/vendor/github.com/joho/godotenv/wercker.yml +++ /dev/null @@ -1 +0,0 @@ -box: pjvds/golang diff --git a/vendor/github.com/urfave/cli/.gitignore b/vendor/github.com/urfave/cli/.gitignore deleted file mode 100644 index faf70c4..0000000 --- a/vendor/github.com/urfave/cli/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -*.coverprofile -node_modules/ diff --git a/vendor/github.com/urfave/cli/.travis.yml b/vendor/github.com/urfave/cli/.travis.yml deleted file mode 100644 index 94836d7..0000000 --- a/vendor/github.com/urfave/cli/.travis.yml +++ /dev/null @@ -1,39 +0,0 @@ -language: go - -sudo: false - -cache: - directories: - - node_modules - -go: -- 1.2.x -- 1.3.x -- 1.4.2 -- 1.5.x -- 1.6.x -- 1.7.x -- master - -matrix: - allow_failures: - - go: master - include: - - go: 1.6.x - os: osx - - go: 1.7.x - os: osx - -before_script: -- go get github.com/urfave/gfmrun/... || true -- go get golang.org/x/tools/... || true -- if [ ! -f node_modules/.bin/markdown-toc ] ; then - npm install markdown-toc ; - fi - -script: -- ./runtests gen -- ./runtests vet -- ./runtests test -- ./runtests gfmrun -- ./runtests toc diff --git a/vendor/github.com/urfave/cli/CHANGELOG.md b/vendor/github.com/urfave/cli/CHANGELOG.md deleted file mode 100644 index 07f7546..0000000 --- a/vendor/github.com/urfave/cli/CHANGELOG.md +++ /dev/null @@ -1,392 +0,0 @@ -# Change Log - -**ATTN**: This project uses [semantic versioning](http://semver.org/). - -## [Unreleased] - -## [1.19.1] - 2016-11-21 - -### Fixed - -- Fixes regression introduced in 1.19.0 where using an `ActionFunc` as - the `Action` for a command would cause it to error rather than calling the - function. Should not have a affected declarative cases using `func(c - *cli.Context) err)`. -- Shell completion now handles the case where the user specifies - `--generate-bash-completion` immediately after a flag that takes an argument. - Previously it call the application with `--generate-bash-completion` as the - flag value. - -## [1.19.0] - 2016-11-19 -### Added -- `FlagsByName` was added to make it easy to sort flags (e.g. `sort.Sort(cli.FlagsByName(app.Flags))`) -- A `Description` field was added to `App` for a more detailed description of - the application (similar to the existing `Description` field on `Command`) -- Flag type code generation via `go generate` -- Write to stderr and exit 1 if action returns non-nil error -- Added support for TOML to the `altsrc` loader -- `SkipArgReorder` was added to allow users to skip the argument reordering. - This is useful if you want to consider all "flags" after an argument as - arguments rather than flags (the default behavior of the stdlib `flag` - library). This is backported functionality from the [removal of the flag - reordering](https://github.com/urfave/cli/pull/398) in the unreleased version - 2 -- For formatted errors (those implementing `ErrorFormatter`), the errors will - be formatted during output. Compatible with `pkg/errors`. - -### Changed -- Raise minimum tested/supported Go version to 1.2+ - -### Fixed -- Consider empty environment variables as set (previously environment variables - with the equivalent of `""` would be skipped rather than their value used). -- Return an error if the value in a given environment variable cannot be parsed - as the flag type. Previously these errors were silently swallowed. -- Print full error when an invalid flag is specified (which includes the invalid flag) -- `App.Writer` defaults to `stdout` when `nil` -- If no action is specified on a command or app, the help is now printed instead of `panic`ing -- `App.Metadata` is initialized automatically now (previously was `nil` unless initialized) -- Correctly show help message if `-h` is provided to a subcommand -- `context.(Global)IsSet` now respects environment variables. Previously it - would return `false` if a flag was specified in the environment rather than - as an argument -- Removed deprecation warnings to STDERR to avoid them leaking to the end-user -- `altsrc`s import paths were updated to use `gopkg.in/urfave/cli.v1`. This - fixes issues that occurred when `gopkg.in/urfave/cli.v1` was imported as well - as `altsrc` where Go would complain that the types didn't match - -## [1.18.1] - 2016-08-28 -### Fixed -- Removed deprecation warnings to STDERR to avoid them leaking to the end-user (backported) - -## [1.18.0] - 2016-06-27 -### Added -- `./runtests` test runner with coverage tracking by default -- testing on OS X -- testing on Windows -- `UintFlag`, `Uint64Flag`, and `Int64Flag` types and supporting code - -### Changed -- Use spaces for alignment in help/usage output instead of tabs, making the - output alignment consistent regardless of tab width - -### Fixed -- Printing of command aliases in help text -- Printing of visible flags for both struct and struct pointer flags -- Display the `help` subcommand when using `CommandCategories` -- No longer swallows `panic`s that occur within the `Action`s themselves when - detecting the signature of the `Action` field - -## [1.17.1] - 2016-08-28 -### Fixed -- Removed deprecation warnings to STDERR to avoid them leaking to the end-user - -## [1.17.0] - 2016-05-09 -### Added -- Pluggable flag-level help text rendering via `cli.DefaultFlagStringFunc` -- `context.GlobalBoolT` was added as an analogue to `context.GlobalBool` -- Support for hiding commands by setting `Hidden: true` -- this will hide the - commands in help output - -### Changed -- `Float64Flag`, `IntFlag`, and `DurationFlag` default values are no longer - quoted in help text output. -- All flag types now include `(default: {value})` strings following usage when a - default value can be (reasonably) detected. -- `IntSliceFlag` and `StringSliceFlag` usage strings are now more consistent - with non-slice flag types -- Apps now exit with a code of 3 if an unknown subcommand is specified - (previously they printed "No help topic for...", but still exited 0. This - makes it easier to script around apps built using `cli` since they can trust - that a 0 exit code indicated a successful execution. -- cleanups based on [Go Report Card - feedback](https://goreportcard.com/report/github.com/urfave/cli) - -## [1.16.1] - 2016-08-28 -### Fixed -- Removed deprecation warnings to STDERR to avoid them leaking to the end-user - -## [1.16.0] - 2016-05-02 -### Added -- `Hidden` field on all flag struct types to omit from generated help text - -### Changed -- `BashCompletionFlag` (`--enable-bash-completion`) is now omitted from -generated help text via the `Hidden` field - -### Fixed -- handling of error values in `HandleAction` and `HandleExitCoder` - -## [1.15.0] - 2016-04-30 -### Added -- This file! -- Support for placeholders in flag usage strings -- `App.Metadata` map for arbitrary data/state management -- `Set` and `GlobalSet` methods on `*cli.Context` for altering values after -parsing. -- Support for nested lookup of dot-delimited keys in structures loaded from -YAML. - -### Changed -- The `App.Action` and `Command.Action` now prefer a return signature of -`func(*cli.Context) error`, as defined by `cli.ActionFunc`. If a non-nil -`error` is returned, there may be two outcomes: - - If the error fulfills `cli.ExitCoder`, then `os.Exit` will be called - automatically - - Else the error is bubbled up and returned from `App.Run` -- Specifying an `Action` with the legacy return signature of -`func(*cli.Context)` will produce a deprecation message to stderr -- Specifying an `Action` that is not a `func` type will produce a non-zero exit -from `App.Run` -- Specifying an `Action` func that has an invalid (input) signature will -produce a non-zero exit from `App.Run` - -### Deprecated -- -`cli.App.RunAndExitOnError`, which should now be done by returning an error -that fulfills `cli.ExitCoder` to `cli.App.Run`. -- the legacy signature for -`cli.App.Action` of `func(*cli.Context)`, which should now have a return -signature of `func(*cli.Context) error`, as defined by `cli.ActionFunc`. - -### Fixed -- Added missing `*cli.Context.GlobalFloat64` method - -## [1.14.0] - 2016-04-03 (backfilled 2016-04-25) -### Added -- Codebeat badge -- Support for categorization via `CategorizedHelp` and `Categories` on app. - -### Changed -- Use `filepath.Base` instead of `path.Base` in `Name` and `HelpName`. - -### Fixed -- Ensure version is not shown in help text when `HideVersion` set. - -## [1.13.0] - 2016-03-06 (backfilled 2016-04-25) -### Added -- YAML file input support. -- `NArg` method on context. - -## [1.12.0] - 2016-02-17 (backfilled 2016-04-25) -### Added -- Custom usage error handling. -- Custom text support in `USAGE` section of help output. -- Improved help messages for empty strings. -- AppVeyor CI configuration. - -### Changed -- Removed `panic` from default help printer func. -- De-duping and optimizations. - -### Fixed -- Correctly handle `Before`/`After` at command level when no subcommands. -- Case of literal `-` argument causing flag reordering. -- Environment variable hints on Windows. -- Docs updates. - -## [1.11.1] - 2015-12-21 (backfilled 2016-04-25) -### Changed -- Use `path.Base` in `Name` and `HelpName` -- Export `GetName` on flag types. - -### Fixed -- Flag parsing when skipping is enabled. -- Test output cleanup. -- Move completion check to account for empty input case. - -## [1.11.0] - 2015-11-15 (backfilled 2016-04-25) -### Added -- Destination scan support for flags. -- Testing against `tip` in Travis CI config. - -### Changed -- Go version in Travis CI config. - -### Fixed -- Removed redundant tests. -- Use correct example naming in tests. - -## [1.10.2] - 2015-10-29 (backfilled 2016-04-25) -### Fixed -- Remove unused var in bash completion. - -## [1.10.1] - 2015-10-21 (backfilled 2016-04-25) -### Added -- Coverage and reference logos in README. - -### Fixed -- Use specified values in help and version parsing. -- Only display app version and help message once. - -## [1.10.0] - 2015-10-06 (backfilled 2016-04-25) -### Added -- More tests for existing functionality. -- `ArgsUsage` at app and command level for help text flexibility. - -### Fixed -- Honor `HideHelp` and `HideVersion` in `App.Run`. -- Remove juvenile word from README. - -## [1.9.0] - 2015-09-08 (backfilled 2016-04-25) -### Added -- `FullName` on command with accompanying help output update. -- Set default `$PROG` in bash completion. - -### Changed -- Docs formatting. - -### Fixed -- Removed self-referential imports in tests. - -## [1.8.0] - 2015-06-30 (backfilled 2016-04-25) -### Added -- Support for `Copyright` at app level. -- `Parent` func at context level to walk up context lineage. - -### Fixed -- Global flag processing at top level. - -## [1.7.1] - 2015-06-11 (backfilled 2016-04-25) -### Added -- Aggregate errors from `Before`/`After` funcs. -- Doc comments on flag structs. -- Include non-global flags when checking version and help. -- Travis CI config updates. - -### Fixed -- Ensure slice type flags have non-nil values. -- Collect global flags from the full command hierarchy. -- Docs prose. - -## [1.7.0] - 2015-05-03 (backfilled 2016-04-25) -### Changed -- `HelpPrinter` signature includes output writer. - -### Fixed -- Specify go 1.1+ in docs. -- Set `Writer` when running command as app. - -## [1.6.0] - 2015-03-23 (backfilled 2016-04-25) -### Added -- Multiple author support. -- `NumFlags` at context level. -- `Aliases` at command level. - -### Deprecated -- `ShortName` at command level. - -### Fixed -- Subcommand help output. -- Backward compatible support for deprecated `Author` and `Email` fields. -- Docs regarding `Names`/`Aliases`. - -## [1.5.0] - 2015-02-20 (backfilled 2016-04-25) -### Added -- `After` hook func support at app and command level. - -### Fixed -- Use parsed context when running command as subcommand. -- Docs prose. - -## [1.4.1] - 2015-01-09 (backfilled 2016-04-25) -### Added -- Support for hiding `-h / --help` flags, but not `help` subcommand. -- Stop flag parsing after `--`. - -### Fixed -- Help text for generic flags to specify single value. -- Use double quotes in output for defaults. -- Use `ParseInt` instead of `ParseUint` for int environment var values. -- Use `0` as base when parsing int environment var values. - -## [1.4.0] - 2014-12-12 (backfilled 2016-04-25) -### Added -- Support for environment variable lookup "cascade". -- Support for `Stdout` on app for output redirection. - -### Fixed -- Print command help instead of app help in `ShowCommandHelp`. - -## [1.3.1] - 2014-11-13 (backfilled 2016-04-25) -### Added -- Docs and example code updates. - -### Changed -- Default `-v / --version` flag made optional. - -## [1.3.0] - 2014-08-10 (backfilled 2016-04-25) -### Added -- `FlagNames` at context level. -- Exposed `VersionPrinter` var for more control over version output. -- Zsh completion hook. -- `AUTHOR` section in default app help template. -- Contribution guidelines. -- `DurationFlag` type. - -## [1.2.0] - 2014-08-02 -### Added -- Support for environment variable defaults on flags plus tests. - -## [1.1.0] - 2014-07-15 -### Added -- Bash completion. -- Optional hiding of built-in help command. -- Optional skipping of flag parsing at command level. -- `Author`, `Email`, and `Compiled` metadata on app. -- `Before` hook func support at app and command level. -- `CommandNotFound` func support at app level. -- Command reference available on context. -- `GenericFlag` type. -- `Float64Flag` type. -- `BoolTFlag` type. -- `IsSet` flag helper on context. -- More flag lookup funcs at context level. -- More tests & docs. - -### Changed -- Help template updates to account for presence/absence of flags. -- Separated subcommand help template. -- Exposed `HelpPrinter` var for more control over help output. - -## [1.0.0] - 2013-11-01 -### Added -- `help` flag in default app flag set and each command flag set. -- Custom handling of argument parsing errors. -- Command lookup by name at app level. -- `StringSliceFlag` type and supporting `StringSlice` type. -- `IntSliceFlag` type and supporting `IntSlice` type. -- Slice type flag lookups by name at context level. -- Export of app and command help functions. -- More tests & docs. - -## 0.1.0 - 2013-07-22 -### Added -- Initial implementation. - -[Unreleased]: https://github.com/urfave/cli/compare/v1.18.0...HEAD -[1.18.0]: https://github.com/urfave/cli/compare/v1.17.0...v1.18.0 -[1.17.0]: https://github.com/urfave/cli/compare/v1.16.0...v1.17.0 -[1.16.0]: https://github.com/urfave/cli/compare/v1.15.0...v1.16.0 -[1.15.0]: https://github.com/urfave/cli/compare/v1.14.0...v1.15.0 -[1.14.0]: https://github.com/urfave/cli/compare/v1.13.0...v1.14.0 -[1.13.0]: https://github.com/urfave/cli/compare/v1.12.0...v1.13.0 -[1.12.0]: https://github.com/urfave/cli/compare/v1.11.1...v1.12.0 -[1.11.1]: https://github.com/urfave/cli/compare/v1.11.0...v1.11.1 -[1.11.0]: https://github.com/urfave/cli/compare/v1.10.2...v1.11.0 -[1.10.2]: https://github.com/urfave/cli/compare/v1.10.1...v1.10.2 -[1.10.1]: https://github.com/urfave/cli/compare/v1.10.0...v1.10.1 -[1.10.0]: https://github.com/urfave/cli/compare/v1.9.0...v1.10.0 -[1.9.0]: https://github.com/urfave/cli/compare/v1.8.0...v1.9.0 -[1.8.0]: https://github.com/urfave/cli/compare/v1.7.1...v1.8.0 -[1.7.1]: https://github.com/urfave/cli/compare/v1.7.0...v1.7.1 -[1.7.0]: https://github.com/urfave/cli/compare/v1.6.0...v1.7.0 -[1.6.0]: https://github.com/urfave/cli/compare/v1.5.0...v1.6.0 -[1.5.0]: https://github.com/urfave/cli/compare/v1.4.1...v1.5.0 -[1.4.1]: https://github.com/urfave/cli/compare/v1.4.0...v1.4.1 -[1.4.0]: https://github.com/urfave/cli/compare/v1.3.1...v1.4.0 -[1.3.1]: https://github.com/urfave/cli/compare/v1.3.0...v1.3.1 -[1.3.0]: https://github.com/urfave/cli/compare/v1.2.0...v1.3.0 -[1.2.0]: https://github.com/urfave/cli/compare/v1.1.0...v1.2.0 -[1.1.0]: https://github.com/urfave/cli/compare/v1.0.0...v1.1.0 -[1.0.0]: https://github.com/urfave/cli/compare/v0.1.0...v1.0.0 diff --git a/vendor/github.com/urfave/cli/LICENSE b/vendor/github.com/urfave/cli/LICENSE deleted file mode 100644 index 42a597e..0000000 --- a/vendor/github.com/urfave/cli/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2016 Jeremy Saenz & Contributors - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/urfave/cli/README.md b/vendor/github.com/urfave/cli/README.md deleted file mode 100644 index bb5f61e..0000000 --- a/vendor/github.com/urfave/cli/README.md +++ /dev/null @@ -1,1364 +0,0 @@ -cli -=== - -[![Build Status](https://travis-ci.org/urfave/cli.svg?branch=master)](https://travis-ci.org/urfave/cli) -[![Windows Build Status](https://ci.appveyor.com/api/projects/status/rtgk5xufi932pb2v?svg=true)](https://ci.appveyor.com/project/urfave/cli) -[![GoDoc](https://godoc.org/github.com/urfave/cli?status.svg)](https://godoc.org/github.com/urfave/cli) -[![codebeat](https://codebeat.co/badges/0a8f30aa-f975-404b-b878-5fab3ae1cc5f)](https://codebeat.co/projects/github-com-urfave-cli) -[![Go Report Card](https://goreportcard.com/badge/urfave/cli)](https://goreportcard.com/report/urfave/cli) -[![top level coverage](https://gocover.io/_badge/github.com/urfave/cli?0 "top level coverage")](http://gocover.io/github.com/urfave/cli) / -[![altsrc coverage](https://gocover.io/_badge/github.com/urfave/cli/altsrc?0 "altsrc coverage")](http://gocover.io/github.com/urfave/cli/altsrc) - -**Notice:** This is the library formerly known as -`github.com/codegangsta/cli` -- Github will automatically redirect requests -to this repository, but we recommend updating your references for clarity. - -cli is a simple, fast, and fun package for building command line apps in Go. The -goal is to enable developers to write fast and distributable command line -applications in an expressive way. - - - -- [Overview](#overview) -- [Installation](#installation) - * [Supported platforms](#supported-platforms) - * [Using the `v2` branch](#using-the-v2-branch) - * [Pinning to the `v1` releases](#pinning-to-the-v1-releases) -- [Getting Started](#getting-started) -- [Examples](#examples) - * [Arguments](#arguments) - * [Flags](#flags) - + [Placeholder Values](#placeholder-values) - + [Alternate Names](#alternate-names) - + [Ordering](#ordering) - + [Values from the Environment](#values-from-the-environment) - + [Values from alternate input sources (YAML, TOML, and others)](#values-from-alternate-input-sources-yaml-toml-and-others) - * [Subcommands](#subcommands) - * [Subcommands categories](#subcommands-categories) - * [Exit code](#exit-code) - * [Bash Completion](#bash-completion) - + [Enabling](#enabling) - + [Distribution](#distribution) - + [Customization](#customization) - * [Generated Help Text](#generated-help-text) - + [Customization](#customization-1) - * [Version Flag](#version-flag) - + [Customization](#customization-2) - + [Full API Example](#full-api-example) -- [Contribution Guidelines](#contribution-guidelines) - - - -## Overview - -Command line apps are usually so tiny that there is absolutely no reason why -your code should *not* be self-documenting. Things like generating help text and -parsing command flags/options should not hinder productivity when writing a -command line app. - -**This is where cli comes into play.** cli makes command line programming fun, -organized, and expressive! - -## Installation - -Make sure you have a working Go environment. Go version 1.2+ is supported. [See -the install instructions for Go](http://golang.org/doc/install.html). - -To install cli, simply run: -``` -$ go get github.com/urfave/cli -``` - -Make sure your `PATH` includes the `$GOPATH/bin` directory so your commands can -be easily used: -``` -export PATH=$PATH:$GOPATH/bin -``` - -### Supported platforms - -cli is tested against multiple versions of Go on Linux, and against the latest -released version of Go on OS X and Windows. For full details, see -[`./.travis.yml`](./.travis.yml) and [`./appveyor.yml`](./appveyor.yml). - -### Using the `v2` branch - -**Warning**: The `v2` branch is currently unreleased and considered unstable. - -There is currently a long-lived branch named `v2` that is intended to land as -the new `master` branch once development there has settled down. The current -`master` branch (mirrored as `v1`) is being manually merged into `v2` on -an irregular human-based schedule, but generally if one wants to "upgrade" to -`v2` *now* and accept the volatility (read: "awesomeness") that comes along with -that, please use whatever version pinning of your preference, such as via -`gopkg.in`: - -``` -$ go get gopkg.in/urfave/cli.v2 -``` - -``` go -... -import ( - "gopkg.in/urfave/cli.v2" // imports as package "cli" -) -... -``` - -### Pinning to the `v1` releases - -Similarly to the section above describing use of the `v2` branch, if one wants -to avoid any unexpected compatibility pains once `v2` becomes `master`, then -pinning to `v1` is an acceptable option, e.g.: - -``` -$ go get gopkg.in/urfave/cli.v1 -``` - -``` go -... -import ( - "gopkg.in/urfave/cli.v1" // imports as package "cli" -) -... -``` - -This will pull the latest tagged `v1` release (e.g. `v1.18.1` at the time of writing). - -## Getting Started - -One of the philosophies behind cli is that an API should be playful and full of -discovery. So a cli app can be as little as one line of code in `main()`. - - -``` go -package main - -import ( - "os" - - "github.com/urfave/cli" -) - -func main() { - cli.NewApp().Run(os.Args) -} -``` - -This app will run and show help text, but is not very useful. Let's give an -action to execute and some help documentation: - - -``` go -package main - -import ( - "fmt" - "os" - - "github.com/urfave/cli" -) - -func main() { - app := cli.NewApp() - app.Name = "boom" - app.Usage = "make an explosive entrance" - app.Action = func(c *cli.Context) error { - fmt.Println("boom! I say!") - return nil - } - - app.Run(os.Args) -} -``` - -Running this already gives you a ton of functionality, plus support for things -like subcommands and flags, which are covered below. - -## Examples - -Being a programmer can be a lonely job. Thankfully by the power of automation -that is not the case! Let's create a greeter app to fend off our demons of -loneliness! - -Start by creating a directory named `greet`, and within it, add a file, -`greet.go` with the following code in it: - - -``` go -package main - -import ( - "fmt" - "os" - - "github.com/urfave/cli" -) - -func main() { - app := cli.NewApp() - app.Name = "greet" - app.Usage = "fight the loneliness!" - app.Action = func(c *cli.Context) error { - fmt.Println("Hello friend!") - return nil - } - - app.Run(os.Args) -} -``` - -Install our command to the `$GOPATH/bin` directory: - -``` -$ go install -``` - -Finally run our new command: - -``` -$ greet -Hello friend! -``` - -cli also generates neat help text: - -``` -$ greet help -NAME: - greet - fight the loneliness! - -USAGE: - greet [global options] command [command options] [arguments...] - -VERSION: - 0.0.0 - -COMMANDS: - help, h Shows a list of commands or help for one command - -GLOBAL OPTIONS - --version Shows version information -``` - -### Arguments - -You can lookup arguments by calling the `Args` function on `cli.Context`, e.g.: - - -``` go -package main - -import ( - "fmt" - "os" - - "github.com/urfave/cli" -) - -func main() { - app := cli.NewApp() - - app.Action = func(c *cli.Context) error { - fmt.Printf("Hello %q", c.Args().Get(0)) - return nil - } - - app.Run(os.Args) -} -``` - -### Flags - -Setting and querying flags is simple. - - -``` go -package main - -import ( - "fmt" - "os" - - "github.com/urfave/cli" -) - -func main() { - app := cli.NewApp() - - app.Flags = []cli.Flag { - cli.StringFlag{ - Name: "lang", - Value: "english", - Usage: "language for the greeting", - }, - } - - app.Action = func(c *cli.Context) error { - name := "Nefertiti" - if c.NArg() > 0 { - name = c.Args().Get(0) - } - if c.String("lang") == "spanish" { - fmt.Println("Hola", name) - } else { - fmt.Println("Hello", name) - } - return nil - } - - app.Run(os.Args) -} -``` - -You can also set a destination variable for a flag, to which the content will be -scanned. - - -``` go -package main - -import ( - "os" - "fmt" - - "github.com/urfave/cli" -) - -func main() { - var language string - - app := cli.NewApp() - - app.Flags = []cli.Flag { - cli.StringFlag{ - Name: "lang", - Value: "english", - Usage: "language for the greeting", - Destination: &language, - }, - } - - app.Action = func(c *cli.Context) error { - name := "someone" - if c.NArg() > 0 { - name = c.Args()[0] - } - if language == "spanish" { - fmt.Println("Hola", name) - } else { - fmt.Println("Hello", name) - } - return nil - } - - app.Run(os.Args) -} -``` - -See full list of flags at http://godoc.org/github.com/urfave/cli - -#### Placeholder Values - -Sometimes it's useful to specify a flag's value within the usage string itself. -Such placeholders are indicated with back quotes. - -For example this: - - -```go -package main - -import ( - "os" - - "github.com/urfave/cli" -) - -func main() { - app := cli.NewApp() - - app.Flags = []cli.Flag{ - cli.StringFlag{ - Name: "config, c", - Usage: "Load configuration from `FILE`", - }, - } - - app.Run(os.Args) -} -``` - -Will result in help output like: - -``` ---config FILE, -c FILE Load configuration from FILE -``` - -Note that only the first placeholder is used. Subsequent back-quoted words will -be left as-is. - -#### Alternate Names - -You can set alternate (or short) names for flags by providing a comma-delimited -list for the `Name`. e.g. - - -``` go -package main - -import ( - "os" - - "github.com/urfave/cli" -) - -func main() { - app := cli.NewApp() - - app.Flags = []cli.Flag { - cli.StringFlag{ - Name: "lang, l", - Value: "english", - Usage: "language for the greeting", - }, - } - - app.Run(os.Args) -} -``` - -That flag can then be set with `--lang spanish` or `-l spanish`. Note that -giving two different forms of the same flag in the same command invocation is an -error. - -#### Ordering - -Flags for the application and commands are shown in the order they are defined. -However, it's possible to sort them from outside this library by using `FlagsByName` -with `sort`. - -For example this: - - -``` go -package main - -import ( - "os" - "sort" - - "github.com/urfave/cli" -) - -func main() { - app := cli.NewApp() - - app.Flags = []cli.Flag { - cli.StringFlag{ - Name: "lang, l", - Value: "english", - Usage: "Language for the greeting", - }, - cli.StringFlag{ - Name: "config, c", - Usage: "Load configuration from `FILE`", - }, - } - - sort.Sort(cli.FlagsByName(app.Flags)) - - app.Run(os.Args) -} -``` - -Will result in help output like: - -``` ---config FILE, -c FILE Load configuration from FILE ---lang value, -l value Language for the greeting (default: "english") -``` - -#### Values from the Environment - -You can also have the default value set from the environment via `EnvVar`. e.g. - - -``` go -package main - -import ( - "os" - - "github.com/urfave/cli" -) - -func main() { - app := cli.NewApp() - - app.Flags = []cli.Flag { - cli.StringFlag{ - Name: "lang, l", - Value: "english", - Usage: "language for the greeting", - EnvVar: "APP_LANG", - }, - } - - app.Run(os.Args) -} -``` - -The `EnvVar` may also be given as a comma-delimited "cascade", where the first -environment variable that resolves is used as the default. - - -``` go -package main - -import ( - "os" - - "github.com/urfave/cli" -) - -func main() { - app := cli.NewApp() - - app.Flags = []cli.Flag { - cli.StringFlag{ - Name: "lang, l", - Value: "english", - Usage: "language for the greeting", - EnvVar: "LEGACY_COMPAT_LANG,APP_LANG,LANG", - }, - } - - app.Run(os.Args) -} -``` - -#### Values from alternate input sources (YAML, TOML, and others) - -There is a separate package altsrc that adds support for getting flag values -from other file input sources. - -Currently supported input source formats: -* YAML -* TOML - -In order to get values for a flag from an alternate input source the following -code would be added to wrap an existing cli.Flag like below: - -``` go - altsrc.NewIntFlag(cli.IntFlag{Name: "test"}) -``` - -Initialization must also occur for these flags. Below is an example initializing -getting data from a yaml file below. - -``` go - command.Before = altsrc.InitInputSourceWithContext(command.Flags, NewYamlSourceFromFlagFunc("load")) -``` - -The code above will use the "load" string as a flag name to get the file name of -a yaml file from the cli.Context. It will then use that file name to initialize -the yaml input source for any flags that are defined on that command. As a note -the "load" flag used would also have to be defined on the command flags in order -for this code snipped to work. - -Currently only the aboved specified formats are supported but developers can -add support for other input sources by implementing the -altsrc.InputSourceContext for their given sources. - -Here is a more complete sample of a command using YAML support: - - -``` go -package notmain - -import ( - "fmt" - "os" - - "github.com/urfave/cli" - "github.com/urfave/cli/altsrc" -) - -func main() { - app := cli.NewApp() - - flags := []cli.Flag{ - altsrc.NewIntFlag(cli.IntFlag{Name: "test"}), - cli.StringFlag{Name: "load"}, - } - - app.Action = func(c *cli.Context) error { - fmt.Println("yaml ist rad") - return nil - } - - app.Before = altsrc.InitInputSourceWithContext(flags, altsrc.NewYamlSourceFromFlagFunc("load")) - app.Flags = flags - - app.Run(os.Args) -} -``` - -### Subcommands - -Subcommands can be defined for a more git-like command line app. - - -```go -package main - -import ( - "fmt" - "os" - - "github.com/urfave/cli" -) - -func main() { - app := cli.NewApp() - - app.Commands = []cli.Command{ - { - Name: "add", - Aliases: []string{"a"}, - Usage: "add a task to the list", - Action: func(c *cli.Context) error { - fmt.Println("added task: ", c.Args().First()) - return nil - }, - }, - { - Name: "complete", - Aliases: []string{"c"}, - Usage: "complete a task on the list", - Action: func(c *cli.Context) error { - fmt.Println("completed task: ", c.Args().First()) - return nil - }, - }, - { - Name: "template", - Aliases: []string{"t"}, - Usage: "options for task templates", - Subcommands: []cli.Command{ - { - Name: "add", - Usage: "add a new template", - Action: func(c *cli.Context) error { - fmt.Println("new task template: ", c.Args().First()) - return nil - }, - }, - { - Name: "remove", - Usage: "remove an existing template", - Action: func(c *cli.Context) error { - fmt.Println("removed task template: ", c.Args().First()) - return nil - }, - }, - }, - }, - } - - app.Run(os.Args) -} -``` - -### Subcommands categories - -For additional organization in apps that have many subcommands, you can -associate a category for each command to group them together in the help -output. - -E.g. - -```go -package main - -import ( - "os" - - "github.com/urfave/cli" -) - -func main() { - app := cli.NewApp() - - app.Commands = []cli.Command{ - { - Name: "noop", - }, - { - Name: "add", - Category: "template", - }, - { - Name: "remove", - Category: "template", - }, - } - - app.Run(os.Args) -} -``` - -Will include: - -``` -COMMANDS: - noop - - Template actions: - add - remove -``` - -### Exit code - -Calling `App.Run` will not automatically call `os.Exit`, which means that by -default the exit code will "fall through" to being `0`. An explicit exit code -may be set by returning a non-nil error that fulfills `cli.ExitCoder`, *or* a -`cli.MultiError` that includes an error that fulfills `cli.ExitCoder`, e.g.: - -``` go -package main - -import ( - "os" - - "github.com/urfave/cli" -) - -func main() { - app := cli.NewApp() - app.Flags = []cli.Flag{ - cli.BoolTFlag{ - Name: "ginger-crouton", - Usage: "is it in the soup?", - }, - } - app.Action = func(ctx *cli.Context) error { - if !ctx.Bool("ginger-crouton") { - return cli.NewExitError("it is not in the soup", 86) - } - return nil - } - - app.Run(os.Args) -} -``` - -### Bash Completion - -You can enable completion commands by setting the `EnableBashCompletion` -flag on the `App` object. By default, this setting will only auto-complete to -show an app's subcommands, but you can write your own completion methods for -the App or its subcommands. - - -``` go -package main - -import ( - "fmt" - "os" - - "github.com/urfave/cli" -) - -func main() { - tasks := []string{"cook", "clean", "laundry", "eat", "sleep", "code"} - - app := cli.NewApp() - app.EnableBashCompletion = true - app.Commands = []cli.Command{ - { - Name: "complete", - Aliases: []string{"c"}, - Usage: "complete a task on the list", - Action: func(c *cli.Context) error { - fmt.Println("completed task: ", c.Args().First()) - return nil - }, - BashComplete: func(c *cli.Context) { - // This will complete if no args are passed - if c.NArg() > 0 { - return - } - for _, t := range tasks { - fmt.Println(t) - } - }, - }, - } - - app.Run(os.Args) -} -``` - -#### Enabling - -Source the `autocomplete/bash_autocomplete` file in your `.bashrc` file while -setting the `PROG` variable to the name of your program: - -`PROG=myprogram source /.../cli/autocomplete/bash_autocomplete` - -#### Distribution - -Copy `autocomplete/bash_autocomplete` into `/etc/bash_completion.d/` and rename -it to the name of the program you wish to add autocomplete support for (or -automatically install it there if you are distributing a package). Don't forget -to source the file to make it active in the current shell. - -``` -sudo cp src/bash_autocomplete /etc/bash_completion.d/ -source /etc/bash_completion.d/ -``` - -Alternatively, you can just document that users should source the generic -`autocomplete/bash_autocomplete` in their bash configuration with `$PROG` set -to the name of their program (as above). - -#### Customization - -The default bash completion flag (`--generate-bash-completion`) is defined as -`cli.BashCompletionFlag`, and may be redefined if desired, e.g.: - - -``` go -package main - -import ( - "os" - - "github.com/urfave/cli" -) - -func main() { - cli.BashCompletionFlag = cli.BoolFlag{ - Name: "compgen", - Hidden: true, - } - - app := cli.NewApp() - app.EnableBashCompletion = true - app.Commands = []cli.Command{ - { - Name: "wat", - }, - } - app.Run(os.Args) -} -``` - -### Generated Help Text - -The default help flag (`-h/--help`) is defined as `cli.HelpFlag` and is checked -by the cli internals in order to print generated help text for the app, command, -or subcommand, and break execution. - -#### Customization - -All of the help text generation may be customized, and at multiple levels. The -templates are exposed as variables `AppHelpTemplate`, `CommandHelpTemplate`, and -`SubcommandHelpTemplate` which may be reassigned or augmented, and full override -is possible by assigning a compatible func to the `cli.HelpPrinter` variable, -e.g.: - - -``` go -package main - -import ( - "fmt" - "io" - "os" - - "github.com/urfave/cli" -) - -func main() { - // EXAMPLE: Append to an existing template - cli.AppHelpTemplate = fmt.Sprintf(`%s - -WEBSITE: http://awesometown.example.com - -SUPPORT: support@awesometown.example.com - -`, cli.AppHelpTemplate) - - // EXAMPLE: Override a template - cli.AppHelpTemplate = `NAME: - {{.Name}} - {{.Usage}} -USAGE: - {{.HelpName}} {{if .VisibleFlags}}[global options]{{end}}{{if .Commands}} command -[command options]{{end}} {{if -.ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}} - {{if len .Authors}} -AUTHOR(S): - {{range .Authors}}{{ . }}{{end}} - {{end}}{{if .Commands}} -COMMANDS: -{{range .Commands}}{{if not .HideHelp}} {{join .Names ", "}}{{ "\t" -}}{{.Usage}}{{ "\n" }}{{end}}{{end}}{{end}}{{if .VisibleFlags}} -GLOBAL OPTIONS: - {{range .VisibleFlags}}{{.}} - {{end}}{{end}}{{if .Copyright }} -COPYRIGHT: - {{.Copyright}} - {{end}}{{if .Version}} -VERSION: - {{.Version}} - {{end}} -` - - // EXAMPLE: Replace the `HelpPrinter` func - cli.HelpPrinter = func(w io.Writer, templ string, data interface{}) { - fmt.Println("Ha HA. I pwnd the help!!1") - } - - cli.NewApp().Run(os.Args) -} -``` - -The default flag may be customized to something other than `-h/--help` by -setting `cli.HelpFlag`, e.g.: - - -``` go -package main - -import ( - "os" - - "github.com/urfave/cli" -) - -func main() { - cli.HelpFlag = cli.BoolFlag{ - Name: "halp, haaaaalp", - Usage: "HALP", - EnvVar: "SHOW_HALP,HALPPLZ", - } - - cli.NewApp().Run(os.Args) -} -``` - -### Version Flag - -The default version flag (`-v/--version`) is defined as `cli.VersionFlag`, which -is checked by the cli internals in order to print the `App.Version` via -`cli.VersionPrinter` and break execution. - -#### Customization - -The default flag may be customized to something other than `-v/--version` by -setting `cli.VersionFlag`, e.g.: - - -``` go -package main - -import ( - "os" - - "github.com/urfave/cli" -) - -func main() { - cli.VersionFlag = cli.BoolFlag{ - Name: "print-version, V", - Usage: "print only the version", - } - - app := cli.NewApp() - app.Name = "partay" - app.Version = "19.99.0" - app.Run(os.Args) -} -``` - -Alternatively, the version printer at `cli.VersionPrinter` may be overridden, e.g.: - - -``` go -package main - -import ( - "fmt" - "os" - - "github.com/urfave/cli" -) - -var ( - Revision = "fafafaf" -) - -func main() { - cli.VersionPrinter = func(c *cli.Context) { - fmt.Printf("version=%s revision=%s\n", c.App.Version, Revision) - } - - app := cli.NewApp() - app.Name = "partay" - app.Version = "19.99.0" - app.Run(os.Args) -} -``` - -#### Full API Example - -**Notice**: This is a contrived (functioning) example meant strictly for API -demonstration purposes. Use of one's imagination is encouraged. - - -``` go -package main - -import ( - "errors" - "flag" - "fmt" - "io" - "io/ioutil" - "os" - "time" - - "github.com/urfave/cli" -) - -func init() { - cli.AppHelpTemplate += "\nCUSTOMIZED: you bet ur muffins\n" - cli.CommandHelpTemplate += "\nYMMV\n" - cli.SubcommandHelpTemplate += "\nor something\n" - - cli.HelpFlag = cli.BoolFlag{Name: "halp"} - cli.BashCompletionFlag = cli.BoolFlag{Name: "compgen", Hidden: true} - cli.VersionFlag = cli.BoolFlag{Name: "print-version, V"} - - cli.HelpPrinter = func(w io.Writer, templ string, data interface{}) { - fmt.Fprintf(w, "best of luck to you\n") - } - cli.VersionPrinter = func(c *cli.Context) { - fmt.Fprintf(c.App.Writer, "version=%s\n", c.App.Version) - } - cli.OsExiter = func(c int) { - fmt.Fprintf(cli.ErrWriter, "refusing to exit %d\n", c) - } - cli.ErrWriter = ioutil.Discard - cli.FlagStringer = func(fl cli.Flag) string { - return fmt.Sprintf("\t\t%s", fl.GetName()) - } -} - -type hexWriter struct{} - -func (w *hexWriter) Write(p []byte) (int, error) { - for _, b := range p { - fmt.Printf("%x", b) - } - fmt.Printf("\n") - - return len(p), nil -} - -type genericType struct{ - s string -} - -func (g *genericType) Set(value string) error { - g.s = value - return nil -} - -func (g *genericType) String() string { - return g.s -} - -func main() { - app := cli.NewApp() - app.Name = "kənˈtrīv" - app.Version = "19.99.0" - app.Compiled = time.Now() - app.Authors = []cli.Author{ - cli.Author{ - Name: "Example Human", - Email: "human@example.com", - }, - } - app.Copyright = "(c) 1999 Serious Enterprise" - app.HelpName = "contrive" - app.Usage = "demonstrate available API" - app.UsageText = "contrive - demonstrating the available API" - app.ArgsUsage = "[args and such]" - app.Commands = []cli.Command{ - cli.Command{ - Name: "doo", - Aliases: []string{"do"}, - Category: "motion", - Usage: "do the doo", - UsageText: "doo - does the dooing", - Description: "no really, there is a lot of dooing to be done", - ArgsUsage: "[arrgh]", - Flags: []cli.Flag{ - cli.BoolFlag{Name: "forever, forevvarr"}, - }, - Subcommands: cli.Commands{ - cli.Command{ - Name: "wop", - Action: wopAction, - }, - }, - SkipFlagParsing: false, - HideHelp: false, - Hidden: false, - HelpName: "doo!", - BashComplete: func(c *cli.Context) { - fmt.Fprintf(c.App.Writer, "--better\n") - }, - Before: func(c *cli.Context) error { - fmt.Fprintf(c.App.Writer, "brace for impact\n") - return nil - }, - After: func(c *cli.Context) error { - fmt.Fprintf(c.App.Writer, "did we lose anyone?\n") - return nil - }, - Action: func(c *cli.Context) error { - c.Command.FullName() - c.Command.HasName("wop") - c.Command.Names() - c.Command.VisibleFlags() - fmt.Fprintf(c.App.Writer, "dodododododoodododddooooododododooo\n") - if c.Bool("forever") { - c.Command.Run(c) - } - return nil - }, - OnUsageError: func(c *cli.Context, err error, isSubcommand bool) error { - fmt.Fprintf(c.App.Writer, "for shame\n") - return err - }, - }, - } - app.Flags = []cli.Flag{ - cli.BoolFlag{Name: "fancy"}, - cli.BoolTFlag{Name: "fancier"}, - cli.DurationFlag{Name: "howlong, H", Value: time.Second * 3}, - cli.Float64Flag{Name: "howmuch"}, - cli.GenericFlag{Name: "wat", Value: &genericType{}}, - cli.Int64Flag{Name: "longdistance"}, - cli.Int64SliceFlag{Name: "intervals"}, - cli.IntFlag{Name: "distance"}, - cli.IntSliceFlag{Name: "times"}, - cli.StringFlag{Name: "dance-move, d"}, - cli.StringSliceFlag{Name: "names, N"}, - cli.UintFlag{Name: "age"}, - cli.Uint64Flag{Name: "bigage"}, - } - app.EnableBashCompletion = true - app.HideHelp = false - app.HideVersion = false - app.BashComplete = func(c *cli.Context) { - fmt.Fprintf(c.App.Writer, "lipstick\nkiss\nme\nlipstick\nringo\n") - } - app.Before = func(c *cli.Context) error { - fmt.Fprintf(c.App.Writer, "HEEEERE GOES\n") - return nil - } - app.After = func(c *cli.Context) error { - fmt.Fprintf(c.App.Writer, "Phew!\n") - return nil - } - app.CommandNotFound = func(c *cli.Context, command string) { - fmt.Fprintf(c.App.Writer, "Thar be no %q here.\n", command) - } - app.OnUsageError = func(c *cli.Context, err error, isSubcommand bool) error { - if isSubcommand { - return err - } - - fmt.Fprintf(c.App.Writer, "WRONG: %#v\n", err) - return nil - } - app.Action = func(c *cli.Context) error { - cli.DefaultAppComplete(c) - cli.HandleExitCoder(errors.New("not an exit coder, though")) - cli.ShowAppHelp(c) - cli.ShowCommandCompletions(c, "nope") - cli.ShowCommandHelp(c, "also-nope") - cli.ShowCompletions(c) - cli.ShowSubcommandHelp(c) - cli.ShowVersion(c) - - categories := c.App.Categories() - categories.AddCommand("sounds", cli.Command{ - Name: "bloop", - }) - - for _, category := range c.App.Categories() { - fmt.Fprintf(c.App.Writer, "%s\n", category.Name) - fmt.Fprintf(c.App.Writer, "%#v\n", category.Commands) - fmt.Fprintf(c.App.Writer, "%#v\n", category.VisibleCommands()) - } - - fmt.Printf("%#v\n", c.App.Command("doo")) - if c.Bool("infinite") { - c.App.Run([]string{"app", "doo", "wop"}) - } - - if c.Bool("forevar") { - c.App.RunAsSubcommand(c) - } - c.App.Setup() - fmt.Printf("%#v\n", c.App.VisibleCategories()) - fmt.Printf("%#v\n", c.App.VisibleCommands()) - fmt.Printf("%#v\n", c.App.VisibleFlags()) - - fmt.Printf("%#v\n", c.Args().First()) - if len(c.Args()) > 0 { - fmt.Printf("%#v\n", c.Args()[1]) - } - fmt.Printf("%#v\n", c.Args().Present()) - fmt.Printf("%#v\n", c.Args().Tail()) - - set := flag.NewFlagSet("contrive", 0) - nc := cli.NewContext(c.App, set, c) - - fmt.Printf("%#v\n", nc.Args()) - fmt.Printf("%#v\n", nc.Bool("nope")) - fmt.Printf("%#v\n", nc.BoolT("nerp")) - fmt.Printf("%#v\n", nc.Duration("howlong")) - fmt.Printf("%#v\n", nc.Float64("hay")) - fmt.Printf("%#v\n", nc.Generic("bloop")) - fmt.Printf("%#v\n", nc.Int64("bonk")) - fmt.Printf("%#v\n", nc.Int64Slice("burnks")) - fmt.Printf("%#v\n", nc.Int("bips")) - fmt.Printf("%#v\n", nc.IntSlice("blups")) - fmt.Printf("%#v\n", nc.String("snurt")) - fmt.Printf("%#v\n", nc.StringSlice("snurkles")) - fmt.Printf("%#v\n", nc.Uint("flub")) - fmt.Printf("%#v\n", nc.Uint64("florb")) - fmt.Printf("%#v\n", nc.GlobalBool("global-nope")) - fmt.Printf("%#v\n", nc.GlobalBoolT("global-nerp")) - fmt.Printf("%#v\n", nc.GlobalDuration("global-howlong")) - fmt.Printf("%#v\n", nc.GlobalFloat64("global-hay")) - fmt.Printf("%#v\n", nc.GlobalGeneric("global-bloop")) - fmt.Printf("%#v\n", nc.GlobalInt("global-bips")) - fmt.Printf("%#v\n", nc.GlobalIntSlice("global-blups")) - fmt.Printf("%#v\n", nc.GlobalString("global-snurt")) - fmt.Printf("%#v\n", nc.GlobalStringSlice("global-snurkles")) - - fmt.Printf("%#v\n", nc.FlagNames()) - fmt.Printf("%#v\n", nc.GlobalFlagNames()) - fmt.Printf("%#v\n", nc.GlobalIsSet("wat")) - fmt.Printf("%#v\n", nc.GlobalSet("wat", "nope")) - fmt.Printf("%#v\n", nc.NArg()) - fmt.Printf("%#v\n", nc.NumFlags()) - fmt.Printf("%#v\n", nc.Parent()) - - nc.Set("wat", "also-nope") - - ec := cli.NewExitError("ohwell", 86) - fmt.Fprintf(c.App.Writer, "%d", ec.ExitCode()) - fmt.Printf("made it!\n") - return ec - } - - if os.Getenv("HEXY") != "" { - app.Writer = &hexWriter{} - app.ErrWriter = &hexWriter{} - } - - app.Metadata = map[string]interface{}{ - "layers": "many", - "explicable": false, - "whatever-values": 19.99, - } - - app.Run(os.Args) -} - -func wopAction(c *cli.Context) error { - fmt.Fprintf(c.App.Writer, ":wave: over here, eh\n") - return nil -} -``` - -## Contribution Guidelines - -Feel free to put up a pull request to fix a bug or maybe add a feature. I will -give it a code review and make sure that it does not break backwards -compatibility. If I or any other collaborators agree that it is in line with -the vision of the project, we will work with you to get the code into -a mergeable state and merge it into the master branch. - -If you have contributed something significant to the project, we will most -likely add you as a collaborator. As a collaborator you are given the ability -to merge others pull requests. It is very important that new code does not -break existing code, so be careful about what code you do choose to merge. - -If you feel like you have contributed to the project but have not yet been -added as a collaborator, we probably forgot to add you, please open an issue. diff --git a/vendor/github.com/urfave/cli/app.go b/vendor/github.com/urfave/cli/app.go deleted file mode 100644 index 95ffc0b..0000000 --- a/vendor/github.com/urfave/cli/app.go +++ /dev/null @@ -1,492 +0,0 @@ -package cli - -import ( - "fmt" - "io" - "io/ioutil" - "os" - "path/filepath" - "sort" - "time" -) - -var ( - changeLogURL = "https://github.com/urfave/cli/blob/master/CHANGELOG.md" - appActionDeprecationURL = fmt.Sprintf("%s#deprecated-cli-app-action-signature", changeLogURL) - runAndExitOnErrorDeprecationURL = fmt.Sprintf("%s#deprecated-cli-app-runandexitonerror", changeLogURL) - - contactSysadmin = "This is an error in the application. Please contact the distributor of this application if this is not you." - - errInvalidActionType = NewExitError("ERROR invalid Action type. "+ - fmt.Sprintf("Must be `func(*Context`)` or `func(*Context) error). %s", contactSysadmin)+ - fmt.Sprintf("See %s", appActionDeprecationURL), 2) -) - -// App is the main structure of a cli application. It is recommended that -// an app be created with the cli.NewApp() function -type App struct { - // The name of the program. Defaults to path.Base(os.Args[0]) - Name string - // Full name of command for help, defaults to Name - HelpName string - // Description of the program. - Usage string - // Text to override the USAGE section of help - UsageText string - // Description of the program argument format. - ArgsUsage string - // Version of the program - Version string - // Description of the program - Description string - // List of commands to execute - Commands []Command - // List of flags to parse - Flags []Flag - // Boolean to enable bash completion commands - EnableBashCompletion bool - // Boolean to hide built-in help command - HideHelp bool - // Boolean to hide built-in version flag and the VERSION section of help - HideVersion bool - // Populate on app startup, only gettable through method Categories() - categories CommandCategories - // An action to execute when the bash-completion flag is set - BashComplete BashCompleteFunc - // An action to execute before any subcommands are run, but after the context is ready - // If a non-nil error is returned, no subcommands are run - Before BeforeFunc - // An action to execute after any subcommands are run, but after the subcommand has finished - // It is run even if Action() panics - After AfterFunc - - // The action to execute when no subcommands are specified - // Expects a `cli.ActionFunc` but will accept the *deprecated* signature of `func(*cli.Context) {}` - // *Note*: support for the deprecated `Action` signature will be removed in a future version - Action interface{} - - // Execute this function if the proper command cannot be found - CommandNotFound CommandNotFoundFunc - // Execute this function if an usage error occurs - OnUsageError OnUsageErrorFunc - // Compilation date - Compiled time.Time - // List of all authors who contributed - Authors []Author - // Copyright of the binary if any - Copyright string - // Name of Author (Note: Use App.Authors, this is deprecated) - Author string - // Email of Author (Note: Use App.Authors, this is deprecated) - Email string - // Writer writer to write output to - Writer io.Writer - // ErrWriter writes error output - ErrWriter io.Writer - // Other custom info - Metadata map[string]interface{} - - didSetup bool -} - -// Tries to find out when this binary was compiled. -// Returns the current time if it fails to find it. -func compileTime() time.Time { - info, err := os.Stat(os.Args[0]) - if err != nil { - return time.Now() - } - return info.ModTime() -} - -// NewApp creates a new cli Application with some reasonable defaults for Name, -// Usage, Version and Action. -func NewApp() *App { - return &App{ - Name: filepath.Base(os.Args[0]), - HelpName: filepath.Base(os.Args[0]), - Usage: "A new cli application", - UsageText: "", - Version: "0.0.0", - BashComplete: DefaultAppComplete, - Action: helpCommand.Action, - Compiled: compileTime(), - Writer: os.Stdout, - } -} - -// Setup runs initialization code to ensure all data structures are ready for -// `Run` or inspection prior to `Run`. It is internally called by `Run`, but -// will return early if setup has already happened. -func (a *App) Setup() { - if a.didSetup { - return - } - - a.didSetup = true - - if a.Author != "" || a.Email != "" { - a.Authors = append(a.Authors, Author{Name: a.Author, Email: a.Email}) - } - - newCmds := []Command{} - for _, c := range a.Commands { - if c.HelpName == "" { - c.HelpName = fmt.Sprintf("%s %s", a.HelpName, c.Name) - } - newCmds = append(newCmds, c) - } - a.Commands = newCmds - - if a.Command(helpCommand.Name) == nil && !a.HideHelp { - a.Commands = append(a.Commands, helpCommand) - if (HelpFlag != BoolFlag{}) { - a.appendFlag(HelpFlag) - } - } - - if !a.HideVersion { - a.appendFlag(VersionFlag) - } - - a.categories = CommandCategories{} - for _, command := range a.Commands { - a.categories = a.categories.AddCommand(command.Category, command) - } - sort.Sort(a.categories) - - if a.Metadata == nil { - a.Metadata = make(map[string]interface{}) - } - - if a.Writer == nil { - a.Writer = os.Stdout - } -} - -// Run is the entry point to the cli app. Parses the arguments slice and routes -// to the proper flag/args combination -func (a *App) Run(arguments []string) (err error) { - a.Setup() - - // handle the completion flag separately from the flagset since - // completion could be attempted after a flag, but before its value was put - // on the command line. this causes the flagset to interpret the completion - // flag name as the value of the flag before it which is undesirable - // note that we can only do this because the shell autocomplete function - // always appends the completion flag at the end of the command - shellComplete, arguments := checkShellCompleteFlag(a, arguments) - - // parse flags - set, err := flagSet(a.Name, a.Flags) - if err != nil { - return err - } - - set.SetOutput(ioutil.Discard) - err = set.Parse(arguments[1:]) - nerr := normalizeFlags(a.Flags, set) - context := NewContext(a, set, nil) - if nerr != nil { - fmt.Fprintln(a.Writer, nerr) - ShowAppHelp(context) - return nerr - } - context.shellComplete = shellComplete - - if checkCompletions(context) { - return nil - } - - if err != nil { - if a.OnUsageError != nil { - err := a.OnUsageError(context, err, false) - HandleExitCoder(err) - return err - } - fmt.Fprintf(a.Writer, "%s %s\n\n", "Incorrect Usage.", err.Error()) - ShowAppHelp(context) - return err - } - - if !a.HideHelp && checkHelp(context) { - ShowAppHelp(context) - return nil - } - - if !a.HideVersion && checkVersion(context) { - ShowVersion(context) - return nil - } - - if a.After != nil { - defer func() { - if afterErr := a.After(context); afterErr != nil { - if err != nil { - err = NewMultiError(err, afterErr) - } else { - err = afterErr - } - } - }() - } - - if a.Before != nil { - beforeErr := a.Before(context) - if beforeErr != nil { - fmt.Fprintf(a.Writer, "%v\n\n", beforeErr) - ShowAppHelp(context) - HandleExitCoder(beforeErr) - err = beforeErr - return err - } - } - - args := context.Args() - if args.Present() { - name := args.First() - c := a.Command(name) - if c != nil { - return c.Run(context) - } - } - - if a.Action == nil { - a.Action = helpCommand.Action - } - - // Run default Action - err = HandleAction(a.Action, context) - - HandleExitCoder(err) - return err -} - -// RunAndExitOnError calls .Run() and exits non-zero if an error was returned -// -// Deprecated: instead you should return an error that fulfills cli.ExitCoder -// to cli.App.Run. This will cause the application to exit with the given eror -// code in the cli.ExitCoder -func (a *App) RunAndExitOnError() { - if err := a.Run(os.Args); err != nil { - fmt.Fprintln(a.errWriter(), err) - OsExiter(1) - } -} - -// RunAsSubcommand invokes the subcommand given the context, parses ctx.Args() to -// generate command-specific flags -func (a *App) RunAsSubcommand(ctx *Context) (err error) { - // append help to commands - if len(a.Commands) > 0 { - if a.Command(helpCommand.Name) == nil && !a.HideHelp { - a.Commands = append(a.Commands, helpCommand) - if (HelpFlag != BoolFlag{}) { - a.appendFlag(HelpFlag) - } - } - } - - newCmds := []Command{} - for _, c := range a.Commands { - if c.HelpName == "" { - c.HelpName = fmt.Sprintf("%s %s", a.HelpName, c.Name) - } - newCmds = append(newCmds, c) - } - a.Commands = newCmds - - // parse flags - set, err := flagSet(a.Name, a.Flags) - if err != nil { - return err - } - - set.SetOutput(ioutil.Discard) - err = set.Parse(ctx.Args().Tail()) - nerr := normalizeFlags(a.Flags, set) - context := NewContext(a, set, ctx) - - if nerr != nil { - fmt.Fprintln(a.Writer, nerr) - fmt.Fprintln(a.Writer) - if len(a.Commands) > 0 { - ShowSubcommandHelp(context) - } else { - ShowCommandHelp(ctx, context.Args().First()) - } - return nerr - } - - if checkCompletions(context) { - return nil - } - - if err != nil { - if a.OnUsageError != nil { - err = a.OnUsageError(context, err, true) - HandleExitCoder(err) - return err - } - fmt.Fprintf(a.Writer, "%s %s\n\n", "Incorrect Usage.", err.Error()) - ShowSubcommandHelp(context) - return err - } - - if len(a.Commands) > 0 { - if checkSubcommandHelp(context) { - return nil - } - } else { - if checkCommandHelp(ctx, context.Args().First()) { - return nil - } - } - - if a.After != nil { - defer func() { - afterErr := a.After(context) - if afterErr != nil { - HandleExitCoder(err) - if err != nil { - err = NewMultiError(err, afterErr) - } else { - err = afterErr - } - } - }() - } - - if a.Before != nil { - beforeErr := a.Before(context) - if beforeErr != nil { - HandleExitCoder(beforeErr) - err = beforeErr - return err - } - } - - args := context.Args() - if args.Present() { - name := args.First() - c := a.Command(name) - if c != nil { - return c.Run(context) - } - } - - // Run default Action - err = HandleAction(a.Action, context) - - HandleExitCoder(err) - return err -} - -// Command returns the named command on App. Returns nil if the command does not exist -func (a *App) Command(name string) *Command { - for _, c := range a.Commands { - if c.HasName(name) { - return &c - } - } - - return nil -} - -// Categories returns a slice containing all the categories with the commands they contain -func (a *App) Categories() CommandCategories { - return a.categories -} - -// VisibleCategories returns a slice of categories and commands that are -// Hidden=false -func (a *App) VisibleCategories() []*CommandCategory { - ret := []*CommandCategory{} - for _, category := range a.categories { - if visible := func() *CommandCategory { - for _, command := range category.Commands { - if !command.Hidden { - return category - } - } - return nil - }(); visible != nil { - ret = append(ret, visible) - } - } - return ret -} - -// VisibleCommands returns a slice of the Commands with Hidden=false -func (a *App) VisibleCommands() []Command { - ret := []Command{} - for _, command := range a.Commands { - if !command.Hidden { - ret = append(ret, command) - } - } - return ret -} - -// VisibleFlags returns a slice of the Flags with Hidden=false -func (a *App) VisibleFlags() []Flag { - return visibleFlags(a.Flags) -} - -func (a *App) hasFlag(flag Flag) bool { - for _, f := range a.Flags { - if flag == f { - return true - } - } - - return false -} - -func (a *App) errWriter() io.Writer { - - // When the app ErrWriter is nil use the package level one. - if a.ErrWriter == nil { - return ErrWriter - } - - return a.ErrWriter -} - -func (a *App) appendFlag(flag Flag) { - if !a.hasFlag(flag) { - a.Flags = append(a.Flags, flag) - } -} - -// Author represents someone who has contributed to a cli project. -type Author struct { - Name string // The Authors name - Email string // The Authors email -} - -// String makes Author comply to the Stringer interface, to allow an easy print in the templating process -func (a Author) String() string { - e := "" - if a.Email != "" { - e = " <" + a.Email + ">" - } - - return fmt.Sprintf("%v%v", a.Name, e) -} - -// HandleAction attempts to figure out which Action signature was used. If -// it's an ActionFunc or a func with the legacy signature for Action, the func -// is run! -func HandleAction(action interface{}, context *Context) (err error) { - if a, ok := action.(ActionFunc); ok { - return a(context) - } else if a, ok := action.(func(*Context) error); ok { - return a(context) - } else if a, ok := action.(func(*Context)); ok { // deprecated function signature - a(context) - return nil - } else { - return errInvalidActionType - } -} diff --git a/vendor/github.com/urfave/cli/appveyor.yml b/vendor/github.com/urfave/cli/appveyor.yml deleted file mode 100644 index 698b188..0000000 --- a/vendor/github.com/urfave/cli/appveyor.yml +++ /dev/null @@ -1,24 +0,0 @@ -version: "{build}" - -os: Windows Server 2012 R2 - -clone_folder: c:\gopath\src\github.com\urfave\cli - -environment: - GOPATH: C:\gopath - GOVERSION: 1.6 - PYTHON: C:\Python27-x64 - PYTHON_VERSION: 2.7.x - PYTHON_ARCH: 64 - -install: -- set PATH=%GOPATH%\bin;C:\go\bin;%PATH% -- go version -- go env -- go get github.com/urfave/gfmrun/... -- go get -v -t ./... - -build_script: -- python runtests vet -- python runtests test -- python runtests gfmrun diff --git a/vendor/github.com/urfave/cli/category.go b/vendor/github.com/urfave/cli/category.go deleted file mode 100644 index 1a60550..0000000 --- a/vendor/github.com/urfave/cli/category.go +++ /dev/null @@ -1,44 +0,0 @@ -package cli - -// CommandCategories is a slice of *CommandCategory. -type CommandCategories []*CommandCategory - -// CommandCategory is a category containing commands. -type CommandCategory struct { - Name string - Commands Commands -} - -func (c CommandCategories) Less(i, j int) bool { - return c[i].Name < c[j].Name -} - -func (c CommandCategories) Len() int { - return len(c) -} - -func (c CommandCategories) Swap(i, j int) { - c[i], c[j] = c[j], c[i] -} - -// AddCommand adds a command to a category. -func (c CommandCategories) AddCommand(category string, command Command) CommandCategories { - for _, commandCategory := range c { - if commandCategory.Name == category { - commandCategory.Commands = append(commandCategory.Commands, command) - return c - } - } - return append(c, &CommandCategory{Name: category, Commands: []Command{command}}) -} - -// VisibleCommands returns a slice of the Commands with Hidden=false -func (c *CommandCategory) VisibleCommands() []Command { - ret := []Command{} - for _, command := range c.Commands { - if !command.Hidden { - ret = append(ret, command) - } - } - return ret -} diff --git a/vendor/github.com/urfave/cli/cli.go b/vendor/github.com/urfave/cli/cli.go deleted file mode 100644 index 74fd101..0000000 --- a/vendor/github.com/urfave/cli/cli.go +++ /dev/null @@ -1,21 +0,0 @@ -// Package cli provides a minimal framework for creating and organizing command line -// Go applications. cli is designed to be easy to understand and write, the most simple -// cli application can be written as follows: -// func main() { -// cli.NewApp().Run(os.Args) -// } -// -// Of course this application does not do much, so let's make this an actual application: -// func main() { -// app := cli.NewApp() -// app.Name = "greet" -// app.Usage = "say a greeting" -// app.Action = func(c *cli.Context) error { -// println("Greetings") -// } -// -// app.Run(os.Args) -// } -package cli - -//go:generate python ./generate-flag-types cli -i flag-types.json -o flag_generated.go diff --git a/vendor/github.com/urfave/cli/command.go b/vendor/github.com/urfave/cli/command.go deleted file mode 100644 index 2628fbf..0000000 --- a/vendor/github.com/urfave/cli/command.go +++ /dev/null @@ -1,286 +0,0 @@ -package cli - -import ( - "fmt" - "io/ioutil" - "sort" - "strings" -) - -// Command is a subcommand for a cli.App. -type Command struct { - // The name of the command - Name string - // short name of the command. Typically one character (deprecated, use `Aliases`) - ShortName string - // A list of aliases for the command - Aliases []string - // A short description of the usage of this command - Usage string - // Custom text to show on USAGE section of help - UsageText string - // A longer explanation of how the command works - Description string - // A short description of the arguments of this command - ArgsUsage string - // The category the command is part of - Category string - // The function to call when checking for bash command completions - BashComplete BashCompleteFunc - // An action to execute before any sub-subcommands are run, but after the context is ready - // If a non-nil error is returned, no sub-subcommands are run - Before BeforeFunc - // An action to execute after any subcommands are run, but after the subcommand has finished - // It is run even if Action() panics - After AfterFunc - // The function to call when this command is invoked - Action interface{} - // TODO: replace `Action: interface{}` with `Action: ActionFunc` once some kind - // of deprecation period has passed, maybe? - - // Execute this function if a usage error occurs. - OnUsageError OnUsageErrorFunc - // List of child commands - Subcommands Commands - // List of flags to parse - Flags []Flag - // Treat all flags as normal arguments if true - SkipFlagParsing bool - // Skip argument reordering which attempts to move flags before arguments, - // but only works if all flags appear after all arguments. This behavior was - // removed n version 2 since it only works under specific conditions so we - // backport here by exposing it as an option for compatibility. - SkipArgReorder bool - // Boolean to hide built-in help command - HideHelp bool - // Boolean to hide this command from help or completion - Hidden bool - - // Full name of command for help, defaults to full command name, including parent commands. - HelpName string - commandNamePath []string -} - -// FullName returns the full name of the command. -// For subcommands this ensures that parent commands are part of the command path -func (c Command) FullName() string { - if c.commandNamePath == nil { - return c.Name - } - return strings.Join(c.commandNamePath, " ") -} - -// Commands is a slice of Command -type Commands []Command - -// Run invokes the command given the context, parses ctx.Args() to generate command-specific flags -func (c Command) Run(ctx *Context) (err error) { - if len(c.Subcommands) > 0 { - return c.startApp(ctx) - } - - if !c.HideHelp && (HelpFlag != BoolFlag{}) { - // append help to flags - c.Flags = append( - c.Flags, - HelpFlag, - ) - } - - set, err := flagSet(c.Name, c.Flags) - if err != nil { - return err - } - set.SetOutput(ioutil.Discard) - - if c.SkipFlagParsing { - err = set.Parse(append([]string{"--"}, ctx.Args().Tail()...)) - } else if !c.SkipArgReorder { - firstFlagIndex := -1 - terminatorIndex := -1 - for index, arg := range ctx.Args() { - if arg == "--" { - terminatorIndex = index - break - } else if arg == "-" { - // Do nothing. A dash alone is not really a flag. - continue - } else if strings.HasPrefix(arg, "-") && firstFlagIndex == -1 { - firstFlagIndex = index - } - } - - if firstFlagIndex > -1 { - args := ctx.Args() - regularArgs := make([]string, len(args[1:firstFlagIndex])) - copy(regularArgs, args[1:firstFlagIndex]) - - var flagArgs []string - if terminatorIndex > -1 { - flagArgs = args[firstFlagIndex:terminatorIndex] - regularArgs = append(regularArgs, args[terminatorIndex:]...) - } else { - flagArgs = args[firstFlagIndex:] - } - - err = set.Parse(append(flagArgs, regularArgs...)) - } else { - err = set.Parse(ctx.Args().Tail()) - } - } else { - err = set.Parse(ctx.Args().Tail()) - } - - nerr := normalizeFlags(c.Flags, set) - if nerr != nil { - fmt.Fprintln(ctx.App.Writer, nerr) - fmt.Fprintln(ctx.App.Writer) - ShowCommandHelp(ctx, c.Name) - return nerr - } - - context := NewContext(ctx.App, set, ctx) - if checkCommandCompletions(context, c.Name) { - return nil - } - - if err != nil { - if c.OnUsageError != nil { - err := c.OnUsageError(ctx, err, false) - HandleExitCoder(err) - return err - } - fmt.Fprintln(ctx.App.Writer, "Incorrect Usage:", err.Error()) - fmt.Fprintln(ctx.App.Writer) - ShowCommandHelp(ctx, c.Name) - return err - } - - if checkCommandHelp(context, c.Name) { - return nil - } - - if c.After != nil { - defer func() { - afterErr := c.After(context) - if afterErr != nil { - HandleExitCoder(err) - if err != nil { - err = NewMultiError(err, afterErr) - } else { - err = afterErr - } - } - }() - } - - if c.Before != nil { - err = c.Before(context) - if err != nil { - fmt.Fprintln(ctx.App.Writer, err) - fmt.Fprintln(ctx.App.Writer) - ShowCommandHelp(ctx, c.Name) - HandleExitCoder(err) - return err - } - } - - if c.Action == nil { - c.Action = helpSubcommand.Action - } - - context.Command = c - err = HandleAction(c.Action, context) - - if err != nil { - HandleExitCoder(err) - } - return err -} - -// Names returns the names including short names and aliases. -func (c Command) Names() []string { - names := []string{c.Name} - - if c.ShortName != "" { - names = append(names, c.ShortName) - } - - return append(names, c.Aliases...) -} - -// HasName returns true if Command.Name or Command.ShortName matches given name -func (c Command) HasName(name string) bool { - for _, n := range c.Names() { - if n == name { - return true - } - } - return false -} - -func (c Command) startApp(ctx *Context) error { - app := NewApp() - app.Metadata = ctx.App.Metadata - // set the name and usage - app.Name = fmt.Sprintf("%s %s", ctx.App.Name, c.Name) - if c.HelpName == "" { - app.HelpName = c.HelpName - } else { - app.HelpName = app.Name - } - - if c.Description != "" { - app.Usage = c.Description - } else { - app.Usage = c.Usage - } - - // set CommandNotFound - app.CommandNotFound = ctx.App.CommandNotFound - - // set the flags and commands - app.Commands = c.Subcommands - app.Flags = c.Flags - app.HideHelp = c.HideHelp - - app.Version = ctx.App.Version - app.HideVersion = ctx.App.HideVersion - app.Compiled = ctx.App.Compiled - app.Author = ctx.App.Author - app.Email = ctx.App.Email - app.Writer = ctx.App.Writer - - app.categories = CommandCategories{} - for _, command := range c.Subcommands { - app.categories = app.categories.AddCommand(command.Category, command) - } - - sort.Sort(app.categories) - - // bash completion - app.EnableBashCompletion = ctx.App.EnableBashCompletion - if c.BashComplete != nil { - app.BashComplete = c.BashComplete - } - - // set the actions - app.Before = c.Before - app.After = c.After - if c.Action != nil { - app.Action = c.Action - } else { - app.Action = helpSubcommand.Action - } - - for index, cc := range app.Commands { - app.Commands[index].commandNamePath = []string{c.Name, cc.Name} - } - - return app.RunAsSubcommand(ctx) -} - -// VisibleFlags returns a slice of the Flags with Hidden=false -func (c Command) VisibleFlags() []Flag { - return visibleFlags(c.Flags) -} diff --git a/vendor/github.com/urfave/cli/context.go b/vendor/github.com/urfave/cli/context.go deleted file mode 100644 index cb89e92..0000000 --- a/vendor/github.com/urfave/cli/context.go +++ /dev/null @@ -1,276 +0,0 @@ -package cli - -import ( - "errors" - "flag" - "reflect" - "strings" - "syscall" -) - -// Context is a type that is passed through to -// each Handler action in a cli application. Context -// can be used to retrieve context-specific Args and -// parsed command-line options. -type Context struct { - App *App - Command Command - shellComplete bool - flagSet *flag.FlagSet - setFlags map[string]bool - parentContext *Context -} - -// NewContext creates a new context. For use in when invoking an App or Command action. -func NewContext(app *App, set *flag.FlagSet, parentCtx *Context) *Context { - c := &Context{App: app, flagSet: set, parentContext: parentCtx} - - if parentCtx != nil { - c.shellComplete = parentCtx.shellComplete - } - - return c -} - -// NumFlags returns the number of flags set -func (c *Context) NumFlags() int { - return c.flagSet.NFlag() -} - -// Set sets a context flag to a value. -func (c *Context) Set(name, value string) error { - return c.flagSet.Set(name, value) -} - -// GlobalSet sets a context flag to a value on the global flagset -func (c *Context) GlobalSet(name, value string) error { - return globalContext(c).flagSet.Set(name, value) -} - -// IsSet determines if the flag was actually set -func (c *Context) IsSet(name string) bool { - if c.setFlags == nil { - c.setFlags = make(map[string]bool) - - c.flagSet.Visit(func(f *flag.Flag) { - c.setFlags[f.Name] = true - }) - - c.flagSet.VisitAll(func(f *flag.Flag) { - if _, ok := c.setFlags[f.Name]; ok { - return - } - c.setFlags[f.Name] = false - }) - - // XXX hack to support IsSet for flags with EnvVar - // - // There isn't an easy way to do this with the current implementation since - // whether a flag was set via an environment variable is very difficult to - // determine here. Instead, we intend to introduce a backwards incompatible - // change in version 2 to add `IsSet` to the Flag interface to push the - // responsibility closer to where the information required to determine - // whether a flag is set by non-standard means such as environment - // variables is avaliable. - // - // See https://github.com/urfave/cli/issues/294 for additional discussion - flags := c.Command.Flags - if c.Command.Name == "" { // cannot == Command{} since it contains slice types - if c.App != nil { - flags = c.App.Flags - } - } - for _, f := range flags { - eachName(f.GetName(), func(name string) { - if isSet, ok := c.setFlags[name]; isSet || !ok { - return - } - - val := reflect.ValueOf(f) - if val.Kind() == reflect.Ptr { - val = val.Elem() - } - - envVarValue := val.FieldByName("EnvVar") - if !envVarValue.IsValid() { - return - } - - eachName(envVarValue.String(), func(envVar string) { - envVar = strings.TrimSpace(envVar) - if _, ok := syscall.Getenv(envVar); ok { - c.setFlags[name] = true - return - } - }) - }) - } - } - - return c.setFlags[name] -} - -// GlobalIsSet determines if the global flag was actually set -func (c *Context) GlobalIsSet(name string) bool { - ctx := c - if ctx.parentContext != nil { - ctx = ctx.parentContext - } - - for ; ctx != nil; ctx = ctx.parentContext { - if ctx.IsSet(name) { - return true - } - } - return false -} - -// FlagNames returns a slice of flag names used in this context. -func (c *Context) FlagNames() (names []string) { - for _, flag := range c.Command.Flags { - name := strings.Split(flag.GetName(), ",")[0] - if name == "help" { - continue - } - names = append(names, name) - } - return -} - -// GlobalFlagNames returns a slice of global flag names used by the app. -func (c *Context) GlobalFlagNames() (names []string) { - for _, flag := range c.App.Flags { - name := strings.Split(flag.GetName(), ",")[0] - if name == "help" || name == "version" { - continue - } - names = append(names, name) - } - return -} - -// Parent returns the parent context, if any -func (c *Context) Parent() *Context { - return c.parentContext -} - -// value returns the value of the flag coressponding to `name` -func (c *Context) value(name string) interface{} { - return c.flagSet.Lookup(name).Value.(flag.Getter).Get() -} - -// Args contains apps console arguments -type Args []string - -// Args returns the command line arguments associated with the context. -func (c *Context) Args() Args { - args := Args(c.flagSet.Args()) - return args -} - -// NArg returns the number of the command line arguments. -func (c *Context) NArg() int { - return len(c.Args()) -} - -// Get returns the nth argument, or else a blank string -func (a Args) Get(n int) string { - if len(a) > n { - return a[n] - } - return "" -} - -// First returns the first argument, or else a blank string -func (a Args) First() string { - return a.Get(0) -} - -// Tail returns the rest of the arguments (not the first one) -// or else an empty string slice -func (a Args) Tail() []string { - if len(a) >= 2 { - return []string(a)[1:] - } - return []string{} -} - -// Present checks if there are any arguments present -func (a Args) Present() bool { - return len(a) != 0 -} - -// Swap swaps arguments at the given indexes -func (a Args) Swap(from, to int) error { - if from >= len(a) || to >= len(a) { - return errors.New("index out of range") - } - a[from], a[to] = a[to], a[from] - return nil -} - -func globalContext(ctx *Context) *Context { - if ctx == nil { - return nil - } - - for { - if ctx.parentContext == nil { - return ctx - } - ctx = ctx.parentContext - } -} - -func lookupGlobalFlagSet(name string, ctx *Context) *flag.FlagSet { - if ctx.parentContext != nil { - ctx = ctx.parentContext - } - for ; ctx != nil; ctx = ctx.parentContext { - if f := ctx.flagSet.Lookup(name); f != nil { - return ctx.flagSet - } - } - return nil -} - -func copyFlag(name string, ff *flag.Flag, set *flag.FlagSet) { - switch ff.Value.(type) { - case *StringSlice: - default: - set.Set(name, ff.Value.String()) - } -} - -func normalizeFlags(flags []Flag, set *flag.FlagSet) error { - visited := make(map[string]bool) - set.Visit(func(f *flag.Flag) { - visited[f.Name] = true - }) - for _, f := range flags { - parts := strings.Split(f.GetName(), ",") - if len(parts) == 1 { - continue - } - var ff *flag.Flag - for _, name := range parts { - name = strings.Trim(name, " ") - if visited[name] { - if ff != nil { - return errors.New("Cannot use two forms of the same flag: " + name + " " + ff.Name) - } - ff = set.Lookup(name) - } - } - if ff == nil { - continue - } - for _, name := range parts { - name = strings.Trim(name, " ") - if !visited[name] { - copyFlag(name, ff, set) - } - } - } - return nil -} diff --git a/vendor/github.com/urfave/cli/errors.go b/vendor/github.com/urfave/cli/errors.go deleted file mode 100644 index 0206ff4..0000000 --- a/vendor/github.com/urfave/cli/errors.go +++ /dev/null @@ -1,110 +0,0 @@ -package cli - -import ( - "fmt" - "io" - "os" - "strings" -) - -// OsExiter is the function used when the app exits. If not set defaults to os.Exit. -var OsExiter = os.Exit - -// ErrWriter is used to write errors to the user. This can be anything -// implementing the io.Writer interface and defaults to os.Stderr. -var ErrWriter io.Writer = os.Stderr - -// MultiError is an error that wraps multiple errors. -type MultiError struct { - Errors []error -} - -// NewMultiError creates a new MultiError. Pass in one or more errors. -func NewMultiError(err ...error) MultiError { - return MultiError{Errors: err} -} - -// Error implements the error interface. -func (m MultiError) Error() string { - errs := make([]string, len(m.Errors)) - for i, err := range m.Errors { - errs[i] = err.Error() - } - - return strings.Join(errs, "\n") -} - -type ErrorFormatter interface { - Format(s fmt.State, verb rune) -} - -// ExitCoder is the interface checked by `App` and `Command` for a custom exit -// code -type ExitCoder interface { - error - ExitCode() int -} - -// ExitError fulfills both the builtin `error` interface and `ExitCoder` -type ExitError struct { - exitCode int - message interface{} -} - -// NewExitError makes a new *ExitError -func NewExitError(message interface{}, exitCode int) *ExitError { - return &ExitError{ - exitCode: exitCode, - message: message, - } -} - -// Error returns the string message, fulfilling the interface required by -// `error` -func (ee *ExitError) Error() string { - return fmt.Sprintf("%v", ee.message) -} - -// ExitCode returns the exit code, fulfilling the interface required by -// `ExitCoder` -func (ee *ExitError) ExitCode() int { - return ee.exitCode -} - -// HandleExitCoder checks if the error fulfills the ExitCoder interface, and if -// so prints the error to stderr (if it is non-empty) and calls OsExiter with the -// given exit code. If the given error is a MultiError, then this func is -// called on all members of the Errors slice. -func HandleExitCoder(err error) { - if err == nil { - return - } - - if exitErr, ok := err.(ExitCoder); ok { - if err.Error() != "" { - if _, ok := exitErr.(ErrorFormatter); ok { - fmt.Fprintf(ErrWriter, "%+v\n", err) - } else { - fmt.Fprintln(ErrWriter, err) - } - } - OsExiter(exitErr.ExitCode()) - return - } - - if multiErr, ok := err.(MultiError); ok { - for _, merr := range multiErr.Errors { - HandleExitCoder(merr) - } - return - } - - if err.Error() != "" { - if _, ok := err.(ErrorFormatter); ok { - fmt.Fprintf(ErrWriter, "%+v\n", err) - } else { - fmt.Fprintln(ErrWriter, err) - } - } - OsExiter(1) -} diff --git a/vendor/github.com/urfave/cli/flag-types.json b/vendor/github.com/urfave/cli/flag-types.json deleted file mode 100644 index 1223107..0000000 --- a/vendor/github.com/urfave/cli/flag-types.json +++ /dev/null @@ -1,93 +0,0 @@ -[ - { - "name": "Bool", - "type": "bool", - "value": false, - "context_default": "false", - "parser": "strconv.ParseBool(f.Value.String())" - }, - { - "name": "BoolT", - "type": "bool", - "value": false, - "doctail": " that is true by default", - "context_default": "false", - "parser": "strconv.ParseBool(f.Value.String())" - }, - { - "name": "Duration", - "type": "time.Duration", - "doctail": " (see https://golang.org/pkg/time/#ParseDuration)", - "context_default": "0", - "parser": "time.ParseDuration(f.Value.String())" - }, - { - "name": "Float64", - "type": "float64", - "context_default": "0", - "parser": "strconv.ParseFloat(f.Value.String(), 64)" - }, - { - "name": "Generic", - "type": "Generic", - "dest": false, - "context_default": "nil", - "context_type": "interface{}" - }, - { - "name": "Int64", - "type": "int64", - "context_default": "0", - "parser": "strconv.ParseInt(f.Value.String(), 0, 64)" - }, - { - "name": "Int", - "type": "int", - "context_default": "0", - "parser": "strconv.ParseInt(f.Value.String(), 0, 64)", - "parser_cast": "int(parsed)" - }, - { - "name": "IntSlice", - "type": "*IntSlice", - "dest": false, - "context_default": "nil", - "context_type": "[]int", - "parser": "(f.Value.(*IntSlice)).Value(), error(nil)" - }, - { - "name": "Int64Slice", - "type": "*Int64Slice", - "dest": false, - "context_default": "nil", - "context_type": "[]int64", - "parser": "(f.Value.(*Int64Slice)).Value(), error(nil)" - }, - { - "name": "String", - "type": "string", - "context_default": "\"\"", - "parser": "f.Value.String(), error(nil)" - }, - { - "name": "StringSlice", - "type": "*StringSlice", - "dest": false, - "context_default": "nil", - "context_type": "[]string", - "parser": "(f.Value.(*StringSlice)).Value(), error(nil)" - }, - { - "name": "Uint64", - "type": "uint64", - "context_default": "0", - "parser": "strconv.ParseUint(f.Value.String(), 0, 64)" - }, - { - "name": "Uint", - "type": "uint", - "context_default": "0", - "parser": "strconv.ParseUint(f.Value.String(), 0, 64)", - "parser_cast": "uint(parsed)" - } -] diff --git a/vendor/github.com/urfave/cli/flag.go b/vendor/github.com/urfave/cli/flag.go deleted file mode 100644 index 7dd8a2c..0000000 --- a/vendor/github.com/urfave/cli/flag.go +++ /dev/null @@ -1,799 +0,0 @@ -package cli - -import ( - "flag" - "fmt" - "reflect" - "runtime" - "strconv" - "strings" - "syscall" - "time" -) - -const defaultPlaceholder = "value" - -// BashCompletionFlag enables bash-completion for all commands and subcommands -var BashCompletionFlag = BoolFlag{ - Name: "generate-bash-completion", - Hidden: true, -} - -// VersionFlag prints the version for the application -var VersionFlag = BoolFlag{ - Name: "version, v", - Usage: "print the version", -} - -// HelpFlag prints the help for all commands and subcommands -// Set to the zero value (BoolFlag{}) to disable flag -- keeps subcommand -// unless HideHelp is set to true) -var HelpFlag = BoolFlag{ - Name: "help, h", - Usage: "show help", -} - -// FlagStringer converts a flag definition to a string. This is used by help -// to display a flag. -var FlagStringer FlagStringFunc = stringifyFlag - -// FlagsByName is a slice of Flag. -type FlagsByName []Flag - -func (f FlagsByName) Len() int { - return len(f) -} - -func (f FlagsByName) Less(i, j int) bool { - return f[i].GetName() < f[j].GetName() -} - -func (f FlagsByName) Swap(i, j int) { - f[i], f[j] = f[j], f[i] -} - -// Flag is a common interface related to parsing flags in cli. -// For more advanced flag parsing techniques, it is recommended that -// this interface be implemented. -type Flag interface { - fmt.Stringer - // Apply Flag settings to the given flag set - Apply(*flag.FlagSet) - GetName() string -} - -// errorableFlag is an interface that allows us to return errors during apply -// it allows flags defined in this library to return errors in a fashion backwards compatible -// TODO remove in v2 and modify the existing Flag interface to return errors -type errorableFlag interface { - Flag - - ApplyWithError(*flag.FlagSet) error -} - -func flagSet(name string, flags []Flag) (*flag.FlagSet, error) { - set := flag.NewFlagSet(name, flag.ContinueOnError) - - for _, f := range flags { - //TODO remove in v2 when errorableFlag is removed - if ef, ok := f.(errorableFlag); ok { - if err := ef.ApplyWithError(set); err != nil { - return nil, err - } - } else { - f.Apply(set) - } - } - return set, nil -} - -func eachName(longName string, fn func(string)) { - parts := strings.Split(longName, ",") - for _, name := range parts { - name = strings.Trim(name, " ") - fn(name) - } -} - -// Generic is a generic parseable type identified by a specific flag -type Generic interface { - Set(value string) error - String() string -} - -// Apply takes the flagset and calls Set on the generic flag with the value -// provided by the user for parsing by the flag -// Ignores parsing errors -func (f GenericFlag) Apply(set *flag.FlagSet) { - f.ApplyWithError(set) -} - -// ApplyWithError takes the flagset and calls Set on the generic flag with the value -// provided by the user for parsing by the flag -func (f GenericFlag) ApplyWithError(set *flag.FlagSet) error { - val := f.Value - if f.EnvVar != "" { - for _, envVar := range strings.Split(f.EnvVar, ",") { - envVar = strings.TrimSpace(envVar) - if envVal, ok := syscall.Getenv(envVar); ok { - if err := val.Set(envVal); err != nil { - return fmt.Errorf("could not parse %s as value for flag %s: %s", envVal, f.Name, err) - } - break - } - } - } - - eachName(f.Name, func(name string) { - set.Var(f.Value, name, f.Usage) - }) - - return nil -} - -// StringSlice is an opaque type for []string to satisfy flag.Value and flag.Getter -type StringSlice []string - -// Set appends the string value to the list of values -func (f *StringSlice) Set(value string) error { - *f = append(*f, value) - return nil -} - -// String returns a readable representation of this value (for usage defaults) -func (f *StringSlice) String() string { - return fmt.Sprintf("%s", *f) -} - -// Value returns the slice of strings set by this flag -func (f *StringSlice) Value() []string { - return *f -} - -// Get returns the slice of strings set by this flag -func (f *StringSlice) Get() interface{} { - return *f -} - -// Apply populates the flag given the flag set and environment -// Ignores errors -func (f StringSliceFlag) Apply(set *flag.FlagSet) { - f.ApplyWithError(set) -} - -// ApplyWithError populates the flag given the flag set and environment -func (f StringSliceFlag) ApplyWithError(set *flag.FlagSet) error { - if f.EnvVar != "" { - for _, envVar := range strings.Split(f.EnvVar, ",") { - envVar = strings.TrimSpace(envVar) - if envVal, ok := syscall.Getenv(envVar); ok { - newVal := &StringSlice{} - for _, s := range strings.Split(envVal, ",") { - s = strings.TrimSpace(s) - if err := newVal.Set(s); err != nil { - return fmt.Errorf("could not parse %s as string value for flag %s: %s", envVal, f.Name, err) - } - } - f.Value = newVal - break - } - } - } - - eachName(f.Name, func(name string) { - if f.Value == nil { - f.Value = &StringSlice{} - } - set.Var(f.Value, name, f.Usage) - }) - - return nil -} - -// IntSlice is an opaque type for []int to satisfy flag.Value and flag.Getter -type IntSlice []int - -// Set parses the value into an integer and appends it to the list of values -func (f *IntSlice) Set(value string) error { - tmp, err := strconv.Atoi(value) - if err != nil { - return err - } - *f = append(*f, tmp) - return nil -} - -// String returns a readable representation of this value (for usage defaults) -func (f *IntSlice) String() string { - return fmt.Sprintf("%#v", *f) -} - -// Value returns the slice of ints set by this flag -func (f *IntSlice) Value() []int { - return *f -} - -// Get returns the slice of ints set by this flag -func (f *IntSlice) Get() interface{} { - return *f -} - -// Apply populates the flag given the flag set and environment -// Ignores errors -func (f IntSliceFlag) Apply(set *flag.FlagSet) { - f.ApplyWithError(set) -} - -// ApplyWithError populates the flag given the flag set and environment -func (f IntSliceFlag) ApplyWithError(set *flag.FlagSet) error { - if f.EnvVar != "" { - for _, envVar := range strings.Split(f.EnvVar, ",") { - envVar = strings.TrimSpace(envVar) - if envVal, ok := syscall.Getenv(envVar); ok { - newVal := &IntSlice{} - for _, s := range strings.Split(envVal, ",") { - s = strings.TrimSpace(s) - if err := newVal.Set(s); err != nil { - return fmt.Errorf("could not parse %s as int slice value for flag %s: %s", envVal, f.Name, err) - } - } - f.Value = newVal - break - } - } - } - - eachName(f.Name, func(name string) { - if f.Value == nil { - f.Value = &IntSlice{} - } - set.Var(f.Value, name, f.Usage) - }) - - return nil -} - -// Int64Slice is an opaque type for []int to satisfy flag.Value and flag.Getter -type Int64Slice []int64 - -// Set parses the value into an integer and appends it to the list of values -func (f *Int64Slice) Set(value string) error { - tmp, err := strconv.ParseInt(value, 10, 64) - if err != nil { - return err - } - *f = append(*f, tmp) - return nil -} - -// String returns a readable representation of this value (for usage defaults) -func (f *Int64Slice) String() string { - return fmt.Sprintf("%#v", *f) -} - -// Value returns the slice of ints set by this flag -func (f *Int64Slice) Value() []int64 { - return *f -} - -// Get returns the slice of ints set by this flag -func (f *Int64Slice) Get() interface{} { - return *f -} - -// Apply populates the flag given the flag set and environment -// Ignores errors -func (f Int64SliceFlag) Apply(set *flag.FlagSet) { - f.ApplyWithError(set) -} - -// ApplyWithError populates the flag given the flag set and environment -func (f Int64SliceFlag) ApplyWithError(set *flag.FlagSet) error { - if f.EnvVar != "" { - for _, envVar := range strings.Split(f.EnvVar, ",") { - envVar = strings.TrimSpace(envVar) - if envVal, ok := syscall.Getenv(envVar); ok { - newVal := &Int64Slice{} - for _, s := range strings.Split(envVal, ",") { - s = strings.TrimSpace(s) - if err := newVal.Set(s); err != nil { - return fmt.Errorf("could not parse %s as int64 slice value for flag %s: %s", envVal, f.Name, err) - } - } - f.Value = newVal - break - } - } - } - - eachName(f.Name, func(name string) { - if f.Value == nil { - f.Value = &Int64Slice{} - } - set.Var(f.Value, name, f.Usage) - }) - return nil -} - -// Apply populates the flag given the flag set and environment -// Ignores errors -func (f BoolFlag) Apply(set *flag.FlagSet) { - f.ApplyWithError(set) -} - -// ApplyWithError populates the flag given the flag set and environment -func (f BoolFlag) ApplyWithError(set *flag.FlagSet) error { - val := false - if f.EnvVar != "" { - for _, envVar := range strings.Split(f.EnvVar, ",") { - envVar = strings.TrimSpace(envVar) - if envVal, ok := syscall.Getenv(envVar); ok { - if envVal == "" { - val = false - break - } - - envValBool, err := strconv.ParseBool(envVal) - if err != nil { - return fmt.Errorf("could not parse %s as bool value for flag %s: %s", envVal, f.Name, err) - } - - val = envValBool - break - } - } - } - - eachName(f.Name, func(name string) { - if f.Destination != nil { - set.BoolVar(f.Destination, name, val, f.Usage) - return - } - set.Bool(name, val, f.Usage) - }) - - return nil -} - -// Apply populates the flag given the flag set and environment -// Ignores errors -func (f BoolTFlag) Apply(set *flag.FlagSet) { - f.ApplyWithError(set) -} - -// ApplyWithError populates the flag given the flag set and environment -func (f BoolTFlag) ApplyWithError(set *flag.FlagSet) error { - val := true - if f.EnvVar != "" { - for _, envVar := range strings.Split(f.EnvVar, ",") { - envVar = strings.TrimSpace(envVar) - if envVal, ok := syscall.Getenv(envVar); ok { - if envVal == "" { - val = false - break - } - - envValBool, err := strconv.ParseBool(envVal) - if err != nil { - return fmt.Errorf("could not parse %s as bool value for flag %s: %s", envVal, f.Name, err) - } - - val = envValBool - break - } - } - } - - eachName(f.Name, func(name string) { - if f.Destination != nil { - set.BoolVar(f.Destination, name, val, f.Usage) - return - } - set.Bool(name, val, f.Usage) - }) - - return nil -} - -// Apply populates the flag given the flag set and environment -// Ignores errors -func (f StringFlag) Apply(set *flag.FlagSet) { - f.ApplyWithError(set) -} - -// ApplyWithError populates the flag given the flag set and environment -func (f StringFlag) ApplyWithError(set *flag.FlagSet) error { - if f.EnvVar != "" { - for _, envVar := range strings.Split(f.EnvVar, ",") { - envVar = strings.TrimSpace(envVar) - if envVal, ok := syscall.Getenv(envVar); ok { - f.Value = envVal - break - } - } - } - - eachName(f.Name, func(name string) { - if f.Destination != nil { - set.StringVar(f.Destination, name, f.Value, f.Usage) - return - } - set.String(name, f.Value, f.Usage) - }) - - return nil -} - -// Apply populates the flag given the flag set and environment -// Ignores errors -func (f IntFlag) Apply(set *flag.FlagSet) { - f.ApplyWithError(set) -} - -// ApplyWithError populates the flag given the flag set and environment -func (f IntFlag) ApplyWithError(set *flag.FlagSet) error { - if f.EnvVar != "" { - for _, envVar := range strings.Split(f.EnvVar, ",") { - envVar = strings.TrimSpace(envVar) - if envVal, ok := syscall.Getenv(envVar); ok { - envValInt, err := strconv.ParseInt(envVal, 0, 64) - if err != nil { - return fmt.Errorf("could not parse %s as int value for flag %s: %s", envVal, f.Name, err) - } - f.Value = int(envValInt) - break - } - } - } - - eachName(f.Name, func(name string) { - if f.Destination != nil { - set.IntVar(f.Destination, name, f.Value, f.Usage) - return - } - set.Int(name, f.Value, f.Usage) - }) - - return nil -} - -// Apply populates the flag given the flag set and environment -// Ignores errors -func (f Int64Flag) Apply(set *flag.FlagSet) { - f.ApplyWithError(set) -} - -// ApplyWithError populates the flag given the flag set and environment -func (f Int64Flag) ApplyWithError(set *flag.FlagSet) error { - if f.EnvVar != "" { - for _, envVar := range strings.Split(f.EnvVar, ",") { - envVar = strings.TrimSpace(envVar) - if envVal, ok := syscall.Getenv(envVar); ok { - envValInt, err := strconv.ParseInt(envVal, 0, 64) - if err != nil { - return fmt.Errorf("could not parse %s as int value for flag %s: %s", envVal, f.Name, err) - } - - f.Value = envValInt - break - } - } - } - - eachName(f.Name, func(name string) { - if f.Destination != nil { - set.Int64Var(f.Destination, name, f.Value, f.Usage) - return - } - set.Int64(name, f.Value, f.Usage) - }) - - return nil -} - -// Apply populates the flag given the flag set and environment -// Ignores errors -func (f UintFlag) Apply(set *flag.FlagSet) { - f.ApplyWithError(set) -} - -// ApplyWithError populates the flag given the flag set and environment -func (f UintFlag) ApplyWithError(set *flag.FlagSet) error { - if f.EnvVar != "" { - for _, envVar := range strings.Split(f.EnvVar, ",") { - envVar = strings.TrimSpace(envVar) - if envVal, ok := syscall.Getenv(envVar); ok { - envValInt, err := strconv.ParseUint(envVal, 0, 64) - if err != nil { - return fmt.Errorf("could not parse %s as uint value for flag %s: %s", envVal, f.Name, err) - } - - f.Value = uint(envValInt) - break - } - } - } - - eachName(f.Name, func(name string) { - if f.Destination != nil { - set.UintVar(f.Destination, name, f.Value, f.Usage) - return - } - set.Uint(name, f.Value, f.Usage) - }) - - return nil -} - -// Apply populates the flag given the flag set and environment -// Ignores errors -func (f Uint64Flag) Apply(set *flag.FlagSet) { - f.ApplyWithError(set) -} - -// ApplyWithError populates the flag given the flag set and environment -func (f Uint64Flag) ApplyWithError(set *flag.FlagSet) error { - if f.EnvVar != "" { - for _, envVar := range strings.Split(f.EnvVar, ",") { - envVar = strings.TrimSpace(envVar) - if envVal, ok := syscall.Getenv(envVar); ok { - envValInt, err := strconv.ParseUint(envVal, 0, 64) - if err != nil { - return fmt.Errorf("could not parse %s as uint64 value for flag %s: %s", envVal, f.Name, err) - } - - f.Value = uint64(envValInt) - break - } - } - } - - eachName(f.Name, func(name string) { - if f.Destination != nil { - set.Uint64Var(f.Destination, name, f.Value, f.Usage) - return - } - set.Uint64(name, f.Value, f.Usage) - }) - - return nil -} - -// Apply populates the flag given the flag set and environment -// Ignores errors -func (f DurationFlag) Apply(set *flag.FlagSet) { - f.ApplyWithError(set) -} - -// ApplyWithError populates the flag given the flag set and environment -func (f DurationFlag) ApplyWithError(set *flag.FlagSet) error { - if f.EnvVar != "" { - for _, envVar := range strings.Split(f.EnvVar, ",") { - envVar = strings.TrimSpace(envVar) - if envVal, ok := syscall.Getenv(envVar); ok { - envValDuration, err := time.ParseDuration(envVal) - if err != nil { - return fmt.Errorf("could not parse %s as duration for flag %s: %s", envVal, f.Name, err) - } - - f.Value = envValDuration - break - } - } - } - - eachName(f.Name, func(name string) { - if f.Destination != nil { - set.DurationVar(f.Destination, name, f.Value, f.Usage) - return - } - set.Duration(name, f.Value, f.Usage) - }) - - return nil -} - -// Apply populates the flag given the flag set and environment -// Ignores errors -func (f Float64Flag) Apply(set *flag.FlagSet) { - f.ApplyWithError(set) -} - -// ApplyWithError populates the flag given the flag set and environment -func (f Float64Flag) ApplyWithError(set *flag.FlagSet) error { - if f.EnvVar != "" { - for _, envVar := range strings.Split(f.EnvVar, ",") { - envVar = strings.TrimSpace(envVar) - if envVal, ok := syscall.Getenv(envVar); ok { - envValFloat, err := strconv.ParseFloat(envVal, 10) - if err != nil { - return fmt.Errorf("could not parse %s as float64 value for flag %s: %s", envVal, f.Name, err) - } - - f.Value = float64(envValFloat) - break - } - } - } - - eachName(f.Name, func(name string) { - if f.Destination != nil { - set.Float64Var(f.Destination, name, f.Value, f.Usage) - return - } - set.Float64(name, f.Value, f.Usage) - }) - - return nil -} - -func visibleFlags(fl []Flag) []Flag { - visible := []Flag{} - for _, flag := range fl { - if !flagValue(flag).FieldByName("Hidden").Bool() { - visible = append(visible, flag) - } - } - return visible -} - -func prefixFor(name string) (prefix string) { - if len(name) == 1 { - prefix = "-" - } else { - prefix = "--" - } - - return -} - -// Returns the placeholder, if any, and the unquoted usage string. -func unquoteUsage(usage string) (string, string) { - for i := 0; i < len(usage); i++ { - if usage[i] == '`' { - for j := i + 1; j < len(usage); j++ { - if usage[j] == '`' { - name := usage[i+1 : j] - usage = usage[:i] + name + usage[j+1:] - return name, usage - } - } - break - } - } - return "", usage -} - -func prefixedNames(fullName, placeholder string) string { - var prefixed string - parts := strings.Split(fullName, ",") - for i, name := range parts { - name = strings.Trim(name, " ") - prefixed += prefixFor(name) + name - if placeholder != "" { - prefixed += " " + placeholder - } - if i < len(parts)-1 { - prefixed += ", " - } - } - return prefixed -} - -func withEnvHint(envVar, str string) string { - envText := "" - if envVar != "" { - prefix := "$" - suffix := "" - sep := ", $" - if runtime.GOOS == "windows" { - prefix = "%" - suffix = "%" - sep = "%, %" - } - envText = fmt.Sprintf(" [%s%s%s]", prefix, strings.Join(strings.Split(envVar, ","), sep), suffix) - } - return str + envText -} - -func flagValue(f Flag) reflect.Value { - fv := reflect.ValueOf(f) - for fv.Kind() == reflect.Ptr { - fv = reflect.Indirect(fv) - } - return fv -} - -func stringifyFlag(f Flag) string { - fv := flagValue(f) - - switch f.(type) { - case IntSliceFlag: - return withEnvHint(fv.FieldByName("EnvVar").String(), - stringifyIntSliceFlag(f.(IntSliceFlag))) - case Int64SliceFlag: - return withEnvHint(fv.FieldByName("EnvVar").String(), - stringifyInt64SliceFlag(f.(Int64SliceFlag))) - case StringSliceFlag: - return withEnvHint(fv.FieldByName("EnvVar").String(), - stringifyStringSliceFlag(f.(StringSliceFlag))) - } - - placeholder, usage := unquoteUsage(fv.FieldByName("Usage").String()) - - needsPlaceholder := false - defaultValueString := "" - val := fv.FieldByName("Value") - - if val.IsValid() { - needsPlaceholder = true - defaultValueString = fmt.Sprintf(" (default: %v)", val.Interface()) - - if val.Kind() == reflect.String && val.String() != "" { - defaultValueString = fmt.Sprintf(" (default: %q)", val.String()) - } - } - - if defaultValueString == " (default: )" { - defaultValueString = "" - } - - if needsPlaceholder && placeholder == "" { - placeholder = defaultPlaceholder - } - - usageWithDefault := strings.TrimSpace(fmt.Sprintf("%s%s", usage, defaultValueString)) - - return withEnvHint(fv.FieldByName("EnvVar").String(), - fmt.Sprintf("%s\t%s", prefixedNames(fv.FieldByName("Name").String(), placeholder), usageWithDefault)) -} - -func stringifyIntSliceFlag(f IntSliceFlag) string { - defaultVals := []string{} - if f.Value != nil && len(f.Value.Value()) > 0 { - for _, i := range f.Value.Value() { - defaultVals = append(defaultVals, fmt.Sprintf("%d", i)) - } - } - - return stringifySliceFlag(f.Usage, f.Name, defaultVals) -} - -func stringifyInt64SliceFlag(f Int64SliceFlag) string { - defaultVals := []string{} - if f.Value != nil && len(f.Value.Value()) > 0 { - for _, i := range f.Value.Value() { - defaultVals = append(defaultVals, fmt.Sprintf("%d", i)) - } - } - - return stringifySliceFlag(f.Usage, f.Name, defaultVals) -} - -func stringifyStringSliceFlag(f StringSliceFlag) string { - defaultVals := []string{} - if f.Value != nil && len(f.Value.Value()) > 0 { - for _, s := range f.Value.Value() { - if len(s) > 0 { - defaultVals = append(defaultVals, fmt.Sprintf("%q", s)) - } - } - } - - return stringifySliceFlag(f.Usage, f.Name, defaultVals) -} - -func stringifySliceFlag(usage, name string, defaultVals []string) string { - placeholder, usage := unquoteUsage(usage) - if placeholder == "" { - placeholder = defaultPlaceholder - } - - defaultVal := "" - if len(defaultVals) > 0 { - defaultVal = fmt.Sprintf(" (default: %s)", strings.Join(defaultVals, ", ")) - } - - usageWithDefault := strings.TrimSpace(fmt.Sprintf("%s%s", usage, defaultVal)) - return fmt.Sprintf("%s\t%s", prefixedNames(name, placeholder), usageWithDefault) -} diff --git a/vendor/github.com/urfave/cli/flag_generated.go b/vendor/github.com/urfave/cli/flag_generated.go deleted file mode 100644 index 491b619..0000000 --- a/vendor/github.com/urfave/cli/flag_generated.go +++ /dev/null @@ -1,627 +0,0 @@ -package cli - -import ( - "flag" - "strconv" - "time" -) - -// WARNING: This file is generated! - -// BoolFlag is a flag with type bool -type BoolFlag struct { - Name string - Usage string - EnvVar string - Hidden bool - Destination *bool -} - -// String returns a readable representation of this value -// (for usage defaults) -func (f BoolFlag) String() string { - return FlagStringer(f) -} - -// GetName returns the name of the flag -func (f BoolFlag) GetName() string { - return f.Name -} - -// Bool looks up the value of a local BoolFlag, returns -// false if not found -func (c *Context) Bool(name string) bool { - return lookupBool(name, c.flagSet) -} - -// GlobalBool looks up the value of a global BoolFlag, returns -// false if not found -func (c *Context) GlobalBool(name string) bool { - if fs := lookupGlobalFlagSet(name, c); fs != nil { - return lookupBool(name, fs) - } - return false -} - -func lookupBool(name string, set *flag.FlagSet) bool { - f := set.Lookup(name) - if f != nil { - parsed, err := strconv.ParseBool(f.Value.String()) - if err != nil { - return false - } - return parsed - } - return false -} - -// BoolTFlag is a flag with type bool that is true by default -type BoolTFlag struct { - Name string - Usage string - EnvVar string - Hidden bool - Destination *bool -} - -// String returns a readable representation of this value -// (for usage defaults) -func (f BoolTFlag) String() string { - return FlagStringer(f) -} - -// GetName returns the name of the flag -func (f BoolTFlag) GetName() string { - return f.Name -} - -// BoolT looks up the value of a local BoolTFlag, returns -// false if not found -func (c *Context) BoolT(name string) bool { - return lookupBoolT(name, c.flagSet) -} - -// GlobalBoolT looks up the value of a global BoolTFlag, returns -// false if not found -func (c *Context) GlobalBoolT(name string) bool { - if fs := lookupGlobalFlagSet(name, c); fs != nil { - return lookupBoolT(name, fs) - } - return false -} - -func lookupBoolT(name string, set *flag.FlagSet) bool { - f := set.Lookup(name) - if f != nil { - parsed, err := strconv.ParseBool(f.Value.String()) - if err != nil { - return false - } - return parsed - } - return false -} - -// DurationFlag is a flag with type time.Duration (see https://golang.org/pkg/time/#ParseDuration) -type DurationFlag struct { - Name string - Usage string - EnvVar string - Hidden bool - Value time.Duration - Destination *time.Duration -} - -// String returns a readable representation of this value -// (for usage defaults) -func (f DurationFlag) String() string { - return FlagStringer(f) -} - -// GetName returns the name of the flag -func (f DurationFlag) GetName() string { - return f.Name -} - -// Duration looks up the value of a local DurationFlag, returns -// 0 if not found -func (c *Context) Duration(name string) time.Duration { - return lookupDuration(name, c.flagSet) -} - -// GlobalDuration looks up the value of a global DurationFlag, returns -// 0 if not found -func (c *Context) GlobalDuration(name string) time.Duration { - if fs := lookupGlobalFlagSet(name, c); fs != nil { - return lookupDuration(name, fs) - } - return 0 -} - -func lookupDuration(name string, set *flag.FlagSet) time.Duration { - f := set.Lookup(name) - if f != nil { - parsed, err := time.ParseDuration(f.Value.String()) - if err != nil { - return 0 - } - return parsed - } - return 0 -} - -// Float64Flag is a flag with type float64 -type Float64Flag struct { - Name string - Usage string - EnvVar string - Hidden bool - Value float64 - Destination *float64 -} - -// String returns a readable representation of this value -// (for usage defaults) -func (f Float64Flag) String() string { - return FlagStringer(f) -} - -// GetName returns the name of the flag -func (f Float64Flag) GetName() string { - return f.Name -} - -// Float64 looks up the value of a local Float64Flag, returns -// 0 if not found -func (c *Context) Float64(name string) float64 { - return lookupFloat64(name, c.flagSet) -} - -// GlobalFloat64 looks up the value of a global Float64Flag, returns -// 0 if not found -func (c *Context) GlobalFloat64(name string) float64 { - if fs := lookupGlobalFlagSet(name, c); fs != nil { - return lookupFloat64(name, fs) - } - return 0 -} - -func lookupFloat64(name string, set *flag.FlagSet) float64 { - f := set.Lookup(name) - if f != nil { - parsed, err := strconv.ParseFloat(f.Value.String(), 64) - if err != nil { - return 0 - } - return parsed - } - return 0 -} - -// GenericFlag is a flag with type Generic -type GenericFlag struct { - Name string - Usage string - EnvVar string - Hidden bool - Value Generic -} - -// String returns a readable representation of this value -// (for usage defaults) -func (f GenericFlag) String() string { - return FlagStringer(f) -} - -// GetName returns the name of the flag -func (f GenericFlag) GetName() string { - return f.Name -} - -// Generic looks up the value of a local GenericFlag, returns -// nil if not found -func (c *Context) Generic(name string) interface{} { - return lookupGeneric(name, c.flagSet) -} - -// GlobalGeneric looks up the value of a global GenericFlag, returns -// nil if not found -func (c *Context) GlobalGeneric(name string) interface{} { - if fs := lookupGlobalFlagSet(name, c); fs != nil { - return lookupGeneric(name, fs) - } - return nil -} - -func lookupGeneric(name string, set *flag.FlagSet) interface{} { - f := set.Lookup(name) - if f != nil { - parsed, err := f.Value, error(nil) - if err != nil { - return nil - } - return parsed - } - return nil -} - -// Int64Flag is a flag with type int64 -type Int64Flag struct { - Name string - Usage string - EnvVar string - Hidden bool - Value int64 - Destination *int64 -} - -// String returns a readable representation of this value -// (for usage defaults) -func (f Int64Flag) String() string { - return FlagStringer(f) -} - -// GetName returns the name of the flag -func (f Int64Flag) GetName() string { - return f.Name -} - -// Int64 looks up the value of a local Int64Flag, returns -// 0 if not found -func (c *Context) Int64(name string) int64 { - return lookupInt64(name, c.flagSet) -} - -// GlobalInt64 looks up the value of a global Int64Flag, returns -// 0 if not found -func (c *Context) GlobalInt64(name string) int64 { - if fs := lookupGlobalFlagSet(name, c); fs != nil { - return lookupInt64(name, fs) - } - return 0 -} - -func lookupInt64(name string, set *flag.FlagSet) int64 { - f := set.Lookup(name) - if f != nil { - parsed, err := strconv.ParseInt(f.Value.String(), 0, 64) - if err != nil { - return 0 - } - return parsed - } - return 0 -} - -// IntFlag is a flag with type int -type IntFlag struct { - Name string - Usage string - EnvVar string - Hidden bool - Value int - Destination *int -} - -// String returns a readable representation of this value -// (for usage defaults) -func (f IntFlag) String() string { - return FlagStringer(f) -} - -// GetName returns the name of the flag -func (f IntFlag) GetName() string { - return f.Name -} - -// Int looks up the value of a local IntFlag, returns -// 0 if not found -func (c *Context) Int(name string) int { - return lookupInt(name, c.flagSet) -} - -// GlobalInt looks up the value of a global IntFlag, returns -// 0 if not found -func (c *Context) GlobalInt(name string) int { - if fs := lookupGlobalFlagSet(name, c); fs != nil { - return lookupInt(name, fs) - } - return 0 -} - -func lookupInt(name string, set *flag.FlagSet) int { - f := set.Lookup(name) - if f != nil { - parsed, err := strconv.ParseInt(f.Value.String(), 0, 64) - if err != nil { - return 0 - } - return int(parsed) - } - return 0 -} - -// IntSliceFlag is a flag with type *IntSlice -type IntSliceFlag struct { - Name string - Usage string - EnvVar string - Hidden bool - Value *IntSlice -} - -// String returns a readable representation of this value -// (for usage defaults) -func (f IntSliceFlag) String() string { - return FlagStringer(f) -} - -// GetName returns the name of the flag -func (f IntSliceFlag) GetName() string { - return f.Name -} - -// IntSlice looks up the value of a local IntSliceFlag, returns -// nil if not found -func (c *Context) IntSlice(name string) []int { - return lookupIntSlice(name, c.flagSet) -} - -// GlobalIntSlice looks up the value of a global IntSliceFlag, returns -// nil if not found -func (c *Context) GlobalIntSlice(name string) []int { - if fs := lookupGlobalFlagSet(name, c); fs != nil { - return lookupIntSlice(name, fs) - } - return nil -} - -func lookupIntSlice(name string, set *flag.FlagSet) []int { - f := set.Lookup(name) - if f != nil { - parsed, err := (f.Value.(*IntSlice)).Value(), error(nil) - if err != nil { - return nil - } - return parsed - } - return nil -} - -// Int64SliceFlag is a flag with type *Int64Slice -type Int64SliceFlag struct { - Name string - Usage string - EnvVar string - Hidden bool - Value *Int64Slice -} - -// String returns a readable representation of this value -// (for usage defaults) -func (f Int64SliceFlag) String() string { - return FlagStringer(f) -} - -// GetName returns the name of the flag -func (f Int64SliceFlag) GetName() string { - return f.Name -} - -// Int64Slice looks up the value of a local Int64SliceFlag, returns -// nil if not found -func (c *Context) Int64Slice(name string) []int64 { - return lookupInt64Slice(name, c.flagSet) -} - -// GlobalInt64Slice looks up the value of a global Int64SliceFlag, returns -// nil if not found -func (c *Context) GlobalInt64Slice(name string) []int64 { - if fs := lookupGlobalFlagSet(name, c); fs != nil { - return lookupInt64Slice(name, fs) - } - return nil -} - -func lookupInt64Slice(name string, set *flag.FlagSet) []int64 { - f := set.Lookup(name) - if f != nil { - parsed, err := (f.Value.(*Int64Slice)).Value(), error(nil) - if err != nil { - return nil - } - return parsed - } - return nil -} - -// StringFlag is a flag with type string -type StringFlag struct { - Name string - Usage string - EnvVar string - Hidden bool - Value string - Destination *string -} - -// String returns a readable representation of this value -// (for usage defaults) -func (f StringFlag) String() string { - return FlagStringer(f) -} - -// GetName returns the name of the flag -func (f StringFlag) GetName() string { - return f.Name -} - -// String looks up the value of a local StringFlag, returns -// "" if not found -func (c *Context) String(name string) string { - return lookupString(name, c.flagSet) -} - -// GlobalString looks up the value of a global StringFlag, returns -// "" if not found -func (c *Context) GlobalString(name string) string { - if fs := lookupGlobalFlagSet(name, c); fs != nil { - return lookupString(name, fs) - } - return "" -} - -func lookupString(name string, set *flag.FlagSet) string { - f := set.Lookup(name) - if f != nil { - parsed, err := f.Value.String(), error(nil) - if err != nil { - return "" - } - return parsed - } - return "" -} - -// StringSliceFlag is a flag with type *StringSlice -type StringSliceFlag struct { - Name string - Usage string - EnvVar string - Hidden bool - Value *StringSlice -} - -// String returns a readable representation of this value -// (for usage defaults) -func (f StringSliceFlag) String() string { - return FlagStringer(f) -} - -// GetName returns the name of the flag -func (f StringSliceFlag) GetName() string { - return f.Name -} - -// StringSlice looks up the value of a local StringSliceFlag, returns -// nil if not found -func (c *Context) StringSlice(name string) []string { - return lookupStringSlice(name, c.flagSet) -} - -// GlobalStringSlice looks up the value of a global StringSliceFlag, returns -// nil if not found -func (c *Context) GlobalStringSlice(name string) []string { - if fs := lookupGlobalFlagSet(name, c); fs != nil { - return lookupStringSlice(name, fs) - } - return nil -} - -func lookupStringSlice(name string, set *flag.FlagSet) []string { - f := set.Lookup(name) - if f != nil { - parsed, err := (f.Value.(*StringSlice)).Value(), error(nil) - if err != nil { - return nil - } - return parsed - } - return nil -} - -// Uint64Flag is a flag with type uint64 -type Uint64Flag struct { - Name string - Usage string - EnvVar string - Hidden bool - Value uint64 - Destination *uint64 -} - -// String returns a readable representation of this value -// (for usage defaults) -func (f Uint64Flag) String() string { - return FlagStringer(f) -} - -// GetName returns the name of the flag -func (f Uint64Flag) GetName() string { - return f.Name -} - -// Uint64 looks up the value of a local Uint64Flag, returns -// 0 if not found -func (c *Context) Uint64(name string) uint64 { - return lookupUint64(name, c.flagSet) -} - -// GlobalUint64 looks up the value of a global Uint64Flag, returns -// 0 if not found -func (c *Context) GlobalUint64(name string) uint64 { - if fs := lookupGlobalFlagSet(name, c); fs != nil { - return lookupUint64(name, fs) - } - return 0 -} - -func lookupUint64(name string, set *flag.FlagSet) uint64 { - f := set.Lookup(name) - if f != nil { - parsed, err := strconv.ParseUint(f.Value.String(), 0, 64) - if err != nil { - return 0 - } - return parsed - } - return 0 -} - -// UintFlag is a flag with type uint -type UintFlag struct { - Name string - Usage string - EnvVar string - Hidden bool - Value uint - Destination *uint -} - -// String returns a readable representation of this value -// (for usage defaults) -func (f UintFlag) String() string { - return FlagStringer(f) -} - -// GetName returns the name of the flag -func (f UintFlag) GetName() string { - return f.Name -} - -// Uint looks up the value of a local UintFlag, returns -// 0 if not found -func (c *Context) Uint(name string) uint { - return lookupUint(name, c.flagSet) -} - -// GlobalUint looks up the value of a global UintFlag, returns -// 0 if not found -func (c *Context) GlobalUint(name string) uint { - if fs := lookupGlobalFlagSet(name, c); fs != nil { - return lookupUint(name, fs) - } - return 0 -} - -func lookupUint(name string, set *flag.FlagSet) uint { - f := set.Lookup(name) - if f != nil { - parsed, err := strconv.ParseUint(f.Value.String(), 0, 64) - if err != nil { - return 0 - } - return uint(parsed) - } - return 0 -} diff --git a/vendor/github.com/urfave/cli/funcs.go b/vendor/github.com/urfave/cli/funcs.go deleted file mode 100644 index cba5e6c..0000000 --- a/vendor/github.com/urfave/cli/funcs.go +++ /dev/null @@ -1,28 +0,0 @@ -package cli - -// BashCompleteFunc is an action to execute when the bash-completion flag is set -type BashCompleteFunc func(*Context) - -// BeforeFunc is an action to execute before any subcommands are run, but after -// the context is ready if a non-nil error is returned, no subcommands are run -type BeforeFunc func(*Context) error - -// AfterFunc is an action to execute after any subcommands are run, but after the -// subcommand has finished it is run even if Action() panics -type AfterFunc func(*Context) error - -// ActionFunc is the action to execute when no subcommands are specified -type ActionFunc func(*Context) error - -// CommandNotFoundFunc is executed if the proper command cannot be found -type CommandNotFoundFunc func(*Context, string) - -// OnUsageErrorFunc is executed if an usage error occurs. This is useful for displaying -// customized usage error messages. This function is able to replace the -// original error messages. If this function is not set, the "Incorrect usage" -// is displayed and the execution is interrupted. -type OnUsageErrorFunc func(context *Context, err error, isSubcommand bool) error - -// FlagStringFunc is used by the help generation to display a flag, which is -// expected to be a single line. -type FlagStringFunc func(Flag) string diff --git a/vendor/github.com/urfave/cli/generate-flag-types b/vendor/github.com/urfave/cli/generate-flag-types deleted file mode 100644 index 7147381..0000000 --- a/vendor/github.com/urfave/cli/generate-flag-types +++ /dev/null @@ -1,255 +0,0 @@ -#!/usr/bin/env python -""" -The flag types that ship with the cli library have many things in common, and -so we can take advantage of the `go generate` command to create much of the -source code from a list of definitions. These definitions attempt to cover -the parts that vary between flag types, and should evolve as needed. - -An example of the minimum definition needed is: - - { - "name": "SomeType", - "type": "sometype", - "context_default": "nil" - } - -In this example, the code generated for the `cli` package will include a type -named `SomeTypeFlag` that is expected to wrap a value of type `sometype`. -Fetching values by name via `*cli.Context` will default to a value of `nil`. - -A more complete, albeit somewhat redundant, example showing all available -definition keys is: - - { - "name": "VeryMuchType", - "type": "*VeryMuchType", - "value": true, - "dest": false, - "doctail": " which really only wraps a []float64, oh well!", - "context_type": "[]float64", - "context_default": "nil", - "parser": "parseVeryMuchType(f.Value.String())", - "parser_cast": "[]float64(parsed)" - } - -The meaning of each field is as follows: - - name (string) - The type "name", which will be suffixed with - `Flag` when generating the type definition - for `cli` and the wrapper type for `altsrc` - type (string) - The type that the generated `Flag` type for `cli` - is expected to "contain" as its `.Value` member - value (bool) - Should the generated `cli` type have a `Value` - member? - dest (bool) - Should the generated `cli` type support a - destination pointer? - doctail (string) - Additional docs for the `cli` flag type comment - context_type (string) - The literal type used in the `*cli.Context` - reader func signature - context_default (string) - The literal value used as the default by the - `*cli.Context` reader funcs when no value is - present - parser (string) - Literal code used to parse the flag `f`, - expected to have a return signature of - (value, error) - parser_cast (string) - Literal code used to cast the `parsed` value - returned from the `parser` code -""" - -from __future__ import print_function, unicode_literals - -import argparse -import json -import os -import subprocess -import sys -import tempfile -import textwrap - - -class _FancyFormatter(argparse.ArgumentDefaultsHelpFormatter, - argparse.RawDescriptionHelpFormatter): - pass - - -def main(sysargs=sys.argv[:]): - parser = argparse.ArgumentParser( - description='Generate flag type code!', - formatter_class=_FancyFormatter) - parser.add_argument( - 'package', - type=str, default='cli', choices=_WRITEFUNCS.keys(), - help='Package for which flag types will be generated' - ) - parser.add_argument( - '-i', '--in-json', - type=argparse.FileType('r'), - default=sys.stdin, - help='Input JSON file which defines each type to be generated' - ) - parser.add_argument( - '-o', '--out-go', - type=argparse.FileType('w'), - default=sys.stdout, - help='Output file/stream to which generated source will be written' - ) - parser.epilog = __doc__ - - args = parser.parse_args(sysargs[1:]) - _generate_flag_types(_WRITEFUNCS[args.package], args.out_go, args.in_json) - return 0 - - -def _generate_flag_types(writefunc, output_go, input_json): - types = json.load(input_json) - - tmp = tempfile.NamedTemporaryFile(suffix='.go', delete=False) - writefunc(tmp, types) - tmp.close() - - new_content = subprocess.check_output( - ['goimports', tmp.name] - ).decode('utf-8') - - print(new_content, file=output_go, end='') - output_go.flush() - os.remove(tmp.name) - - -def _set_typedef_defaults(typedef): - typedef.setdefault('doctail', '') - typedef.setdefault('context_type', typedef['type']) - typedef.setdefault('dest', True) - typedef.setdefault('value', True) - typedef.setdefault('parser', 'f.Value, error(nil)') - typedef.setdefault('parser_cast', 'parsed') - - -def _write_cli_flag_types(outfile, types): - _fwrite(outfile, """\ - package cli - - // WARNING: This file is generated! - - """) - - for typedef in types: - _set_typedef_defaults(typedef) - - _fwrite(outfile, """\ - // {name}Flag is a flag with type {type}{doctail} - type {name}Flag struct {{ - Name string - Usage string - EnvVar string - Hidden bool - """.format(**typedef)) - - if typedef['value']: - _fwrite(outfile, """\ - Value {type} - """.format(**typedef)) - - if typedef['dest']: - _fwrite(outfile, """\ - Destination *{type} - """.format(**typedef)) - - _fwrite(outfile, "\n}\n\n") - - _fwrite(outfile, """\ - // String returns a readable representation of this value - // (for usage defaults) - func (f {name}Flag) String() string {{ - return FlagStringer(f) - }} - - // GetName returns the name of the flag - func (f {name}Flag) GetName() string {{ - return f.Name - }} - - // {name} looks up the value of a local {name}Flag, returns - // {context_default} if not found - func (c *Context) {name}(name string) {context_type} {{ - return lookup{name}(name, c.flagSet) - }} - - // Global{name} looks up the value of a global {name}Flag, returns - // {context_default} if not found - func (c *Context) Global{name}(name string) {context_type} {{ - if fs := lookupGlobalFlagSet(name, c); fs != nil {{ - return lookup{name}(name, fs) - }} - return {context_default} - }} - - func lookup{name}(name string, set *flag.FlagSet) {context_type} {{ - f := set.Lookup(name) - if f != nil {{ - parsed, err := {parser} - if err != nil {{ - return {context_default} - }} - return {parser_cast} - }} - return {context_default} - }} - """.format(**typedef)) - - -def _write_altsrc_flag_types(outfile, types): - _fwrite(outfile, """\ - package altsrc - - import ( - "gopkg.in/urfave/cli.v1" - ) - - // WARNING: This file is generated! - - """) - - for typedef in types: - _set_typedef_defaults(typedef) - - _fwrite(outfile, """\ - // {name}Flag is the flag type that wraps cli.{name}Flag to allow - // for other values to be specified - type {name}Flag struct {{ - cli.{name}Flag - set *flag.FlagSet - }} - - // New{name}Flag creates a new {name}Flag - func New{name}Flag(fl cli.{name}Flag) *{name}Flag {{ - return &{name}Flag{{{name}Flag: fl, set: nil}} - }} - - // Apply saves the flagSet for later usage calls, then calls the - // wrapped {name}Flag.Apply - func (f *{name}Flag) Apply(set *flag.FlagSet) {{ - f.set = set - f.{name}Flag.Apply(set) - }} - - // ApplyWithError saves the flagSet for later usage calls, then calls the - // wrapped {name}Flag.ApplyWithError - func (f *{name}Flag) ApplyWithError(set *flag.FlagSet) error {{ - f.set = set - return f.{name}Flag.ApplyWithError(set) - }} - """.format(**typedef)) - - -def _fwrite(outfile, text): - print(textwrap.dedent(text), end='', file=outfile) - - -_WRITEFUNCS = { - 'cli': _write_cli_flag_types, - 'altsrc': _write_altsrc_flag_types -} - -if __name__ == '__main__': - sys.exit(main()) diff --git a/vendor/github.com/urfave/cli/help.go b/vendor/github.com/urfave/cli/help.go deleted file mode 100644 index c8c1aee..0000000 --- a/vendor/github.com/urfave/cli/help.go +++ /dev/null @@ -1,294 +0,0 @@ -package cli - -import ( - "fmt" - "io" - "os" - "strings" - "text/tabwriter" - "text/template" -) - -// AppHelpTemplate is the text template for the Default help topic. -// cli.go uses text/template to render templates. You can -// render custom help text by setting this variable. -var AppHelpTemplate = `NAME: - {{.Name}}{{if .Usage}} - {{.Usage}}{{end}} - -USAGE: - {{if .UsageText}}{{.UsageText}}{{else}}{{.HelpName}} {{if .VisibleFlags}}[global options]{{end}}{{if .Commands}} command [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Version}}{{if not .HideVersion}} - -VERSION: - {{.Version}}{{end}}{{end}}{{if .Description}} - -DESCRIPTION: - {{.Description}}{{end}}{{if len .Authors}} - -AUTHOR{{with $length := len .Authors}}{{if ne 1 $length}}S{{end}}{{end}}: - {{range $index, $author := .Authors}}{{if $index}} - {{end}}{{$author}}{{end}}{{end}}{{if .VisibleCommands}} - -COMMANDS:{{range .VisibleCategories}}{{if .Name}} - {{.Name}}:{{end}}{{range .VisibleCommands}} - {{join .Names ", "}}{{"\t"}}{{.Usage}}{{end}}{{end}}{{end}}{{if .VisibleFlags}} - -GLOBAL OPTIONS: - {{range $index, $option := .VisibleFlags}}{{if $index}} - {{end}}{{$option}}{{end}}{{end}}{{if .Copyright}} - -COPYRIGHT: - {{.Copyright}}{{end}} -` - -// CommandHelpTemplate is the text template for the command help topic. -// cli.go uses text/template to render templates. You can -// render custom help text by setting this variable. -var CommandHelpTemplate = `NAME: - {{.HelpName}} - {{.Usage}} - -USAGE: - {{.HelpName}}{{if .VisibleFlags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{if .Category}} - -CATEGORY: - {{.Category}}{{end}}{{if .Description}} - -DESCRIPTION: - {{.Description}}{{end}}{{if .VisibleFlags}} - -OPTIONS: - {{range .VisibleFlags}}{{.}} - {{end}}{{end}} -` - -// SubcommandHelpTemplate is the text template for the subcommand help topic. -// cli.go uses text/template to render templates. You can -// render custom help text by setting this variable. -var SubcommandHelpTemplate = `NAME: - {{.HelpName}} - {{.Usage}} - -USAGE: - {{.HelpName}} command{{if .VisibleFlags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}} - -COMMANDS:{{range .VisibleCategories}}{{if .Name}} - {{.Name}}:{{end}}{{range .VisibleCommands}} - {{join .Names ", "}}{{"\t"}}{{.Usage}}{{end}} -{{end}}{{if .VisibleFlags}} -OPTIONS: - {{range .VisibleFlags}}{{.}} - {{end}}{{end}} -` - -var helpCommand = Command{ - Name: "help", - Aliases: []string{"h"}, - Usage: "Shows a list of commands or help for one command", - ArgsUsage: "[command]", - Action: func(c *Context) error { - args := c.Args() - if args.Present() { - return ShowCommandHelp(c, args.First()) - } - - ShowAppHelp(c) - return nil - }, -} - -var helpSubcommand = Command{ - Name: "help", - Aliases: []string{"h"}, - Usage: "Shows a list of commands or help for one command", - ArgsUsage: "[command]", - Action: func(c *Context) error { - args := c.Args() - if args.Present() { - return ShowCommandHelp(c, args.First()) - } - - return ShowSubcommandHelp(c) - }, -} - -// Prints help for the App or Command -type helpPrinter func(w io.Writer, templ string, data interface{}) - -// HelpPrinter is a function that writes the help output. If not set a default -// is used. The function signature is: -// func(w io.Writer, templ string, data interface{}) -var HelpPrinter helpPrinter = printHelp - -// VersionPrinter prints the version for the App -var VersionPrinter = printVersion - -// ShowAppHelp is an action that displays the help. -func ShowAppHelp(c *Context) error { - HelpPrinter(c.App.Writer, AppHelpTemplate, c.App) - return nil -} - -// DefaultAppComplete prints the list of subcommands as the default app completion method -func DefaultAppComplete(c *Context) { - for _, command := range c.App.Commands { - if command.Hidden { - continue - } - for _, name := range command.Names() { - fmt.Fprintln(c.App.Writer, name) - } - } -} - -// ShowCommandHelp prints help for the given command -func ShowCommandHelp(ctx *Context, command string) error { - // show the subcommand help for a command with subcommands - if command == "" { - HelpPrinter(ctx.App.Writer, SubcommandHelpTemplate, ctx.App) - return nil - } - - for _, c := range ctx.App.Commands { - if c.HasName(command) { - HelpPrinter(ctx.App.Writer, CommandHelpTemplate, c) - return nil - } - } - - if ctx.App.CommandNotFound == nil { - return NewExitError(fmt.Sprintf("No help topic for '%v'", command), 3) - } - - ctx.App.CommandNotFound(ctx, command) - return nil -} - -// ShowSubcommandHelp prints help for the given subcommand -func ShowSubcommandHelp(c *Context) error { - return ShowCommandHelp(c, c.Command.Name) -} - -// ShowVersion prints the version number of the App -func ShowVersion(c *Context) { - VersionPrinter(c) -} - -func printVersion(c *Context) { - fmt.Fprintf(c.App.Writer, "%v version %v\n", c.App.Name, c.App.Version) -} - -// ShowCompletions prints the lists of commands within a given context -func ShowCompletions(c *Context) { - a := c.App - if a != nil && a.BashComplete != nil { - a.BashComplete(c) - } -} - -// ShowCommandCompletions prints the custom completions for a given command -func ShowCommandCompletions(ctx *Context, command string) { - c := ctx.App.Command(command) - if c != nil && c.BashComplete != nil { - c.BashComplete(ctx) - } -} - -func printHelp(out io.Writer, templ string, data interface{}) { - funcMap := template.FuncMap{ - "join": strings.Join, - } - - w := tabwriter.NewWriter(out, 1, 8, 2, ' ', 0) - t := template.Must(template.New("help").Funcs(funcMap).Parse(templ)) - err := t.Execute(w, data) - if err != nil { - // If the writer is closed, t.Execute will fail, and there's nothing - // we can do to recover. - if os.Getenv("CLI_TEMPLATE_ERROR_DEBUG") != "" { - fmt.Fprintf(ErrWriter, "CLI TEMPLATE ERROR: %#v\n", err) - } - return - } - w.Flush() -} - -func checkVersion(c *Context) bool { - found := false - if VersionFlag.Name != "" { - eachName(VersionFlag.Name, func(name string) { - if c.GlobalBool(name) || c.Bool(name) { - found = true - } - }) - } - return found -} - -func checkHelp(c *Context) bool { - found := false - if HelpFlag.Name != "" { - eachName(HelpFlag.Name, func(name string) { - if c.GlobalBool(name) || c.Bool(name) { - found = true - } - }) - } - return found -} - -func checkCommandHelp(c *Context, name string) bool { - if c.Bool("h") || c.Bool("help") { - ShowCommandHelp(c, name) - return true - } - - return false -} - -func checkSubcommandHelp(c *Context) bool { - if c.Bool("h") || c.Bool("help") { - ShowSubcommandHelp(c) - return true - } - - return false -} - -func checkShellCompleteFlag(a *App, arguments []string) (bool, []string) { - if !a.EnableBashCompletion { - return false, arguments - } - - pos := len(arguments) - 1 - lastArg := arguments[pos] - - if lastArg != "--"+BashCompletionFlag.Name { - return false, arguments - } - - return true, arguments[:pos] -} - -func checkCompletions(c *Context) bool { - if !c.shellComplete { - return false - } - - if args := c.Args(); args.Present() { - name := args.First() - if cmd := c.App.Command(name); cmd != nil { - // let the command handle the completion - return false - } - } - - ShowCompletions(c) - return true -} - -func checkCommandCompletions(c *Context, name string) bool { - if !c.shellComplete { - return false - } - - ShowCommandCompletions(c, name) - return true -} diff --git a/vendor/github.com/urfave/cli/runtests b/vendor/github.com/urfave/cli/runtests deleted file mode 100644 index ee22bde..0000000 --- a/vendor/github.com/urfave/cli/runtests +++ /dev/null @@ -1,122 +0,0 @@ -#!/usr/bin/env python -from __future__ import print_function - -import argparse -import os -import sys -import tempfile - -from subprocess import check_call, check_output - - -PACKAGE_NAME = os.environ.get( - 'CLI_PACKAGE_NAME', 'github.com/urfave/cli' -) - - -def main(sysargs=sys.argv[:]): - targets = { - 'vet': _vet, - 'test': _test, - 'gfmrun': _gfmrun, - 'toc': _toc, - 'gen': _gen, - } - - parser = argparse.ArgumentParser() - parser.add_argument( - 'target', nargs='?', choices=tuple(targets.keys()), default='test' - ) - args = parser.parse_args(sysargs[1:]) - - targets[args.target]() - return 0 - - -def _test(): - if check_output('go version'.split()).split()[2] < 'go1.2': - _run('go test -v .') - return - - coverprofiles = [] - for subpackage in ['', 'altsrc']: - coverprofile = 'cli.coverprofile' - if subpackage != '': - coverprofile = '{}.coverprofile'.format(subpackage) - - coverprofiles.append(coverprofile) - - _run('go test -v'.split() + [ - '-coverprofile={}'.format(coverprofile), - ('{}/{}'.format(PACKAGE_NAME, subpackage)).rstrip('/') - ]) - - combined_name = _combine_coverprofiles(coverprofiles) - _run('go tool cover -func={}'.format(combined_name)) - os.remove(combined_name) - - -def _gfmrun(): - go_version = check_output('go version'.split()).split()[2] - if go_version < 'go1.3': - print('runtests: skip on {}'.format(go_version), file=sys.stderr) - return - _run(['gfmrun', '-c', str(_gfmrun_count()), '-s', 'README.md']) - - -def _vet(): - _run('go vet ./...') - - -def _toc(): - _run('node_modules/.bin/markdown-toc -i README.md') - _run('git diff --exit-code') - - -def _gen(): - go_version = check_output('go version'.split()).split()[2] - if go_version < 'go1.5': - print('runtests: skip on {}'.format(go_version), file=sys.stderr) - return - - _run('go generate ./...') - _run('git diff --exit-code') - - -def _run(command): - if hasattr(command, 'split'): - command = command.split() - print('runtests: {}'.format(' '.join(command)), file=sys.stderr) - check_call(command) - - -def _gfmrun_count(): - with open('README.md') as infile: - lines = infile.read().splitlines() - return len(filter(_is_go_runnable, lines)) - - -def _is_go_runnable(line): - return line.startswith('package main') - - -def _combine_coverprofiles(coverprofiles): - combined = tempfile.NamedTemporaryFile( - suffix='.coverprofile', delete=False - ) - combined.write('mode: set\n') - - for coverprofile in coverprofiles: - with open(coverprofile, 'r') as infile: - for line in infile.readlines(): - if not line.startswith('mode: '): - combined.write(line) - - combined.flush() - name = combined.name - combined.close() - return name - - -if __name__ == '__main__': - sys.exit(main()) diff --git a/vendor/golang.org/x/net/AUTHORS b/vendor/golang.org/x/net/AUTHORS deleted file mode 100644 index 15167cd..0000000 --- a/vendor/golang.org/x/net/AUTHORS +++ /dev/null @@ -1,3 +0,0 @@ -# This source code refers to The Go Authors for copyright purposes. -# The master list of authors is in the main Go distribution, -# visible at http://tip.golang.org/AUTHORS. diff --git a/vendor/golang.org/x/net/CONTRIBUTORS b/vendor/golang.org/x/net/CONTRIBUTORS deleted file mode 100644 index 1c4577e..0000000 --- a/vendor/golang.org/x/net/CONTRIBUTORS +++ /dev/null @@ -1,3 +0,0 @@ -# This source code was written by the Go contributors. -# The master list of contributors is in the main Go distribution, -# visible at http://tip.golang.org/CONTRIBUTORS. diff --git a/vendor/golang.org/x/net/LICENSE b/vendor/golang.org/x/net/LICENSE deleted file mode 100644 index 6a66aea..0000000 --- a/vendor/golang.org/x/net/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2009 The Go Authors. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/golang.org/x/net/PATENTS b/vendor/golang.org/x/net/PATENTS deleted file mode 100644 index 7330990..0000000 --- a/vendor/golang.org/x/net/PATENTS +++ /dev/null @@ -1,22 +0,0 @@ -Additional IP Rights Grant (Patents) - -"This implementation" means the copyrightable works distributed by -Google as part of the Go project. - -Google hereby grants to You a perpetual, worldwide, non-exclusive, -no-charge, royalty-free, irrevocable (except as stated in this section) -patent license to make, have made, use, offer to sell, sell, import, -transfer and otherwise run, modify and propagate the contents of this -implementation of Go, where such license applies only to those patent -claims, both currently owned or controlled by Google and acquired in -the future, licensable by Google that are necessarily infringed by this -implementation of Go. This grant does not include claims that would be -infringed only as a consequence of further modification of this -implementation. If you or your agent or exclusive licensee institute or -order or agree to the institution of patent litigation against any -entity (including a cross-claim or counterclaim in a lawsuit) alleging -that this implementation of Go or any code incorporated within this -implementation of Go constitutes direct or contributory patent -infringement, or inducement of patent infringement, then any patent -rights granted to you under this License for this implementation of Go -shall terminate as of the date such litigation is filed. diff --git a/vendor/golang.org/x/net/html/atom/atom.go b/vendor/golang.org/x/net/html/atom/atom.go deleted file mode 100644 index cd0a8ac..0000000 --- a/vendor/golang.org/x/net/html/atom/atom.go +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package atom provides integer codes (also known as atoms) for a fixed set of -// frequently occurring HTML strings: tag names and attribute keys such as "p" -// and "id". -// -// Sharing an atom's name between all elements with the same tag can result in -// fewer string allocations when tokenizing and parsing HTML. Integer -// comparisons are also generally faster than string comparisons. -// -// The value of an atom's particular code is not guaranteed to stay the same -// between versions of this package. Neither is any ordering guaranteed: -// whether atom.H1 < atom.H2 may also change. The codes are not guaranteed to -// be dense. The only guarantees are that e.g. looking up "div" will yield -// atom.Div, calling atom.Div.String will return "div", and atom.Div != 0. -package atom // import "golang.org/x/net/html/atom" - -// Atom is an integer code for a string. The zero value maps to "". -type Atom uint32 - -// String returns the atom's name. -func (a Atom) String() string { - start := uint32(a >> 8) - n := uint32(a & 0xff) - if start+n > uint32(len(atomText)) { - return "" - } - return atomText[start : start+n] -} - -func (a Atom) string() string { - return atomText[a>>8 : a>>8+a&0xff] -} - -// fnv computes the FNV hash with an arbitrary starting value h. -func fnv(h uint32, s []byte) uint32 { - for i := range s { - h ^= uint32(s[i]) - h *= 16777619 - } - return h -} - -func match(s string, t []byte) bool { - for i, c := range t { - if s[i] != c { - return false - } - } - return true -} - -// Lookup returns the atom whose name is s. It returns zero if there is no -// such atom. The lookup is case sensitive. -func Lookup(s []byte) Atom { - if len(s) == 0 || len(s) > maxAtomLen { - return 0 - } - h := fnv(hash0, s) - if a := table[h&uint32(len(table)-1)]; int(a&0xff) == len(s) && match(a.string(), s) { - return a - } - if a := table[(h>>16)&uint32(len(table)-1)]; int(a&0xff) == len(s) && match(a.string(), s) { - return a - } - return 0 -} - -// String returns a string whose contents are equal to s. In that sense, it is -// equivalent to string(s) but may be more efficient. -func String(s []byte) string { - if a := Lookup(s); a != 0 { - return a.String() - } - return string(s) -} diff --git a/vendor/golang.org/x/net/html/atom/table.go b/vendor/golang.org/x/net/html/atom/table.go deleted file mode 100644 index 2605ba3..0000000 --- a/vendor/golang.org/x/net/html/atom/table.go +++ /dev/null @@ -1,713 +0,0 @@ -// generated by go run gen.go; DO NOT EDIT - -package atom - -const ( - A Atom = 0x1 - Abbr Atom = 0x4 - Accept Atom = 0x2106 - AcceptCharset Atom = 0x210e - Accesskey Atom = 0x3309 - Action Atom = 0x1f606 - Address Atom = 0x4f307 - Align Atom = 0x1105 - Alt Atom = 0x4503 - Annotation Atom = 0x1670a - AnnotationXml Atom = 0x1670e - Applet Atom = 0x2b306 - Area Atom = 0x2fa04 - Article Atom = 0x38807 - Aside Atom = 0x8305 - Async Atom = 0x7b05 - Audio Atom = 0xa605 - Autocomplete Atom = 0x1fc0c - Autofocus Atom = 0xb309 - Autoplay Atom = 0xce08 - B Atom = 0x101 - Base Atom = 0xd604 - Basefont Atom = 0xd608 - Bdi Atom = 0x1a03 - Bdo Atom = 0xe703 - Bgsound Atom = 0x11807 - Big Atom = 0x12403 - Blink Atom = 0x12705 - Blockquote Atom = 0x12c0a - Body Atom = 0x2f04 - Br Atom = 0x202 - Button Atom = 0x13606 - Canvas Atom = 0x7f06 - Caption Atom = 0x1bb07 - Center Atom = 0x5b506 - Challenge Atom = 0x21f09 - Charset Atom = 0x2807 - Checked Atom = 0x32807 - Cite Atom = 0x3c804 - Class Atom = 0x4de05 - Code Atom = 0x14904 - Col Atom = 0x15003 - Colgroup Atom = 0x15008 - Color Atom = 0x15d05 - Cols Atom = 0x16204 - Colspan Atom = 0x16207 - Command Atom = 0x17507 - Content Atom = 0x42307 - Contenteditable Atom = 0x4230f - Contextmenu Atom = 0x3310b - Controls Atom = 0x18808 - Coords Atom = 0x19406 - Crossorigin Atom = 0x19f0b - Data Atom = 0x44a04 - Datalist Atom = 0x44a08 - Datetime Atom = 0x23c08 - Dd Atom = 0x26702 - Default Atom = 0x8607 - Defer Atom = 0x14b05 - Del Atom = 0x3ef03 - Desc Atom = 0x4db04 - Details Atom = 0x4807 - Dfn Atom = 0x6103 - Dialog Atom = 0x1b06 - Dir Atom = 0x6903 - Dirname Atom = 0x6907 - Disabled Atom = 0x10c08 - Div Atom = 0x11303 - Dl Atom = 0x11e02 - Download Atom = 0x40008 - Draggable Atom = 0x17b09 - Dropzone Atom = 0x39108 - Dt Atom = 0x50902 - Em Atom = 0x6502 - Embed Atom = 0x6505 - Enctype Atom = 0x21107 - Face Atom = 0x5b304 - Fieldset Atom = 0x1b008 - Figcaption Atom = 0x1b80a - Figure Atom = 0x1cc06 - Font Atom = 0xda04 - Footer Atom = 0x8d06 - For Atom = 0x1d803 - ForeignObject Atom = 0x1d80d - Foreignobject Atom = 0x1e50d - Form Atom = 0x1f204 - Formaction Atom = 0x1f20a - Formenctype Atom = 0x20d0b - Formmethod Atom = 0x2280a - Formnovalidate Atom = 0x2320e - Formtarget Atom = 0x2470a - Frame Atom = 0x9a05 - Frameset Atom = 0x9a08 - H1 Atom = 0x26e02 - H2 Atom = 0x29402 - H3 Atom = 0x2a702 - H4 Atom = 0x2e902 - H5 Atom = 0x2f302 - H6 Atom = 0x50b02 - Head Atom = 0x2d504 - Header Atom = 0x2d506 - Headers Atom = 0x2d507 - Height Atom = 0x25106 - Hgroup Atom = 0x25906 - Hidden Atom = 0x26506 - High Atom = 0x26b04 - Hr Atom = 0x27002 - Href Atom = 0x27004 - Hreflang Atom = 0x27008 - Html Atom = 0x25504 - HttpEquiv Atom = 0x2780a - I Atom = 0x601 - Icon Atom = 0x42204 - Id Atom = 0x8502 - Iframe Atom = 0x29606 - Image Atom = 0x29c05 - Img Atom = 0x2a103 - Input Atom = 0x3e805 - Inputmode Atom = 0x3e809 - Ins Atom = 0x1a803 - Isindex Atom = 0x2a907 - Ismap Atom = 0x2b005 - Itemid Atom = 0x33c06 - Itemprop Atom = 0x3c908 - Itemref Atom = 0x5ad07 - Itemscope Atom = 0x2b909 - Itemtype Atom = 0x2c308 - Kbd Atom = 0x1903 - Keygen Atom = 0x3906 - Keytype Atom = 0x53707 - Kind Atom = 0x10904 - Label Atom = 0xf005 - Lang Atom = 0x27404 - Legend Atom = 0x18206 - Li Atom = 0x1202 - Link Atom = 0x12804 - List Atom = 0x44e04 - Listing Atom = 0x44e07 - Loop Atom = 0xf404 - Low Atom = 0x11f03 - Malignmark Atom = 0x100a - Manifest Atom = 0x5f108 - Map Atom = 0x2b203 - Mark Atom = 0x1604 - Marquee Atom = 0x2cb07 - Math Atom = 0x2d204 - Max Atom = 0x2e103 - Maxlength Atom = 0x2e109 - Media Atom = 0x6e05 - Mediagroup Atom = 0x6e0a - Menu Atom = 0x33804 - Menuitem Atom = 0x33808 - Meta Atom = 0x45d04 - Meter Atom = 0x24205 - Method Atom = 0x22c06 - Mglyph Atom = 0x2a206 - Mi Atom = 0x2eb02 - Min Atom = 0x2eb03 - Minlength Atom = 0x2eb09 - Mn Atom = 0x23502 - Mo Atom = 0x3ed02 - Ms Atom = 0x2bc02 - Mtext Atom = 0x2f505 - Multiple Atom = 0x30308 - Muted Atom = 0x30b05 - Name Atom = 0x6c04 - Nav Atom = 0x3e03 - Nobr Atom = 0x5704 - Noembed Atom = 0x6307 - Noframes Atom = 0x9808 - Noscript Atom = 0x3d208 - Novalidate Atom = 0x2360a - Object Atom = 0x1ec06 - Ol Atom = 0xc902 - Onabort Atom = 0x13a07 - Onafterprint Atom = 0x1c00c - Onautocomplete Atom = 0x1fa0e - Onautocompleteerror Atom = 0x1fa13 - Onbeforeprint Atom = 0x6040d - Onbeforeunload Atom = 0x4e70e - Onblur Atom = 0xaa06 - Oncancel Atom = 0xe908 - Oncanplay Atom = 0x28509 - Oncanplaythrough Atom = 0x28510 - Onchange Atom = 0x3a708 - Onclick Atom = 0x31007 - Onclose Atom = 0x31707 - Oncontextmenu Atom = 0x32f0d - Oncuechange Atom = 0x3420b - Ondblclick Atom = 0x34d0a - Ondrag Atom = 0x35706 - Ondragend Atom = 0x35709 - Ondragenter Atom = 0x3600b - Ondragleave Atom = 0x36b0b - Ondragover Atom = 0x3760a - Ondragstart Atom = 0x3800b - Ondrop Atom = 0x38f06 - Ondurationchange Atom = 0x39f10 - Onemptied Atom = 0x39609 - Onended Atom = 0x3af07 - Onerror Atom = 0x3b607 - Onfocus Atom = 0x3bd07 - Onhashchange Atom = 0x3da0c - Oninput Atom = 0x3e607 - Oninvalid Atom = 0x3f209 - Onkeydown Atom = 0x3fb09 - Onkeypress Atom = 0x4080a - Onkeyup Atom = 0x41807 - Onlanguagechange Atom = 0x43210 - Onload Atom = 0x44206 - Onloadeddata Atom = 0x4420c - Onloadedmetadata Atom = 0x45510 - Onloadstart Atom = 0x46b0b - Onmessage Atom = 0x47609 - Onmousedown Atom = 0x47f0b - Onmousemove Atom = 0x48a0b - Onmouseout Atom = 0x4950a - Onmouseover Atom = 0x4a20b - Onmouseup Atom = 0x4ad09 - Onmousewheel Atom = 0x4b60c - Onoffline Atom = 0x4c209 - Ononline Atom = 0x4cb08 - Onpagehide Atom = 0x4d30a - Onpageshow Atom = 0x4fe0a - Onpause Atom = 0x50d07 - Onplay Atom = 0x51706 - Onplaying Atom = 0x51709 - Onpopstate Atom = 0x5200a - Onprogress Atom = 0x52a0a - Onratechange Atom = 0x53e0c - Onreset Atom = 0x54a07 - Onresize Atom = 0x55108 - Onscroll Atom = 0x55f08 - Onseeked Atom = 0x56708 - Onseeking Atom = 0x56f09 - Onselect Atom = 0x57808 - Onshow Atom = 0x58206 - Onsort Atom = 0x58b06 - Onstalled Atom = 0x59509 - Onstorage Atom = 0x59e09 - Onsubmit Atom = 0x5a708 - Onsuspend Atom = 0x5bb09 - Ontimeupdate Atom = 0xdb0c - Ontoggle Atom = 0x5c408 - Onunload Atom = 0x5cc08 - Onvolumechange Atom = 0x5d40e - Onwaiting Atom = 0x5e209 - Open Atom = 0x3cf04 - Optgroup Atom = 0xf608 - Optimum Atom = 0x5eb07 - Option Atom = 0x60006 - Output Atom = 0x49c06 - P Atom = 0xc01 - Param Atom = 0xc05 - Pattern Atom = 0x5107 - Ping Atom = 0x7704 - Placeholder Atom = 0xc30b - Plaintext Atom = 0xfd09 - Poster Atom = 0x15706 - Pre Atom = 0x25e03 - Preload Atom = 0x25e07 - Progress Atom = 0x52c08 - Prompt Atom = 0x5fa06 - Public Atom = 0x41e06 - Q Atom = 0x13101 - Radiogroup Atom = 0x30a - Readonly Atom = 0x2fb08 - Rel Atom = 0x25f03 - Required Atom = 0x1d008 - Reversed Atom = 0x5a08 - Rows Atom = 0x9204 - Rowspan Atom = 0x9207 - Rp Atom = 0x1c602 - Rt Atom = 0x13f02 - Ruby Atom = 0xaf04 - S Atom = 0x2c01 - Samp Atom = 0x4e04 - Sandbox Atom = 0xbb07 - Scope Atom = 0x2bd05 - Scoped Atom = 0x2bd06 - Script Atom = 0x3d406 - Seamless Atom = 0x31c08 - Section Atom = 0x4e207 - Select Atom = 0x57a06 - Selected Atom = 0x57a08 - Shape Atom = 0x4f905 - Size Atom = 0x55504 - Sizes Atom = 0x55505 - Small Atom = 0x18f05 - Sortable Atom = 0x58d08 - Sorted Atom = 0x19906 - Source Atom = 0x1aa06 - Spacer Atom = 0x2db06 - Span Atom = 0x9504 - Spellcheck Atom = 0x3230a - Src Atom = 0x3c303 - Srcdoc Atom = 0x3c306 - Srclang Atom = 0x41107 - Start Atom = 0x38605 - Step Atom = 0x5f704 - Strike Atom = 0x53306 - Strong Atom = 0x55906 - Style Atom = 0x61105 - Sub Atom = 0x5a903 - Summary Atom = 0x61607 - Sup Atom = 0x61d03 - Svg Atom = 0x62003 - System Atom = 0x62306 - Tabindex Atom = 0x46308 - Table Atom = 0x42d05 - Target Atom = 0x24b06 - Tbody Atom = 0x2e05 - Td Atom = 0x4702 - Template Atom = 0x62608 - Textarea Atom = 0x2f608 - Tfoot Atom = 0x8c05 - Th Atom = 0x22e02 - Thead Atom = 0x2d405 - Time Atom = 0xdd04 - Title Atom = 0xa105 - Tr Atom = 0x10502 - Track Atom = 0x10505 - Translate Atom = 0x14009 - Tt Atom = 0x5302 - Type Atom = 0x21404 - Typemustmatch Atom = 0x2140d - U Atom = 0xb01 - Ul Atom = 0x8a02 - Usemap Atom = 0x51106 - Value Atom = 0x4005 - Var Atom = 0x11503 - Video Atom = 0x28105 - Wbr Atom = 0x12103 - Width Atom = 0x50705 - Wrap Atom = 0x58704 - Xmp Atom = 0xc103 -) - -const hash0 = 0xc17da63e - -const maxAtomLen = 19 - -var table = [1 << 9]Atom{ - 0x1: 0x48a0b, // onmousemove - 0x2: 0x5e209, // onwaiting - 0x3: 0x1fa13, // onautocompleteerror - 0x4: 0x5fa06, // prompt - 0x7: 0x5eb07, // optimum - 0x8: 0x1604, // mark - 0xa: 0x5ad07, // itemref - 0xb: 0x4fe0a, // onpageshow - 0xc: 0x57a06, // select - 0xd: 0x17b09, // draggable - 0xe: 0x3e03, // nav - 0xf: 0x17507, // command - 0x11: 0xb01, // u - 0x14: 0x2d507, // headers - 0x15: 0x44a08, // datalist - 0x17: 0x4e04, // samp - 0x1a: 0x3fb09, // onkeydown - 0x1b: 0x55f08, // onscroll - 0x1c: 0x15003, // col - 0x20: 0x3c908, // itemprop - 0x21: 0x2780a, // http-equiv - 0x22: 0x61d03, // sup - 0x24: 0x1d008, // required - 0x2b: 0x25e07, // preload - 0x2c: 0x6040d, // onbeforeprint - 0x2d: 0x3600b, // ondragenter - 0x2e: 0x50902, // dt - 0x2f: 0x5a708, // onsubmit - 0x30: 0x27002, // hr - 0x31: 0x32f0d, // oncontextmenu - 0x33: 0x29c05, // image - 0x34: 0x50d07, // onpause - 0x35: 0x25906, // hgroup - 0x36: 0x7704, // ping - 0x37: 0x57808, // onselect - 0x3a: 0x11303, // div - 0x3b: 0x1fa0e, // onautocomplete - 0x40: 0x2eb02, // mi - 0x41: 0x31c08, // seamless - 0x42: 0x2807, // charset - 0x43: 0x8502, // id - 0x44: 0x5200a, // onpopstate - 0x45: 0x3ef03, // del - 0x46: 0x2cb07, // marquee - 0x47: 0x3309, // accesskey - 0x49: 0x8d06, // footer - 0x4a: 0x44e04, // list - 0x4b: 0x2b005, // ismap - 0x51: 0x33804, // menu - 0x52: 0x2f04, // body - 0x55: 0x9a08, // frameset - 0x56: 0x54a07, // onreset - 0x57: 0x12705, // blink - 0x58: 0xa105, // title - 0x59: 0x38807, // article - 0x5b: 0x22e02, // th - 0x5d: 0x13101, // q - 0x5e: 0x3cf04, // open - 0x5f: 0x2fa04, // area - 0x61: 0x44206, // onload - 0x62: 0xda04, // font - 0x63: 0xd604, // base - 0x64: 0x16207, // colspan - 0x65: 0x53707, // keytype - 0x66: 0x11e02, // dl - 0x68: 0x1b008, // fieldset - 0x6a: 0x2eb03, // min - 0x6b: 0x11503, // var - 0x6f: 0x2d506, // header - 0x70: 0x13f02, // rt - 0x71: 0x15008, // colgroup - 0x72: 0x23502, // mn - 0x74: 0x13a07, // onabort - 0x75: 0x3906, // keygen - 0x76: 0x4c209, // onoffline - 0x77: 0x21f09, // challenge - 0x78: 0x2b203, // map - 0x7a: 0x2e902, // h4 - 0x7b: 0x3b607, // onerror - 0x7c: 0x2e109, // maxlength - 0x7d: 0x2f505, // mtext - 0x7e: 0xbb07, // sandbox - 0x7f: 0x58b06, // onsort - 0x80: 0x100a, // malignmark - 0x81: 0x45d04, // meta - 0x82: 0x7b05, // async - 0x83: 0x2a702, // h3 - 0x84: 0x26702, // dd - 0x85: 0x27004, // href - 0x86: 0x6e0a, // mediagroup - 0x87: 0x19406, // coords - 0x88: 0x41107, // srclang - 0x89: 0x34d0a, // ondblclick - 0x8a: 0x4005, // value - 0x8c: 0xe908, // oncancel - 0x8e: 0x3230a, // spellcheck - 0x8f: 0x9a05, // frame - 0x91: 0x12403, // big - 0x94: 0x1f606, // action - 0x95: 0x6903, // dir - 0x97: 0x2fb08, // readonly - 0x99: 0x42d05, // table - 0x9a: 0x61607, // summary - 0x9b: 0x12103, // wbr - 0x9c: 0x30a, // radiogroup - 0x9d: 0x6c04, // name - 0x9f: 0x62306, // system - 0xa1: 0x15d05, // color - 0xa2: 0x7f06, // canvas - 0xa3: 0x25504, // html - 0xa5: 0x56f09, // onseeking - 0xac: 0x4f905, // shape - 0xad: 0x25f03, // rel - 0xae: 0x28510, // oncanplaythrough - 0xaf: 0x3760a, // ondragover - 0xb0: 0x62608, // template - 0xb1: 0x1d80d, // foreignObject - 0xb3: 0x9204, // rows - 0xb6: 0x44e07, // listing - 0xb7: 0x49c06, // output - 0xb9: 0x3310b, // contextmenu - 0xbb: 0x11f03, // low - 0xbc: 0x1c602, // rp - 0xbd: 0x5bb09, // onsuspend - 0xbe: 0x13606, // button - 0xbf: 0x4db04, // desc - 0xc1: 0x4e207, // section - 0xc2: 0x52a0a, // onprogress - 0xc3: 0x59e09, // onstorage - 0xc4: 0x2d204, // math - 0xc5: 0x4503, // alt - 0xc7: 0x8a02, // ul - 0xc8: 0x5107, // pattern - 0xc9: 0x4b60c, // onmousewheel - 0xca: 0x35709, // ondragend - 0xcb: 0xaf04, // ruby - 0xcc: 0xc01, // p - 0xcd: 0x31707, // onclose - 0xce: 0x24205, // meter - 0xcf: 0x11807, // bgsound - 0xd2: 0x25106, // height - 0xd4: 0x101, // b - 0xd5: 0x2c308, // itemtype - 0xd8: 0x1bb07, // caption - 0xd9: 0x10c08, // disabled - 0xdb: 0x33808, // menuitem - 0xdc: 0x62003, // svg - 0xdd: 0x18f05, // small - 0xde: 0x44a04, // data - 0xe0: 0x4cb08, // ononline - 0xe1: 0x2a206, // mglyph - 0xe3: 0x6505, // embed - 0xe4: 0x10502, // tr - 0xe5: 0x46b0b, // onloadstart - 0xe7: 0x3c306, // srcdoc - 0xeb: 0x5c408, // ontoggle - 0xed: 0xe703, // bdo - 0xee: 0x4702, // td - 0xef: 0x8305, // aside - 0xf0: 0x29402, // h2 - 0xf1: 0x52c08, // progress - 0xf2: 0x12c0a, // blockquote - 0xf4: 0xf005, // label - 0xf5: 0x601, // i - 0xf7: 0x9207, // rowspan - 0xfb: 0x51709, // onplaying - 0xfd: 0x2a103, // img - 0xfe: 0xf608, // optgroup - 0xff: 0x42307, // content - 0x101: 0x53e0c, // onratechange - 0x103: 0x3da0c, // onhashchange - 0x104: 0x4807, // details - 0x106: 0x40008, // download - 0x109: 0x14009, // translate - 0x10b: 0x4230f, // contenteditable - 0x10d: 0x36b0b, // ondragleave - 0x10e: 0x2106, // accept - 0x10f: 0x57a08, // selected - 0x112: 0x1f20a, // formaction - 0x113: 0x5b506, // center - 0x115: 0x45510, // onloadedmetadata - 0x116: 0x12804, // link - 0x117: 0xdd04, // time - 0x118: 0x19f0b, // crossorigin - 0x119: 0x3bd07, // onfocus - 0x11a: 0x58704, // wrap - 0x11b: 0x42204, // icon - 0x11d: 0x28105, // video - 0x11e: 0x4de05, // class - 0x121: 0x5d40e, // onvolumechange - 0x122: 0xaa06, // onblur - 0x123: 0x2b909, // itemscope - 0x124: 0x61105, // style - 0x127: 0x41e06, // public - 0x129: 0x2320e, // formnovalidate - 0x12a: 0x58206, // onshow - 0x12c: 0x51706, // onplay - 0x12d: 0x3c804, // cite - 0x12e: 0x2bc02, // ms - 0x12f: 0xdb0c, // ontimeupdate - 0x130: 0x10904, // kind - 0x131: 0x2470a, // formtarget - 0x135: 0x3af07, // onended - 0x136: 0x26506, // hidden - 0x137: 0x2c01, // s - 0x139: 0x2280a, // formmethod - 0x13a: 0x3e805, // input - 0x13c: 0x50b02, // h6 - 0x13d: 0xc902, // ol - 0x13e: 0x3420b, // oncuechange - 0x13f: 0x1e50d, // foreignobject - 0x143: 0x4e70e, // onbeforeunload - 0x144: 0x2bd05, // scope - 0x145: 0x39609, // onemptied - 0x146: 0x14b05, // defer - 0x147: 0xc103, // xmp - 0x148: 0x39f10, // ondurationchange - 0x149: 0x1903, // kbd - 0x14c: 0x47609, // onmessage - 0x14d: 0x60006, // option - 0x14e: 0x2eb09, // minlength - 0x14f: 0x32807, // checked - 0x150: 0xce08, // autoplay - 0x152: 0x202, // br - 0x153: 0x2360a, // novalidate - 0x156: 0x6307, // noembed - 0x159: 0x31007, // onclick - 0x15a: 0x47f0b, // onmousedown - 0x15b: 0x3a708, // onchange - 0x15e: 0x3f209, // oninvalid - 0x15f: 0x2bd06, // scoped - 0x160: 0x18808, // controls - 0x161: 0x30b05, // muted - 0x162: 0x58d08, // sortable - 0x163: 0x51106, // usemap - 0x164: 0x1b80a, // figcaption - 0x165: 0x35706, // ondrag - 0x166: 0x26b04, // high - 0x168: 0x3c303, // src - 0x169: 0x15706, // poster - 0x16b: 0x1670e, // annotation-xml - 0x16c: 0x5f704, // step - 0x16d: 0x4, // abbr - 0x16e: 0x1b06, // dialog - 0x170: 0x1202, // li - 0x172: 0x3ed02, // mo - 0x175: 0x1d803, // for - 0x176: 0x1a803, // ins - 0x178: 0x55504, // size - 0x179: 0x43210, // onlanguagechange - 0x17a: 0x8607, // default - 0x17b: 0x1a03, // bdi - 0x17c: 0x4d30a, // onpagehide - 0x17d: 0x6907, // dirname - 0x17e: 0x21404, // type - 0x17f: 0x1f204, // form - 0x181: 0x28509, // oncanplay - 0x182: 0x6103, // dfn - 0x183: 0x46308, // tabindex - 0x186: 0x6502, // em - 0x187: 0x27404, // lang - 0x189: 0x39108, // dropzone - 0x18a: 0x4080a, // onkeypress - 0x18b: 0x23c08, // datetime - 0x18c: 0x16204, // cols - 0x18d: 0x1, // a - 0x18e: 0x4420c, // onloadeddata - 0x190: 0xa605, // audio - 0x192: 0x2e05, // tbody - 0x193: 0x22c06, // method - 0x195: 0xf404, // loop - 0x196: 0x29606, // iframe - 0x198: 0x2d504, // head - 0x19e: 0x5f108, // manifest - 0x19f: 0xb309, // autofocus - 0x1a0: 0x14904, // code - 0x1a1: 0x55906, // strong - 0x1a2: 0x30308, // multiple - 0x1a3: 0xc05, // param - 0x1a6: 0x21107, // enctype - 0x1a7: 0x5b304, // face - 0x1a8: 0xfd09, // plaintext - 0x1a9: 0x26e02, // h1 - 0x1aa: 0x59509, // onstalled - 0x1ad: 0x3d406, // script - 0x1ae: 0x2db06, // spacer - 0x1af: 0x55108, // onresize - 0x1b0: 0x4a20b, // onmouseover - 0x1b1: 0x5cc08, // onunload - 0x1b2: 0x56708, // onseeked - 0x1b4: 0x2140d, // typemustmatch - 0x1b5: 0x1cc06, // figure - 0x1b6: 0x4950a, // onmouseout - 0x1b7: 0x25e03, // pre - 0x1b8: 0x50705, // width - 0x1b9: 0x19906, // sorted - 0x1bb: 0x5704, // nobr - 0x1be: 0x5302, // tt - 0x1bf: 0x1105, // align - 0x1c0: 0x3e607, // oninput - 0x1c3: 0x41807, // onkeyup - 0x1c6: 0x1c00c, // onafterprint - 0x1c7: 0x210e, // accept-charset - 0x1c8: 0x33c06, // itemid - 0x1c9: 0x3e809, // inputmode - 0x1cb: 0x53306, // strike - 0x1cc: 0x5a903, // sub - 0x1cd: 0x10505, // track - 0x1ce: 0x38605, // start - 0x1d0: 0xd608, // basefont - 0x1d6: 0x1aa06, // source - 0x1d7: 0x18206, // legend - 0x1d8: 0x2d405, // thead - 0x1da: 0x8c05, // tfoot - 0x1dd: 0x1ec06, // object - 0x1de: 0x6e05, // media - 0x1df: 0x1670a, // annotation - 0x1e0: 0x20d0b, // formenctype - 0x1e2: 0x3d208, // noscript - 0x1e4: 0x55505, // sizes - 0x1e5: 0x1fc0c, // autocomplete - 0x1e6: 0x9504, // span - 0x1e7: 0x9808, // noframes - 0x1e8: 0x24b06, // target - 0x1e9: 0x38f06, // ondrop - 0x1ea: 0x2b306, // applet - 0x1ec: 0x5a08, // reversed - 0x1f0: 0x2a907, // isindex - 0x1f3: 0x27008, // hreflang - 0x1f5: 0x2f302, // h5 - 0x1f6: 0x4f307, // address - 0x1fa: 0x2e103, // max - 0x1fb: 0xc30b, // placeholder - 0x1fc: 0x2f608, // textarea - 0x1fe: 0x4ad09, // onmouseup - 0x1ff: 0x3800b, // ondragstart -} - -const atomText = "abbradiogrouparamalignmarkbdialogaccept-charsetbodyaccesskey" + - "genavaluealtdetailsampatternobreversedfnoembedirnamediagroup" + - "ingasyncanvasidefaultfooterowspanoframesetitleaudionblurubya" + - "utofocusandboxmplaceholderautoplaybasefontimeupdatebdoncance" + - "labelooptgrouplaintextrackindisabledivarbgsoundlowbrbigblink" + - "blockquotebuttonabortranslatecodefercolgroupostercolorcolspa" + - "nnotation-xmlcommandraggablegendcontrolsmallcoordsortedcross" + - "originsourcefieldsetfigcaptionafterprintfigurequiredforeignO" + - "bjectforeignobjectformactionautocompleteerrorformenctypemust" + - "matchallengeformmethodformnovalidatetimeterformtargetheightm" + - "lhgroupreloadhiddenhigh1hreflanghttp-equivideoncanplaythroug" + - "h2iframeimageimglyph3isindexismappletitemscopeditemtypemarqu" + - "eematheaderspacermaxlength4minlength5mtextareadonlymultiplem" + - "utedonclickoncloseamlesspellcheckedoncontextmenuitemidoncuec" + - "hangeondblclickondragendondragenterondragleaveondragoverondr" + - "agstarticleondropzonemptiedondurationchangeonendedonerroronf" + - "ocusrcdocitempropenoscriptonhashchangeoninputmodeloninvalido" + - "nkeydownloadonkeypressrclangonkeyupublicontenteditableonlang" + - "uagechangeonloadeddatalistingonloadedmetadatabindexonloadsta" + - "rtonmessageonmousedownonmousemoveonmouseoutputonmouseoveronm" + - "ouseuponmousewheelonofflineononlineonpagehidesclassectionbef" + - "oreunloaddresshapeonpageshowidth6onpausemaponplayingonpopsta" + - "teonprogresstrikeytypeonratechangeonresetonresizestrongonscr" + - "ollonseekedonseekingonselectedonshowraponsortableonstalledon" + - "storageonsubmitemrefacenteronsuspendontoggleonunloadonvolume" + - "changeonwaitingoptimumanifestepromptoptionbeforeprintstylesu" + - "mmarysupsvgsystemplate" diff --git a/vendor/golang.org/x/net/html/const.go b/vendor/golang.org/x/net/html/const.go deleted file mode 100644 index 52f651f..0000000 --- a/vendor/golang.org/x/net/html/const.go +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package html - -// Section 12.2.3.2 of the HTML5 specification says "The following elements -// have varying levels of special parsing rules". -// https://html.spec.whatwg.org/multipage/syntax.html#the-stack-of-open-elements -var isSpecialElementMap = map[string]bool{ - "address": true, - "applet": true, - "area": true, - "article": true, - "aside": true, - "base": true, - "basefont": true, - "bgsound": true, - "blockquote": true, - "body": true, - "br": true, - "button": true, - "caption": true, - "center": true, - "col": true, - "colgroup": true, - "dd": true, - "details": true, - "dir": true, - "div": true, - "dl": true, - "dt": true, - "embed": true, - "fieldset": true, - "figcaption": true, - "figure": true, - "footer": true, - "form": true, - "frame": true, - "frameset": true, - "h1": true, - "h2": true, - "h3": true, - "h4": true, - "h5": true, - "h6": true, - "head": true, - "header": true, - "hgroup": true, - "hr": true, - "html": true, - "iframe": true, - "img": true, - "input": true, - "isindex": true, - "li": true, - "link": true, - "listing": true, - "marquee": true, - "menu": true, - "meta": true, - "nav": true, - "noembed": true, - "noframes": true, - "noscript": true, - "object": true, - "ol": true, - "p": true, - "param": true, - "plaintext": true, - "pre": true, - "script": true, - "section": true, - "select": true, - "source": true, - "style": true, - "summary": true, - "table": true, - "tbody": true, - "td": true, - "template": true, - "textarea": true, - "tfoot": true, - "th": true, - "thead": true, - "title": true, - "tr": true, - "track": true, - "ul": true, - "wbr": true, - "xmp": true, -} - -func isSpecialElement(element *Node) bool { - switch element.Namespace { - case "", "html": - return isSpecialElementMap[element.Data] - case "svg": - return element.Data == "foreignObject" - } - return false -} diff --git a/vendor/golang.org/x/net/html/doc.go b/vendor/golang.org/x/net/html/doc.go deleted file mode 100644 index 94f4968..0000000 --- a/vendor/golang.org/x/net/html/doc.go +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -/* -Package html implements an HTML5-compliant tokenizer and parser. - -Tokenization is done by creating a Tokenizer for an io.Reader r. It is the -caller's responsibility to ensure that r provides UTF-8 encoded HTML. - - z := html.NewTokenizer(r) - -Given a Tokenizer z, the HTML is tokenized by repeatedly calling z.Next(), -which parses the next token and returns its type, or an error: - - for { - tt := z.Next() - if tt == html.ErrorToken { - // ... - return ... - } - // Process the current token. - } - -There are two APIs for retrieving the current token. The high-level API is to -call Token; the low-level API is to call Text or TagName / TagAttr. Both APIs -allow optionally calling Raw after Next but before Token, Text, TagName, or -TagAttr. In EBNF notation, the valid call sequence per token is: - - Next {Raw} [ Token | Text | TagName {TagAttr} ] - -Token returns an independent data structure that completely describes a token. -Entities (such as "<") are unescaped, tag names and attribute keys are -lower-cased, and attributes are collected into a []Attribute. For example: - - for { - if z.Next() == html.ErrorToken { - // Returning io.EOF indicates success. - return z.Err() - } - emitToken(z.Token()) - } - -The low-level API performs fewer allocations and copies, but the contents of -the []byte values returned by Text, TagName and TagAttr may change on the next -call to Next. For example, to extract an HTML page's anchor text: - - depth := 0 - for { - tt := z.Next() - switch tt { - case ErrorToken: - return z.Err() - case TextToken: - if depth > 0 { - // emitBytes should copy the []byte it receives, - // if it doesn't process it immediately. - emitBytes(z.Text()) - } - case StartTagToken, EndTagToken: - tn, _ := z.TagName() - if len(tn) == 1 && tn[0] == 'a' { - if tt == StartTagToken { - depth++ - } else { - depth-- - } - } - } - } - -Parsing is done by calling Parse with an io.Reader, which returns the root of -the parse tree (the document element) as a *Node. It is the caller's -responsibility to ensure that the Reader provides UTF-8 encoded HTML. For -example, to process each anchor node in depth-first order: - - doc, err := html.Parse(r) - if err != nil { - // ... - } - var f func(*html.Node) - f = func(n *html.Node) { - if n.Type == html.ElementNode && n.Data == "a" { - // Do something with n... - } - for c := n.FirstChild; c != nil; c = c.NextSibling { - f(c) - } - } - f(doc) - -The relevant specifications include: -https://html.spec.whatwg.org/multipage/syntax.html and -https://html.spec.whatwg.org/multipage/syntax.html#tokenization -*/ -package html // import "golang.org/x/net/html" - -// The tokenization algorithm implemented by this package is not a line-by-line -// transliteration of the relatively verbose state-machine in the WHATWG -// specification. A more direct approach is used instead, where the program -// counter implies the state, such as whether it is tokenizing a tag or a text -// node. Specification compliance is verified by checking expected and actual -// outputs over a test suite rather than aiming for algorithmic fidelity. - -// TODO(nigeltao): Does a DOM API belong in this package or a separate one? -// TODO(nigeltao): How does parsing interact with a JavaScript engine? diff --git a/vendor/golang.org/x/net/html/doctype.go b/vendor/golang.org/x/net/html/doctype.go deleted file mode 100644 index c484e5a..0000000 --- a/vendor/golang.org/x/net/html/doctype.go +++ /dev/null @@ -1,156 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package html - -import ( - "strings" -) - -// parseDoctype parses the data from a DoctypeToken into a name, -// public identifier, and system identifier. It returns a Node whose Type -// is DoctypeNode, whose Data is the name, and which has attributes -// named "system" and "public" for the two identifiers if they were present. -// quirks is whether the document should be parsed in "quirks mode". -func parseDoctype(s string) (n *Node, quirks bool) { - n = &Node{Type: DoctypeNode} - - // Find the name. - space := strings.IndexAny(s, whitespace) - if space == -1 { - space = len(s) - } - n.Data = s[:space] - // The comparison to "html" is case-sensitive. - if n.Data != "html" { - quirks = true - } - n.Data = strings.ToLower(n.Data) - s = strings.TrimLeft(s[space:], whitespace) - - if len(s) < 6 { - // It can't start with "PUBLIC" or "SYSTEM". - // Ignore the rest of the string. - return n, quirks || s != "" - } - - key := strings.ToLower(s[:6]) - s = s[6:] - for key == "public" || key == "system" { - s = strings.TrimLeft(s, whitespace) - if s == "" { - break - } - quote := s[0] - if quote != '"' && quote != '\'' { - break - } - s = s[1:] - q := strings.IndexRune(s, rune(quote)) - var id string - if q == -1 { - id = s - s = "" - } else { - id = s[:q] - s = s[q+1:] - } - n.Attr = append(n.Attr, Attribute{Key: key, Val: id}) - if key == "public" { - key = "system" - } else { - key = "" - } - } - - if key != "" || s != "" { - quirks = true - } else if len(n.Attr) > 0 { - if n.Attr[0].Key == "public" { - public := strings.ToLower(n.Attr[0].Val) - switch public { - case "-//w3o//dtd w3 html strict 3.0//en//", "-/w3d/dtd html 4.0 transitional/en", "html": - quirks = true - default: - for _, q := range quirkyIDs { - if strings.HasPrefix(public, q) { - quirks = true - break - } - } - } - // The following two public IDs only cause quirks mode if there is no system ID. - if len(n.Attr) == 1 && (strings.HasPrefix(public, "-//w3c//dtd html 4.01 frameset//") || - strings.HasPrefix(public, "-//w3c//dtd html 4.01 transitional//")) { - quirks = true - } - } - if lastAttr := n.Attr[len(n.Attr)-1]; lastAttr.Key == "system" && - strings.ToLower(lastAttr.Val) == "http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd" { - quirks = true - } - } - - return n, quirks -} - -// quirkyIDs is a list of public doctype identifiers that cause a document -// to be interpreted in quirks mode. The identifiers should be in lower case. -var quirkyIDs = []string{ - "+//silmaril//dtd html pro v0r11 19970101//", - "-//advasoft ltd//dtd html 3.0 aswedit + extensions//", - "-//as//dtd html 3.0 aswedit + extensions//", - "-//ietf//dtd html 2.0 level 1//", - "-//ietf//dtd html 2.0 level 2//", - "-//ietf//dtd html 2.0 strict level 1//", - "-//ietf//dtd html 2.0 strict level 2//", - "-//ietf//dtd html 2.0 strict//", - "-//ietf//dtd html 2.0//", - "-//ietf//dtd html 2.1e//", - "-//ietf//dtd html 3.0//", - "-//ietf//dtd html 3.2 final//", - "-//ietf//dtd html 3.2//", - "-//ietf//dtd html 3//", - "-//ietf//dtd html level 0//", - "-//ietf//dtd html level 1//", - "-//ietf//dtd html level 2//", - "-//ietf//dtd html level 3//", - "-//ietf//dtd html strict level 0//", - "-//ietf//dtd html strict level 1//", - "-//ietf//dtd html strict level 2//", - "-//ietf//dtd html strict level 3//", - "-//ietf//dtd html strict//", - "-//ietf//dtd html//", - "-//metrius//dtd metrius presentational//", - "-//microsoft//dtd internet explorer 2.0 html strict//", - "-//microsoft//dtd internet explorer 2.0 html//", - "-//microsoft//dtd internet explorer 2.0 tables//", - "-//microsoft//dtd internet explorer 3.0 html strict//", - "-//microsoft//dtd internet explorer 3.0 html//", - "-//microsoft//dtd internet explorer 3.0 tables//", - "-//netscape comm. corp.//dtd html//", - "-//netscape comm. corp.//dtd strict html//", - "-//o'reilly and associates//dtd html 2.0//", - "-//o'reilly and associates//dtd html extended 1.0//", - "-//o'reilly and associates//dtd html extended relaxed 1.0//", - "-//softquad software//dtd hotmetal pro 6.0::19990601::extensions to html 4.0//", - "-//softquad//dtd hotmetal pro 4.0::19971010::extensions to html 4.0//", - "-//spyglass//dtd html 2.0 extended//", - "-//sq//dtd html 2.0 hotmetal + extensions//", - "-//sun microsystems corp.//dtd hotjava html//", - "-//sun microsystems corp.//dtd hotjava strict html//", - "-//w3c//dtd html 3 1995-03-24//", - "-//w3c//dtd html 3.2 draft//", - "-//w3c//dtd html 3.2 final//", - "-//w3c//dtd html 3.2//", - "-//w3c//dtd html 3.2s draft//", - "-//w3c//dtd html 4.0 frameset//", - "-//w3c//dtd html 4.0 transitional//", - "-//w3c//dtd html experimental 19960712//", - "-//w3c//dtd html experimental 970421//", - "-//w3c//dtd w3 html//", - "-//w3o//dtd w3 html 3.0//", - "-//webtechs//dtd mozilla html 2.0//", - "-//webtechs//dtd mozilla html//", -} diff --git a/vendor/golang.org/x/net/html/entity.go b/vendor/golang.org/x/net/html/entity.go deleted file mode 100644 index a50c04c..0000000 --- a/vendor/golang.org/x/net/html/entity.go +++ /dev/null @@ -1,2253 +0,0 @@ -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package html - -// All entities that do not end with ';' are 6 or fewer bytes long. -const longestEntityWithoutSemicolon = 6 - -// entity is a map from HTML entity names to their values. The semicolon matters: -// https://html.spec.whatwg.org/multipage/syntax.html#named-character-references -// lists both "amp" and "amp;" as two separate entries. -// -// Note that the HTML5 list is larger than the HTML4 list at -// http://www.w3.org/TR/html4/sgml/entities.html -var entity = map[string]rune{ - "AElig;": '\U000000C6', - "AMP;": '\U00000026', - "Aacute;": '\U000000C1', - "Abreve;": '\U00000102', - "Acirc;": '\U000000C2', - "Acy;": '\U00000410', - "Afr;": '\U0001D504', - "Agrave;": '\U000000C0', - "Alpha;": '\U00000391', - "Amacr;": '\U00000100', - "And;": '\U00002A53', - "Aogon;": '\U00000104', - "Aopf;": '\U0001D538', - "ApplyFunction;": '\U00002061', - "Aring;": '\U000000C5', - "Ascr;": '\U0001D49C', - "Assign;": '\U00002254', - "Atilde;": '\U000000C3', - "Auml;": '\U000000C4', - "Backslash;": '\U00002216', - "Barv;": '\U00002AE7', - "Barwed;": '\U00002306', - "Bcy;": '\U00000411', - "Because;": '\U00002235', - "Bernoullis;": '\U0000212C', - "Beta;": '\U00000392', - "Bfr;": '\U0001D505', - "Bopf;": '\U0001D539', - "Breve;": '\U000002D8', - "Bscr;": '\U0000212C', - "Bumpeq;": '\U0000224E', - "CHcy;": '\U00000427', - "COPY;": '\U000000A9', - "Cacute;": '\U00000106', - "Cap;": '\U000022D2', - "CapitalDifferentialD;": '\U00002145', - "Cayleys;": '\U0000212D', - "Ccaron;": '\U0000010C', - "Ccedil;": '\U000000C7', - "Ccirc;": '\U00000108', - "Cconint;": '\U00002230', - "Cdot;": '\U0000010A', - "Cedilla;": '\U000000B8', - "CenterDot;": '\U000000B7', - "Cfr;": '\U0000212D', - "Chi;": '\U000003A7', - "CircleDot;": '\U00002299', - "CircleMinus;": '\U00002296', - "CirclePlus;": '\U00002295', - "CircleTimes;": '\U00002297', - "ClockwiseContourIntegral;": '\U00002232', - "CloseCurlyDoubleQuote;": '\U0000201D', - "CloseCurlyQuote;": '\U00002019', - "Colon;": '\U00002237', - "Colone;": '\U00002A74', - "Congruent;": '\U00002261', - "Conint;": '\U0000222F', - "ContourIntegral;": '\U0000222E', - "Copf;": '\U00002102', - "Coproduct;": '\U00002210', - "CounterClockwiseContourIntegral;": '\U00002233', - "Cross;": '\U00002A2F', - "Cscr;": '\U0001D49E', - "Cup;": '\U000022D3', - "CupCap;": '\U0000224D', - "DD;": '\U00002145', - "DDotrahd;": '\U00002911', - "DJcy;": '\U00000402', - "DScy;": '\U00000405', - "DZcy;": '\U0000040F', - "Dagger;": '\U00002021', - "Darr;": '\U000021A1', - "Dashv;": '\U00002AE4', - "Dcaron;": '\U0000010E', - "Dcy;": '\U00000414', - "Del;": '\U00002207', - "Delta;": '\U00000394', - "Dfr;": '\U0001D507', - "DiacriticalAcute;": '\U000000B4', - "DiacriticalDot;": '\U000002D9', - "DiacriticalDoubleAcute;": '\U000002DD', - "DiacriticalGrave;": '\U00000060', - "DiacriticalTilde;": '\U000002DC', - "Diamond;": '\U000022C4', - "DifferentialD;": '\U00002146', - "Dopf;": '\U0001D53B', - "Dot;": '\U000000A8', - "DotDot;": '\U000020DC', - "DotEqual;": '\U00002250', - "DoubleContourIntegral;": '\U0000222F', - "DoubleDot;": '\U000000A8', - "DoubleDownArrow;": '\U000021D3', - "DoubleLeftArrow;": '\U000021D0', - "DoubleLeftRightArrow;": '\U000021D4', - "DoubleLeftTee;": '\U00002AE4', - "DoubleLongLeftArrow;": '\U000027F8', - "DoubleLongLeftRightArrow;": '\U000027FA', - "DoubleLongRightArrow;": '\U000027F9', - "DoubleRightArrow;": '\U000021D2', - "DoubleRightTee;": '\U000022A8', - "DoubleUpArrow;": '\U000021D1', - "DoubleUpDownArrow;": '\U000021D5', - "DoubleVerticalBar;": '\U00002225', - "DownArrow;": '\U00002193', - "DownArrowBar;": '\U00002913', - "DownArrowUpArrow;": '\U000021F5', - "DownBreve;": '\U00000311', - "DownLeftRightVector;": '\U00002950', - "DownLeftTeeVector;": '\U0000295E', - "DownLeftVector;": '\U000021BD', - "DownLeftVectorBar;": '\U00002956', - "DownRightTeeVector;": '\U0000295F', - "DownRightVector;": '\U000021C1', - "DownRightVectorBar;": '\U00002957', - "DownTee;": '\U000022A4', - "DownTeeArrow;": '\U000021A7', - "Downarrow;": '\U000021D3', - "Dscr;": '\U0001D49F', - "Dstrok;": '\U00000110', - "ENG;": '\U0000014A', - "ETH;": '\U000000D0', - "Eacute;": '\U000000C9', - "Ecaron;": '\U0000011A', - "Ecirc;": '\U000000CA', - "Ecy;": '\U0000042D', - "Edot;": '\U00000116', - "Efr;": '\U0001D508', - "Egrave;": '\U000000C8', - "Element;": '\U00002208', - "Emacr;": '\U00000112', - "EmptySmallSquare;": '\U000025FB', - "EmptyVerySmallSquare;": '\U000025AB', - "Eogon;": '\U00000118', - "Eopf;": '\U0001D53C', - "Epsilon;": '\U00000395', - "Equal;": '\U00002A75', - "EqualTilde;": '\U00002242', - "Equilibrium;": '\U000021CC', - "Escr;": '\U00002130', - "Esim;": '\U00002A73', - "Eta;": '\U00000397', - "Euml;": '\U000000CB', - "Exists;": '\U00002203', - "ExponentialE;": '\U00002147', - "Fcy;": '\U00000424', - "Ffr;": '\U0001D509', - "FilledSmallSquare;": '\U000025FC', - "FilledVerySmallSquare;": '\U000025AA', - "Fopf;": '\U0001D53D', - "ForAll;": '\U00002200', - "Fouriertrf;": '\U00002131', - "Fscr;": '\U00002131', - "GJcy;": '\U00000403', - "GT;": '\U0000003E', - "Gamma;": '\U00000393', - "Gammad;": '\U000003DC', - "Gbreve;": '\U0000011E', - "Gcedil;": '\U00000122', - "Gcirc;": '\U0000011C', - "Gcy;": '\U00000413', - "Gdot;": '\U00000120', - "Gfr;": '\U0001D50A', - "Gg;": '\U000022D9', - "Gopf;": '\U0001D53E', - "GreaterEqual;": '\U00002265', - "GreaterEqualLess;": '\U000022DB', - "GreaterFullEqual;": '\U00002267', - "GreaterGreater;": '\U00002AA2', - "GreaterLess;": '\U00002277', - "GreaterSlantEqual;": '\U00002A7E', - "GreaterTilde;": '\U00002273', - "Gscr;": '\U0001D4A2', - "Gt;": '\U0000226B', - "HARDcy;": '\U0000042A', - "Hacek;": '\U000002C7', - "Hat;": '\U0000005E', - "Hcirc;": '\U00000124', - "Hfr;": '\U0000210C', - "HilbertSpace;": '\U0000210B', - "Hopf;": '\U0000210D', - "HorizontalLine;": '\U00002500', - "Hscr;": '\U0000210B', - "Hstrok;": '\U00000126', - "HumpDownHump;": '\U0000224E', - "HumpEqual;": '\U0000224F', - "IEcy;": '\U00000415', - "IJlig;": '\U00000132', - "IOcy;": '\U00000401', - "Iacute;": '\U000000CD', - "Icirc;": '\U000000CE', - "Icy;": '\U00000418', - "Idot;": '\U00000130', - "Ifr;": '\U00002111', - "Igrave;": '\U000000CC', - "Im;": '\U00002111', - "Imacr;": '\U0000012A', - "ImaginaryI;": '\U00002148', - "Implies;": '\U000021D2', - "Int;": '\U0000222C', - "Integral;": '\U0000222B', - "Intersection;": '\U000022C2', - "InvisibleComma;": '\U00002063', - "InvisibleTimes;": '\U00002062', - "Iogon;": '\U0000012E', - "Iopf;": '\U0001D540', - "Iota;": '\U00000399', - "Iscr;": '\U00002110', - "Itilde;": '\U00000128', - "Iukcy;": '\U00000406', - "Iuml;": '\U000000CF', - "Jcirc;": '\U00000134', - "Jcy;": '\U00000419', - "Jfr;": '\U0001D50D', - "Jopf;": '\U0001D541', - "Jscr;": '\U0001D4A5', - "Jsercy;": '\U00000408', - "Jukcy;": '\U00000404', - "KHcy;": '\U00000425', - "KJcy;": '\U0000040C', - "Kappa;": '\U0000039A', - "Kcedil;": '\U00000136', - "Kcy;": '\U0000041A', - "Kfr;": '\U0001D50E', - "Kopf;": '\U0001D542', - "Kscr;": '\U0001D4A6', - "LJcy;": '\U00000409', - "LT;": '\U0000003C', - "Lacute;": '\U00000139', - "Lambda;": '\U0000039B', - "Lang;": '\U000027EA', - "Laplacetrf;": '\U00002112', - "Larr;": '\U0000219E', - "Lcaron;": '\U0000013D', - "Lcedil;": '\U0000013B', - "Lcy;": '\U0000041B', - "LeftAngleBracket;": '\U000027E8', - "LeftArrow;": '\U00002190', - "LeftArrowBar;": '\U000021E4', - "LeftArrowRightArrow;": '\U000021C6', - "LeftCeiling;": '\U00002308', - "LeftDoubleBracket;": '\U000027E6', - "LeftDownTeeVector;": '\U00002961', - "LeftDownVector;": '\U000021C3', - "LeftDownVectorBar;": '\U00002959', - "LeftFloor;": '\U0000230A', - "LeftRightArrow;": '\U00002194', - "LeftRightVector;": '\U0000294E', - "LeftTee;": '\U000022A3', - "LeftTeeArrow;": '\U000021A4', - "LeftTeeVector;": '\U0000295A', - "LeftTriangle;": '\U000022B2', - "LeftTriangleBar;": '\U000029CF', - "LeftTriangleEqual;": '\U000022B4', - "LeftUpDownVector;": '\U00002951', - "LeftUpTeeVector;": '\U00002960', - "LeftUpVector;": '\U000021BF', - "LeftUpVectorBar;": '\U00002958', - "LeftVector;": '\U000021BC', - "LeftVectorBar;": '\U00002952', - "Leftarrow;": '\U000021D0', - "Leftrightarrow;": '\U000021D4', - "LessEqualGreater;": '\U000022DA', - "LessFullEqual;": '\U00002266', - "LessGreater;": '\U00002276', - "LessLess;": '\U00002AA1', - "LessSlantEqual;": '\U00002A7D', - "LessTilde;": '\U00002272', - "Lfr;": '\U0001D50F', - "Ll;": '\U000022D8', - "Lleftarrow;": '\U000021DA', - "Lmidot;": '\U0000013F', - "LongLeftArrow;": '\U000027F5', - "LongLeftRightArrow;": '\U000027F7', - "LongRightArrow;": '\U000027F6', - "Longleftarrow;": '\U000027F8', - "Longleftrightarrow;": '\U000027FA', - "Longrightarrow;": '\U000027F9', - "Lopf;": '\U0001D543', - "LowerLeftArrow;": '\U00002199', - "LowerRightArrow;": '\U00002198', - "Lscr;": '\U00002112', - "Lsh;": '\U000021B0', - "Lstrok;": '\U00000141', - "Lt;": '\U0000226A', - "Map;": '\U00002905', - "Mcy;": '\U0000041C', - "MediumSpace;": '\U0000205F', - "Mellintrf;": '\U00002133', - "Mfr;": '\U0001D510', - "MinusPlus;": '\U00002213', - "Mopf;": '\U0001D544', - "Mscr;": '\U00002133', - "Mu;": '\U0000039C', - "NJcy;": '\U0000040A', - "Nacute;": '\U00000143', - "Ncaron;": '\U00000147', - "Ncedil;": '\U00000145', - "Ncy;": '\U0000041D', - "NegativeMediumSpace;": '\U0000200B', - "NegativeThickSpace;": '\U0000200B', - "NegativeThinSpace;": '\U0000200B', - "NegativeVeryThinSpace;": '\U0000200B', - "NestedGreaterGreater;": '\U0000226B', - "NestedLessLess;": '\U0000226A', - "NewLine;": '\U0000000A', - "Nfr;": '\U0001D511', - "NoBreak;": '\U00002060', - "NonBreakingSpace;": '\U000000A0', - "Nopf;": '\U00002115', - "Not;": '\U00002AEC', - "NotCongruent;": '\U00002262', - "NotCupCap;": '\U0000226D', - "NotDoubleVerticalBar;": '\U00002226', - "NotElement;": '\U00002209', - "NotEqual;": '\U00002260', - "NotExists;": '\U00002204', - "NotGreater;": '\U0000226F', - "NotGreaterEqual;": '\U00002271', - "NotGreaterLess;": '\U00002279', - "NotGreaterTilde;": '\U00002275', - "NotLeftTriangle;": '\U000022EA', - "NotLeftTriangleEqual;": '\U000022EC', - "NotLess;": '\U0000226E', - "NotLessEqual;": '\U00002270', - "NotLessGreater;": '\U00002278', - "NotLessTilde;": '\U00002274', - "NotPrecedes;": '\U00002280', - "NotPrecedesSlantEqual;": '\U000022E0', - "NotReverseElement;": '\U0000220C', - "NotRightTriangle;": '\U000022EB', - "NotRightTriangleEqual;": '\U000022ED', - "NotSquareSubsetEqual;": '\U000022E2', - "NotSquareSupersetEqual;": '\U000022E3', - "NotSubsetEqual;": '\U00002288', - "NotSucceeds;": '\U00002281', - "NotSucceedsSlantEqual;": '\U000022E1', - "NotSupersetEqual;": '\U00002289', - "NotTilde;": '\U00002241', - "NotTildeEqual;": '\U00002244', - "NotTildeFullEqual;": '\U00002247', - "NotTildeTilde;": '\U00002249', - "NotVerticalBar;": '\U00002224', - "Nscr;": '\U0001D4A9', - "Ntilde;": '\U000000D1', - "Nu;": '\U0000039D', - "OElig;": '\U00000152', - "Oacute;": '\U000000D3', - "Ocirc;": '\U000000D4', - "Ocy;": '\U0000041E', - "Odblac;": '\U00000150', - "Ofr;": '\U0001D512', - "Ograve;": '\U000000D2', - "Omacr;": '\U0000014C', - "Omega;": '\U000003A9', - "Omicron;": '\U0000039F', - "Oopf;": '\U0001D546', - "OpenCurlyDoubleQuote;": '\U0000201C', - "OpenCurlyQuote;": '\U00002018', - "Or;": '\U00002A54', - "Oscr;": '\U0001D4AA', - "Oslash;": '\U000000D8', - "Otilde;": '\U000000D5', - "Otimes;": '\U00002A37', - "Ouml;": '\U000000D6', - "OverBar;": '\U0000203E', - "OverBrace;": '\U000023DE', - "OverBracket;": '\U000023B4', - "OverParenthesis;": '\U000023DC', - "PartialD;": '\U00002202', - "Pcy;": '\U0000041F', - "Pfr;": '\U0001D513', - "Phi;": '\U000003A6', - "Pi;": '\U000003A0', - "PlusMinus;": '\U000000B1', - "Poincareplane;": '\U0000210C', - "Popf;": '\U00002119', - "Pr;": '\U00002ABB', - "Precedes;": '\U0000227A', - "PrecedesEqual;": '\U00002AAF', - "PrecedesSlantEqual;": '\U0000227C', - "PrecedesTilde;": '\U0000227E', - "Prime;": '\U00002033', - "Product;": '\U0000220F', - "Proportion;": '\U00002237', - "Proportional;": '\U0000221D', - "Pscr;": '\U0001D4AB', - "Psi;": '\U000003A8', - "QUOT;": '\U00000022', - "Qfr;": '\U0001D514', - "Qopf;": '\U0000211A', - "Qscr;": '\U0001D4AC', - "RBarr;": '\U00002910', - "REG;": '\U000000AE', - "Racute;": '\U00000154', - "Rang;": '\U000027EB', - "Rarr;": '\U000021A0', - "Rarrtl;": '\U00002916', - "Rcaron;": '\U00000158', - "Rcedil;": '\U00000156', - "Rcy;": '\U00000420', - "Re;": '\U0000211C', - "ReverseElement;": '\U0000220B', - "ReverseEquilibrium;": '\U000021CB', - "ReverseUpEquilibrium;": '\U0000296F', - "Rfr;": '\U0000211C', - "Rho;": '\U000003A1', - "RightAngleBracket;": '\U000027E9', - "RightArrow;": '\U00002192', - "RightArrowBar;": '\U000021E5', - "RightArrowLeftArrow;": '\U000021C4', - "RightCeiling;": '\U00002309', - "RightDoubleBracket;": '\U000027E7', - "RightDownTeeVector;": '\U0000295D', - "RightDownVector;": '\U000021C2', - "RightDownVectorBar;": '\U00002955', - "RightFloor;": '\U0000230B', - "RightTee;": '\U000022A2', - "RightTeeArrow;": '\U000021A6', - "RightTeeVector;": '\U0000295B', - "RightTriangle;": '\U000022B3', - "RightTriangleBar;": '\U000029D0', - "RightTriangleEqual;": '\U000022B5', - "RightUpDownVector;": '\U0000294F', - "RightUpTeeVector;": '\U0000295C', - "RightUpVector;": '\U000021BE', - "RightUpVectorBar;": '\U00002954', - "RightVector;": '\U000021C0', - "RightVectorBar;": '\U00002953', - "Rightarrow;": '\U000021D2', - "Ropf;": '\U0000211D', - "RoundImplies;": '\U00002970', - "Rrightarrow;": '\U000021DB', - "Rscr;": '\U0000211B', - "Rsh;": '\U000021B1', - "RuleDelayed;": '\U000029F4', - "SHCHcy;": '\U00000429', - "SHcy;": '\U00000428', - "SOFTcy;": '\U0000042C', - "Sacute;": '\U0000015A', - "Sc;": '\U00002ABC', - "Scaron;": '\U00000160', - "Scedil;": '\U0000015E', - "Scirc;": '\U0000015C', - "Scy;": '\U00000421', - "Sfr;": '\U0001D516', - "ShortDownArrow;": '\U00002193', - "ShortLeftArrow;": '\U00002190', - "ShortRightArrow;": '\U00002192', - "ShortUpArrow;": '\U00002191', - "Sigma;": '\U000003A3', - "SmallCircle;": '\U00002218', - "Sopf;": '\U0001D54A', - "Sqrt;": '\U0000221A', - "Square;": '\U000025A1', - "SquareIntersection;": '\U00002293', - "SquareSubset;": '\U0000228F', - "SquareSubsetEqual;": '\U00002291', - "SquareSuperset;": '\U00002290', - "SquareSupersetEqual;": '\U00002292', - "SquareUnion;": '\U00002294', - "Sscr;": '\U0001D4AE', - "Star;": '\U000022C6', - "Sub;": '\U000022D0', - "Subset;": '\U000022D0', - "SubsetEqual;": '\U00002286', - "Succeeds;": '\U0000227B', - "SucceedsEqual;": '\U00002AB0', - "SucceedsSlantEqual;": '\U0000227D', - "SucceedsTilde;": '\U0000227F', - "SuchThat;": '\U0000220B', - "Sum;": '\U00002211', - "Sup;": '\U000022D1', - "Superset;": '\U00002283', - "SupersetEqual;": '\U00002287', - "Supset;": '\U000022D1', - "THORN;": '\U000000DE', - "TRADE;": '\U00002122', - "TSHcy;": '\U0000040B', - "TScy;": '\U00000426', - "Tab;": '\U00000009', - "Tau;": '\U000003A4', - "Tcaron;": '\U00000164', - "Tcedil;": '\U00000162', - "Tcy;": '\U00000422', - "Tfr;": '\U0001D517', - "Therefore;": '\U00002234', - "Theta;": '\U00000398', - "ThinSpace;": '\U00002009', - "Tilde;": '\U0000223C', - "TildeEqual;": '\U00002243', - "TildeFullEqual;": '\U00002245', - "TildeTilde;": '\U00002248', - "Topf;": '\U0001D54B', - "TripleDot;": '\U000020DB', - "Tscr;": '\U0001D4AF', - "Tstrok;": '\U00000166', - "Uacute;": '\U000000DA', - "Uarr;": '\U0000219F', - "Uarrocir;": '\U00002949', - "Ubrcy;": '\U0000040E', - "Ubreve;": '\U0000016C', - "Ucirc;": '\U000000DB', - "Ucy;": '\U00000423', - "Udblac;": '\U00000170', - "Ufr;": '\U0001D518', - "Ugrave;": '\U000000D9', - "Umacr;": '\U0000016A', - "UnderBar;": '\U0000005F', - "UnderBrace;": '\U000023DF', - "UnderBracket;": '\U000023B5', - "UnderParenthesis;": '\U000023DD', - "Union;": '\U000022C3', - "UnionPlus;": '\U0000228E', - "Uogon;": '\U00000172', - "Uopf;": '\U0001D54C', - "UpArrow;": '\U00002191', - "UpArrowBar;": '\U00002912', - "UpArrowDownArrow;": '\U000021C5', - "UpDownArrow;": '\U00002195', - "UpEquilibrium;": '\U0000296E', - "UpTee;": '\U000022A5', - "UpTeeArrow;": '\U000021A5', - "Uparrow;": '\U000021D1', - "Updownarrow;": '\U000021D5', - "UpperLeftArrow;": '\U00002196', - "UpperRightArrow;": '\U00002197', - "Upsi;": '\U000003D2', - "Upsilon;": '\U000003A5', - "Uring;": '\U0000016E', - "Uscr;": '\U0001D4B0', - "Utilde;": '\U00000168', - "Uuml;": '\U000000DC', - "VDash;": '\U000022AB', - "Vbar;": '\U00002AEB', - "Vcy;": '\U00000412', - "Vdash;": '\U000022A9', - "Vdashl;": '\U00002AE6', - "Vee;": '\U000022C1', - "Verbar;": '\U00002016', - "Vert;": '\U00002016', - "VerticalBar;": '\U00002223', - "VerticalLine;": '\U0000007C', - "VerticalSeparator;": '\U00002758', - "VerticalTilde;": '\U00002240', - "VeryThinSpace;": '\U0000200A', - "Vfr;": '\U0001D519', - "Vopf;": '\U0001D54D', - "Vscr;": '\U0001D4B1', - "Vvdash;": '\U000022AA', - "Wcirc;": '\U00000174', - "Wedge;": '\U000022C0', - "Wfr;": '\U0001D51A', - "Wopf;": '\U0001D54E', - "Wscr;": '\U0001D4B2', - "Xfr;": '\U0001D51B', - "Xi;": '\U0000039E', - "Xopf;": '\U0001D54F', - "Xscr;": '\U0001D4B3', - "YAcy;": '\U0000042F', - "YIcy;": '\U00000407', - "YUcy;": '\U0000042E', - "Yacute;": '\U000000DD', - "Ycirc;": '\U00000176', - "Ycy;": '\U0000042B', - "Yfr;": '\U0001D51C', - "Yopf;": '\U0001D550', - "Yscr;": '\U0001D4B4', - "Yuml;": '\U00000178', - "ZHcy;": '\U00000416', - "Zacute;": '\U00000179', - "Zcaron;": '\U0000017D', - "Zcy;": '\U00000417', - "Zdot;": '\U0000017B', - "ZeroWidthSpace;": '\U0000200B', - "Zeta;": '\U00000396', - "Zfr;": '\U00002128', - "Zopf;": '\U00002124', - "Zscr;": '\U0001D4B5', - "aacute;": '\U000000E1', - "abreve;": '\U00000103', - "ac;": '\U0000223E', - "acd;": '\U0000223F', - "acirc;": '\U000000E2', - "acute;": '\U000000B4', - "acy;": '\U00000430', - "aelig;": '\U000000E6', - "af;": '\U00002061', - "afr;": '\U0001D51E', - "agrave;": '\U000000E0', - "alefsym;": '\U00002135', - "aleph;": '\U00002135', - "alpha;": '\U000003B1', - "amacr;": '\U00000101', - "amalg;": '\U00002A3F', - "amp;": '\U00000026', - "and;": '\U00002227', - "andand;": '\U00002A55', - "andd;": '\U00002A5C', - "andslope;": '\U00002A58', - "andv;": '\U00002A5A', - "ang;": '\U00002220', - "ange;": '\U000029A4', - "angle;": '\U00002220', - "angmsd;": '\U00002221', - "angmsdaa;": '\U000029A8', - "angmsdab;": '\U000029A9', - "angmsdac;": '\U000029AA', - "angmsdad;": '\U000029AB', - "angmsdae;": '\U000029AC', - "angmsdaf;": '\U000029AD', - "angmsdag;": '\U000029AE', - "angmsdah;": '\U000029AF', - "angrt;": '\U0000221F', - "angrtvb;": '\U000022BE', - "angrtvbd;": '\U0000299D', - "angsph;": '\U00002222', - "angst;": '\U000000C5', - "angzarr;": '\U0000237C', - "aogon;": '\U00000105', - "aopf;": '\U0001D552', - "ap;": '\U00002248', - "apE;": '\U00002A70', - "apacir;": '\U00002A6F', - "ape;": '\U0000224A', - "apid;": '\U0000224B', - "apos;": '\U00000027', - "approx;": '\U00002248', - "approxeq;": '\U0000224A', - "aring;": '\U000000E5', - "ascr;": '\U0001D4B6', - "ast;": '\U0000002A', - "asymp;": '\U00002248', - "asympeq;": '\U0000224D', - "atilde;": '\U000000E3', - "auml;": '\U000000E4', - "awconint;": '\U00002233', - "awint;": '\U00002A11', - "bNot;": '\U00002AED', - "backcong;": '\U0000224C', - "backepsilon;": '\U000003F6', - "backprime;": '\U00002035', - "backsim;": '\U0000223D', - "backsimeq;": '\U000022CD', - "barvee;": '\U000022BD', - "barwed;": '\U00002305', - "barwedge;": '\U00002305', - "bbrk;": '\U000023B5', - "bbrktbrk;": '\U000023B6', - "bcong;": '\U0000224C', - "bcy;": '\U00000431', - "bdquo;": '\U0000201E', - "becaus;": '\U00002235', - "because;": '\U00002235', - "bemptyv;": '\U000029B0', - "bepsi;": '\U000003F6', - "bernou;": '\U0000212C', - "beta;": '\U000003B2', - "beth;": '\U00002136', - "between;": '\U0000226C', - "bfr;": '\U0001D51F', - "bigcap;": '\U000022C2', - "bigcirc;": '\U000025EF', - "bigcup;": '\U000022C3', - "bigodot;": '\U00002A00', - "bigoplus;": '\U00002A01', - "bigotimes;": '\U00002A02', - "bigsqcup;": '\U00002A06', - "bigstar;": '\U00002605', - "bigtriangledown;": '\U000025BD', - "bigtriangleup;": '\U000025B3', - "biguplus;": '\U00002A04', - "bigvee;": '\U000022C1', - "bigwedge;": '\U000022C0', - "bkarow;": '\U0000290D', - "blacklozenge;": '\U000029EB', - "blacksquare;": '\U000025AA', - "blacktriangle;": '\U000025B4', - "blacktriangledown;": '\U000025BE', - "blacktriangleleft;": '\U000025C2', - "blacktriangleright;": '\U000025B8', - "blank;": '\U00002423', - "blk12;": '\U00002592', - "blk14;": '\U00002591', - "blk34;": '\U00002593', - "block;": '\U00002588', - "bnot;": '\U00002310', - "bopf;": '\U0001D553', - "bot;": '\U000022A5', - "bottom;": '\U000022A5', - "bowtie;": '\U000022C8', - "boxDL;": '\U00002557', - "boxDR;": '\U00002554', - "boxDl;": '\U00002556', - "boxDr;": '\U00002553', - "boxH;": '\U00002550', - "boxHD;": '\U00002566', - "boxHU;": '\U00002569', - "boxHd;": '\U00002564', - "boxHu;": '\U00002567', - "boxUL;": '\U0000255D', - "boxUR;": '\U0000255A', - "boxUl;": '\U0000255C', - "boxUr;": '\U00002559', - "boxV;": '\U00002551', - "boxVH;": '\U0000256C', - "boxVL;": '\U00002563', - "boxVR;": '\U00002560', - "boxVh;": '\U0000256B', - "boxVl;": '\U00002562', - "boxVr;": '\U0000255F', - "boxbox;": '\U000029C9', - "boxdL;": '\U00002555', - "boxdR;": '\U00002552', - "boxdl;": '\U00002510', - "boxdr;": '\U0000250C', - "boxh;": '\U00002500', - "boxhD;": '\U00002565', - "boxhU;": '\U00002568', - "boxhd;": '\U0000252C', - "boxhu;": '\U00002534', - "boxminus;": '\U0000229F', - "boxplus;": '\U0000229E', - "boxtimes;": '\U000022A0', - "boxuL;": '\U0000255B', - "boxuR;": '\U00002558', - "boxul;": '\U00002518', - "boxur;": '\U00002514', - "boxv;": '\U00002502', - "boxvH;": '\U0000256A', - "boxvL;": '\U00002561', - "boxvR;": '\U0000255E', - "boxvh;": '\U0000253C', - "boxvl;": '\U00002524', - "boxvr;": '\U0000251C', - "bprime;": '\U00002035', - "breve;": '\U000002D8', - "brvbar;": '\U000000A6', - "bscr;": '\U0001D4B7', - "bsemi;": '\U0000204F', - "bsim;": '\U0000223D', - "bsime;": '\U000022CD', - "bsol;": '\U0000005C', - "bsolb;": '\U000029C5', - "bsolhsub;": '\U000027C8', - "bull;": '\U00002022', - "bullet;": '\U00002022', - "bump;": '\U0000224E', - "bumpE;": '\U00002AAE', - "bumpe;": '\U0000224F', - "bumpeq;": '\U0000224F', - "cacute;": '\U00000107', - "cap;": '\U00002229', - "capand;": '\U00002A44', - "capbrcup;": '\U00002A49', - "capcap;": '\U00002A4B', - "capcup;": '\U00002A47', - "capdot;": '\U00002A40', - "caret;": '\U00002041', - "caron;": '\U000002C7', - "ccaps;": '\U00002A4D', - "ccaron;": '\U0000010D', - "ccedil;": '\U000000E7', - "ccirc;": '\U00000109', - "ccups;": '\U00002A4C', - "ccupssm;": '\U00002A50', - "cdot;": '\U0000010B', - "cedil;": '\U000000B8', - "cemptyv;": '\U000029B2', - "cent;": '\U000000A2', - "centerdot;": '\U000000B7', - "cfr;": '\U0001D520', - "chcy;": '\U00000447', - "check;": '\U00002713', - "checkmark;": '\U00002713', - "chi;": '\U000003C7', - "cir;": '\U000025CB', - "cirE;": '\U000029C3', - "circ;": '\U000002C6', - "circeq;": '\U00002257', - "circlearrowleft;": '\U000021BA', - "circlearrowright;": '\U000021BB', - "circledR;": '\U000000AE', - "circledS;": '\U000024C8', - "circledast;": '\U0000229B', - "circledcirc;": '\U0000229A', - "circleddash;": '\U0000229D', - "cire;": '\U00002257', - "cirfnint;": '\U00002A10', - "cirmid;": '\U00002AEF', - "cirscir;": '\U000029C2', - "clubs;": '\U00002663', - "clubsuit;": '\U00002663', - "colon;": '\U0000003A', - "colone;": '\U00002254', - "coloneq;": '\U00002254', - "comma;": '\U0000002C', - "commat;": '\U00000040', - "comp;": '\U00002201', - "compfn;": '\U00002218', - "complement;": '\U00002201', - "complexes;": '\U00002102', - "cong;": '\U00002245', - "congdot;": '\U00002A6D', - "conint;": '\U0000222E', - "copf;": '\U0001D554', - "coprod;": '\U00002210', - "copy;": '\U000000A9', - "copysr;": '\U00002117', - "crarr;": '\U000021B5', - "cross;": '\U00002717', - "cscr;": '\U0001D4B8', - "csub;": '\U00002ACF', - "csube;": '\U00002AD1', - "csup;": '\U00002AD0', - "csupe;": '\U00002AD2', - "ctdot;": '\U000022EF', - "cudarrl;": '\U00002938', - "cudarrr;": '\U00002935', - "cuepr;": '\U000022DE', - "cuesc;": '\U000022DF', - "cularr;": '\U000021B6', - "cularrp;": '\U0000293D', - "cup;": '\U0000222A', - "cupbrcap;": '\U00002A48', - "cupcap;": '\U00002A46', - "cupcup;": '\U00002A4A', - "cupdot;": '\U0000228D', - "cupor;": '\U00002A45', - "curarr;": '\U000021B7', - "curarrm;": '\U0000293C', - "curlyeqprec;": '\U000022DE', - "curlyeqsucc;": '\U000022DF', - "curlyvee;": '\U000022CE', - "curlywedge;": '\U000022CF', - "curren;": '\U000000A4', - "curvearrowleft;": '\U000021B6', - "curvearrowright;": '\U000021B7', - "cuvee;": '\U000022CE', - "cuwed;": '\U000022CF', - "cwconint;": '\U00002232', - "cwint;": '\U00002231', - "cylcty;": '\U0000232D', - "dArr;": '\U000021D3', - "dHar;": '\U00002965', - "dagger;": '\U00002020', - "daleth;": '\U00002138', - "darr;": '\U00002193', - "dash;": '\U00002010', - "dashv;": '\U000022A3', - "dbkarow;": '\U0000290F', - "dblac;": '\U000002DD', - "dcaron;": '\U0000010F', - "dcy;": '\U00000434', - "dd;": '\U00002146', - "ddagger;": '\U00002021', - "ddarr;": '\U000021CA', - "ddotseq;": '\U00002A77', - "deg;": '\U000000B0', - "delta;": '\U000003B4', - "demptyv;": '\U000029B1', - "dfisht;": '\U0000297F', - "dfr;": '\U0001D521', - "dharl;": '\U000021C3', - "dharr;": '\U000021C2', - "diam;": '\U000022C4', - "diamond;": '\U000022C4', - "diamondsuit;": '\U00002666', - "diams;": '\U00002666', - "die;": '\U000000A8', - "digamma;": '\U000003DD', - "disin;": '\U000022F2', - "div;": '\U000000F7', - "divide;": '\U000000F7', - "divideontimes;": '\U000022C7', - "divonx;": '\U000022C7', - "djcy;": '\U00000452', - "dlcorn;": '\U0000231E', - "dlcrop;": '\U0000230D', - "dollar;": '\U00000024', - "dopf;": '\U0001D555', - "dot;": '\U000002D9', - "doteq;": '\U00002250', - "doteqdot;": '\U00002251', - "dotminus;": '\U00002238', - "dotplus;": '\U00002214', - "dotsquare;": '\U000022A1', - "doublebarwedge;": '\U00002306', - "downarrow;": '\U00002193', - "downdownarrows;": '\U000021CA', - "downharpoonleft;": '\U000021C3', - "downharpoonright;": '\U000021C2', - "drbkarow;": '\U00002910', - "drcorn;": '\U0000231F', - "drcrop;": '\U0000230C', - "dscr;": '\U0001D4B9', - "dscy;": '\U00000455', - "dsol;": '\U000029F6', - "dstrok;": '\U00000111', - "dtdot;": '\U000022F1', - "dtri;": '\U000025BF', - "dtrif;": '\U000025BE', - "duarr;": '\U000021F5', - "duhar;": '\U0000296F', - "dwangle;": '\U000029A6', - "dzcy;": '\U0000045F', - "dzigrarr;": '\U000027FF', - "eDDot;": '\U00002A77', - "eDot;": '\U00002251', - "eacute;": '\U000000E9', - "easter;": '\U00002A6E', - "ecaron;": '\U0000011B', - "ecir;": '\U00002256', - "ecirc;": '\U000000EA', - "ecolon;": '\U00002255', - "ecy;": '\U0000044D', - "edot;": '\U00000117', - "ee;": '\U00002147', - "efDot;": '\U00002252', - "efr;": '\U0001D522', - "eg;": '\U00002A9A', - "egrave;": '\U000000E8', - "egs;": '\U00002A96', - "egsdot;": '\U00002A98', - "el;": '\U00002A99', - "elinters;": '\U000023E7', - "ell;": '\U00002113', - "els;": '\U00002A95', - "elsdot;": '\U00002A97', - "emacr;": '\U00000113', - "empty;": '\U00002205', - "emptyset;": '\U00002205', - "emptyv;": '\U00002205', - "emsp;": '\U00002003', - "emsp13;": '\U00002004', - "emsp14;": '\U00002005', - "eng;": '\U0000014B', - "ensp;": '\U00002002', - "eogon;": '\U00000119', - "eopf;": '\U0001D556', - "epar;": '\U000022D5', - "eparsl;": '\U000029E3', - "eplus;": '\U00002A71', - "epsi;": '\U000003B5', - "epsilon;": '\U000003B5', - "epsiv;": '\U000003F5', - "eqcirc;": '\U00002256', - "eqcolon;": '\U00002255', - "eqsim;": '\U00002242', - "eqslantgtr;": '\U00002A96', - "eqslantless;": '\U00002A95', - "equals;": '\U0000003D', - "equest;": '\U0000225F', - "equiv;": '\U00002261', - "equivDD;": '\U00002A78', - "eqvparsl;": '\U000029E5', - "erDot;": '\U00002253', - "erarr;": '\U00002971', - "escr;": '\U0000212F', - "esdot;": '\U00002250', - "esim;": '\U00002242', - "eta;": '\U000003B7', - "eth;": '\U000000F0', - "euml;": '\U000000EB', - "euro;": '\U000020AC', - "excl;": '\U00000021', - "exist;": '\U00002203', - "expectation;": '\U00002130', - "exponentiale;": '\U00002147', - "fallingdotseq;": '\U00002252', - "fcy;": '\U00000444', - "female;": '\U00002640', - "ffilig;": '\U0000FB03', - "fflig;": '\U0000FB00', - "ffllig;": '\U0000FB04', - "ffr;": '\U0001D523', - "filig;": '\U0000FB01', - "flat;": '\U0000266D', - "fllig;": '\U0000FB02', - "fltns;": '\U000025B1', - "fnof;": '\U00000192', - "fopf;": '\U0001D557', - "forall;": '\U00002200', - "fork;": '\U000022D4', - "forkv;": '\U00002AD9', - "fpartint;": '\U00002A0D', - "frac12;": '\U000000BD', - "frac13;": '\U00002153', - "frac14;": '\U000000BC', - "frac15;": '\U00002155', - "frac16;": '\U00002159', - "frac18;": '\U0000215B', - "frac23;": '\U00002154', - "frac25;": '\U00002156', - "frac34;": '\U000000BE', - "frac35;": '\U00002157', - "frac38;": '\U0000215C', - "frac45;": '\U00002158', - "frac56;": '\U0000215A', - "frac58;": '\U0000215D', - "frac78;": '\U0000215E', - "frasl;": '\U00002044', - "frown;": '\U00002322', - "fscr;": '\U0001D4BB', - "gE;": '\U00002267', - "gEl;": '\U00002A8C', - "gacute;": '\U000001F5', - "gamma;": '\U000003B3', - "gammad;": '\U000003DD', - "gap;": '\U00002A86', - "gbreve;": '\U0000011F', - "gcirc;": '\U0000011D', - "gcy;": '\U00000433', - "gdot;": '\U00000121', - "ge;": '\U00002265', - "gel;": '\U000022DB', - "geq;": '\U00002265', - "geqq;": '\U00002267', - "geqslant;": '\U00002A7E', - "ges;": '\U00002A7E', - "gescc;": '\U00002AA9', - "gesdot;": '\U00002A80', - "gesdoto;": '\U00002A82', - "gesdotol;": '\U00002A84', - "gesles;": '\U00002A94', - "gfr;": '\U0001D524', - "gg;": '\U0000226B', - "ggg;": '\U000022D9', - "gimel;": '\U00002137', - "gjcy;": '\U00000453', - "gl;": '\U00002277', - "glE;": '\U00002A92', - "gla;": '\U00002AA5', - "glj;": '\U00002AA4', - "gnE;": '\U00002269', - "gnap;": '\U00002A8A', - "gnapprox;": '\U00002A8A', - "gne;": '\U00002A88', - "gneq;": '\U00002A88', - "gneqq;": '\U00002269', - "gnsim;": '\U000022E7', - "gopf;": '\U0001D558', - "grave;": '\U00000060', - "gscr;": '\U0000210A', - "gsim;": '\U00002273', - "gsime;": '\U00002A8E', - "gsiml;": '\U00002A90', - "gt;": '\U0000003E', - "gtcc;": '\U00002AA7', - "gtcir;": '\U00002A7A', - "gtdot;": '\U000022D7', - "gtlPar;": '\U00002995', - "gtquest;": '\U00002A7C', - "gtrapprox;": '\U00002A86', - "gtrarr;": '\U00002978', - "gtrdot;": '\U000022D7', - "gtreqless;": '\U000022DB', - "gtreqqless;": '\U00002A8C', - "gtrless;": '\U00002277', - "gtrsim;": '\U00002273', - "hArr;": '\U000021D4', - "hairsp;": '\U0000200A', - "half;": '\U000000BD', - "hamilt;": '\U0000210B', - "hardcy;": '\U0000044A', - "harr;": '\U00002194', - "harrcir;": '\U00002948', - "harrw;": '\U000021AD', - "hbar;": '\U0000210F', - "hcirc;": '\U00000125', - "hearts;": '\U00002665', - "heartsuit;": '\U00002665', - "hellip;": '\U00002026', - "hercon;": '\U000022B9', - "hfr;": '\U0001D525', - "hksearow;": '\U00002925', - "hkswarow;": '\U00002926', - "hoarr;": '\U000021FF', - "homtht;": '\U0000223B', - "hookleftarrow;": '\U000021A9', - "hookrightarrow;": '\U000021AA', - "hopf;": '\U0001D559', - "horbar;": '\U00002015', - "hscr;": '\U0001D4BD', - "hslash;": '\U0000210F', - "hstrok;": '\U00000127', - "hybull;": '\U00002043', - "hyphen;": '\U00002010', - "iacute;": '\U000000ED', - "ic;": '\U00002063', - "icirc;": '\U000000EE', - "icy;": '\U00000438', - "iecy;": '\U00000435', - "iexcl;": '\U000000A1', - "iff;": '\U000021D4', - "ifr;": '\U0001D526', - "igrave;": '\U000000EC', - "ii;": '\U00002148', - "iiiint;": '\U00002A0C', - "iiint;": '\U0000222D', - "iinfin;": '\U000029DC', - "iiota;": '\U00002129', - "ijlig;": '\U00000133', - "imacr;": '\U0000012B', - "image;": '\U00002111', - "imagline;": '\U00002110', - "imagpart;": '\U00002111', - "imath;": '\U00000131', - "imof;": '\U000022B7', - "imped;": '\U000001B5', - "in;": '\U00002208', - "incare;": '\U00002105', - "infin;": '\U0000221E', - "infintie;": '\U000029DD', - "inodot;": '\U00000131', - "int;": '\U0000222B', - "intcal;": '\U000022BA', - "integers;": '\U00002124', - "intercal;": '\U000022BA', - "intlarhk;": '\U00002A17', - "intprod;": '\U00002A3C', - "iocy;": '\U00000451', - "iogon;": '\U0000012F', - "iopf;": '\U0001D55A', - "iota;": '\U000003B9', - "iprod;": '\U00002A3C', - "iquest;": '\U000000BF', - "iscr;": '\U0001D4BE', - "isin;": '\U00002208', - "isinE;": '\U000022F9', - "isindot;": '\U000022F5', - "isins;": '\U000022F4', - "isinsv;": '\U000022F3', - "isinv;": '\U00002208', - "it;": '\U00002062', - "itilde;": '\U00000129', - "iukcy;": '\U00000456', - "iuml;": '\U000000EF', - "jcirc;": '\U00000135', - "jcy;": '\U00000439', - "jfr;": '\U0001D527', - "jmath;": '\U00000237', - "jopf;": '\U0001D55B', - "jscr;": '\U0001D4BF', - "jsercy;": '\U00000458', - "jukcy;": '\U00000454', - "kappa;": '\U000003BA', - "kappav;": '\U000003F0', - "kcedil;": '\U00000137', - "kcy;": '\U0000043A', - "kfr;": '\U0001D528', - "kgreen;": '\U00000138', - "khcy;": '\U00000445', - "kjcy;": '\U0000045C', - "kopf;": '\U0001D55C', - "kscr;": '\U0001D4C0', - "lAarr;": '\U000021DA', - "lArr;": '\U000021D0', - "lAtail;": '\U0000291B', - "lBarr;": '\U0000290E', - "lE;": '\U00002266', - "lEg;": '\U00002A8B', - "lHar;": '\U00002962', - "lacute;": '\U0000013A', - "laemptyv;": '\U000029B4', - "lagran;": '\U00002112', - "lambda;": '\U000003BB', - "lang;": '\U000027E8', - "langd;": '\U00002991', - "langle;": '\U000027E8', - "lap;": '\U00002A85', - "laquo;": '\U000000AB', - "larr;": '\U00002190', - "larrb;": '\U000021E4', - "larrbfs;": '\U0000291F', - "larrfs;": '\U0000291D', - "larrhk;": '\U000021A9', - "larrlp;": '\U000021AB', - "larrpl;": '\U00002939', - "larrsim;": '\U00002973', - "larrtl;": '\U000021A2', - "lat;": '\U00002AAB', - "latail;": '\U00002919', - "late;": '\U00002AAD', - "lbarr;": '\U0000290C', - "lbbrk;": '\U00002772', - "lbrace;": '\U0000007B', - "lbrack;": '\U0000005B', - "lbrke;": '\U0000298B', - "lbrksld;": '\U0000298F', - "lbrkslu;": '\U0000298D', - "lcaron;": '\U0000013E', - "lcedil;": '\U0000013C', - "lceil;": '\U00002308', - "lcub;": '\U0000007B', - "lcy;": '\U0000043B', - "ldca;": '\U00002936', - "ldquo;": '\U0000201C', - "ldquor;": '\U0000201E', - "ldrdhar;": '\U00002967', - "ldrushar;": '\U0000294B', - "ldsh;": '\U000021B2', - "le;": '\U00002264', - "leftarrow;": '\U00002190', - "leftarrowtail;": '\U000021A2', - "leftharpoondown;": '\U000021BD', - "leftharpoonup;": '\U000021BC', - "leftleftarrows;": '\U000021C7', - "leftrightarrow;": '\U00002194', - "leftrightarrows;": '\U000021C6', - "leftrightharpoons;": '\U000021CB', - "leftrightsquigarrow;": '\U000021AD', - "leftthreetimes;": '\U000022CB', - "leg;": '\U000022DA', - "leq;": '\U00002264', - "leqq;": '\U00002266', - "leqslant;": '\U00002A7D', - "les;": '\U00002A7D', - "lescc;": '\U00002AA8', - "lesdot;": '\U00002A7F', - "lesdoto;": '\U00002A81', - "lesdotor;": '\U00002A83', - "lesges;": '\U00002A93', - "lessapprox;": '\U00002A85', - "lessdot;": '\U000022D6', - "lesseqgtr;": '\U000022DA', - "lesseqqgtr;": '\U00002A8B', - "lessgtr;": '\U00002276', - "lesssim;": '\U00002272', - "lfisht;": '\U0000297C', - "lfloor;": '\U0000230A', - "lfr;": '\U0001D529', - "lg;": '\U00002276', - "lgE;": '\U00002A91', - "lhard;": '\U000021BD', - "lharu;": '\U000021BC', - "lharul;": '\U0000296A', - "lhblk;": '\U00002584', - "ljcy;": '\U00000459', - "ll;": '\U0000226A', - "llarr;": '\U000021C7', - "llcorner;": '\U0000231E', - "llhard;": '\U0000296B', - "lltri;": '\U000025FA', - "lmidot;": '\U00000140', - "lmoust;": '\U000023B0', - "lmoustache;": '\U000023B0', - "lnE;": '\U00002268', - "lnap;": '\U00002A89', - "lnapprox;": '\U00002A89', - "lne;": '\U00002A87', - "lneq;": '\U00002A87', - "lneqq;": '\U00002268', - "lnsim;": '\U000022E6', - "loang;": '\U000027EC', - "loarr;": '\U000021FD', - "lobrk;": '\U000027E6', - "longleftarrow;": '\U000027F5', - "longleftrightarrow;": '\U000027F7', - "longmapsto;": '\U000027FC', - "longrightarrow;": '\U000027F6', - "looparrowleft;": '\U000021AB', - "looparrowright;": '\U000021AC', - "lopar;": '\U00002985', - "lopf;": '\U0001D55D', - "loplus;": '\U00002A2D', - "lotimes;": '\U00002A34', - "lowast;": '\U00002217', - "lowbar;": '\U0000005F', - "loz;": '\U000025CA', - "lozenge;": '\U000025CA', - "lozf;": '\U000029EB', - "lpar;": '\U00000028', - "lparlt;": '\U00002993', - "lrarr;": '\U000021C6', - "lrcorner;": '\U0000231F', - "lrhar;": '\U000021CB', - "lrhard;": '\U0000296D', - "lrm;": '\U0000200E', - "lrtri;": '\U000022BF', - "lsaquo;": '\U00002039', - "lscr;": '\U0001D4C1', - "lsh;": '\U000021B0', - "lsim;": '\U00002272', - "lsime;": '\U00002A8D', - "lsimg;": '\U00002A8F', - "lsqb;": '\U0000005B', - "lsquo;": '\U00002018', - "lsquor;": '\U0000201A', - "lstrok;": '\U00000142', - "lt;": '\U0000003C', - "ltcc;": '\U00002AA6', - "ltcir;": '\U00002A79', - "ltdot;": '\U000022D6', - "lthree;": '\U000022CB', - "ltimes;": '\U000022C9', - "ltlarr;": '\U00002976', - "ltquest;": '\U00002A7B', - "ltrPar;": '\U00002996', - "ltri;": '\U000025C3', - "ltrie;": '\U000022B4', - "ltrif;": '\U000025C2', - "lurdshar;": '\U0000294A', - "luruhar;": '\U00002966', - "mDDot;": '\U0000223A', - "macr;": '\U000000AF', - "male;": '\U00002642', - "malt;": '\U00002720', - "maltese;": '\U00002720', - "map;": '\U000021A6', - "mapsto;": '\U000021A6', - "mapstodown;": '\U000021A7', - "mapstoleft;": '\U000021A4', - "mapstoup;": '\U000021A5', - "marker;": '\U000025AE', - "mcomma;": '\U00002A29', - "mcy;": '\U0000043C', - "mdash;": '\U00002014', - "measuredangle;": '\U00002221', - "mfr;": '\U0001D52A', - "mho;": '\U00002127', - "micro;": '\U000000B5', - "mid;": '\U00002223', - "midast;": '\U0000002A', - "midcir;": '\U00002AF0', - "middot;": '\U000000B7', - "minus;": '\U00002212', - "minusb;": '\U0000229F', - "minusd;": '\U00002238', - "minusdu;": '\U00002A2A', - "mlcp;": '\U00002ADB', - "mldr;": '\U00002026', - "mnplus;": '\U00002213', - "models;": '\U000022A7', - "mopf;": '\U0001D55E', - "mp;": '\U00002213', - "mscr;": '\U0001D4C2', - "mstpos;": '\U0000223E', - "mu;": '\U000003BC', - "multimap;": '\U000022B8', - "mumap;": '\U000022B8', - "nLeftarrow;": '\U000021CD', - "nLeftrightarrow;": '\U000021CE', - "nRightarrow;": '\U000021CF', - "nVDash;": '\U000022AF', - "nVdash;": '\U000022AE', - "nabla;": '\U00002207', - "nacute;": '\U00000144', - "nap;": '\U00002249', - "napos;": '\U00000149', - "napprox;": '\U00002249', - "natur;": '\U0000266E', - "natural;": '\U0000266E', - "naturals;": '\U00002115', - "nbsp;": '\U000000A0', - "ncap;": '\U00002A43', - "ncaron;": '\U00000148', - "ncedil;": '\U00000146', - "ncong;": '\U00002247', - "ncup;": '\U00002A42', - "ncy;": '\U0000043D', - "ndash;": '\U00002013', - "ne;": '\U00002260', - "neArr;": '\U000021D7', - "nearhk;": '\U00002924', - "nearr;": '\U00002197', - "nearrow;": '\U00002197', - "nequiv;": '\U00002262', - "nesear;": '\U00002928', - "nexist;": '\U00002204', - "nexists;": '\U00002204', - "nfr;": '\U0001D52B', - "nge;": '\U00002271', - "ngeq;": '\U00002271', - "ngsim;": '\U00002275', - "ngt;": '\U0000226F', - "ngtr;": '\U0000226F', - "nhArr;": '\U000021CE', - "nharr;": '\U000021AE', - "nhpar;": '\U00002AF2', - "ni;": '\U0000220B', - "nis;": '\U000022FC', - "nisd;": '\U000022FA', - "niv;": '\U0000220B', - "njcy;": '\U0000045A', - "nlArr;": '\U000021CD', - "nlarr;": '\U0000219A', - "nldr;": '\U00002025', - "nle;": '\U00002270', - "nleftarrow;": '\U0000219A', - "nleftrightarrow;": '\U000021AE', - "nleq;": '\U00002270', - "nless;": '\U0000226E', - "nlsim;": '\U00002274', - "nlt;": '\U0000226E', - "nltri;": '\U000022EA', - "nltrie;": '\U000022EC', - "nmid;": '\U00002224', - "nopf;": '\U0001D55F', - "not;": '\U000000AC', - "notin;": '\U00002209', - "notinva;": '\U00002209', - "notinvb;": '\U000022F7', - "notinvc;": '\U000022F6', - "notni;": '\U0000220C', - "notniva;": '\U0000220C', - "notnivb;": '\U000022FE', - "notnivc;": '\U000022FD', - "npar;": '\U00002226', - "nparallel;": '\U00002226', - "npolint;": '\U00002A14', - "npr;": '\U00002280', - "nprcue;": '\U000022E0', - "nprec;": '\U00002280', - "nrArr;": '\U000021CF', - "nrarr;": '\U0000219B', - "nrightarrow;": '\U0000219B', - "nrtri;": '\U000022EB', - "nrtrie;": '\U000022ED', - "nsc;": '\U00002281', - "nsccue;": '\U000022E1', - "nscr;": '\U0001D4C3', - "nshortmid;": '\U00002224', - "nshortparallel;": '\U00002226', - "nsim;": '\U00002241', - "nsime;": '\U00002244', - "nsimeq;": '\U00002244', - "nsmid;": '\U00002224', - "nspar;": '\U00002226', - "nsqsube;": '\U000022E2', - "nsqsupe;": '\U000022E3', - "nsub;": '\U00002284', - "nsube;": '\U00002288', - "nsubseteq;": '\U00002288', - "nsucc;": '\U00002281', - "nsup;": '\U00002285', - "nsupe;": '\U00002289', - "nsupseteq;": '\U00002289', - "ntgl;": '\U00002279', - "ntilde;": '\U000000F1', - "ntlg;": '\U00002278', - "ntriangleleft;": '\U000022EA', - "ntrianglelefteq;": '\U000022EC', - "ntriangleright;": '\U000022EB', - "ntrianglerighteq;": '\U000022ED', - "nu;": '\U000003BD', - "num;": '\U00000023', - "numero;": '\U00002116', - "numsp;": '\U00002007', - "nvDash;": '\U000022AD', - "nvHarr;": '\U00002904', - "nvdash;": '\U000022AC', - "nvinfin;": '\U000029DE', - "nvlArr;": '\U00002902', - "nvrArr;": '\U00002903', - "nwArr;": '\U000021D6', - "nwarhk;": '\U00002923', - "nwarr;": '\U00002196', - "nwarrow;": '\U00002196', - "nwnear;": '\U00002927', - "oS;": '\U000024C8', - "oacute;": '\U000000F3', - "oast;": '\U0000229B', - "ocir;": '\U0000229A', - "ocirc;": '\U000000F4', - "ocy;": '\U0000043E', - "odash;": '\U0000229D', - "odblac;": '\U00000151', - "odiv;": '\U00002A38', - "odot;": '\U00002299', - "odsold;": '\U000029BC', - "oelig;": '\U00000153', - "ofcir;": '\U000029BF', - "ofr;": '\U0001D52C', - "ogon;": '\U000002DB', - "ograve;": '\U000000F2', - "ogt;": '\U000029C1', - "ohbar;": '\U000029B5', - "ohm;": '\U000003A9', - "oint;": '\U0000222E', - "olarr;": '\U000021BA', - "olcir;": '\U000029BE', - "olcross;": '\U000029BB', - "oline;": '\U0000203E', - "olt;": '\U000029C0', - "omacr;": '\U0000014D', - "omega;": '\U000003C9', - "omicron;": '\U000003BF', - "omid;": '\U000029B6', - "ominus;": '\U00002296', - "oopf;": '\U0001D560', - "opar;": '\U000029B7', - "operp;": '\U000029B9', - "oplus;": '\U00002295', - "or;": '\U00002228', - "orarr;": '\U000021BB', - "ord;": '\U00002A5D', - "order;": '\U00002134', - "orderof;": '\U00002134', - "ordf;": '\U000000AA', - "ordm;": '\U000000BA', - "origof;": '\U000022B6', - "oror;": '\U00002A56', - "orslope;": '\U00002A57', - "orv;": '\U00002A5B', - "oscr;": '\U00002134', - "oslash;": '\U000000F8', - "osol;": '\U00002298', - "otilde;": '\U000000F5', - "otimes;": '\U00002297', - "otimesas;": '\U00002A36', - "ouml;": '\U000000F6', - "ovbar;": '\U0000233D', - "par;": '\U00002225', - "para;": '\U000000B6', - "parallel;": '\U00002225', - "parsim;": '\U00002AF3', - "parsl;": '\U00002AFD', - "part;": '\U00002202', - "pcy;": '\U0000043F', - "percnt;": '\U00000025', - "period;": '\U0000002E', - "permil;": '\U00002030', - "perp;": '\U000022A5', - "pertenk;": '\U00002031', - "pfr;": '\U0001D52D', - "phi;": '\U000003C6', - "phiv;": '\U000003D5', - "phmmat;": '\U00002133', - "phone;": '\U0000260E', - "pi;": '\U000003C0', - "pitchfork;": '\U000022D4', - "piv;": '\U000003D6', - "planck;": '\U0000210F', - "planckh;": '\U0000210E', - "plankv;": '\U0000210F', - "plus;": '\U0000002B', - "plusacir;": '\U00002A23', - "plusb;": '\U0000229E', - "pluscir;": '\U00002A22', - "plusdo;": '\U00002214', - "plusdu;": '\U00002A25', - "pluse;": '\U00002A72', - "plusmn;": '\U000000B1', - "plussim;": '\U00002A26', - "plustwo;": '\U00002A27', - "pm;": '\U000000B1', - "pointint;": '\U00002A15', - "popf;": '\U0001D561', - "pound;": '\U000000A3', - "pr;": '\U0000227A', - "prE;": '\U00002AB3', - "prap;": '\U00002AB7', - "prcue;": '\U0000227C', - "pre;": '\U00002AAF', - "prec;": '\U0000227A', - "precapprox;": '\U00002AB7', - "preccurlyeq;": '\U0000227C', - "preceq;": '\U00002AAF', - "precnapprox;": '\U00002AB9', - "precneqq;": '\U00002AB5', - "precnsim;": '\U000022E8', - "precsim;": '\U0000227E', - "prime;": '\U00002032', - "primes;": '\U00002119', - "prnE;": '\U00002AB5', - "prnap;": '\U00002AB9', - "prnsim;": '\U000022E8', - "prod;": '\U0000220F', - "profalar;": '\U0000232E', - "profline;": '\U00002312', - "profsurf;": '\U00002313', - "prop;": '\U0000221D', - "propto;": '\U0000221D', - "prsim;": '\U0000227E', - "prurel;": '\U000022B0', - "pscr;": '\U0001D4C5', - "psi;": '\U000003C8', - "puncsp;": '\U00002008', - "qfr;": '\U0001D52E', - "qint;": '\U00002A0C', - "qopf;": '\U0001D562', - "qprime;": '\U00002057', - "qscr;": '\U0001D4C6', - "quaternions;": '\U0000210D', - "quatint;": '\U00002A16', - "quest;": '\U0000003F', - "questeq;": '\U0000225F', - "quot;": '\U00000022', - "rAarr;": '\U000021DB', - "rArr;": '\U000021D2', - "rAtail;": '\U0000291C', - "rBarr;": '\U0000290F', - "rHar;": '\U00002964', - "racute;": '\U00000155', - "radic;": '\U0000221A', - "raemptyv;": '\U000029B3', - "rang;": '\U000027E9', - "rangd;": '\U00002992', - "range;": '\U000029A5', - "rangle;": '\U000027E9', - "raquo;": '\U000000BB', - "rarr;": '\U00002192', - "rarrap;": '\U00002975', - "rarrb;": '\U000021E5', - "rarrbfs;": '\U00002920', - "rarrc;": '\U00002933', - "rarrfs;": '\U0000291E', - "rarrhk;": '\U000021AA', - "rarrlp;": '\U000021AC', - "rarrpl;": '\U00002945', - "rarrsim;": '\U00002974', - "rarrtl;": '\U000021A3', - "rarrw;": '\U0000219D', - "ratail;": '\U0000291A', - "ratio;": '\U00002236', - "rationals;": '\U0000211A', - "rbarr;": '\U0000290D', - "rbbrk;": '\U00002773', - "rbrace;": '\U0000007D', - "rbrack;": '\U0000005D', - "rbrke;": '\U0000298C', - "rbrksld;": '\U0000298E', - "rbrkslu;": '\U00002990', - "rcaron;": '\U00000159', - "rcedil;": '\U00000157', - "rceil;": '\U00002309', - "rcub;": '\U0000007D', - "rcy;": '\U00000440', - "rdca;": '\U00002937', - "rdldhar;": '\U00002969', - "rdquo;": '\U0000201D', - "rdquor;": '\U0000201D', - "rdsh;": '\U000021B3', - "real;": '\U0000211C', - "realine;": '\U0000211B', - "realpart;": '\U0000211C', - "reals;": '\U0000211D', - "rect;": '\U000025AD', - "reg;": '\U000000AE', - "rfisht;": '\U0000297D', - "rfloor;": '\U0000230B', - "rfr;": '\U0001D52F', - "rhard;": '\U000021C1', - "rharu;": '\U000021C0', - "rharul;": '\U0000296C', - "rho;": '\U000003C1', - "rhov;": '\U000003F1', - "rightarrow;": '\U00002192', - "rightarrowtail;": '\U000021A3', - "rightharpoondown;": '\U000021C1', - "rightharpoonup;": '\U000021C0', - "rightleftarrows;": '\U000021C4', - "rightleftharpoons;": '\U000021CC', - "rightrightarrows;": '\U000021C9', - "rightsquigarrow;": '\U0000219D', - "rightthreetimes;": '\U000022CC', - "ring;": '\U000002DA', - "risingdotseq;": '\U00002253', - "rlarr;": '\U000021C4', - "rlhar;": '\U000021CC', - "rlm;": '\U0000200F', - "rmoust;": '\U000023B1', - "rmoustache;": '\U000023B1', - "rnmid;": '\U00002AEE', - "roang;": '\U000027ED', - "roarr;": '\U000021FE', - "robrk;": '\U000027E7', - "ropar;": '\U00002986', - "ropf;": '\U0001D563', - "roplus;": '\U00002A2E', - "rotimes;": '\U00002A35', - "rpar;": '\U00000029', - "rpargt;": '\U00002994', - "rppolint;": '\U00002A12', - "rrarr;": '\U000021C9', - "rsaquo;": '\U0000203A', - "rscr;": '\U0001D4C7', - "rsh;": '\U000021B1', - "rsqb;": '\U0000005D', - "rsquo;": '\U00002019', - "rsquor;": '\U00002019', - "rthree;": '\U000022CC', - "rtimes;": '\U000022CA', - "rtri;": '\U000025B9', - "rtrie;": '\U000022B5', - "rtrif;": '\U000025B8', - "rtriltri;": '\U000029CE', - "ruluhar;": '\U00002968', - "rx;": '\U0000211E', - "sacute;": '\U0000015B', - "sbquo;": '\U0000201A', - "sc;": '\U0000227B', - "scE;": '\U00002AB4', - "scap;": '\U00002AB8', - "scaron;": '\U00000161', - "sccue;": '\U0000227D', - "sce;": '\U00002AB0', - "scedil;": '\U0000015F', - "scirc;": '\U0000015D', - "scnE;": '\U00002AB6', - "scnap;": '\U00002ABA', - "scnsim;": '\U000022E9', - "scpolint;": '\U00002A13', - "scsim;": '\U0000227F', - "scy;": '\U00000441', - "sdot;": '\U000022C5', - "sdotb;": '\U000022A1', - "sdote;": '\U00002A66', - "seArr;": '\U000021D8', - "searhk;": '\U00002925', - "searr;": '\U00002198', - "searrow;": '\U00002198', - "sect;": '\U000000A7', - "semi;": '\U0000003B', - "seswar;": '\U00002929', - "setminus;": '\U00002216', - "setmn;": '\U00002216', - "sext;": '\U00002736', - "sfr;": '\U0001D530', - "sfrown;": '\U00002322', - "sharp;": '\U0000266F', - "shchcy;": '\U00000449', - "shcy;": '\U00000448', - "shortmid;": '\U00002223', - "shortparallel;": '\U00002225', - "shy;": '\U000000AD', - "sigma;": '\U000003C3', - "sigmaf;": '\U000003C2', - "sigmav;": '\U000003C2', - "sim;": '\U0000223C', - "simdot;": '\U00002A6A', - "sime;": '\U00002243', - "simeq;": '\U00002243', - "simg;": '\U00002A9E', - "simgE;": '\U00002AA0', - "siml;": '\U00002A9D', - "simlE;": '\U00002A9F', - "simne;": '\U00002246', - "simplus;": '\U00002A24', - "simrarr;": '\U00002972', - "slarr;": '\U00002190', - "smallsetminus;": '\U00002216', - "smashp;": '\U00002A33', - "smeparsl;": '\U000029E4', - "smid;": '\U00002223', - "smile;": '\U00002323', - "smt;": '\U00002AAA', - "smte;": '\U00002AAC', - "softcy;": '\U0000044C', - "sol;": '\U0000002F', - "solb;": '\U000029C4', - "solbar;": '\U0000233F', - "sopf;": '\U0001D564', - "spades;": '\U00002660', - "spadesuit;": '\U00002660', - "spar;": '\U00002225', - "sqcap;": '\U00002293', - "sqcup;": '\U00002294', - "sqsub;": '\U0000228F', - "sqsube;": '\U00002291', - "sqsubset;": '\U0000228F', - "sqsubseteq;": '\U00002291', - "sqsup;": '\U00002290', - "sqsupe;": '\U00002292', - "sqsupset;": '\U00002290', - "sqsupseteq;": '\U00002292', - "squ;": '\U000025A1', - "square;": '\U000025A1', - "squarf;": '\U000025AA', - "squf;": '\U000025AA', - "srarr;": '\U00002192', - "sscr;": '\U0001D4C8', - "ssetmn;": '\U00002216', - "ssmile;": '\U00002323', - "sstarf;": '\U000022C6', - "star;": '\U00002606', - "starf;": '\U00002605', - "straightepsilon;": '\U000003F5', - "straightphi;": '\U000003D5', - "strns;": '\U000000AF', - "sub;": '\U00002282', - "subE;": '\U00002AC5', - "subdot;": '\U00002ABD', - "sube;": '\U00002286', - "subedot;": '\U00002AC3', - "submult;": '\U00002AC1', - "subnE;": '\U00002ACB', - "subne;": '\U0000228A', - "subplus;": '\U00002ABF', - "subrarr;": '\U00002979', - "subset;": '\U00002282', - "subseteq;": '\U00002286', - "subseteqq;": '\U00002AC5', - "subsetneq;": '\U0000228A', - "subsetneqq;": '\U00002ACB', - "subsim;": '\U00002AC7', - "subsub;": '\U00002AD5', - "subsup;": '\U00002AD3', - "succ;": '\U0000227B', - "succapprox;": '\U00002AB8', - "succcurlyeq;": '\U0000227D', - "succeq;": '\U00002AB0', - "succnapprox;": '\U00002ABA', - "succneqq;": '\U00002AB6', - "succnsim;": '\U000022E9', - "succsim;": '\U0000227F', - "sum;": '\U00002211', - "sung;": '\U0000266A', - "sup;": '\U00002283', - "sup1;": '\U000000B9', - "sup2;": '\U000000B2', - "sup3;": '\U000000B3', - "supE;": '\U00002AC6', - "supdot;": '\U00002ABE', - "supdsub;": '\U00002AD8', - "supe;": '\U00002287', - "supedot;": '\U00002AC4', - "suphsol;": '\U000027C9', - "suphsub;": '\U00002AD7', - "suplarr;": '\U0000297B', - "supmult;": '\U00002AC2', - "supnE;": '\U00002ACC', - "supne;": '\U0000228B', - "supplus;": '\U00002AC0', - "supset;": '\U00002283', - "supseteq;": '\U00002287', - "supseteqq;": '\U00002AC6', - "supsetneq;": '\U0000228B', - "supsetneqq;": '\U00002ACC', - "supsim;": '\U00002AC8', - "supsub;": '\U00002AD4', - "supsup;": '\U00002AD6', - "swArr;": '\U000021D9', - "swarhk;": '\U00002926', - "swarr;": '\U00002199', - "swarrow;": '\U00002199', - "swnwar;": '\U0000292A', - "szlig;": '\U000000DF', - "target;": '\U00002316', - "tau;": '\U000003C4', - "tbrk;": '\U000023B4', - "tcaron;": '\U00000165', - "tcedil;": '\U00000163', - "tcy;": '\U00000442', - "tdot;": '\U000020DB', - "telrec;": '\U00002315', - "tfr;": '\U0001D531', - "there4;": '\U00002234', - "therefore;": '\U00002234', - "theta;": '\U000003B8', - "thetasym;": '\U000003D1', - "thetav;": '\U000003D1', - "thickapprox;": '\U00002248', - "thicksim;": '\U0000223C', - "thinsp;": '\U00002009', - "thkap;": '\U00002248', - "thksim;": '\U0000223C', - "thorn;": '\U000000FE', - "tilde;": '\U000002DC', - "times;": '\U000000D7', - "timesb;": '\U000022A0', - "timesbar;": '\U00002A31', - "timesd;": '\U00002A30', - "tint;": '\U0000222D', - "toea;": '\U00002928', - "top;": '\U000022A4', - "topbot;": '\U00002336', - "topcir;": '\U00002AF1', - "topf;": '\U0001D565', - "topfork;": '\U00002ADA', - "tosa;": '\U00002929', - "tprime;": '\U00002034', - "trade;": '\U00002122', - "triangle;": '\U000025B5', - "triangledown;": '\U000025BF', - "triangleleft;": '\U000025C3', - "trianglelefteq;": '\U000022B4', - "triangleq;": '\U0000225C', - "triangleright;": '\U000025B9', - "trianglerighteq;": '\U000022B5', - "tridot;": '\U000025EC', - "trie;": '\U0000225C', - "triminus;": '\U00002A3A', - "triplus;": '\U00002A39', - "trisb;": '\U000029CD', - "tritime;": '\U00002A3B', - "trpezium;": '\U000023E2', - "tscr;": '\U0001D4C9', - "tscy;": '\U00000446', - "tshcy;": '\U0000045B', - "tstrok;": '\U00000167', - "twixt;": '\U0000226C', - "twoheadleftarrow;": '\U0000219E', - "twoheadrightarrow;": '\U000021A0', - "uArr;": '\U000021D1', - "uHar;": '\U00002963', - "uacute;": '\U000000FA', - "uarr;": '\U00002191', - "ubrcy;": '\U0000045E', - "ubreve;": '\U0000016D', - "ucirc;": '\U000000FB', - "ucy;": '\U00000443', - "udarr;": '\U000021C5', - "udblac;": '\U00000171', - "udhar;": '\U0000296E', - "ufisht;": '\U0000297E', - "ufr;": '\U0001D532', - "ugrave;": '\U000000F9', - "uharl;": '\U000021BF', - "uharr;": '\U000021BE', - "uhblk;": '\U00002580', - "ulcorn;": '\U0000231C', - "ulcorner;": '\U0000231C', - "ulcrop;": '\U0000230F', - "ultri;": '\U000025F8', - "umacr;": '\U0000016B', - "uml;": '\U000000A8', - "uogon;": '\U00000173', - "uopf;": '\U0001D566', - "uparrow;": '\U00002191', - "updownarrow;": '\U00002195', - "upharpoonleft;": '\U000021BF', - "upharpoonright;": '\U000021BE', - "uplus;": '\U0000228E', - "upsi;": '\U000003C5', - "upsih;": '\U000003D2', - "upsilon;": '\U000003C5', - "upuparrows;": '\U000021C8', - "urcorn;": '\U0000231D', - "urcorner;": '\U0000231D', - "urcrop;": '\U0000230E', - "uring;": '\U0000016F', - "urtri;": '\U000025F9', - "uscr;": '\U0001D4CA', - "utdot;": '\U000022F0', - "utilde;": '\U00000169', - "utri;": '\U000025B5', - "utrif;": '\U000025B4', - "uuarr;": '\U000021C8', - "uuml;": '\U000000FC', - "uwangle;": '\U000029A7', - "vArr;": '\U000021D5', - "vBar;": '\U00002AE8', - "vBarv;": '\U00002AE9', - "vDash;": '\U000022A8', - "vangrt;": '\U0000299C', - "varepsilon;": '\U000003F5', - "varkappa;": '\U000003F0', - "varnothing;": '\U00002205', - "varphi;": '\U000003D5', - "varpi;": '\U000003D6', - "varpropto;": '\U0000221D', - "varr;": '\U00002195', - "varrho;": '\U000003F1', - "varsigma;": '\U000003C2', - "vartheta;": '\U000003D1', - "vartriangleleft;": '\U000022B2', - "vartriangleright;": '\U000022B3', - "vcy;": '\U00000432', - "vdash;": '\U000022A2', - "vee;": '\U00002228', - "veebar;": '\U000022BB', - "veeeq;": '\U0000225A', - "vellip;": '\U000022EE', - "verbar;": '\U0000007C', - "vert;": '\U0000007C', - "vfr;": '\U0001D533', - "vltri;": '\U000022B2', - "vopf;": '\U0001D567', - "vprop;": '\U0000221D', - "vrtri;": '\U000022B3', - "vscr;": '\U0001D4CB', - "vzigzag;": '\U0000299A', - "wcirc;": '\U00000175', - "wedbar;": '\U00002A5F', - "wedge;": '\U00002227', - "wedgeq;": '\U00002259', - "weierp;": '\U00002118', - "wfr;": '\U0001D534', - "wopf;": '\U0001D568', - "wp;": '\U00002118', - "wr;": '\U00002240', - "wreath;": '\U00002240', - "wscr;": '\U0001D4CC', - "xcap;": '\U000022C2', - "xcirc;": '\U000025EF', - "xcup;": '\U000022C3', - "xdtri;": '\U000025BD', - "xfr;": '\U0001D535', - "xhArr;": '\U000027FA', - "xharr;": '\U000027F7', - "xi;": '\U000003BE', - "xlArr;": '\U000027F8', - "xlarr;": '\U000027F5', - "xmap;": '\U000027FC', - "xnis;": '\U000022FB', - "xodot;": '\U00002A00', - "xopf;": '\U0001D569', - "xoplus;": '\U00002A01', - "xotime;": '\U00002A02', - "xrArr;": '\U000027F9', - "xrarr;": '\U000027F6', - "xscr;": '\U0001D4CD', - "xsqcup;": '\U00002A06', - "xuplus;": '\U00002A04', - "xutri;": '\U000025B3', - "xvee;": '\U000022C1', - "xwedge;": '\U000022C0', - "yacute;": '\U000000FD', - "yacy;": '\U0000044F', - "ycirc;": '\U00000177', - "ycy;": '\U0000044B', - "yen;": '\U000000A5', - "yfr;": '\U0001D536', - "yicy;": '\U00000457', - "yopf;": '\U0001D56A', - "yscr;": '\U0001D4CE', - "yucy;": '\U0000044E', - "yuml;": '\U000000FF', - "zacute;": '\U0000017A', - "zcaron;": '\U0000017E', - "zcy;": '\U00000437', - "zdot;": '\U0000017C', - "zeetrf;": '\U00002128', - "zeta;": '\U000003B6', - "zfr;": '\U0001D537', - "zhcy;": '\U00000436', - "zigrarr;": '\U000021DD', - "zopf;": '\U0001D56B', - "zscr;": '\U0001D4CF', - "zwj;": '\U0000200D', - "zwnj;": '\U0000200C', - "AElig": '\U000000C6', - "AMP": '\U00000026', - "Aacute": '\U000000C1', - "Acirc": '\U000000C2', - "Agrave": '\U000000C0', - "Aring": '\U000000C5', - "Atilde": '\U000000C3', - "Auml": '\U000000C4', - "COPY": '\U000000A9', - "Ccedil": '\U000000C7', - "ETH": '\U000000D0', - "Eacute": '\U000000C9', - "Ecirc": '\U000000CA', - "Egrave": '\U000000C8', - "Euml": '\U000000CB', - "GT": '\U0000003E', - "Iacute": '\U000000CD', - "Icirc": '\U000000CE', - "Igrave": '\U000000CC', - "Iuml": '\U000000CF', - "LT": '\U0000003C', - "Ntilde": '\U000000D1', - "Oacute": '\U000000D3', - "Ocirc": '\U000000D4', - "Ograve": '\U000000D2', - "Oslash": '\U000000D8', - "Otilde": '\U000000D5', - "Ouml": '\U000000D6', - "QUOT": '\U00000022', - "REG": '\U000000AE', - "THORN": '\U000000DE', - "Uacute": '\U000000DA', - "Ucirc": '\U000000DB', - "Ugrave": '\U000000D9', - "Uuml": '\U000000DC', - "Yacute": '\U000000DD', - "aacute": '\U000000E1', - "acirc": '\U000000E2', - "acute": '\U000000B4', - "aelig": '\U000000E6', - "agrave": '\U000000E0', - "amp": '\U00000026', - "aring": '\U000000E5', - "atilde": '\U000000E3', - "auml": '\U000000E4', - "brvbar": '\U000000A6', - "ccedil": '\U000000E7', - "cedil": '\U000000B8', - "cent": '\U000000A2', - "copy": '\U000000A9', - "curren": '\U000000A4', - "deg": '\U000000B0', - "divide": '\U000000F7', - "eacute": '\U000000E9', - "ecirc": '\U000000EA', - "egrave": '\U000000E8', - "eth": '\U000000F0', - "euml": '\U000000EB', - "frac12": '\U000000BD', - "frac14": '\U000000BC', - "frac34": '\U000000BE', - "gt": '\U0000003E', - "iacute": '\U000000ED', - "icirc": '\U000000EE', - "iexcl": '\U000000A1', - "igrave": '\U000000EC', - "iquest": '\U000000BF', - "iuml": '\U000000EF', - "laquo": '\U000000AB', - "lt": '\U0000003C', - "macr": '\U000000AF', - "micro": '\U000000B5', - "middot": '\U000000B7', - "nbsp": '\U000000A0', - "not": '\U000000AC', - "ntilde": '\U000000F1', - "oacute": '\U000000F3', - "ocirc": '\U000000F4', - "ograve": '\U000000F2', - "ordf": '\U000000AA', - "ordm": '\U000000BA', - "oslash": '\U000000F8', - "otilde": '\U000000F5', - "ouml": '\U000000F6', - "para": '\U000000B6', - "plusmn": '\U000000B1', - "pound": '\U000000A3', - "quot": '\U00000022', - "raquo": '\U000000BB', - "reg": '\U000000AE', - "sect": '\U000000A7', - "shy": '\U000000AD', - "sup1": '\U000000B9', - "sup2": '\U000000B2', - "sup3": '\U000000B3', - "szlig": '\U000000DF', - "thorn": '\U000000FE', - "times": '\U000000D7', - "uacute": '\U000000FA', - "ucirc": '\U000000FB', - "ugrave": '\U000000F9', - "uml": '\U000000A8', - "uuml": '\U000000FC', - "yacute": '\U000000FD', - "yen": '\U000000A5', - "yuml": '\U000000FF', -} - -// HTML entities that are two unicode codepoints. -var entity2 = map[string][2]rune{ - // TODO(nigeltao): Handle replacements that are wider than their names. - // "nLt;": {'\u226A', '\u20D2'}, - // "nGt;": {'\u226B', '\u20D2'}, - "NotEqualTilde;": {'\u2242', '\u0338'}, - "NotGreaterFullEqual;": {'\u2267', '\u0338'}, - "NotGreaterGreater;": {'\u226B', '\u0338'}, - "NotGreaterSlantEqual;": {'\u2A7E', '\u0338'}, - "NotHumpDownHump;": {'\u224E', '\u0338'}, - "NotHumpEqual;": {'\u224F', '\u0338'}, - "NotLeftTriangleBar;": {'\u29CF', '\u0338'}, - "NotLessLess;": {'\u226A', '\u0338'}, - "NotLessSlantEqual;": {'\u2A7D', '\u0338'}, - "NotNestedGreaterGreater;": {'\u2AA2', '\u0338'}, - "NotNestedLessLess;": {'\u2AA1', '\u0338'}, - "NotPrecedesEqual;": {'\u2AAF', '\u0338'}, - "NotRightTriangleBar;": {'\u29D0', '\u0338'}, - "NotSquareSubset;": {'\u228F', '\u0338'}, - "NotSquareSuperset;": {'\u2290', '\u0338'}, - "NotSubset;": {'\u2282', '\u20D2'}, - "NotSucceedsEqual;": {'\u2AB0', '\u0338'}, - "NotSucceedsTilde;": {'\u227F', '\u0338'}, - "NotSuperset;": {'\u2283', '\u20D2'}, - "ThickSpace;": {'\u205F', '\u200A'}, - "acE;": {'\u223E', '\u0333'}, - "bne;": {'\u003D', '\u20E5'}, - "bnequiv;": {'\u2261', '\u20E5'}, - "caps;": {'\u2229', '\uFE00'}, - "cups;": {'\u222A', '\uFE00'}, - "fjlig;": {'\u0066', '\u006A'}, - "gesl;": {'\u22DB', '\uFE00'}, - "gvertneqq;": {'\u2269', '\uFE00'}, - "gvnE;": {'\u2269', '\uFE00'}, - "lates;": {'\u2AAD', '\uFE00'}, - "lesg;": {'\u22DA', '\uFE00'}, - "lvertneqq;": {'\u2268', '\uFE00'}, - "lvnE;": {'\u2268', '\uFE00'}, - "nGg;": {'\u22D9', '\u0338'}, - "nGtv;": {'\u226B', '\u0338'}, - "nLl;": {'\u22D8', '\u0338'}, - "nLtv;": {'\u226A', '\u0338'}, - "nang;": {'\u2220', '\u20D2'}, - "napE;": {'\u2A70', '\u0338'}, - "napid;": {'\u224B', '\u0338'}, - "nbump;": {'\u224E', '\u0338'}, - "nbumpe;": {'\u224F', '\u0338'}, - "ncongdot;": {'\u2A6D', '\u0338'}, - "nedot;": {'\u2250', '\u0338'}, - "nesim;": {'\u2242', '\u0338'}, - "ngE;": {'\u2267', '\u0338'}, - "ngeqq;": {'\u2267', '\u0338'}, - "ngeqslant;": {'\u2A7E', '\u0338'}, - "nges;": {'\u2A7E', '\u0338'}, - "nlE;": {'\u2266', '\u0338'}, - "nleqq;": {'\u2266', '\u0338'}, - "nleqslant;": {'\u2A7D', '\u0338'}, - "nles;": {'\u2A7D', '\u0338'}, - "notinE;": {'\u22F9', '\u0338'}, - "notindot;": {'\u22F5', '\u0338'}, - "nparsl;": {'\u2AFD', '\u20E5'}, - "npart;": {'\u2202', '\u0338'}, - "npre;": {'\u2AAF', '\u0338'}, - "npreceq;": {'\u2AAF', '\u0338'}, - "nrarrc;": {'\u2933', '\u0338'}, - "nrarrw;": {'\u219D', '\u0338'}, - "nsce;": {'\u2AB0', '\u0338'}, - "nsubE;": {'\u2AC5', '\u0338'}, - "nsubset;": {'\u2282', '\u20D2'}, - "nsubseteqq;": {'\u2AC5', '\u0338'}, - "nsucceq;": {'\u2AB0', '\u0338'}, - "nsupE;": {'\u2AC6', '\u0338'}, - "nsupset;": {'\u2283', '\u20D2'}, - "nsupseteqq;": {'\u2AC6', '\u0338'}, - "nvap;": {'\u224D', '\u20D2'}, - "nvge;": {'\u2265', '\u20D2'}, - "nvgt;": {'\u003E', '\u20D2'}, - "nvle;": {'\u2264', '\u20D2'}, - "nvlt;": {'\u003C', '\u20D2'}, - "nvltrie;": {'\u22B4', '\u20D2'}, - "nvrtrie;": {'\u22B5', '\u20D2'}, - "nvsim;": {'\u223C', '\u20D2'}, - "race;": {'\u223D', '\u0331'}, - "smtes;": {'\u2AAC', '\uFE00'}, - "sqcaps;": {'\u2293', '\uFE00'}, - "sqcups;": {'\u2294', '\uFE00'}, - "varsubsetneq;": {'\u228A', '\uFE00'}, - "varsubsetneqq;": {'\u2ACB', '\uFE00'}, - "varsupsetneq;": {'\u228B', '\uFE00'}, - "varsupsetneqq;": {'\u2ACC', '\uFE00'}, - "vnsub;": {'\u2282', '\u20D2'}, - "vnsup;": {'\u2283', '\u20D2'}, - "vsubnE;": {'\u2ACB', '\uFE00'}, - "vsubne;": {'\u228A', '\uFE00'}, - "vsupnE;": {'\u2ACC', '\uFE00'}, - "vsupne;": {'\u228B', '\uFE00'}, -} diff --git a/vendor/golang.org/x/net/html/escape.go b/vendor/golang.org/x/net/html/escape.go deleted file mode 100644 index d856139..0000000 --- a/vendor/golang.org/x/net/html/escape.go +++ /dev/null @@ -1,258 +0,0 @@ -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package html - -import ( - "bytes" - "strings" - "unicode/utf8" -) - -// These replacements permit compatibility with old numeric entities that -// assumed Windows-1252 encoding. -// https://html.spec.whatwg.org/multipage/syntax.html#consume-a-character-reference -var replacementTable = [...]rune{ - '\u20AC', // First entry is what 0x80 should be replaced with. - '\u0081', - '\u201A', - '\u0192', - '\u201E', - '\u2026', - '\u2020', - '\u2021', - '\u02C6', - '\u2030', - '\u0160', - '\u2039', - '\u0152', - '\u008D', - '\u017D', - '\u008F', - '\u0090', - '\u2018', - '\u2019', - '\u201C', - '\u201D', - '\u2022', - '\u2013', - '\u2014', - '\u02DC', - '\u2122', - '\u0161', - '\u203A', - '\u0153', - '\u009D', - '\u017E', - '\u0178', // Last entry is 0x9F. - // 0x00->'\uFFFD' is handled programmatically. - // 0x0D->'\u000D' is a no-op. -} - -// unescapeEntity reads an entity like "<" from b[src:] and writes the -// corresponding "<" to b[dst:], returning the incremented dst and src cursors. -// Precondition: b[src] == '&' && dst <= src. -// attribute should be true if parsing an attribute value. -func unescapeEntity(b []byte, dst, src int, attribute bool) (dst1, src1 int) { - // https://html.spec.whatwg.org/multipage/syntax.html#consume-a-character-reference - - // i starts at 1 because we already know that s[0] == '&'. - i, s := 1, b[src:] - - if len(s) <= 1 { - b[dst] = b[src] - return dst + 1, src + 1 - } - - if s[i] == '#' { - if len(s) <= 3 { // We need to have at least "&#.". - b[dst] = b[src] - return dst + 1, src + 1 - } - i++ - c := s[i] - hex := false - if c == 'x' || c == 'X' { - hex = true - i++ - } - - x := '\x00' - for i < len(s) { - c = s[i] - i++ - if hex { - if '0' <= c && c <= '9' { - x = 16*x + rune(c) - '0' - continue - } else if 'a' <= c && c <= 'f' { - x = 16*x + rune(c) - 'a' + 10 - continue - } else if 'A' <= c && c <= 'F' { - x = 16*x + rune(c) - 'A' + 10 - continue - } - } else if '0' <= c && c <= '9' { - x = 10*x + rune(c) - '0' - continue - } - if c != ';' { - i-- - } - break - } - - if i <= 3 { // No characters matched. - b[dst] = b[src] - return dst + 1, src + 1 - } - - if 0x80 <= x && x <= 0x9F { - // Replace characters from Windows-1252 with UTF-8 equivalents. - x = replacementTable[x-0x80] - } else if x == 0 || (0xD800 <= x && x <= 0xDFFF) || x > 0x10FFFF { - // Replace invalid characters with the replacement character. - x = '\uFFFD' - } - - return dst + utf8.EncodeRune(b[dst:], x), src + i - } - - // Consume the maximum number of characters possible, with the - // consumed characters matching one of the named references. - - for i < len(s) { - c := s[i] - i++ - // Lower-cased characters are more common in entities, so we check for them first. - if 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' || '0' <= c && c <= '9' { - continue - } - if c != ';' { - i-- - } - break - } - - entityName := string(s[1:i]) - if entityName == "" { - // No-op. - } else if attribute && entityName[len(entityName)-1] != ';' && len(s) > i && s[i] == '=' { - // No-op. - } else if x := entity[entityName]; x != 0 { - return dst + utf8.EncodeRune(b[dst:], x), src + i - } else if x := entity2[entityName]; x[0] != 0 { - dst1 := dst + utf8.EncodeRune(b[dst:], x[0]) - return dst1 + utf8.EncodeRune(b[dst1:], x[1]), src + i - } else if !attribute { - maxLen := len(entityName) - 1 - if maxLen > longestEntityWithoutSemicolon { - maxLen = longestEntityWithoutSemicolon - } - for j := maxLen; j > 1; j-- { - if x := entity[entityName[:j]]; x != 0 { - return dst + utf8.EncodeRune(b[dst:], x), src + j + 1 - } - } - } - - dst1, src1 = dst+i, src+i - copy(b[dst:dst1], b[src:src1]) - return dst1, src1 -} - -// unescape unescapes b's entities in-place, so that "a<b" becomes "a': - esc = ">" - case '"': - // """ is shorter than """. - esc = """ - case '\r': - esc = " " - default: - panic("unrecognized escape character") - } - s = s[i+1:] - if _, err := w.WriteString(esc); err != nil { - return err - } - i = strings.IndexAny(s, escapedChars) - } - _, err := w.WriteString(s) - return err -} - -// EscapeString escapes special characters like "<" to become "<". It -// escapes only five such characters: <, >, &, ' and ". -// UnescapeString(EscapeString(s)) == s always holds, but the converse isn't -// always true. -func EscapeString(s string) string { - if strings.IndexAny(s, escapedChars) == -1 { - return s - } - var buf bytes.Buffer - escape(&buf, s) - return buf.String() -} - -// UnescapeString unescapes entities like "<" to become "<". It unescapes a -// larger range of entities than EscapeString escapes. For example, "á" -// unescapes to "á", as does "á" and "&xE1;". -// UnescapeString(EscapeString(s)) == s always holds, but the converse isn't -// always true. -func UnescapeString(s string) string { - for _, c := range s { - if c == '&' { - return string(unescape([]byte(s), false)) - } - } - return s -} diff --git a/vendor/golang.org/x/net/html/foreign.go b/vendor/golang.org/x/net/html/foreign.go deleted file mode 100644 index d3b3844..0000000 --- a/vendor/golang.org/x/net/html/foreign.go +++ /dev/null @@ -1,226 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package html - -import ( - "strings" -) - -func adjustAttributeNames(aa []Attribute, nameMap map[string]string) { - for i := range aa { - if newName, ok := nameMap[aa[i].Key]; ok { - aa[i].Key = newName - } - } -} - -func adjustForeignAttributes(aa []Attribute) { - for i, a := range aa { - if a.Key == "" || a.Key[0] != 'x' { - continue - } - switch a.Key { - case "xlink:actuate", "xlink:arcrole", "xlink:href", "xlink:role", "xlink:show", - "xlink:title", "xlink:type", "xml:base", "xml:lang", "xml:space", "xmlns:xlink": - j := strings.Index(a.Key, ":") - aa[i].Namespace = a.Key[:j] - aa[i].Key = a.Key[j+1:] - } - } -} - -func htmlIntegrationPoint(n *Node) bool { - if n.Type != ElementNode { - return false - } - switch n.Namespace { - case "math": - if n.Data == "annotation-xml" { - for _, a := range n.Attr { - if a.Key == "encoding" { - val := strings.ToLower(a.Val) - if val == "text/html" || val == "application/xhtml+xml" { - return true - } - } - } - } - case "svg": - switch n.Data { - case "desc", "foreignObject", "title": - return true - } - } - return false -} - -func mathMLTextIntegrationPoint(n *Node) bool { - if n.Namespace != "math" { - return false - } - switch n.Data { - case "mi", "mo", "mn", "ms", "mtext": - return true - } - return false -} - -// Section 12.2.5.5. -var breakout = map[string]bool{ - "b": true, - "big": true, - "blockquote": true, - "body": true, - "br": true, - "center": true, - "code": true, - "dd": true, - "div": true, - "dl": true, - "dt": true, - "em": true, - "embed": true, - "h1": true, - "h2": true, - "h3": true, - "h4": true, - "h5": true, - "h6": true, - "head": true, - "hr": true, - "i": true, - "img": true, - "li": true, - "listing": true, - "menu": true, - "meta": true, - "nobr": true, - "ol": true, - "p": true, - "pre": true, - "ruby": true, - "s": true, - "small": true, - "span": true, - "strong": true, - "strike": true, - "sub": true, - "sup": true, - "table": true, - "tt": true, - "u": true, - "ul": true, - "var": true, -} - -// Section 12.2.5.5. -var svgTagNameAdjustments = map[string]string{ - "altglyph": "altGlyph", - "altglyphdef": "altGlyphDef", - "altglyphitem": "altGlyphItem", - "animatecolor": "animateColor", - "animatemotion": "animateMotion", - "animatetransform": "animateTransform", - "clippath": "clipPath", - "feblend": "feBlend", - "fecolormatrix": "feColorMatrix", - "fecomponenttransfer": "feComponentTransfer", - "fecomposite": "feComposite", - "feconvolvematrix": "feConvolveMatrix", - "fediffuselighting": "feDiffuseLighting", - "fedisplacementmap": "feDisplacementMap", - "fedistantlight": "feDistantLight", - "feflood": "feFlood", - "fefunca": "feFuncA", - "fefuncb": "feFuncB", - "fefuncg": "feFuncG", - "fefuncr": "feFuncR", - "fegaussianblur": "feGaussianBlur", - "feimage": "feImage", - "femerge": "feMerge", - "femergenode": "feMergeNode", - "femorphology": "feMorphology", - "feoffset": "feOffset", - "fepointlight": "fePointLight", - "fespecularlighting": "feSpecularLighting", - "fespotlight": "feSpotLight", - "fetile": "feTile", - "feturbulence": "feTurbulence", - "foreignobject": "foreignObject", - "glyphref": "glyphRef", - "lineargradient": "linearGradient", - "radialgradient": "radialGradient", - "textpath": "textPath", -} - -// Section 12.2.5.1 -var mathMLAttributeAdjustments = map[string]string{ - "definitionurl": "definitionURL", -} - -var svgAttributeAdjustments = map[string]string{ - "attributename": "attributeName", - "attributetype": "attributeType", - "basefrequency": "baseFrequency", - "baseprofile": "baseProfile", - "calcmode": "calcMode", - "clippathunits": "clipPathUnits", - "contentscripttype": "contentScriptType", - "contentstyletype": "contentStyleType", - "diffuseconstant": "diffuseConstant", - "edgemode": "edgeMode", - "externalresourcesrequired": "externalResourcesRequired", - "filterres": "filterRes", - "filterunits": "filterUnits", - "glyphref": "glyphRef", - "gradienttransform": "gradientTransform", - "gradientunits": "gradientUnits", - "kernelmatrix": "kernelMatrix", - "kernelunitlength": "kernelUnitLength", - "keypoints": "keyPoints", - "keysplines": "keySplines", - "keytimes": "keyTimes", - "lengthadjust": "lengthAdjust", - "limitingconeangle": "limitingConeAngle", - "markerheight": "markerHeight", - "markerunits": "markerUnits", - "markerwidth": "markerWidth", - "maskcontentunits": "maskContentUnits", - "maskunits": "maskUnits", - "numoctaves": "numOctaves", - "pathlength": "pathLength", - "patterncontentunits": "patternContentUnits", - "patterntransform": "patternTransform", - "patternunits": "patternUnits", - "pointsatx": "pointsAtX", - "pointsaty": "pointsAtY", - "pointsatz": "pointsAtZ", - "preservealpha": "preserveAlpha", - "preserveaspectratio": "preserveAspectRatio", - "primitiveunits": "primitiveUnits", - "refx": "refX", - "refy": "refY", - "repeatcount": "repeatCount", - "repeatdur": "repeatDur", - "requiredextensions": "requiredExtensions", - "requiredfeatures": "requiredFeatures", - "specularconstant": "specularConstant", - "specularexponent": "specularExponent", - "spreadmethod": "spreadMethod", - "startoffset": "startOffset", - "stddeviation": "stdDeviation", - "stitchtiles": "stitchTiles", - "surfacescale": "surfaceScale", - "systemlanguage": "systemLanguage", - "tablevalues": "tableValues", - "targetx": "targetX", - "targety": "targetY", - "textlength": "textLength", - "viewbox": "viewBox", - "viewtarget": "viewTarget", - "xchannelselector": "xChannelSelector", - "ychannelselector": "yChannelSelector", - "zoomandpan": "zoomAndPan", -} diff --git a/vendor/golang.org/x/net/html/node.go b/vendor/golang.org/x/net/html/node.go deleted file mode 100644 index 26b657a..0000000 --- a/vendor/golang.org/x/net/html/node.go +++ /dev/null @@ -1,193 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package html - -import ( - "golang.org/x/net/html/atom" -) - -// A NodeType is the type of a Node. -type NodeType uint32 - -const ( - ErrorNode NodeType = iota - TextNode - DocumentNode - ElementNode - CommentNode - DoctypeNode - scopeMarkerNode -) - -// Section 12.2.3.3 says "scope markers are inserted when entering applet -// elements, buttons, object elements, marquees, table cells, and table -// captions, and are used to prevent formatting from 'leaking'". -var scopeMarker = Node{Type: scopeMarkerNode} - -// A Node consists of a NodeType and some Data (tag name for element nodes, -// content for text) and are part of a tree of Nodes. Element nodes may also -// have a Namespace and contain a slice of Attributes. Data is unescaped, so -// that it looks like "a 0 { - return (*s)[i-1] - } - return nil -} - -// index returns the index of the top-most occurrence of n in the stack, or -1 -// if n is not present. -func (s *nodeStack) index(n *Node) int { - for i := len(*s) - 1; i >= 0; i-- { - if (*s)[i] == n { - return i - } - } - return -1 -} - -// insert inserts a node at the given index. -func (s *nodeStack) insert(i int, n *Node) { - (*s) = append(*s, nil) - copy((*s)[i+1:], (*s)[i:]) - (*s)[i] = n -} - -// remove removes a node from the stack. It is a no-op if n is not present. -func (s *nodeStack) remove(n *Node) { - i := s.index(n) - if i == -1 { - return - } - copy((*s)[i:], (*s)[i+1:]) - j := len(*s) - 1 - (*s)[j] = nil - *s = (*s)[:j] -} diff --git a/vendor/golang.org/x/net/html/parse.go b/vendor/golang.org/x/net/html/parse.go deleted file mode 100644 index be4b2bf..0000000 --- a/vendor/golang.org/x/net/html/parse.go +++ /dev/null @@ -1,2094 +0,0 @@ -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package html - -import ( - "errors" - "fmt" - "io" - "strings" - - a "golang.org/x/net/html/atom" -) - -// A parser implements the HTML5 parsing algorithm: -// https://html.spec.whatwg.org/multipage/syntax.html#tree-construction -type parser struct { - // tokenizer provides the tokens for the parser. - tokenizer *Tokenizer - // tok is the most recently read token. - tok Token - // Self-closing tags like
are treated as start tags, except that - // hasSelfClosingToken is set while they are being processed. - hasSelfClosingToken bool - // doc is the document root element. - doc *Node - // The stack of open elements (section 12.2.3.2) and active formatting - // elements (section 12.2.3.3). - oe, afe nodeStack - // Element pointers (section 12.2.3.4). - head, form *Node - // Other parsing state flags (section 12.2.3.5). - scripting, framesetOK bool - // im is the current insertion mode. - im insertionMode - // originalIM is the insertion mode to go back to after completing a text - // or inTableText insertion mode. - originalIM insertionMode - // fosterParenting is whether new elements should be inserted according to - // the foster parenting rules (section 12.2.5.3). - fosterParenting bool - // quirks is whether the parser is operating in "quirks mode." - quirks bool - // fragment is whether the parser is parsing an HTML fragment. - fragment bool - // context is the context element when parsing an HTML fragment - // (section 12.4). - context *Node -} - -func (p *parser) top() *Node { - if n := p.oe.top(); n != nil { - return n - } - return p.doc -} - -// Stop tags for use in popUntil. These come from section 12.2.3.2. -var ( - defaultScopeStopTags = map[string][]a.Atom{ - "": {a.Applet, a.Caption, a.Html, a.Table, a.Td, a.Th, a.Marquee, a.Object, a.Template}, - "math": {a.AnnotationXml, a.Mi, a.Mn, a.Mo, a.Ms, a.Mtext}, - "svg": {a.Desc, a.ForeignObject, a.Title}, - } -) - -type scope int - -const ( - defaultScope scope = iota - listItemScope - buttonScope - tableScope - tableRowScope - tableBodyScope - selectScope -) - -// popUntil pops the stack of open elements at the highest element whose tag -// is in matchTags, provided there is no higher element in the scope's stop -// tags (as defined in section 12.2.3.2). It returns whether or not there was -// such an element. If there was not, popUntil leaves the stack unchanged. -// -// For example, the set of stop tags for table scope is: "html", "table". If -// the stack was: -// ["html", "body", "font", "table", "b", "i", "u"] -// then popUntil(tableScope, "font") would return false, but -// popUntil(tableScope, "i") would return true and the stack would become: -// ["html", "body", "font", "table", "b"] -// -// If an element's tag is in both the stop tags and matchTags, then the stack -// will be popped and the function returns true (provided, of course, there was -// no higher element in the stack that was also in the stop tags). For example, -// popUntil(tableScope, "table") returns true and leaves: -// ["html", "body", "font"] -func (p *parser) popUntil(s scope, matchTags ...a.Atom) bool { - if i := p.indexOfElementInScope(s, matchTags...); i != -1 { - p.oe = p.oe[:i] - return true - } - return false -} - -// indexOfElementInScope returns the index in p.oe of the highest element whose -// tag is in matchTags that is in scope. If no matching element is in scope, it -// returns -1. -func (p *parser) indexOfElementInScope(s scope, matchTags ...a.Atom) int { - for i := len(p.oe) - 1; i >= 0; i-- { - tagAtom := p.oe[i].DataAtom - if p.oe[i].Namespace == "" { - for _, t := range matchTags { - if t == tagAtom { - return i - } - } - switch s { - case defaultScope: - // No-op. - case listItemScope: - if tagAtom == a.Ol || tagAtom == a.Ul { - return -1 - } - case buttonScope: - if tagAtom == a.Button { - return -1 - } - case tableScope: - if tagAtom == a.Html || tagAtom == a.Table { - return -1 - } - case selectScope: - if tagAtom != a.Optgroup && tagAtom != a.Option { - return -1 - } - default: - panic("unreachable") - } - } - switch s { - case defaultScope, listItemScope, buttonScope: - for _, t := range defaultScopeStopTags[p.oe[i].Namespace] { - if t == tagAtom { - return -1 - } - } - } - } - return -1 -} - -// elementInScope is like popUntil, except that it doesn't modify the stack of -// open elements. -func (p *parser) elementInScope(s scope, matchTags ...a.Atom) bool { - return p.indexOfElementInScope(s, matchTags...) != -1 -} - -// clearStackToContext pops elements off the stack of open elements until a -// scope-defined element is found. -func (p *parser) clearStackToContext(s scope) { - for i := len(p.oe) - 1; i >= 0; i-- { - tagAtom := p.oe[i].DataAtom - switch s { - case tableScope: - if tagAtom == a.Html || tagAtom == a.Table { - p.oe = p.oe[:i+1] - return - } - case tableRowScope: - if tagAtom == a.Html || tagAtom == a.Tr { - p.oe = p.oe[:i+1] - return - } - case tableBodyScope: - if tagAtom == a.Html || tagAtom == a.Tbody || tagAtom == a.Tfoot || tagAtom == a.Thead { - p.oe = p.oe[:i+1] - return - } - default: - panic("unreachable") - } - } -} - -// generateImpliedEndTags pops nodes off the stack of open elements as long as -// the top node has a tag name of dd, dt, li, option, optgroup, p, rp, or rt. -// If exceptions are specified, nodes with that name will not be popped off. -func (p *parser) generateImpliedEndTags(exceptions ...string) { - var i int -loop: - for i = len(p.oe) - 1; i >= 0; i-- { - n := p.oe[i] - if n.Type == ElementNode { - switch n.DataAtom { - case a.Dd, a.Dt, a.Li, a.Option, a.Optgroup, a.P, a.Rp, a.Rt: - for _, except := range exceptions { - if n.Data == except { - break loop - } - } - continue - } - } - break - } - - p.oe = p.oe[:i+1] -} - -// addChild adds a child node n to the top element, and pushes n onto the stack -// of open elements if it is an element node. -func (p *parser) addChild(n *Node) { - if p.shouldFosterParent() { - p.fosterParent(n) - } else { - p.top().AppendChild(n) - } - - if n.Type == ElementNode { - p.oe = append(p.oe, n) - } -} - -// shouldFosterParent returns whether the next node to be added should be -// foster parented. -func (p *parser) shouldFosterParent() bool { - if p.fosterParenting { - switch p.top().DataAtom { - case a.Table, a.Tbody, a.Tfoot, a.Thead, a.Tr: - return true - } - } - return false -} - -// fosterParent adds a child node according to the foster parenting rules. -// Section 12.2.5.3, "foster parenting". -func (p *parser) fosterParent(n *Node) { - var table, parent, prev *Node - var i int - for i = len(p.oe) - 1; i >= 0; i-- { - if p.oe[i].DataAtom == a.Table { - table = p.oe[i] - break - } - } - - if table == nil { - // The foster parent is the html element. - parent = p.oe[0] - } else { - parent = table.Parent - } - if parent == nil { - parent = p.oe[i-1] - } - - if table != nil { - prev = table.PrevSibling - } else { - prev = parent.LastChild - } - if prev != nil && prev.Type == TextNode && n.Type == TextNode { - prev.Data += n.Data - return - } - - parent.InsertBefore(n, table) -} - -// addText adds text to the preceding node if it is a text node, or else it -// calls addChild with a new text node. -func (p *parser) addText(text string) { - if text == "" { - return - } - - if p.shouldFosterParent() { - p.fosterParent(&Node{ - Type: TextNode, - Data: text, - }) - return - } - - t := p.top() - if n := t.LastChild; n != nil && n.Type == TextNode { - n.Data += text - return - } - p.addChild(&Node{ - Type: TextNode, - Data: text, - }) -} - -// addElement adds a child element based on the current token. -func (p *parser) addElement() { - p.addChild(&Node{ - Type: ElementNode, - DataAtom: p.tok.DataAtom, - Data: p.tok.Data, - Attr: p.tok.Attr, - }) -} - -// Section 12.2.3.3. -func (p *parser) addFormattingElement() { - tagAtom, attr := p.tok.DataAtom, p.tok.Attr - p.addElement() - - // Implement the Noah's Ark clause, but with three per family instead of two. - identicalElements := 0 -findIdenticalElements: - for i := len(p.afe) - 1; i >= 0; i-- { - n := p.afe[i] - if n.Type == scopeMarkerNode { - break - } - if n.Type != ElementNode { - continue - } - if n.Namespace != "" { - continue - } - if n.DataAtom != tagAtom { - continue - } - if len(n.Attr) != len(attr) { - continue - } - compareAttributes: - for _, t0 := range n.Attr { - for _, t1 := range attr { - if t0.Key == t1.Key && t0.Namespace == t1.Namespace && t0.Val == t1.Val { - // Found a match for this attribute, continue with the next attribute. - continue compareAttributes - } - } - // If we get here, there is no attribute that matches a. - // Therefore the element is not identical to the new one. - continue findIdenticalElements - } - - identicalElements++ - if identicalElements >= 3 { - p.afe.remove(n) - } - } - - p.afe = append(p.afe, p.top()) -} - -// Section 12.2.3.3. -func (p *parser) clearActiveFormattingElements() { - for { - n := p.afe.pop() - if len(p.afe) == 0 || n.Type == scopeMarkerNode { - return - } - } -} - -// Section 12.2.3.3. -func (p *parser) reconstructActiveFormattingElements() { - n := p.afe.top() - if n == nil { - return - } - if n.Type == scopeMarkerNode || p.oe.index(n) != -1 { - return - } - i := len(p.afe) - 1 - for n.Type != scopeMarkerNode && p.oe.index(n) == -1 { - if i == 0 { - i = -1 - break - } - i-- - n = p.afe[i] - } - for { - i++ - clone := p.afe[i].clone() - p.addChild(clone) - p.afe[i] = clone - if i == len(p.afe)-1 { - break - } - } -} - -// Section 12.2.4. -func (p *parser) acknowledgeSelfClosingTag() { - p.hasSelfClosingToken = false -} - -// An insertion mode (section 12.2.3.1) is the state transition function from -// a particular state in the HTML5 parser's state machine. It updates the -// parser's fields depending on parser.tok (where ErrorToken means EOF). -// It returns whether the token was consumed. -type insertionMode func(*parser) bool - -// setOriginalIM sets the insertion mode to return to after completing a text or -// inTableText insertion mode. -// Section 12.2.3.1, "using the rules for". -func (p *parser) setOriginalIM() { - if p.originalIM != nil { - panic("html: bad parser state: originalIM was set twice") - } - p.originalIM = p.im -} - -// Section 12.2.3.1, "reset the insertion mode". -func (p *parser) resetInsertionMode() { - for i := len(p.oe) - 1; i >= 0; i-- { - n := p.oe[i] - if i == 0 && p.context != nil { - n = p.context - } - - switch n.DataAtom { - case a.Select: - p.im = inSelectIM - case a.Td, a.Th: - p.im = inCellIM - case a.Tr: - p.im = inRowIM - case a.Tbody, a.Thead, a.Tfoot: - p.im = inTableBodyIM - case a.Caption: - p.im = inCaptionIM - case a.Colgroup: - p.im = inColumnGroupIM - case a.Table: - p.im = inTableIM - case a.Head: - p.im = inBodyIM - case a.Body: - p.im = inBodyIM - case a.Frameset: - p.im = inFramesetIM - case a.Html: - p.im = beforeHeadIM - default: - continue - } - return - } - p.im = inBodyIM -} - -const whitespace = " \t\r\n\f" - -// Section 12.2.5.4.1. -func initialIM(p *parser) bool { - switch p.tok.Type { - case TextToken: - p.tok.Data = strings.TrimLeft(p.tok.Data, whitespace) - if len(p.tok.Data) == 0 { - // It was all whitespace, so ignore it. - return true - } - case CommentToken: - p.doc.AppendChild(&Node{ - Type: CommentNode, - Data: p.tok.Data, - }) - return true - case DoctypeToken: - n, quirks := parseDoctype(p.tok.Data) - p.doc.AppendChild(n) - p.quirks = quirks - p.im = beforeHTMLIM - return true - } - p.quirks = true - p.im = beforeHTMLIM - return false -} - -// Section 12.2.5.4.2. -func beforeHTMLIM(p *parser) bool { - switch p.tok.Type { - case DoctypeToken: - // Ignore the token. - return true - case TextToken: - p.tok.Data = strings.TrimLeft(p.tok.Data, whitespace) - if len(p.tok.Data) == 0 { - // It was all whitespace, so ignore it. - return true - } - case StartTagToken: - if p.tok.DataAtom == a.Html { - p.addElement() - p.im = beforeHeadIM - return true - } - case EndTagToken: - switch p.tok.DataAtom { - case a.Head, a.Body, a.Html, a.Br: - p.parseImpliedToken(StartTagToken, a.Html, a.Html.String()) - return false - default: - // Ignore the token. - return true - } - case CommentToken: - p.doc.AppendChild(&Node{ - Type: CommentNode, - Data: p.tok.Data, - }) - return true - } - p.parseImpliedToken(StartTagToken, a.Html, a.Html.String()) - return false -} - -// Section 12.2.5.4.3. -func beforeHeadIM(p *parser) bool { - switch p.tok.Type { - case TextToken: - p.tok.Data = strings.TrimLeft(p.tok.Data, whitespace) - if len(p.tok.Data) == 0 { - // It was all whitespace, so ignore it. - return true - } - case StartTagToken: - switch p.tok.DataAtom { - case a.Head: - p.addElement() - p.head = p.top() - p.im = inHeadIM - return true - case a.Html: - return inBodyIM(p) - } - case EndTagToken: - switch p.tok.DataAtom { - case a.Head, a.Body, a.Html, a.Br: - p.parseImpliedToken(StartTagToken, a.Head, a.Head.String()) - return false - default: - // Ignore the token. - return true - } - case CommentToken: - p.addChild(&Node{ - Type: CommentNode, - Data: p.tok.Data, - }) - return true - case DoctypeToken: - // Ignore the token. - return true - } - - p.parseImpliedToken(StartTagToken, a.Head, a.Head.String()) - return false -} - -// Section 12.2.5.4.4. -func inHeadIM(p *parser) bool { - switch p.tok.Type { - case TextToken: - s := strings.TrimLeft(p.tok.Data, whitespace) - if len(s) < len(p.tok.Data) { - // Add the initial whitespace to the current node. - p.addText(p.tok.Data[:len(p.tok.Data)-len(s)]) - if s == "" { - return true - } - p.tok.Data = s - } - case StartTagToken: - switch p.tok.DataAtom { - case a.Html: - return inBodyIM(p) - case a.Base, a.Basefont, a.Bgsound, a.Command, a.Link, a.Meta: - p.addElement() - p.oe.pop() - p.acknowledgeSelfClosingTag() - return true - case a.Script, a.Title, a.Noscript, a.Noframes, a.Style: - p.addElement() - p.setOriginalIM() - p.im = textIM - return true - case a.Head: - // Ignore the token. - return true - } - case EndTagToken: - switch p.tok.DataAtom { - case a.Head: - n := p.oe.pop() - if n.DataAtom != a.Head { - panic("html: bad parser state: element not found, in the in-head insertion mode") - } - p.im = afterHeadIM - return true - case a.Body, a.Html, a.Br: - p.parseImpliedToken(EndTagToken, a.Head, a.Head.String()) - return false - default: - // Ignore the token. - return true - } - case CommentToken: - p.addChild(&Node{ - Type: CommentNode, - Data: p.tok.Data, - }) - return true - case DoctypeToken: - // Ignore the token. - return true - } - - p.parseImpliedToken(EndTagToken, a.Head, a.Head.String()) - return false -} - -// Section 12.2.5.4.6. -func afterHeadIM(p *parser) bool { - switch p.tok.Type { - case TextToken: - s := strings.TrimLeft(p.tok.Data, whitespace) - if len(s) < len(p.tok.Data) { - // Add the initial whitespace to the current node. - p.addText(p.tok.Data[:len(p.tok.Data)-len(s)]) - if s == "" { - return true - } - p.tok.Data = s - } - case StartTagToken: - switch p.tok.DataAtom { - case a.Html: - return inBodyIM(p) - case a.Body: - p.addElement() - p.framesetOK = false - p.im = inBodyIM - return true - case a.Frameset: - p.addElement() - p.im = inFramesetIM - return true - case a.Base, a.Basefont, a.Bgsound, a.Link, a.Meta, a.Noframes, a.Script, a.Style, a.Title: - p.oe = append(p.oe, p.head) - defer p.oe.remove(p.head) - return inHeadIM(p) - case a.Head: - // Ignore the token. - return true - } - case EndTagToken: - switch p.tok.DataAtom { - case a.Body, a.Html, a.Br: - // Drop down to creating an implied tag. - default: - // Ignore the token. - return true - } - case CommentToken: - p.addChild(&Node{ - Type: CommentNode, - Data: p.tok.Data, - }) - return true - case DoctypeToken: - // Ignore the token. - return true - } - - p.parseImpliedToken(StartTagToken, a.Body, a.Body.String()) - p.framesetOK = true - return false -} - -// copyAttributes copies attributes of src not found on dst to dst. -func copyAttributes(dst *Node, src Token) { - if len(src.Attr) == 0 { - return - } - attr := map[string]string{} - for _, t := range dst.Attr { - attr[t.Key] = t.Val - } - for _, t := range src.Attr { - if _, ok := attr[t.Key]; !ok { - dst.Attr = append(dst.Attr, t) - attr[t.Key] = t.Val - } - } -} - -// Section 12.2.5.4.7. -func inBodyIM(p *parser) bool { - switch p.tok.Type { - case TextToken: - d := p.tok.Data - switch n := p.oe.top(); n.DataAtom { - case a.Pre, a.Listing: - if n.FirstChild == nil { - // Ignore a newline at the start of a
 block.
-				if d != "" && d[0] == '\r' {
-					d = d[1:]
-				}
-				if d != "" && d[0] == '\n' {
-					d = d[1:]
-				}
-			}
-		}
-		d = strings.Replace(d, "\x00", "", -1)
-		if d == "" {
-			return true
-		}
-		p.reconstructActiveFormattingElements()
-		p.addText(d)
-		if p.framesetOK && strings.TrimLeft(d, whitespace) != "" {
-			// There were non-whitespace characters inserted.
-			p.framesetOK = false
-		}
-	case StartTagToken:
-		switch p.tok.DataAtom {
-		case a.Html:
-			copyAttributes(p.oe[0], p.tok)
-		case a.Base, a.Basefont, a.Bgsound, a.Command, a.Link, a.Meta, a.Noframes, a.Script, a.Style, a.Title:
-			return inHeadIM(p)
-		case a.Body:
-			if len(p.oe) >= 2 {
-				body := p.oe[1]
-				if body.Type == ElementNode && body.DataAtom == a.Body {
-					p.framesetOK = false
-					copyAttributes(body, p.tok)
-				}
-			}
-		case a.Frameset:
-			if !p.framesetOK || len(p.oe) < 2 || p.oe[1].DataAtom != a.Body {
-				// Ignore the token.
-				return true
-			}
-			body := p.oe[1]
-			if body.Parent != nil {
-				body.Parent.RemoveChild(body)
-			}
-			p.oe = p.oe[:1]
-			p.addElement()
-			p.im = inFramesetIM
-			return true
-		case a.Address, a.Article, a.Aside, a.Blockquote, a.Center, a.Details, a.Dir, a.Div, a.Dl, a.Fieldset, a.Figcaption, a.Figure, a.Footer, a.Header, a.Hgroup, a.Menu, a.Nav, a.Ol, a.P, a.Section, a.Summary, a.Ul:
-			p.popUntil(buttonScope, a.P)
-			p.addElement()
-		case a.H1, a.H2, a.H3, a.H4, a.H5, a.H6:
-			p.popUntil(buttonScope, a.P)
-			switch n := p.top(); n.DataAtom {
-			case a.H1, a.H2, a.H3, a.H4, a.H5, a.H6:
-				p.oe.pop()
-			}
-			p.addElement()
-		case a.Pre, a.Listing:
-			p.popUntil(buttonScope, a.P)
-			p.addElement()
-			// The newline, if any, will be dealt with by the TextToken case.
-			p.framesetOK = false
-		case a.Form:
-			if p.form == nil {
-				p.popUntil(buttonScope, a.P)
-				p.addElement()
-				p.form = p.top()
-			}
-		case a.Li:
-			p.framesetOK = false
-			for i := len(p.oe) - 1; i >= 0; i-- {
-				node := p.oe[i]
-				switch node.DataAtom {
-				case a.Li:
-					p.oe = p.oe[:i]
-				case a.Address, a.Div, a.P:
-					continue
-				default:
-					if !isSpecialElement(node) {
-						continue
-					}
-				}
-				break
-			}
-			p.popUntil(buttonScope, a.P)
-			p.addElement()
-		case a.Dd, a.Dt:
-			p.framesetOK = false
-			for i := len(p.oe) - 1; i >= 0; i-- {
-				node := p.oe[i]
-				switch node.DataAtom {
-				case a.Dd, a.Dt:
-					p.oe = p.oe[:i]
-				case a.Address, a.Div, a.P:
-					continue
-				default:
-					if !isSpecialElement(node) {
-						continue
-					}
-				}
-				break
-			}
-			p.popUntil(buttonScope, a.P)
-			p.addElement()
-		case a.Plaintext:
-			p.popUntil(buttonScope, a.P)
-			p.addElement()
-		case a.Button:
-			p.popUntil(defaultScope, a.Button)
-			p.reconstructActiveFormattingElements()
-			p.addElement()
-			p.framesetOK = false
-		case a.A:
-			for i := len(p.afe) - 1; i >= 0 && p.afe[i].Type != scopeMarkerNode; i-- {
-				if n := p.afe[i]; n.Type == ElementNode && n.DataAtom == a.A {
-					p.inBodyEndTagFormatting(a.A)
-					p.oe.remove(n)
-					p.afe.remove(n)
-					break
-				}
-			}
-			p.reconstructActiveFormattingElements()
-			p.addFormattingElement()
-		case a.B, a.Big, a.Code, a.Em, a.Font, a.I, a.S, a.Small, a.Strike, a.Strong, a.Tt, a.U:
-			p.reconstructActiveFormattingElements()
-			p.addFormattingElement()
-		case a.Nobr:
-			p.reconstructActiveFormattingElements()
-			if p.elementInScope(defaultScope, a.Nobr) {
-				p.inBodyEndTagFormatting(a.Nobr)
-				p.reconstructActiveFormattingElements()
-			}
-			p.addFormattingElement()
-		case a.Applet, a.Marquee, a.Object:
-			p.reconstructActiveFormattingElements()
-			p.addElement()
-			p.afe = append(p.afe, &scopeMarker)
-			p.framesetOK = false
-		case a.Table:
-			if !p.quirks {
-				p.popUntil(buttonScope, a.P)
-			}
-			p.addElement()
-			p.framesetOK = false
-			p.im = inTableIM
-			return true
-		case a.Area, a.Br, a.Embed, a.Img, a.Input, a.Keygen, a.Wbr:
-			p.reconstructActiveFormattingElements()
-			p.addElement()
-			p.oe.pop()
-			p.acknowledgeSelfClosingTag()
-			if p.tok.DataAtom == a.Input {
-				for _, t := range p.tok.Attr {
-					if t.Key == "type" {
-						if strings.ToLower(t.Val) == "hidden" {
-							// Skip setting framesetOK = false
-							return true
-						}
-					}
-				}
-			}
-			p.framesetOK = false
-		case a.Param, a.Source, a.Track:
-			p.addElement()
-			p.oe.pop()
-			p.acknowledgeSelfClosingTag()
-		case a.Hr:
-			p.popUntil(buttonScope, a.P)
-			p.addElement()
-			p.oe.pop()
-			p.acknowledgeSelfClosingTag()
-			p.framesetOK = false
-		case a.Image:
-			p.tok.DataAtom = a.Img
-			p.tok.Data = a.Img.String()
-			return false
-		case a.Isindex:
-			if p.form != nil {
-				// Ignore the token.
-				return true
-			}
-			action := ""
-			prompt := "This is a searchable index. Enter search keywords: "
-			attr := []Attribute{{Key: "name", Val: "isindex"}}
-			for _, t := range p.tok.Attr {
-				switch t.Key {
-				case "action":
-					action = t.Val
-				case "name":
-					// Ignore the attribute.
-				case "prompt":
-					prompt = t.Val
-				default:
-					attr = append(attr, t)
-				}
-			}
-			p.acknowledgeSelfClosingTag()
-			p.popUntil(buttonScope, a.P)
-			p.parseImpliedToken(StartTagToken, a.Form, a.Form.String())
-			if action != "" {
-				p.form.Attr = []Attribute{{Key: "action", Val: action}}
-			}
-			p.parseImpliedToken(StartTagToken, a.Hr, a.Hr.String())
-			p.parseImpliedToken(StartTagToken, a.Label, a.Label.String())
-			p.addText(prompt)
-			p.addChild(&Node{
-				Type:     ElementNode,
-				DataAtom: a.Input,
-				Data:     a.Input.String(),
-				Attr:     attr,
-			})
-			p.oe.pop()
-			p.parseImpliedToken(EndTagToken, a.Label, a.Label.String())
-			p.parseImpliedToken(StartTagToken, a.Hr, a.Hr.String())
-			p.parseImpliedToken(EndTagToken, a.Form, a.Form.String())
-		case a.Textarea:
-			p.addElement()
-			p.setOriginalIM()
-			p.framesetOK = false
-			p.im = textIM
-		case a.Xmp:
-			p.popUntil(buttonScope, a.P)
-			p.reconstructActiveFormattingElements()
-			p.framesetOK = false
-			p.addElement()
-			p.setOriginalIM()
-			p.im = textIM
-		case a.Iframe:
-			p.framesetOK = false
-			p.addElement()
-			p.setOriginalIM()
-			p.im = textIM
-		case a.Noembed, a.Noscript:
-			p.addElement()
-			p.setOriginalIM()
-			p.im = textIM
-		case a.Select:
-			p.reconstructActiveFormattingElements()
-			p.addElement()
-			p.framesetOK = false
-			p.im = inSelectIM
-			return true
-		case a.Optgroup, a.Option:
-			if p.top().DataAtom == a.Option {
-				p.oe.pop()
-			}
-			p.reconstructActiveFormattingElements()
-			p.addElement()
-		case a.Rp, a.Rt:
-			if p.elementInScope(defaultScope, a.Ruby) {
-				p.generateImpliedEndTags()
-			}
-			p.addElement()
-		case a.Math, a.Svg:
-			p.reconstructActiveFormattingElements()
-			if p.tok.DataAtom == a.Math {
-				adjustAttributeNames(p.tok.Attr, mathMLAttributeAdjustments)
-			} else {
-				adjustAttributeNames(p.tok.Attr, svgAttributeAdjustments)
-			}
-			adjustForeignAttributes(p.tok.Attr)
-			p.addElement()
-			p.top().Namespace = p.tok.Data
-			if p.hasSelfClosingToken {
-				p.oe.pop()
-				p.acknowledgeSelfClosingTag()
-			}
-			return true
-		case a.Caption, a.Col, a.Colgroup, a.Frame, a.Head, a.Tbody, a.Td, a.Tfoot, a.Th, a.Thead, a.Tr:
-			// Ignore the token.
-		default:
-			p.reconstructActiveFormattingElements()
-			p.addElement()
-		}
-	case EndTagToken:
-		switch p.tok.DataAtom {
-		case a.Body:
-			if p.elementInScope(defaultScope, a.Body) {
-				p.im = afterBodyIM
-			}
-		case a.Html:
-			if p.elementInScope(defaultScope, a.Body) {
-				p.parseImpliedToken(EndTagToken, a.Body, a.Body.String())
-				return false
-			}
-			return true
-		case a.Address, a.Article, a.Aside, a.Blockquote, a.Button, a.Center, a.Details, a.Dir, a.Div, a.Dl, a.Fieldset, a.Figcaption, a.Figure, a.Footer, a.Header, a.Hgroup, a.Listing, a.Menu, a.Nav, a.Ol, a.Pre, a.Section, a.Summary, a.Ul:
-			p.popUntil(defaultScope, p.tok.DataAtom)
-		case a.Form:
-			node := p.form
-			p.form = nil
-			i := p.indexOfElementInScope(defaultScope, a.Form)
-			if node == nil || i == -1 || p.oe[i] != node {
-				// Ignore the token.
-				return true
-			}
-			p.generateImpliedEndTags()
-			p.oe.remove(node)
-		case a.P:
-			if !p.elementInScope(buttonScope, a.P) {
-				p.parseImpliedToken(StartTagToken, a.P, a.P.String())
-			}
-			p.popUntil(buttonScope, a.P)
-		case a.Li:
-			p.popUntil(listItemScope, a.Li)
-		case a.Dd, a.Dt:
-			p.popUntil(defaultScope, p.tok.DataAtom)
-		case a.H1, a.H2, a.H3, a.H4, a.H5, a.H6:
-			p.popUntil(defaultScope, a.H1, a.H2, a.H3, a.H4, a.H5, a.H6)
-		case a.A, a.B, a.Big, a.Code, a.Em, a.Font, a.I, a.Nobr, a.S, a.Small, a.Strike, a.Strong, a.Tt, a.U:
-			p.inBodyEndTagFormatting(p.tok.DataAtom)
-		case a.Applet, a.Marquee, a.Object:
-			if p.popUntil(defaultScope, p.tok.DataAtom) {
-				p.clearActiveFormattingElements()
-			}
-		case a.Br:
-			p.tok.Type = StartTagToken
-			return false
-		default:
-			p.inBodyEndTagOther(p.tok.DataAtom)
-		}
-	case CommentToken:
-		p.addChild(&Node{
-			Type: CommentNode,
-			Data: p.tok.Data,
-		})
-	}
-
-	return true
-}
-
-func (p *parser) inBodyEndTagFormatting(tagAtom a.Atom) {
-	// This is the "adoption agency" algorithm, described at
-	// https://html.spec.whatwg.org/multipage/syntax.html#adoptionAgency
-
-	// TODO: this is a fairly literal line-by-line translation of that algorithm.
-	// Once the code successfully parses the comprehensive test suite, we should
-	// refactor this code to be more idiomatic.
-
-	// Steps 1-4. The outer loop.
-	for i := 0; i < 8; i++ {
-		// Step 5. Find the formatting element.
-		var formattingElement *Node
-		for j := len(p.afe) - 1; j >= 0; j-- {
-			if p.afe[j].Type == scopeMarkerNode {
-				break
-			}
-			if p.afe[j].DataAtom == tagAtom {
-				formattingElement = p.afe[j]
-				break
-			}
-		}
-		if formattingElement == nil {
-			p.inBodyEndTagOther(tagAtom)
-			return
-		}
-		feIndex := p.oe.index(formattingElement)
-		if feIndex == -1 {
-			p.afe.remove(formattingElement)
-			return
-		}
-		if !p.elementInScope(defaultScope, tagAtom) {
-			// Ignore the tag.
-			return
-		}
-
-		// Steps 9-10. Find the furthest block.
-		var furthestBlock *Node
-		for _, e := range p.oe[feIndex:] {
-			if isSpecialElement(e) {
-				furthestBlock = e
-				break
-			}
-		}
-		if furthestBlock == nil {
-			e := p.oe.pop()
-			for e != formattingElement {
-				e = p.oe.pop()
-			}
-			p.afe.remove(e)
-			return
-		}
-
-		// Steps 11-12. Find the common ancestor and bookmark node.
-		commonAncestor := p.oe[feIndex-1]
-		bookmark := p.afe.index(formattingElement)
-
-		// Step 13. The inner loop. Find the lastNode to reparent.
-		lastNode := furthestBlock
-		node := furthestBlock
-		x := p.oe.index(node)
-		// Steps 13.1-13.2
-		for j := 0; j < 3; j++ {
-			// Step 13.3.
-			x--
-			node = p.oe[x]
-			// Step 13.4 - 13.5.
-			if p.afe.index(node) == -1 {
-				p.oe.remove(node)
-				continue
-			}
-			// Step 13.6.
-			if node == formattingElement {
-				break
-			}
-			// Step 13.7.
-			clone := node.clone()
-			p.afe[p.afe.index(node)] = clone
-			p.oe[p.oe.index(node)] = clone
-			node = clone
-			// Step 13.8.
-			if lastNode == furthestBlock {
-				bookmark = p.afe.index(node) + 1
-			}
-			// Step 13.9.
-			if lastNode.Parent != nil {
-				lastNode.Parent.RemoveChild(lastNode)
-			}
-			node.AppendChild(lastNode)
-			// Step 13.10.
-			lastNode = node
-		}
-
-		// Step 14. Reparent lastNode to the common ancestor,
-		// or for misnested table nodes, to the foster parent.
-		if lastNode.Parent != nil {
-			lastNode.Parent.RemoveChild(lastNode)
-		}
-		switch commonAncestor.DataAtom {
-		case a.Table, a.Tbody, a.Tfoot, a.Thead, a.Tr:
-			p.fosterParent(lastNode)
-		default:
-			commonAncestor.AppendChild(lastNode)
-		}
-
-		// Steps 15-17. Reparent nodes from the furthest block's children
-		// to a clone of the formatting element.
-		clone := formattingElement.clone()
-		reparentChildren(clone, furthestBlock)
-		furthestBlock.AppendChild(clone)
-
-		// Step 18. Fix up the list of active formatting elements.
-		if oldLoc := p.afe.index(formattingElement); oldLoc != -1 && oldLoc < bookmark {
-			// Move the bookmark with the rest of the list.
-			bookmark--
-		}
-		p.afe.remove(formattingElement)
-		p.afe.insert(bookmark, clone)
-
-		// Step 19. Fix up the stack of open elements.
-		p.oe.remove(formattingElement)
-		p.oe.insert(p.oe.index(furthestBlock)+1, clone)
-	}
-}
-
-// inBodyEndTagOther performs the "any other end tag" algorithm for inBodyIM.
-// "Any other end tag" handling from 12.2.5.5 The rules for parsing tokens in foreign content
-// https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inforeign
-func (p *parser) inBodyEndTagOther(tagAtom a.Atom) {
-	for i := len(p.oe) - 1; i >= 0; i-- {
-		if p.oe[i].DataAtom == tagAtom {
-			p.oe = p.oe[:i]
-			break
-		}
-		if isSpecialElement(p.oe[i]) {
-			break
-		}
-	}
-}
-
-// Section 12.2.5.4.8.
-func textIM(p *parser) bool {
-	switch p.tok.Type {
-	case ErrorToken:
-		p.oe.pop()
-	case TextToken:
-		d := p.tok.Data
-		if n := p.oe.top(); n.DataAtom == a.Textarea && n.FirstChild == nil {
-			// Ignore a newline at the start of a