From 645601a17660e1a9d231d76a18bff667f8a8fe77 Mon Sep 17 00:00:00 2001 From: Thomas Boerger Date: Thu, 22 Mar 2018 02:53:41 +0100 Subject: [PATCH] Updated to current build process (#26) * Dropped vendoring directory * Updated to current build process --- .appveyor.yml | 14 +- .drone.yml | 34 +- .github/issue_template.md | 9 - .github/pull_request_template.md | 7 - .gitignore | 2 + Dockerfile.windows | 4 +- Gopkg.lock | 26 + Gopkg.toml | 11 + logo.svg | 29 - .../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/urfave/cli/CHANGELOG.md | 392 ----- vendor/github.com/urfave/cli/LICENSE | 21 - vendor/github.com/urfave/cli/README.md | 1381 ---------------- vendor/github.com/urfave/cli/app.go | 497 ------ vendor/github.com/urfave/cli/appveyor.yml | 24 - vendor/github.com/urfave/cli/category.go | 44 - vendor/github.com/urfave/cli/cli.go | 22 - vendor/github.com/urfave/cli/command.go | 304 ---- vendor/github.com/urfave/cli/context.go | 278 ---- vendor/github.com/urfave/cli/errors.go | 115 -- 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 | 338 ---- vendor/github.com/urfave/cli/runtests | 122 -- vendor/vendor.json | 37 - 48 files changed, 71 insertions(+), 12130 deletions(-) create mode 100644 Gopkg.lock create mode 100644 Gopkg.toml delete mode 100644 logo.svg 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/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 100755 vendor/github.com/urfave/cli/generate-flag-types delete mode 100644 vendor/github.com/urfave/cli/help.go delete mode 100755 vendor/github.com/urfave/cli/runtests delete mode 100644 vendor/vendor.json diff --git a/.appveyor.yml b/.appveyor.yml index 1365bc1..b07610f 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -1,11 +1,12 @@ version: '{build}' image: 'Visual Studio 2017' -platform: x64 +platform: 'x64' -clone_folder: 'c:\go\src\github.com\drone-plugins\drone-webhook' +clone_folder: 'c:\gopath\src\github.com\drone-plugins\drone-webhook' max_jobs: 1 environment: + GOPATH: c:\gopath DOCKER_USERNAME: secure: '4YzzahbEiMZQJpOCOd1LAw==' DOCKER_PASSWORD: @@ -15,14 +16,19 @@ install: - ps: | docker version go version + - ps: | + $env:Path = "c:\gopath\bin;$env:Path" build_script: - ps: | + go get -u github.com/golang/dep/cmd/dep + dep ensure + if ( $env:APPVEYOR_REPO_TAG -eq 'false' ) { - go build -ldflags "-X main.build=$env:APPVEYOR_BUILD_VERSION" -a -o drone-webhook.exe + go build -ldflags "-X main.build=$env:APPVEYOR_BUILD_VERSION" -a -o release/drone-webhook.exe } else { $version = $env:APPVEYOR_REPO_TAG_NAME.substring(1) - go build -ldflags "-X main.version=$version -X main.build=$env:APPVEYOR_BUILD_VERSION" -a -o drone-webhook.exe + go build -ldflags "-X main.version=$version -X main.build=$env:APPVEYOR_BUILD_VERSION" -a -o release/drone-webhook.exe } docker pull microsoft/nanoserver:10.0.14393.1593 diff --git a/.drone.yml b/.drone.yml index c326e9b..05e2efd 100644 --- a/.drone.yml +++ b/.drone.yml @@ -3,18 +3,22 @@ workspace: path: src/github.com/drone-plugins/drone-webhook pipeline: - test: - image: golang:1.9 + deps: + image: golang:1.10 pull: true commands: - - go vet - - | - for PKG in $(go list ./... | grep -v /vendor/); do - go test -cover -coverprofile $GOPATH/src/$PKG/coverage.out $PKG - done + - go get -u github.com/golang/dep/cmd/dep + - dep ensure + + test: + image: golang:1.10 + pull: true + commands: + - go vet ./... + - go test -cover ./... build_linux_amd64: - image: golang:1.9 + image: golang:1.10 pull: true group: build environment: @@ -30,7 +34,7 @@ pipeline: fi build_linux_i386: - image: golang:1.9 + image: golang:1.10 pull: true group: build environment: @@ -46,7 +50,7 @@ pipeline: fi build_linux_arm64: - image: golang:1.9 + image: golang:1.10 pull: true group: build environment: @@ -62,7 +66,7 @@ pipeline: fi build_linux_arm: - image: golang:1.9 + image: golang:1.10 pull: true group: build environment: @@ -79,7 +83,7 @@ pipeline: fi publish_linux_amd64: - image: plugins/docker:17.05 + image: plugins/docker:17.12 pull: true secrets: [ docker_username, docker_password ] group: docker @@ -91,7 +95,7 @@ pipeline: event: [ push, tag ] publish_linux_i386: - image: plugins/docker:17.05 + image: plugins/docker:17.12 pull: true secrets: [ docker_username, docker_password ] group: docker @@ -103,7 +107,7 @@ pipeline: event: [ push, tag ] publish_linux_arm64: - image: plugins/docker:17.05 + image: plugins/docker:17.12 pull: true secrets: [ docker_username, docker_password ] group: docker @@ -115,7 +119,7 @@ pipeline: event: [ push, tag ] publish_linux_arm: - image: plugins/docker:17.05 + image: plugins/docker:17.12 pull: true secrets: [ docker_username, docker_password ] group: docker diff --git a/.github/issue_template.md b/.github/issue_template.md index d2ebe9a..e69de29 100644 --- a/.github/issue_template.md +++ b/.github/issue_template.md @@ -1,9 +0,0 @@ - diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 5eb6578..e69de29 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,7 +0,0 @@ - diff --git a/.gitignore b/.gitignore index 80f22a9..177da81 100644 --- a/.gitignore +++ b/.gitignore @@ -24,5 +24,7 @@ _testmain.go *.prof release/ +vendor/ + coverage.out drone-webhook diff --git a/Dockerfile.windows b/Dockerfile.windows index 98cba3c..0f547a1 100644 --- a/Dockerfile.windows +++ b/Dockerfile.windows @@ -6,5 +6,7 @@ LABEL maintainer="Drone.IO Community " ` org.label-schema.vendor="Drone.IO Community" ` org.label-schema.schema-version="1.0" -ADD drone-webhook.exe c:\drone-webhook.exe +SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"] + +ADD release\drone-webhook.exe c:\drone-webhook.exe ENTRYPOINT [ "c:\\drone-webhook.exe" ] diff --git a/Gopkg.lock b/Gopkg.lock new file mode 100644 index 0000000..ed9fea5 --- /dev/null +++ b/Gopkg.lock @@ -0,0 +1,26 @@ +# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. + + +[[projects]] + name = "github.com/aymerick/raymond" + packages = [ + ".", + "ast", + "lexer", + "parser" + ] + revision = "a2232af10b53ef1ae5a767f5178db3a6c1dab655" + version = "v2.0.1" + +[[projects]] + name = "github.com/urfave/cli" + packages = ["."] + revision = "cfb38830724cc34fedffe9a2a29fb54fa9169cd1" + version = "v1.20.0" + +[solve-meta] + analyzer-name = "dep" + analyzer-version = 1 + inputs-digest = "f0f9f5cbe5ccddecfff2301c3783e001bde86bec1082c3026fda1ec005c18af5" + solver-name = "gps-cdcl" + solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml new file mode 100644 index 0000000..b11bf48 --- /dev/null +++ b/Gopkg.toml @@ -0,0 +1,11 @@ +[[constraint]] + name = "github.com/aymerick/raymond" + version = "2.0.1" + +[[constraint]] + name = "github.com/urfave/cli" + version = "1.20.0" + +[prune] + go-tests = true + unused-packages = true diff --git a/logo.svg b/logo.svg deleted file mode 100644 index 2977c92..0000000 --- a/logo.svg +++ /dev/null @@ -1,29 +0,0 @@ - -image/svg+xml \ No newline at end of file diff --git a/vendor/github.com/aymerick/raymond/BENCHMARKS.md b/vendor/github.com/aymerick/raymond/BENCHMARKS.md deleted file mode 100644 index c3af56c..0000000 --- a/vendor/github.com/aymerick/raymond/BENCHMARKS.md +++ /dev/null @@ -1,46 +0,0 @@ -# Benchmarks - -Hardware: MacBookPro11,1 - Intel Core i5 - 2,6 GHz - 8 Go RAM - -With: - - - handlebars.js #8cba84df119c317fcebc49fb285518542ca9c2d0 - - raymond #7bbaaf50ed03c96b56687d7fa6c6e04e02375a98 - - -## handlebars.js (ops/ms) - - arguments 198 ±4 (5) - array-each 568 ±23 (5) - array-mustache 522 ±18 (4) - complex 71 ±7 (3) - data 67 ±2 (3) - depth-1 47 ±2 (3) - depth-2 14 ±1 (2) - object-mustache 1099 ±47 (5) - object 907 ±58 (4) - partial-recursion 46 ±3 (4) - partial 68 ±3 (3) - paths 1650 ±50 (3) - string 2552 ±157 (3) - subexpression 141 ±2 (4) - variables 2671 ±83 (4) - - -## raymond - - BenchmarkArguments 200000 6642 ns/op 151 ops/ms - BenchmarkArrayEach 100000 19584 ns/op 51 ops/ms - BenchmarkArrayMustache 100000 17305 ns/op 58 ops/ms - BenchmarkComplex 30000 50270 ns/op 20 ops/ms - BenchmarkData 50000 25551 ns/op 39 ops/ms - BenchmarkDepth1 100000 20162 ns/op 50 ops/ms - BenchmarkDepth2 30000 47782 ns/op 21 ops/ms - BenchmarkObjectMustache 200000 7668 ns/op 130 ops/ms - BenchmarkObject 200000 8843 ns/op 113 ops/ms - BenchmarkPartialRecursion 50000 23139 ns/op 43 ops/ms - BenchmarkPartial 50000 31015 ns/op 32 ops/ms - BenchmarkPath 200000 8997 ns/op 111 ops/ms - BenchmarkString 1000000 1879 ns/op 532 ops/ms - BenchmarkSubExpression 300000 4935 ns/op 203 ops/ms - BenchmarkVariables 200000 6478 ns/op 154 ops/ms diff --git a/vendor/github.com/aymerick/raymond/CHANGELOG.md b/vendor/github.com/aymerick/raymond/CHANGELOG.md deleted file mode 100644 index c438a5c..0000000 --- a/vendor/github.com/aymerick/raymond/CHANGELOG.md +++ /dev/null @@ -1,33 +0,0 @@ -# Raymond Changelog - -### Raymond 2.0.1 _(June 01, 2016)_ - -- [BUGFIX] Removes data races [#3](https://github.com/aymerick/raymond/issues/3) - Thanks [@markbates](https://github.com/markbates) - -### Raymond 2.0.0 _(May 01, 2016)_ - -- [BUGFIX] Fixes passing of context in helper options [#2](https://github.com/aymerick/raymond/issues/2) - Thanks [@GhostRussia](https://github.com/GhostRussia) -- [BREAKING] Renames and unexports constants: - - - `handlebars.DUMP_TPL` - - `lexer.ESCAPED_ESCAPED_OPEN_MUSTACHE` - - `lexer.ESCAPED_OPEN_MUSTACHE` - - `lexer.OPEN_MUSTACHE` - - `lexer.CLOSE_MUSTACHE` - - `lexer.CLOSE_STRIP_MUSTACHE` - - `lexer.CLOSE_UNESCAPED_STRIP_MUSTACHE` - - `lexer.DUMP_TOKEN_POS` - - `lexer.DUMP_ALL_TOKENS_VAL` - - -### Raymond 1.1.0 _(June 15, 2015)_ - -- Permits templates references with lowercase versions of struct fields. -- Adds `ParseFile()` function. -- Adds `RegisterPartialFile()`, `RegisterPartialFiles()` and `Clone()` methods on `Template`. -- Helpers can now be struct methods. -- Ensures safe concurrent access to helpers and partials. - -### Raymond 1.0.0 _(June 09, 2015)_ - -- This is the first release. Raymond supports almost all handlebars features. See https://github.com/aymerick/raymond#limitations for a list of differences with the javascript implementation. diff --git a/vendor/github.com/aymerick/raymond/LICENSE b/vendor/github.com/aymerick/raymond/LICENSE deleted file mode 100644 index 6ce87cd..0000000 --- a/vendor/github.com/aymerick/raymond/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/raymond/README.md b/vendor/github.com/aymerick/raymond/README.md deleted file mode 100644 index d9a6d9a..0000000 --- a/vendor/github.com/aymerick/raymond/README.md +++ /dev/null @@ -1,1417 +0,0 @@ -# raymond [![Build Status](https://secure.travis-ci.org/aymerick/raymond.svg?branch=master)](http://travis-ci.org/aymerick/raymond) [![GoDoc](https://godoc.org/github.com/aymerick/raymond?status.svg)](http://godoc.org/github.com/aymerick/raymond) - -Handlebars for [golang](https://golang.org) with the same features as [handlebars.js](http://handlebarsjs.com) `3.0`. - -The full API documentation is available here: . - -![Raymond Logo](https://github.com/aymerick/raymond/blob/master/raymond.png?raw=true "Raymond") - - -# Table of Contents - -- [Quick Start](#quick-start) -- [Correct Usage](#correct-usage) -- [Context](#context) -- [HTML Escaping](#html-escaping) -- [Helpers](#helpers) - - [Template Helpers](#template-helpers) - - [Built-In Helpers](#built-in-helpers) - - [The `if` block helper](#the-if-block-helper) - - [The `unless` block helper](#the-unless-block-helper) - - [The `each` block helper](#the-each-block-helper) - - [The `with` block helper](#the-with-block-helper) - - [The `lookup` helper](#the-lookup-helper) - - [The `log` helper](#the-log-helper) - - [The `equal` helper](#the-equal-helper) - - [Block Helpers](#block-helpers) - - [Block Evaluation](#block-evaluation) - - [Conditional](#conditional) - - [Else Block Evaluation](#else-block-evaluation) - - [Block Parameters](#block-parameters) - - [Helper Parameters](#helper-parameters) - - [Automatic conversion](#automatic-conversion) - - [Options Argument](#options-argument) - - [Context Values](#context-values) - - [Helper Hash Arguments](#helper-hash-arguments) - - [Private Data](#private-data) - - [Utilites](#utilites) - - [`Str()`](#str) - - [`IsTrue()`](#istrue) -- [Context Functions](#context-functions) -- [Partials](#partials) - - [Template Partials](#template-partials) - - [Global Partials](#global-partials) - - [Dynamic Partials](#dynamic-partials) - - [Partial Contexts](#partial-contexts) - - [Partial Parameters](#partial-parameters) -- [Utility Functions](#utility-functions) -- [Mustache](#mustache) -- [Limitations](#limitations) -- [Handlebars Lexer](#handlebars-lexer) -- [Handlebars Parser](#handlebars-parser) -- [Test](#test) -- [References](#references) -- [Others Implementations](#others-implementations) - - -## Quick Start - - $ go get github.com/aymerick/raymond - -The quick and dirty way of rendering a handlebars template: - -```go -package main - -import ( - "fmt" - - "github.com/aymerick/raymond" -) - -func main() { - tpl := `
-

{{title}}

-
- {{body}} -
-
-` - - ctx := map[string]string{ - "title": "My New Post", - "body": "This is my first post!", - } - - result, err := raymond.Render(tpl, ctx) - if err != nil { - panic("Please report a bug :)") - } - - fmt.Print(result) -} -``` - -Displays: - -```html -
-

My New Post

-
- This is my first post! -
-
-``` - -Please note that the template will be parsed everytime you call `Render()` function. So you probably want to read the next section. - - -## Correct Usage - -To avoid parsing a template several times, use the `Parse()` and `Exec()` functions: - -```go -package main - -import ( - "fmt" - - "github.com/aymerick/raymond" -) - -func main() { - source := `
-

{{title}}

-
- {{body}} -
-
-` - - ctxList := []map[string]string{ - { - "title": "My New Post", - "body": "This is my first post!", - }, - { - "title": "Here is another post", - "body": "This is my second post!", - }, - } - - // parse template - tpl, err := raymond.Parse(source) - if err != nil { - panic(err) - } - - for _, ctx := range ctxList { - // render template - result, err := tpl.Exec(ctx) - if err != nil { - panic(err) - } - - fmt.Print(result) - } -} - -``` - -Displays: - -```html -
-

My New Post

-
- This is my first post! -
-
-
-

Here is another post

-
- This is my second post! -
-
-``` - -You can use `MustParse()` and `MustExec()` functions if you don't want to deal with errors: - -```go -// parse template -tpl := raymond.MustParse(source) - -// render template -result := tpl.MustExec(ctx) -``` - - -## Context - -The rendering context can contain any type of values, including `array`, `slice`, `map`, `struct` and `func`. - -When using structs, be warned that only exported fields are accessible. However you can access exported fields in template with their lowercase names. For example, both `{{author.firstName}}` and `{{Author.FirstName}}` references give the same result, as long as `Author` and `FirstName` are exported struct fields. - -More, you can use the `handlebars` struct tag to specify a template variable name different from the struct field name. - -```go -package main - -import ( - "fmt" - - "github.com/aymerick/raymond" -) - -func main() { - source := `
-

By {{author.firstName}} {{author.lastName}}

-
{{body}}
- -

Comments

- - {{#each comments}} -

By {{author.firstName}} {{author.lastName}}

-
{{content}}
- {{/each}} -
` - - type Person struct { - FirstName string - LastName string - } - - type Comment struct { - Author Person - Body string `handlebars:"content"` - } - - type Post struct { - Author Person - Body string - Comments []Comment - } - - ctx := Post{ - Person{"Jean", "Valjean"}, - "Life is difficult", - []Comment{ - Comment{ - Person{"Marcel", "Beliveau"}, - "LOL!", - }, - }, - } - - output := raymond.MustRender(source, ctx) - - fmt.Print(output) -} -``` - -Output: - -```html -
-

By Jean Valjean

-
Life is difficult
- -

Comments

- -

By Marcel Beliveau

-
LOL!
-
-``` - -## HTML Escaping - -By default, the result of a mustache expression is HTML escaped. Use the triple mustache `{{{` to output unescaped values. - -```go -source := `
-

{{title}}

-
- {{{body}}} -
-
-` - -ctx := map[string]string{ - "title": "All about

Tags", - "body": "

This is a post about <p> tags

", -} - -tpl := raymond.MustParse(source) -result := tpl.MustExec(ctx) - -fmt.Print(result) -``` - -Output: - -```html -
-

All about <p> Tags

-
-

This is a post about <p> tags

-
-
-``` - -When returning HTML from a helper, you should return a `SafeString` if you don't want it to be escaped by default. When using `SafeString` all unknown or unsafe data should be manually escaped with the `Escape` method. - -```go -raymond.RegisterHelper("link", func(url, text string) raymond.SafeString { - return raymond.SafeString("" + raymond.Escape(text) + "") -}) - -tpl := raymond.MustParse("{{link url text}}") - -ctx := map[string]string{ - "url": "http://www.aymerick.com/", - "text": "This is a cool website", -} - -result := tpl.MustExec(ctx) -fmt.Print(result) -``` - -Output: - -```html -This is a <em>cool</em> website -``` - - -## Helpers - -Helpers can be accessed from any context in a template. You can register a helper with the `RegisterHelper` function. - -For example: - -```html -
-

By {{fullName author}}

-
{{body}}
- -

Comments

- - {{#each comments}} -

By {{fullName author}}

-
{{body}}
- {{/each}} -
-``` - -With this context and helper: - -```go -ctx := map[string]interface{}{ - "author": map[string]string{"firstName": "Jean", "lastName": "Valjean"}, - "body": "Life is difficult", - "comments": []map[string]interface{}{{ - "author": map[string]string{"firstName": "Marcel", "lastName": "Beliveau"}, - "body": "LOL!", - }}, -} - -raymond.RegisterHelper("fullName", func(person map[string]string) string { - return person["firstName"] + " " + person["lastName"] -}) -``` - -Outputs: - -```html -
-

By Jean Valjean

-
Life is difficult
- -

Comments

- -

By Marcel Beliveau

-
LOL!
-
-``` - -Helper arguments can be any type. - -The following example uses structs instead of maps and produces the same output as the previous one: - -```html -
-

By {{fullName author}}

-
{{body}}
- -

Comments

- - {{#each comments}} -

By {{fullName author}}

-
{{body}}
- {{/each}} -
-``` - -With this context and helper: - -```go -type Post struct { - Author Person - Body string - Comments []Comment -} - -type Person struct { - FirstName string - LastName string -} - -type Comment struct { - Author Person - Body string -} - -ctx := Post{ - Person{"Jean", "Valjean"}, - "Life is difficult", - []Comment{ - Comment{ - Person{"Marcel", "Beliveau"}, - "LOL!", - }, - }, -} - -RegisterHelper("fullName", func(person Person) string { - return person.FirstName + " " + person.LastName -}) -``` - - -### Template Helpers - -You can register a helper on a specific template, and in that case that helper will be available to that template only: - -```go -tpl := raymond.MustParse("User: {{fullName user.firstName user.lastName}}") - -tpl.RegisterHelper("fullName", func(firstName, lastName string) string { - return firstName + " " + lastName -}) -``` - - -### Built-In Helpers - -Those built-in helpers are available to all templates. - - -#### The `if` block helper - -You can use the `if` helper to conditionally render a block. If its argument returns `false`, `nil`, `0`, `""`, an empty array, an empty slice or an empty map, then raymond will not render the block. - -```html -
- {{#if author}} -

{{firstName}} {{lastName}}

- {{/if}} -
-``` - -When using a block expression, you can specify a template section to run if the expression returns a falsy value. That section, marked by `{{else}}` is called an "else section". - -```html -
- {{#if author}} -

{{firstName}} {{lastName}}

- {{else}} -

Unknown Author

- {{/if}} -
-``` - -You can chain several blocks. For example that template: - -```html -{{#if isActive}} - Active -{{else if isInactive}} - Inactive -{{else}} - Unknown -{{/if}} -``` - -With that context: - -```go -ctx := map[string]interface{}{ - "isActive": false, - "isInactive": false, -} -``` - -Outputs: - -```html - Unknown -``` - - -#### The `unless` block helper - -You can use the `unless` helper as the inverse of the `if` helper. Its block will be rendered if the expression returns a falsy value. - -```html -
- {{#unless license}} -

WARNING: This entry does not have a license!

- {{/unless}} -
-``` - - -#### The `each` block helper - -You can iterate over an array, a slice, a map or a struct instance using this built-in `each` helper. Inside the block, you can use `this` to reference the element being iterated over. - -For example: - -```html -
    - {{#each people}} -
  • {{this}}
  • - {{/each}} -
-``` - -With this context: - -```go -map[string]interface{}{ - "people": []string{ - "Marcel", "Jean-Claude", "Yvette", - }, -} -``` - -Outputs: - -```html -
    -
  • Marcel
  • -
  • Jean-Claude
  • -
  • Yvette
  • -
-``` - -You can optionally provide an `{{else}}` section which will display only when the passed argument is an empty array, an empty slice or an empty map (a `struct` instance is never considered empty). - -```html -{{#each paragraphs}} -

{{this}}

-{{else}} -

No content

-{{/each}} -``` - -When looping through items in `each`, you can optionally reference the current loop index via `{{@index}}`. - -```html -{{#each array}} - {{@index}}: {{this}} -{{/each}} -``` - -Additionally for map and struct instance iteration, `{{@key}}` references the current map key or struct field name: - -```html -{{#each map}} - {{@key}}: {{this}} -{{/each}} -``` - -The first and last steps of iteration are noted via the `@first` and `@last` variables. - - -#### The `with` block helper - -You can shift the context for a section of a template by using the built-in `with` block helper. - -```html -
-

{{title}}

- - {{#with author}} -

By {{firstName}} {{lastName}}

- {{/with}} -
-``` - -With this context: - -```go -map[string]interface{}{ - "title": "My first post!", - "author": map[string]string{ - "firstName": "Jean", - "lastName": "Valjean", - }, -} -``` - -Outputs: - -```html -
-

My first post!

- -

By Jean Valjean

-
-``` - -You can optionally provide an `{{else}}` section which will display only when the passed argument is falsy. - -```html -{{#with author}} -

{{name}}

-{{else}} -

No content

-{{/with}} -``` - - -#### The `lookup` helper - -The `lookup` helper allows for dynamic parameter resolution using handlebars variables. - -```html -{{#each bar}} - {{lookup ../foo @index}} -{{/each}} -``` - - -#### The `log` helper - -The `log` helper allows for logging while rendering a template. - -```html -{{log "Look at me!"}} -``` - -Note that the handlebars.js `@level` variable is not supported. - - -#### The `equal` helper - -The `equal` helper renders a block if the string version of both arguments are equals. - -For example that template: - -```html -{{#equal foo "bar"}}foo is bar{{/equal}} -{{#equal foo baz}}foo is the same as baz{{/equal}} -{{#equal nb 0}}nothing{{/equal}} -{{#equal nb 1}}there is one{{/equal}} -{{#equal nb "1"}}everything is stringified before comparison{{/equal}} -``` - -With that context: - -```go -ctx := map[string]interface{}{ - "foo": "bar", - "baz": "bar", - "nb": 1, -} -``` - -Outputs: - -```html -foo is bar -foo is the same as baz - -there is one -everything is stringified before comparison -``` - - -### Block Helpers - -Block helpers make it possible to define custom iterators and other functionality that can invoke the passed block with a new context. - - -#### Block Evaluation - -As an example, let's define a block helper that adds some markup to the wrapped text. - -```html -
-

{{title}}

-
- {{#bold}}{{body}}{{/bold}} -
-
-``` - -The `bold` helper will add markup to make its text bold. - -```go -raymond.RegisterHelper("bold", func(options *raymond.Options) raymond.SafeString { - return raymond.SafeString(`
` + options.Fn() + "
") -}) -``` - -A helper evaluates the block content with current context by calling `options.Fn()`. - -If you want to evaluate the block with another context, then use `options.FnWith(ctx)`, like this french version of built-in `with` block helper: - -```go -raymond.RegisterHelper("avec", func(context interface{}, options *raymond.Options) string { - return options.FnWith(context) -}) -``` - -With that template: - -```html -{{#avec obj.text}}{{this}}{{/avec}} -``` - - -#### Conditional - -Let's write a french version of `if` block helper: - -```go -source := `{{#si yep}}YEP !{{/si}}` - -ctx := map[string]interface{}{"yep": true} - -raymond.RegisterHelper("si", func(conditional bool, options *raymond.Options) string { - if conditional { - return options.Fn() - } - return "" -}) -``` - -Note that as the first parameter of the helper is typed as `bool` an automatic conversion is made if corresponding context value is not a boolean. So this helper works with that context too: - -```go -ctx := map[string]interface{}{"yep": "message"} -``` - -Here, `"message"` is converted to `true` because it is an non-empty string. See `IsTrue()` function for more informations on boolean conversion. - - -#### Else Block Evaluation - -We can enhance the `si` block helper to evaluate the `else block` by calling `options.Inverse()` if conditional is false: - -```go -source := `{{#si yep}}YEP !{{else}}NOP !{{/si}}` - -ctx := map[string]interface{}{"yep": false} - -raymond.RegisterHelper("si", func(conditional bool, options *raymond.Options) string { - if conditional { - return options.Fn() - } - return options.Inverse() -}) -``` - -Outputs: -``` -NOP ! -``` - - -#### Block Parameters - -It's possible to receive named parameters from supporting helpers. - -```html -{{#each users as |user userId|}} - Id: {{userId}} Name: {{user.name}} -{{/each}} -``` - -In this particular example, `user` will have the same value as the current context and `userId` will have the index/key value for the iteration. - -This allows for nested helpers to avoid name conflicts. - -For example: - -```html -{{#each users as |user userId|}} - {{#each user.books as |book bookId|}} - User: {{userId}} Book: {{bookId}} - {{/each}} -{{/each}} -``` - -With this context: - -```go -ctx := map[string]interface{}{ - "users": map[string]interface{}{ - "marcel": map[string]interface{}{ - "books": map[string]interface{}{ - "book1": "My first book", - "book2": "My second book", - }, - }, - "didier": map[string]interface{}{ - "books": map[string]interface{}{ - "bookA": "Good book", - "bookB": "Bad book", - }, - }, - }, -} -``` - -Outputs: - -```html - User: marcel Book: book1 - User: marcel Book: book2 - User: didier Book: bookA - User: didier Book: bookB -``` - -As you can see, the second block parameter is the map key. When using structs, it is the struct field name. - -When using arrays and slices, the second parameter is element index: - -```go -ctx := map[string]interface{}{ - "users": []map[string]interface{}{ - { - "id": "marcel", - "books": []map[string]interface{}{ - {"id": "book1", "title": "My first book"}, - {"id": "book2", "title": "My second book"}, - }, - }, - { - "id": "didier", - "books": []map[string]interface{}{ - {"id": "bookA", "title": "Good book"}, - {"id": "bookB", "title": "Bad book"}, - }, - }, - }, -} -``` - -Outputs: - -```html - User: 0 Book: 0 - User: 0 Book: 1 - User: 1 Book: 0 - User: 1 Book: 1 -``` - - -### Helper Parameters - -When calling a helper in a template, raymond expects the same number of arguments as the number of helper function parameters. - -So this template: - -```html -{{add a}} -``` - -With this helper: - -```go -raymond.RegisterHelper("add", func(val1, val2 int) string { - return strconv.Itoa(val1 + val2) -}) -``` - -Will simply panics, because we call the helper with one argument whereas it expects two. - - -#### Automatic conversion - -Let's create a `concat` helper that expects two strings and concat them: - -```go -source := `{{concat a b}}` - -ctx := map[string]interface{}{ - "a": "Jean", - "b": "Valjean", -} - -raymond.RegisterHelper("concat", func(val1, val2 string) string { - return val1 + " " + val2 -}) -``` - -Everything goes well, two strings are passed as arguments to the helper that outputs: - -```html -Jean VALJEAN -``` - -But what happens if there is another type than `string` in the context ? For example: - -```go -ctx := map[string]interface{}{ - "a": 10, - "b": "Valjean", -} -``` - -Actually, raymond perfoms automatic string conversion. So because the first parameter of the helper is typed as `string`, the first argument will be converted from the `10` integer to `"10"`, and the helper outputs: - -```html -10 VALJEAN -``` - -Note that this kind of automatic conversion is done with `bool` type too, thanks to the `IsTrue()` function. - - -### Options Argument - -If a helper needs the `Options` argument, just add it at the end of helper parameters: - -```go -raymond.RegisterHelper("add", func(val1, val2 int, options *raymond.Options) string { - return strconv.Itoa(val1 + val2) + " " + options.ValueStr("bananas") -}) -``` - -Thanks to the `options` argument, helpers have access to the current evaluation context, to the `Hash` arguments, and they can manipulate the private data variables. - -The `Options` argument is even necessary for Block Helpers to evaluate block and "else block". - - -#### Context Values - -Helpers fetch current context values with `options.Value()` and `options.ValuesStr()`. - -`Value()` returns an `interface{}` and lets the helper do the type assertions whereas `ValueStr()` automatically converts the value to a `string`. - -For example: - -```go -source := `{{concat a b}}` - -ctx := map[string]interface{}{ - "a": "Marcel", - "b": "Beliveau", - "suffix": "FOREVER !", -} - -raymond.RegisterHelper("concat", func(val1, val2 string, options *raymond.Options) string { - return val1 + " " + val2 + " " + options.ValueStr("suffix") -}) -``` - -Outputs: - -```html -Marcel Beliveau FOREVER ! -``` - -Helpers can get the entire current context with `options.Ctx()` that returns an `interface{}`. - - -#### Helper Hash Arguments - -Helpers access hash arguments with `options.HashProp()` and `options.HashStr()`. - -`HashProp()` returns an `interface{}` and lets the helper do the type assertions whereas `HashStr()` automatically converts the value to a `string`. - -For example: - -```go -source := `{{concat suffix first=a second=b}}` - -ctx := map[string]interface{}{ - "a": "Marcel", - "b": "Beliveau", - "suffix": "FOREVER !", -} - -raymond.RegisterHelper("concat", func(suffix string, options *raymond.Options) string { - return options.HashStr("first") + " " + options.HashStr("second") + " " + suffix -}) -``` - -Outputs: - -```html -Marcel Beliveau FOREVER ! -``` - -Helpers can get the full hash with `options.Hash()` that returns a `map[string]interface{}`. - - -#### Private Data - -Helpers access private data variables with `options.Data()` and `options.DataStr()`. - -`Data()` returns an `interface{}` and lets the helper do the type assertions whereas `DataStr()` automatically converts the value to a `string`. - -Helpers can get the entire current data frame with `options.DataFrame()` that returns a `*DataFrame`. - -For helpers that need to inject their own private data frame, use `options.NewDataFrame()` to create the frame and `options.FnData()` to evaluate the block with that frame. - -For example: - -```go -source := `{{#voodoo kind=a}}Voodoo is {{@magix}}{{/voodoo}}` - -ctx := map[string]interface{}{ - "a": "awesome", -} - -raymond.RegisterHelper("voodoo", func(options *raymond.Options) string { - // create data frame with @magix data - frame := options.NewDataFrame() - frame.Set("magix", options.HashProp("kind")) - - // evaluates block with new data frame - return options.FnData(frame) -}) -``` - -Helpers that need to evaluate the block with a private data frame and a new context can call `options.FnCtxData()`. - - -### Utilites - -In addition to `Escape()`, raymond provides utility functions that can be usefull for helpers. - - -#### `Str()` - -`Str()` converts its parameter to a `string`. - -Booleans: - -```go -raymond.Str(3) + " foos and " + raymond.Str(-1.25) + " bars" -// Outputs: "3 foos and -1.25 bars" -``` - -Numbers: - -``` go -"everything is " + raymond.Str(true) + " and nothing is " + raymond.Str(false) -// Outputs: "everything is true and nothing is false" -``` - -Maps: - -```go -raymond.Str(map[string]string{"foo": "bar"}) -// Outputs: "map[foo:bar]" -``` - -Arrays and Slices: - -```go -raymond.Str([]interface{}{true, 10, "foo", 5, "bar"}) -// Outputs: "true10foo5bar" -``` - - -#### `IsTrue()` - -`IsTrue()` returns the truthy version of its parameter. - -It returns `false` when parameter is either: - - - an empty array - - an empty slice - - an empty map - - `""` - - `nil` - - `0` - - `false` - -For all others values, `IsTrue()` returns `true`. - - -## Context Functions - -In addition to helpers, lambdas found in context are evaluated. - -For example, that template and context: - -```go -source := "I {{feeling}} you" - -ctx := map[string]interface{}{ - "feeling": func() string { - rand.Seed(time.Now().UTC().UnixNano()) - - feelings := []string{"hate", "love"} - return feelings[rand.Intn(len(feelings))] - }, -} -``` - -Randomly renders `I hate you` or `I love you`. - -Those context functions behave like helper functions: they can be called with parameters and they can have an `Options` argument. - - -## Partials - -### Template Partials - -You can register template partials before execution: - -```go -tpl := raymond.MustParse("{{> foo}} baz") -tpl.RegisterPartial("foo", "bar") - -result := tpl.MustExec(nil) -fmt.Print(result) -``` - -Output: - -```html -bar baz -``` - -You can register several partials at once: - -```go -tpl := raymond.MustParse("{{> foo}} and {{> baz}}") -tpl.RegisterPartials(map[string]string{ - "foo": "bar", - "baz": "bat", -}) - -result := tpl.MustExec(nil) -fmt.Print(result) -``` - -Output: - -```html -bar and bat -``` - - -### Global Partials - -You can registers global partials that will be accessible by all templates: - -```go -raymond.RegisterPartial("foo", "bar") - -tpl := raymond.MustParse("{{> foo}} baz") -result := tpl.MustExec(nil) -fmt.Print(result) -``` - -Or: - -```go -raymond.RegisterPartials(map[string]string{ - "foo": "bar", - "baz": "bat", -}) - -tpl := raymond.MustParse("{{> foo}} and {{> baz}}") -result := tpl.MustExec(nil) -fmt.Print(result) -``` - - -### Dynamic Partials - -It's possible to dynamically select the partial to be executed by using sub expression syntax. - -For example, that template randomly evaluates the `foo` or `baz` partial: - -```go -tpl := raymond.MustParse("{{> (whichPartial) }}") -tpl.RegisterPartials(map[string]string{ - "foo": "bar", - "baz": "bat", -}) - -ctx := map[string]interface{}{ - "whichPartial": func() string { - rand.Seed(time.Now().UTC().UnixNano()) - - names := []string{"foo", "baz"} - return names[rand.Intn(len(names))] - }, -} - -result := tpl.MustExec(ctx) -fmt.Print(result) -``` - - -### Partial Contexts - -It's possible to execute partials on a custom context by passing in the context to the partial call. - -For example: - -```go -tpl := raymond.MustParse("User: {{> userDetails user }}") -tpl.RegisterPartial("userDetails", "{{firstname}} {{lastname}}") - -ctx := map[string]interface{}{ - "user": map[string]string{ - "firstname": "Jean", - "lastname": "Valjean", - }, -} - -result := tpl.MustExec(ctx) -fmt.Print(result) -``` - -Displays: - -```html -User: Jean Valjean -``` - - -### Partial Parameters - -Custom data can be passed to partials through hash parameters. - -For example: - -```go -tpl := raymond.MustParse("{{> myPartial name=hero }}") -tpl.RegisterPartial("myPartial", "My hero is {{name}}") - -ctx := map[string]interface{}{ - "hero": "Goldorak", -} - -result := tpl.MustExec(ctx) -fmt.Print(result) -``` - -Displays: - -```html -My hero is Goldorak -``` - - -## Utility Functions - -You can use following utility fuctions to parse and register partials from files: - -- `ParseFile()` - reads a file and return parsed template -- `Template.RegisterPartialFile()` - reads a file and registers its content as a partial with given name -- `Template.RegisterPartialFiles()` - reads several files and registers them as partials, the filename base is used as the partial name - - -## Mustache - -Handlebars is a superset of [mustache](https://mustache.github.io) but it differs on those points: - -- Alternative delimiters are not supported -- There is no recursive lookup - - -## Limitations - -These handlebars options are currently NOT implemented: - -- `compat` - enables recursive field lookup -- `knownHelpers` - list of helpers that are known to exist (truthy) at template execution time -- `knownHelpersOnly` - allows further optimizations based on the known helpers list -- `trackIds` - include the id names used to resolve parameters for helpers -- `noEscape` - disables HTML escaping globally -- `strict` - templates will throw rather than silently ignore missing fields -- `assumeObjects` - removes object existence checks when traversing paths -- `preventIndent` - disables the auto-indententation of nested partials -- `stringParams` - resolves a parameter to it's name if the value isn't present in the context stack - -These handlebars features are currently NOT implemented: - -- raw block content is not passed as a parameter to helper -- `blockHelperMissing` - helper called when a helper can not be directly resolved -- `helperMissing` - helper called when a potential helper expression was not found -- `@contextPath` - value set in `trackIds` mode that records the lookup path for the current context -- `@level` - log level - - -## Handlebars Lexer - -You should not use the lexer directly, but for your information here is an example: - -```go -package main - -import ( - "fmt" - - "github.com/aymerick/raymond/lexer" -) - -func main() { - source := "You know {{nothing}} John Snow" - - output := "" - - lex := lexer.Scan(source) - for { - // consume next token - token := lex.NextToken() - - output += fmt.Sprintf(" %s", token) - - // stops when all tokens have been consumed, or on error - if token.Kind == lexer.TokenEOF || token.Kind == lexer.TokenError { - break - } - } - - fmt.Print(output) -} -``` - -Outputs: - -``` -Content{"You know "} Open{"{{"} ID{"nothing"} Close{"}}"} Content{" John Snow"} EOF -``` - - -## Handlebars Parser - -You should not use the parser directly, but for your information here is an example: - -```go -package main - -import ( - "fmt" - - "github.com/aymerick/raymond/ast" - "github.com/aymerick/raymond/parser" -) - -fu nc main() { - source := "You know {{nothing}} John Snow" - - // parse template - program, err := parser.Parse(source) - if err != nil { - panic(err) - } - - // print AST - output := ast.Print(program) - - fmt.Print(output) -} -``` - -Outputs: - -``` -CONTENT[ 'You know ' ] -{{ PATH:nothing [] }} -CONTENT[ ' John Snow' ] -``` - - -## Test - -First, fetch mustache tests: - - $ git submodule update --init - -To run all tests: - - $ go test ./... - -To filter tests: - - $ go test -run="Partials" - -To run all test and all benchmarks: - - $ go test -bench . ./... - -To test with race detection: - - $ go test -race ./... - - -## References - - - - - - - - - - - -## Others Implementations - -- [handlebars.js](http://handlebarsjs.com) - javascript -- [handlebars.java](https://github.com/jknack/handlebars.java) - java -- [handlebars.rb](https://github.com/cowboyd/handlebars.rb) - ruby -- [handlebars.php](https://github.com/XaminProject/handlebars.php) - php -- [handlebars-objc](https://github.com/Bertrand/handlebars-objc) - Objective C -- [rumblebars](https://github.com/nicolas-cherel/rumblebars) - rust diff --git a/vendor/github.com/aymerick/raymond/VERSION b/vendor/github.com/aymerick/raymond/VERSION deleted file mode 100644 index 38f77a6..0000000 --- a/vendor/github.com/aymerick/raymond/VERSION +++ /dev/null @@ -1 +0,0 @@ -2.0.1 diff --git a/vendor/github.com/aymerick/raymond/ast/node.go b/vendor/github.com/aymerick/raymond/ast/node.go deleted file mode 100644 index aaef066..0000000 --- a/vendor/github.com/aymerick/raymond/ast/node.go +++ /dev/null @@ -1,785 +0,0 @@ -// Package ast provides structures to represent a handlebars Abstract Syntax Tree, and a Visitor interface to visit that tree. -package ast - -import ( - "fmt" - "strconv" -) - -// References: -// - https://github.com/wycats/handlebars.js/blob/master/lib/handlebars/compiler/ast.js -// - https://github.com/wycats/handlebars.js/blob/master/docs/compiler-api.md -// - https://github.com/golang/go/blob/master/src/text/template/parse/node.go - -// Node is an element in the AST. -type Node interface { - // node type - Type() NodeType - - // location of node in original input string - Location() Loc - - // string representation, used for debugging - String() string - - // accepts visitor - Accept(Visitor) interface{} -} - -// Visitor is the interface to visit an AST. -type Visitor interface { - VisitProgram(*Program) interface{} - - // statements - VisitMustache(*MustacheStatement) interface{} - VisitBlock(*BlockStatement) interface{} - VisitPartial(*PartialStatement) interface{} - VisitContent(*ContentStatement) interface{} - VisitComment(*CommentStatement) interface{} - - // expressions - VisitExpression(*Expression) interface{} - VisitSubExpression(*SubExpression) interface{} - VisitPath(*PathExpression) interface{} - - // literals - VisitString(*StringLiteral) interface{} - VisitBoolean(*BooleanLiteral) interface{} - VisitNumber(*NumberLiteral) interface{} - - // miscellaneous - VisitHash(*Hash) interface{} - VisitHashPair(*HashPair) interface{} -} - -// NodeType represents an AST Node type. -type NodeType int - -// Type returns itself, and permits struct includers to satisfy that part of Node interface. -func (t NodeType) Type() NodeType { - return t -} - -const ( - // NodeProgram is the program node - NodeProgram NodeType = iota - - // NodeMustache is the mustache statement node - NodeMustache - - // NodeBlock is the block statement node - NodeBlock - - // NodePartial is the partial statement node - NodePartial - - // NodeContent is the content statement node - NodeContent - - // NodeComment is the comment statement node - NodeComment - - // NodeExpression is the expression node - NodeExpression - - // NodeSubExpression is the subexpression node - NodeSubExpression - - // NodePath is the expression path node - NodePath - - // NodeBoolean is the literal boolean node - NodeBoolean - - // NodeNumber is the literal number node - NodeNumber - - // NodeString is the literal string node - NodeString - - // NodeHash is the hash node - NodeHash - - // NodeHashPair is the hash pair node - NodeHashPair -) - -// Loc represents the position of a parsed node in source file. -type Loc struct { - Pos int // Byte position - Line int // Line number -} - -// Location returns itself, and permits struct includers to satisfy that part of Node interface. -func (l Loc) Location() Loc { - return l -} - -// Strip describes node whitespace management. -type Strip struct { - Open bool - Close bool - - OpenStandalone bool - CloseStandalone bool - InlineStandalone bool -} - -// NewStrip instanciates a Strip for given open and close mustaches. -func NewStrip(openStr, closeStr string) *Strip { - return &Strip{ - Open: (len(openStr) > 2) && openStr[2] == '~', - Close: (len(closeStr) > 2) && closeStr[len(closeStr)-3] == '~', - } -} - -// NewStripForStr instanciates a Strip for given tag. -func NewStripForStr(str string) *Strip { - return &Strip{ - Open: (len(str) > 2) && str[2] == '~', - Close: (len(str) > 2) && str[len(str)-3] == '~', - } -} - -// String returns a string representation of receiver that can be used for debugging. -func (s *Strip) String() string { - return fmt.Sprintf("Open: %t, Close: %t, OpenStandalone: %t, CloseStandalone: %t, InlineStandalone: %t", s.Open, s.Close, s.OpenStandalone, s.CloseStandalone, s.InlineStandalone) -} - -// -// Program -// - -// Program represents a program node. -type Program struct { - NodeType - Loc - - Body []Node // [ Statement ... ] - BlockParams []string - Chained bool - - // whitespace management - Strip *Strip -} - -// NewProgram instanciates a new program node. -func NewProgram(pos int, line int) *Program { - return &Program{ - NodeType: NodeProgram, - Loc: Loc{pos, line}, - } -} - -// String returns a string representation of receiver that can be used for debugging. -func (node *Program) String() string { - return fmt.Sprintf("Program{Pos: %d}", node.Loc.Pos) -} - -// Accept is the receiver entry point for visitors. -func (node *Program) Accept(visitor Visitor) interface{} { - return visitor.VisitProgram(node) -} - -// AddStatement adds given statement to program. -func (node *Program) AddStatement(statement Node) { - node.Body = append(node.Body, statement) -} - -// -// Mustache Statement -// - -// MustacheStatement represents a mustache node. -type MustacheStatement struct { - NodeType - Loc - - Unescaped bool - Expression *Expression - - // whitespace management - Strip *Strip -} - -// NewMustacheStatement instanciates a new mustache node. -func NewMustacheStatement(pos int, line int, unescaped bool) *MustacheStatement { - return &MustacheStatement{ - NodeType: NodeMustache, - Loc: Loc{pos, line}, - Unescaped: unescaped, - } -} - -// String returns a string representation of receiver that can be used for debugging. -func (node *MustacheStatement) String() string { - return fmt.Sprintf("Mustache{Pos: %d}", node.Loc.Pos) -} - -// Accept is the receiver entry point for visitors. -func (node *MustacheStatement) Accept(visitor Visitor) interface{} { - return visitor.VisitMustache(node) -} - -// -// Block Statement -// - -// BlockStatement represents a block node. -type BlockStatement struct { - NodeType - Loc - - Expression *Expression - - Program *Program - Inverse *Program - - // whitespace management - OpenStrip *Strip - InverseStrip *Strip - CloseStrip *Strip -} - -// NewBlockStatement instanciates a new block node. -func NewBlockStatement(pos int, line int) *BlockStatement { - return &BlockStatement{ - NodeType: NodeBlock, - Loc: Loc{pos, line}, - } -} - -// String returns a string representation of receiver that can be used for debugging. -func (node *BlockStatement) String() string { - return fmt.Sprintf("Block{Pos: %d}", node.Loc.Pos) -} - -// Accept is the receiver entry point for visitors. -func (node *BlockStatement) Accept(visitor Visitor) interface{} { - return visitor.VisitBlock(node) -} - -// -// Partial Statement -// - -// PartialStatement represents a partial node. -type PartialStatement struct { - NodeType - Loc - - Name Node // PathExpression | SubExpression - Params []Node // [ Expression ... ] - Hash *Hash - - // whitespace management - Strip *Strip - Indent string -} - -// NewPartialStatement instanciates a new partial node. -func NewPartialStatement(pos int, line int) *PartialStatement { - return &PartialStatement{ - NodeType: NodePartial, - Loc: Loc{pos, line}, - } -} - -// String returns a string representation of receiver that can be used for debugging. -func (node *PartialStatement) String() string { - return fmt.Sprintf("Partial{Name:%s, Pos:%d}", node.Name, node.Loc.Pos) -} - -// Accept is the receiver entry point for visitors. -func (node *PartialStatement) Accept(visitor Visitor) interface{} { - return visitor.VisitPartial(node) -} - -// -// Content Statement -// - -// ContentStatement represents a content node. -type ContentStatement struct { - NodeType - Loc - - Value string - Original string - - // whitespace management - RightStripped bool - LeftStripped bool -} - -// NewContentStatement instanciates a new content node. -func NewContentStatement(pos int, line int, val string) *ContentStatement { - return &ContentStatement{ - NodeType: NodeContent, - Loc: Loc{pos, line}, - - Value: val, - Original: val, - } -} - -// String returns a string representation of receiver that can be used for debugging. -func (node *ContentStatement) String() string { - return fmt.Sprintf("Content{Value:'%s', Pos:%d}", node.Value, node.Loc.Pos) -} - -// Accept is the receiver entry point for visitors. -func (node *ContentStatement) Accept(visitor Visitor) interface{} { - return visitor.VisitContent(node) -} - -// -// Comment Statement -// - -// CommentStatement represents a comment node. -type CommentStatement struct { - NodeType - Loc - - Value string - - // whitespace management - Strip *Strip -} - -// NewCommentStatement instanciates a new comment node. -func NewCommentStatement(pos int, line int, val string) *CommentStatement { - return &CommentStatement{ - NodeType: NodeComment, - Loc: Loc{pos, line}, - - Value: val, - } -} - -// String returns a string representation of receiver that can be used for debugging. -func (node *CommentStatement) String() string { - return fmt.Sprintf("Comment{Value:'%s', Pos:%d}", node.Value, node.Loc.Pos) -} - -// Accept is the receiver entry point for visitors. -func (node *CommentStatement) Accept(visitor Visitor) interface{} { - return visitor.VisitComment(node) -} - -// -// Expression -// - -// Expression represents an expression node. -type Expression struct { - NodeType - Loc - - Path Node // PathExpression | StringLiteral | BooleanLiteral | NumberLiteral - Params []Node // [ Expression ... ] - Hash *Hash -} - -// NewExpression instanciates a new expression node. -func NewExpression(pos int, line int) *Expression { - return &Expression{ - NodeType: NodeExpression, - Loc: Loc{pos, line}, - } -} - -// String returns a string representation of receiver that can be used for debugging. -func (node *Expression) String() string { - return fmt.Sprintf("Expr{Path:%s, Pos:%d}", node.Path, node.Loc.Pos) -} - -// Accept is the receiver entry point for visitors. -func (node *Expression) Accept(visitor Visitor) interface{} { - return visitor.VisitExpression(node) -} - -// HelperName returns helper name, or an empty string if this expression can't be a helper. -func (node *Expression) HelperName() string { - path, ok := node.Path.(*PathExpression) - if !ok { - return "" - } - - if path.Data || (len(path.Parts) != 1) || (path.Depth > 0) || path.Scoped { - return "" - } - - return path.Parts[0] -} - -// FieldPath returns path expression representing a field path, or nil if this is not a field path. -func (node *Expression) FieldPath() *PathExpression { - path, ok := node.Path.(*PathExpression) - if !ok { - return nil - } - - return path -} - -// LiteralStr returns the string representation of literal value, with a boolean set to false if this is not a literal. -func (node *Expression) LiteralStr() (string, bool) { - return LiteralStr(node.Path) -} - -// Canonical returns the canonical form of expression node as a string. -func (node *Expression) Canonical() string { - if str, ok := HelperNameStr(node.Path); ok { - return str - } - - return "" -} - -// HelperNameStr returns the string representation of a helper name, with a boolean set to false if this is not a valid helper name. -// -// helperName : path | dataName | STRING | NUMBER | BOOLEAN | UNDEFINED | NULL -func HelperNameStr(node Node) (string, bool) { - // PathExpression - if str, ok := PathExpressionStr(node); ok { - return str, ok - } - - // Literal - if str, ok := LiteralStr(node); ok { - return str, ok - } - - return "", false -} - -// PathExpressionStr returns the string representation of path expression value, with a boolean set to false if this is not a path expression. -func PathExpressionStr(node Node) (string, bool) { - if path, ok := node.(*PathExpression); ok { - result := path.Original - - // "[foo bar]"" => "foo bar" - if (len(result) >= 2) && (result[0] == '[') && (result[len(result)-1] == ']') { - result = result[1 : len(result)-1] - } - - return result, true - } - - return "", false -} - -// LiteralStr returns the string representation of literal value, with a boolean set to false if this is not a literal. -func LiteralStr(node Node) (string, bool) { - if lit, ok := node.(*StringLiteral); ok { - return lit.Value, true - } - - if lit, ok := node.(*BooleanLiteral); ok { - return lit.Canonical(), true - } - - if lit, ok := node.(*NumberLiteral); ok { - return lit.Canonical(), true - } - - return "", false -} - -// -// SubExpression -// - -// SubExpression represents a subexpression node. -type SubExpression struct { - NodeType - Loc - - Expression *Expression -} - -// NewSubExpression instanciates a new subexpression node. -func NewSubExpression(pos int, line int) *SubExpression { - return &SubExpression{ - NodeType: NodeSubExpression, - Loc: Loc{pos, line}, - } -} - -// String returns a string representation of receiver that can be used for debugging. -func (node *SubExpression) String() string { - return fmt.Sprintf("Sexp{Path:%s, Pos:%d}", node.Expression.Path, node.Loc.Pos) -} - -// Accept is the receiver entry point for visitors. -func (node *SubExpression) Accept(visitor Visitor) interface{} { - return visitor.VisitSubExpression(node) -} - -// -// Path Expression -// - -// PathExpression represents a path expression node. -type PathExpression struct { - NodeType - Loc - - Original string - Depth int - Parts []string - Data bool - Scoped bool -} - -// NewPathExpression instanciates a new path expression node. -func NewPathExpression(pos int, line int, data bool) *PathExpression { - result := &PathExpression{ - NodeType: NodePath, - Loc: Loc{pos, line}, - - Data: data, - } - - if data { - result.Original = "@" - } - - return result -} - -// String returns a string representation of receiver that can be used for debugging. -func (node *PathExpression) String() string { - return fmt.Sprintf("Path{Original:'%s', Pos:%d}", node.Original, node.Loc.Pos) -} - -// Accept is the receiver entry point for visitors. -func (node *PathExpression) Accept(visitor Visitor) interface{} { - return visitor.VisitPath(node) -} - -// Part adds path part. -func (node *PathExpression) Part(part string) { - node.Original += part - - switch part { - case "..": - node.Depth++ - node.Scoped = true - case ".", "this": - node.Scoped = true - default: - node.Parts = append(node.Parts, part) - } -} - -// Sep adds path separator. -func (node *PathExpression) Sep(separator string) { - node.Original += separator -} - -// IsDataRoot returns true if path expression is @root. -func (node *PathExpression) IsDataRoot() bool { - return node.Data && (node.Parts[0] == "root") -} - -// -// String Literal -// - -// StringLiteral represents a string node. -type StringLiteral struct { - NodeType - Loc - - Value string -} - -// NewStringLiteral instanciates a new string node. -func NewStringLiteral(pos int, line int, val string) *StringLiteral { - return &StringLiteral{ - NodeType: NodeString, - Loc: Loc{pos, line}, - - Value: val, - } -} - -// String returns a string representation of receiver that can be used for debugging. -func (node *StringLiteral) String() string { - return fmt.Sprintf("String{Value:'%s', Pos:%d}", node.Value, node.Loc.Pos) -} - -// Accept is the receiver entry point for visitors. -func (node *StringLiteral) Accept(visitor Visitor) interface{} { - return visitor.VisitString(node) -} - -// -// Boolean Literal -// - -// BooleanLiteral represents a boolean node. -type BooleanLiteral struct { - NodeType - Loc - - Value bool - Original string -} - -// NewBooleanLiteral instanciates a new boolean node. -func NewBooleanLiteral(pos int, line int, val bool, original string) *BooleanLiteral { - return &BooleanLiteral{ - NodeType: NodeBoolean, - Loc: Loc{pos, line}, - - Value: val, - Original: original, - } -} - -// String returns a string representation of receiver that can be used for debugging. -func (node *BooleanLiteral) String() string { - return fmt.Sprintf("Boolean{Value:%s, Pos:%d}", node.Canonical(), node.Loc.Pos) -} - -// Accept is the receiver entry point for visitors. -func (node *BooleanLiteral) Accept(visitor Visitor) interface{} { - return visitor.VisitBoolean(node) -} - -// Canonical returns the canonical form of boolean node as a string (ie. "true" | "false"). -func (node *BooleanLiteral) Canonical() string { - if node.Value { - return "true" - } - - return "false" -} - -// -// Number Literal -// - -// NumberLiteral represents a number node. -type NumberLiteral struct { - NodeType - Loc - - Value float64 - IsInt bool - Original string -} - -// NewNumberLiteral instanciates a new number node. -func NewNumberLiteral(pos int, line int, val float64, isInt bool, original string) *NumberLiteral { - return &NumberLiteral{ - NodeType: NodeNumber, - Loc: Loc{pos, line}, - - Value: val, - IsInt: isInt, - Original: original, - } -} - -// String returns a string representation of receiver that can be used for debugging. -func (node *NumberLiteral) String() string { - return fmt.Sprintf("Number{Value:%s, Pos:%d}", node.Canonical(), node.Loc.Pos) -} - -// Accept is the receiver entry point for visitors. -func (node *NumberLiteral) Accept(visitor Visitor) interface{} { - return visitor.VisitNumber(node) -} - -// Canonical returns the canonical form of number node as a string (eg: "12", "-1.51"). -func (node *NumberLiteral) Canonical() string { - prec := -1 - if node.IsInt { - prec = 0 - } - return strconv.FormatFloat(node.Value, 'f', prec, 64) -} - -// Number returns an integer or a float. -func (node *NumberLiteral) Number() interface{} { - if node.IsInt { - return int(node.Value) - } - - return node.Value -} - -// -// Hash -// - -// Hash represents a hash node. -type Hash struct { - NodeType - Loc - - Pairs []*HashPair -} - -// NewHash instanciates a new hash node. -func NewHash(pos int, line int) *Hash { - return &Hash{ - NodeType: NodeHash, - Loc: Loc{pos, line}, - } -} - -// String returns a string representation of receiver that can be used for debugging. -func (node *Hash) String() string { - result := fmt.Sprintf("Hash{[%d", node.Loc.Pos) - - for i, p := range node.Pairs { - if i > 0 { - result += ", " - } - result += p.String() - } - - return result + fmt.Sprintf("], Pos:%d}", node.Loc.Pos) -} - -// Accept is the receiver entry point for visitors. -func (node *Hash) Accept(visitor Visitor) interface{} { - return visitor.VisitHash(node) -} - -// -// HashPair -// - -// HashPair represents a hash pair node. -type HashPair struct { - NodeType - Loc - - Key string - Val Node // Expression -} - -// NewHashPair instanciates a new hash pair node. -func NewHashPair(pos int, line int) *HashPair { - return &HashPair{ - NodeType: NodeHashPair, - Loc: Loc{pos, line}, - } -} - -// String returns a string representation of receiver that can be used for debugging. -func (node *HashPair) String() string { - return node.Key + "=" + node.Val.String() -} - -// Accept is the receiver entry point for visitors. -func (node *HashPair) Accept(visitor Visitor) interface{} { - return visitor.VisitHashPair(node) -} diff --git a/vendor/github.com/aymerick/raymond/ast/print.go b/vendor/github.com/aymerick/raymond/ast/print.go deleted file mode 100644 index 133ae6e..0000000 --- a/vendor/github.com/aymerick/raymond/ast/print.go +++ /dev/null @@ -1,279 +0,0 @@ -package ast - -import ( - "fmt" - "strings" -) - -// printVisitor implements the Visitor interface to print a AST. -type printVisitor struct { - buf string - depth int - - original bool - inBlock bool -} - -func newPrintVisitor() *printVisitor { - return &printVisitor{} -} - -// Print returns a string representation of given AST, that can be used for debugging purpose. -func Print(node Node) string { - visitor := newPrintVisitor() - node.Accept(visitor) - return visitor.output() -} - -func (v *printVisitor) output() string { - return v.buf -} - -func (v *printVisitor) indent() { - for i := 0; i < v.depth; { - v.buf += " " - i++ - } -} - -func (v *printVisitor) str(val string) { - v.buf += val -} - -func (v *printVisitor) nl() { - v.str("\n") -} - -func (v *printVisitor) line(val string) { - v.indent() - v.str(val) - v.nl() -} - -// -// Visitor interface -// - -// Statements - -// VisitProgram implements corresponding Visitor interface method -func (v *printVisitor) VisitProgram(node *Program) interface{} { - if len(node.BlockParams) > 0 { - v.line("BLOCK PARAMS: [ " + strings.Join(node.BlockParams, " ") + " ]") - } - - for _, n := range node.Body { - n.Accept(v) - } - - return nil -} - -// VisitMustache implements corresponding Visitor interface method -func (v *printVisitor) VisitMustache(node *MustacheStatement) interface{} { - v.indent() - v.str("{{ ") - - node.Expression.Accept(v) - - v.str(" }}") - v.nl() - - return nil -} - -// VisitBlock implements corresponding Visitor interface method -func (v *printVisitor) VisitBlock(node *BlockStatement) interface{} { - v.inBlock = true - - v.line("BLOCK:") - v.depth++ - - node.Expression.Accept(v) - - if node.Program != nil { - v.line("PROGRAM:") - v.depth++ - node.Program.Accept(v) - v.depth-- - } - - if node.Inverse != nil { - // if node.Program != nil { - // v.depth++ - // } - - v.line("{{^}}") - v.depth++ - node.Inverse.Accept(v) - v.depth-- - - // if node.Program != nil { - // v.depth-- - // } - } - - v.inBlock = false - - return nil -} - -// VisitPartial implements corresponding Visitor interface method -func (v *printVisitor) VisitPartial(node *PartialStatement) interface{} { - v.indent() - v.str("{{> PARTIAL:") - - v.original = true - node.Name.Accept(v) - v.original = false - - if len(node.Params) > 0 { - v.str(" ") - node.Params[0].Accept(v) - } - - // hash - if node.Hash != nil { - v.str(" ") - node.Hash.Accept(v) - } - - v.str(" }}") - v.nl() - - return nil -} - -// VisitContent implements corresponding Visitor interface method -func (v *printVisitor) VisitContent(node *ContentStatement) interface{} { - v.line("CONTENT[ '" + node.Value + "' ]") - - return nil -} - -// VisitComment implements corresponding Visitor interface method -func (v *printVisitor) VisitComment(node *CommentStatement) interface{} { - v.line("{{! '" + node.Value + "' }}") - - return nil -} - -// Expressions - -// VisitExpression implements corresponding Visitor interface method -func (v *printVisitor) VisitExpression(node *Expression) interface{} { - if v.inBlock { - v.indent() - } - - // path - node.Path.Accept(v) - - // params - v.str(" [") - for i, n := range node.Params { - if i > 0 { - v.str(", ") - } - n.Accept(v) - } - v.str("]") - - // hash - if node.Hash != nil { - v.str(" ") - node.Hash.Accept(v) - } - - if v.inBlock { - v.nl() - } - - return nil -} - -// VisitSubExpression implements corresponding Visitor interface method -func (v *printVisitor) VisitSubExpression(node *SubExpression) interface{} { - node.Expression.Accept(v) - - return nil -} - -// VisitPath implements corresponding Visitor interface method -func (v *printVisitor) VisitPath(node *PathExpression) interface{} { - if v.original { - v.str(node.Original) - } else { - path := strings.Join(node.Parts, "/") - - result := "" - if node.Data { - result += "@" - } - - v.str(result + "PATH:" + path) - } - - return nil -} - -// Literals - -// VisitString implements corresponding Visitor interface method -func (v *printVisitor) VisitString(node *StringLiteral) interface{} { - if v.original { - v.str(node.Value) - } else { - v.str("\"" + node.Value + "\"") - } - - return nil -} - -// VisitBoolean implements corresponding Visitor interface method -func (v *printVisitor) VisitBoolean(node *BooleanLiteral) interface{} { - if v.original { - v.str(node.Original) - } else { - v.str(fmt.Sprintf("BOOLEAN{%s}", node.Canonical())) - } - - return nil -} - -// VisitNumber implements corresponding Visitor interface method -func (v *printVisitor) VisitNumber(node *NumberLiteral) interface{} { - if v.original { - v.str(node.Original) - } else { - v.str(fmt.Sprintf("NUMBER{%s}", node.Canonical())) - } - - return nil -} - -// Miscellaneous - -// VisitHash implements corresponding Visitor interface method -func (v *printVisitor) VisitHash(node *Hash) interface{} { - v.str("HASH{") - - for i, p := range node.Pairs { - if i > 0 { - v.str(", ") - } - p.Accept(v) - } - - v.str("}") - - return nil -} - -// VisitHashPair implements corresponding Visitor interface method -func (v *printVisitor) VisitHashPair(node *HashPair) interface{} { - v.str(node.Key + "=") - node.Val.Accept(v) - - return nil -} diff --git a/vendor/github.com/aymerick/raymond/data_frame.go b/vendor/github.com/aymerick/raymond/data_frame.go deleted file mode 100644 index ce63218..0000000 --- a/vendor/github.com/aymerick/raymond/data_frame.go +++ /dev/null @@ -1,95 +0,0 @@ -package raymond - -import "reflect" - -// DataFrame represents a private data frame. -// -// Cf. private variables documentation at: http://handlebarsjs.com/block_helpers.html -type DataFrame struct { - parent *DataFrame - data map[string]interface{} -} - -// NewDataFrame instanciates a new private data frame. -func NewDataFrame() *DataFrame { - return &DataFrame{ - data: make(map[string]interface{}), - } -} - -// Copy instanciates a new private data frame with receiver as parent. -func (p *DataFrame) Copy() *DataFrame { - result := NewDataFrame() - - for k, v := range p.data { - result.data[k] = v - } - - result.parent = p - - return result -} - -// newIterDataFrame instanciates a new private data frame with receiver as parent and with iteration data set (@index, @key, @first, @last) -func (p *DataFrame) newIterDataFrame(length int, i int, key interface{}) *DataFrame { - result := p.Copy() - - result.Set("index", i) - result.Set("key", key) - result.Set("first", i == 0) - result.Set("last", i == length-1) - - return result -} - -// Set sets a data value. -func (p *DataFrame) Set(key string, val interface{}) { - p.data[key] = val -} - -// Get gets a data value. -func (p *DataFrame) Get(key string) interface{} { - return p.find([]string{key}) -} - -// find gets a deep data value -// -// @todo This is NOT consistent with the way we resolve data in template (cf. `evalDataPathExpression()`) ! FIX THAT ! -func (p *DataFrame) find(parts []string) interface{} { - data := p.data - - for i, part := range parts { - val := data[part] - if val == nil { - return nil - } - - if i == len(parts)-1 { - // found - return val - } - - valValue := reflect.ValueOf(val) - if valValue.Kind() != reflect.Map { - // not found - return nil - } - - // continue - data = mapStringInterface(valValue) - } - - // not found - return nil -} - -// mapStringInterface converts any `map` to `map[string]interface{}` -func mapStringInterface(value reflect.Value) map[string]interface{} { - result := make(map[string]interface{}) - - for _, key := range value.MapKeys() { - result[strValue(key)] = value.MapIndex(key).Interface() - } - - return result -} diff --git a/vendor/github.com/aymerick/raymond/escape.go b/vendor/github.com/aymerick/raymond/escape.go deleted file mode 100644 index 6a0363c..0000000 --- a/vendor/github.com/aymerick/raymond/escape.go +++ /dev/null @@ -1,65 +0,0 @@ -package raymond - -import ( - "bytes" - "strings" -) - -// -// That whole file is borrowed from https://github.com/golang/go/tree/master/src/html/escape.go -// -// With changes: -// ' => ' -// " => " -// -// To stay in sync with JS implementation, and make mustache tests pass. -// - -type writer interface { - WriteString(string) (int, error) -} - -const escapedChars = `&'<>"` - -func escape(w writer, s string) error { - i := strings.IndexAny(s, escapedChars) - for i != -1 { - if _, err := w.WriteString(s[:i]); err != nil { - return err - } - var esc string - switch s[i] { - case '&': - esc = "&" - case '\'': - esc = "'" - case '<': - esc = "<" - case '>': - esc = ">" - case '"': - 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 -} - -// Escape escapes special HTML characters. -// -// It can be used by helpers that return a SafeString and that need to escape some content by themselves. -func Escape(s string) string { - if strings.IndexAny(s, escapedChars) == -1 { - return s - } - var buf bytes.Buffer - escape(&buf, s) - return buf.String() -} diff --git a/vendor/github.com/aymerick/raymond/eval.go b/vendor/github.com/aymerick/raymond/eval.go deleted file mode 100644 index 7683f4e..0000000 --- a/vendor/github.com/aymerick/raymond/eval.go +++ /dev/null @@ -1,1005 +0,0 @@ -package raymond - -import ( - "bytes" - "fmt" - "reflect" - "strconv" - "strings" - - "github.com/aymerick/raymond/ast" -) - -var ( - // @note borrowed from https://github.com/golang/go/tree/master/src/text/template/exec.go - errorType = reflect.TypeOf((*error)(nil)).Elem() - fmtStringerType = reflect.TypeOf((*fmt.Stringer)(nil)).Elem() - - zero reflect.Value -) - -// evalVisitor evaluates a handlebars template with context -type evalVisitor struct { - tpl *Template - - // contexts stack - ctx []reflect.Value - - // current data frame (chained with parent) - dataFrame *DataFrame - - // block parameters stack - blockParams []map[string]interface{} - - // block statements stack - blocks []*ast.BlockStatement - - // expressions stack - exprs []*ast.Expression - - // memoize expressions that were function calls - exprFunc map[*ast.Expression]bool - - // used for info on panic - curNode ast.Node -} - -// NewEvalVisitor instanciate a new evaluation visitor with given context and initial private data frame -// -// If privData is nil, then a default data frame is created -func newEvalVisitor(tpl *Template, ctx interface{}, privData *DataFrame) *evalVisitor { - frame := privData - if frame == nil { - frame = NewDataFrame() - } - - return &evalVisitor{ - tpl: tpl, - ctx: []reflect.Value{reflect.ValueOf(ctx)}, - dataFrame: frame, - exprFunc: make(map[*ast.Expression]bool), - } -} - -// at sets current node -func (v *evalVisitor) at(node ast.Node) { - v.curNode = node -} - -// -// Contexts stack -// - -// pushCtx pushes new context to the stack -func (v *evalVisitor) pushCtx(ctx reflect.Value) { - v.ctx = append(v.ctx, ctx) -} - -// popCtx pops last context from stack -func (v *evalVisitor) popCtx() reflect.Value { - if len(v.ctx) == 0 { - return zero - } - - var result reflect.Value - result, v.ctx = v.ctx[len(v.ctx)-1], v.ctx[:len(v.ctx)-1] - - return result -} - -// rootCtx returns root context -func (v *evalVisitor) rootCtx() reflect.Value { - return v.ctx[0] -} - -// curCtx returns current context -func (v *evalVisitor) curCtx() reflect.Value { - return v.ancestorCtx(0) -} - -// ancestorCtx returns ancestor context -func (v *evalVisitor) ancestorCtx(depth int) reflect.Value { - index := len(v.ctx) - 1 - depth - if index < 0 { - return zero - } - - return v.ctx[index] -} - -// -// Private data frame -// - -// setDataFrame sets new data frame -func (v *evalVisitor) setDataFrame(frame *DataFrame) { - v.dataFrame = frame -} - -// popDataFrame sets back parent data frame -func (v *evalVisitor) popDataFrame() { - v.dataFrame = v.dataFrame.parent -} - -// -// Block Parameters stack -// - -// pushBlockParams pushes new block params to the stack -func (v *evalVisitor) pushBlockParams(params map[string]interface{}) { - v.blockParams = append(v.blockParams, params) -} - -// popBlockParams pops last block params from stack -func (v *evalVisitor) popBlockParams() map[string]interface{} { - var result map[string]interface{} - - if len(v.blockParams) == 0 { - return result - } - - result, v.blockParams = v.blockParams[len(v.blockParams)-1], v.blockParams[:len(v.blockParams)-1] - return result -} - -// blockParam iterates on stack to find given block parameter, and returns its value or nil if not founc -func (v *evalVisitor) blockParam(name string) interface{} { - for i := len(v.blockParams) - 1; i >= 0; i-- { - for k, v := range v.blockParams[i] { - if name == k { - return v - } - } - } - - return nil -} - -// -// Blocks stack -// - -// pushBlock pushes new block statement to stack -func (v *evalVisitor) pushBlock(block *ast.BlockStatement) { - v.blocks = append(v.blocks, block) -} - -// popBlock pops last block statement from stack -func (v *evalVisitor) popBlock() *ast.BlockStatement { - if len(v.blocks) == 0 { - return nil - } - - var result *ast.BlockStatement - result, v.blocks = v.blocks[len(v.blocks)-1], v.blocks[:len(v.blocks)-1] - - return result -} - -// curBlock returns current block statement -func (v *evalVisitor) curBlock() *ast.BlockStatement { - if len(v.blocks) == 0 { - return nil - } - - return v.blocks[len(v.blocks)-1] -} - -// -// Expressions stack -// - -// pushExpr pushes new expression to stack -func (v *evalVisitor) pushExpr(expression *ast.Expression) { - v.exprs = append(v.exprs, expression) -} - -// popExpr pops last expression from stack -func (v *evalVisitor) popExpr() *ast.Expression { - if len(v.exprs) == 0 { - return nil - } - - var result *ast.Expression - result, v.exprs = v.exprs[len(v.exprs)-1], v.exprs[:len(v.exprs)-1] - - return result -} - -// curExpr returns current expression -func (v *evalVisitor) curExpr() *ast.Expression { - if len(v.exprs) == 0 { - return nil - } - - return v.exprs[len(v.exprs)-1] -} - -// -// Error functions -// - -// errPanic panics -func (v *evalVisitor) errPanic(err error) { - panic(fmt.Errorf("Evaluation error: %s\nCurrent node:\n\t%s", err, v.curNode)) -} - -// errorf panics with a custom message -func (v *evalVisitor) errorf(format string, args ...interface{}) { - v.errPanic(fmt.Errorf(format, args...)) -} - -// -// Evaluation -// - -// evalProgram eEvaluates program with given context and returns string result -func (v *evalVisitor) evalProgram(program *ast.Program, ctx interface{}, data *DataFrame, key interface{}) string { - blockParams := make(map[string]interface{}) - - // compute block params - if len(program.BlockParams) > 0 { - blockParams[program.BlockParams[0]] = ctx - } - - if (len(program.BlockParams) > 1) && (key != nil) { - blockParams[program.BlockParams[1]] = key - } - - // push contexts - if len(blockParams) > 0 { - v.pushBlockParams(blockParams) - } - - ctxVal := reflect.ValueOf(ctx) - if ctxVal.IsValid() { - v.pushCtx(ctxVal) - } - - if data != nil { - v.setDataFrame(data) - } - - // evaluate program - result, _ := program.Accept(v).(string) - - // pop contexts - if data != nil { - v.popDataFrame() - } - - if ctxVal.IsValid() { - v.popCtx() - } - - if len(blockParams) > 0 { - v.popBlockParams() - } - - return result -} - -// evalPath evaluates all path parts with given context -func (v *evalVisitor) evalPath(ctx reflect.Value, parts []string, exprRoot bool) (reflect.Value, bool) { - partResolved := false - - for i := 0; i < len(parts); i++ { - part := parts[i] - - // "[foo bar]"" => "foo bar" - if (len(part) >= 2) && (part[0] == '[') && (part[len(part)-1] == ']') { - part = part[1 : len(part)-1] - } - - ctx = v.evalField(ctx, part, exprRoot) - if !ctx.IsValid() { - break - } - - // we resolved at least one part of path - partResolved = true - } - - return ctx, partResolved -} - -// evalField evaluates field with given context -func (v *evalVisitor) evalField(ctx reflect.Value, fieldName string, exprRoot bool) reflect.Value { - result := zero - - ctx, _ = indirect(ctx) - if !ctx.IsValid() { - return result - } - - // check if this is a method call - result, isMeth := v.evalMethod(ctx, fieldName, exprRoot) - if !isMeth { - switch ctx.Kind() { - case reflect.Struct: - // example: firstName => FirstName - expFieldName := strings.Title(fieldName) - - // check if struct have this field and that it is exported - if tField, ok := ctx.Type().FieldByName(expFieldName); ok && (tField.PkgPath == "") { - // struct field - result = ctx.FieldByIndex(tField.Index) - break - } - - // attempts to find template variable name as a struct tag - result = v.evalStructTag(ctx, fieldName) - case reflect.Map: - nameVal := reflect.ValueOf(fieldName) - if nameVal.Type().AssignableTo(ctx.Type().Key()) { - // map key - result = ctx.MapIndex(nameVal) - } - case reflect.Array, reflect.Slice: - if i, err := strconv.Atoi(fieldName); (err == nil) && (i < ctx.Len()) { - result = ctx.Index(i) - } - } - } - - // check if result is a function - result, _ = indirect(result) - if result.Kind() == reflect.Func { - result = v.evalFieldFunc(fieldName, result, exprRoot) - } - - return result -} - -// evalFieldFunc tries to evaluate given method name, and a boolean to indicate if this was a method call -func (v *evalVisitor) evalMethod(ctx reflect.Value, name string, exprRoot bool) (reflect.Value, bool) { - if ctx.Kind() != reflect.Interface && ctx.CanAddr() { - ctx = ctx.Addr() - } - - method := ctx.MethodByName(name) - if !method.IsValid() { - // example: subject() => Subject() - method = ctx.MethodByName(strings.Title(name)) - } - - if !method.IsValid() { - return zero, false - } - - return v.evalFieldFunc(name, method, exprRoot), true -} - -// evalFieldFunc evaluates given function -func (v *evalVisitor) evalFieldFunc(name string, funcVal reflect.Value, exprRoot bool) reflect.Value { - ensureValidHelper(name, funcVal) - - var options *Options - if exprRoot { - // create function arg with all params/hash - expr := v.curExpr() - options = v.helperOptions(expr) - - // ok, that expression was a function call - v.exprFunc[expr] = true - } else { - // we are not at root of expression, so we are a parameter... and we don't like - // infinite loops caused by trying to parse ourself forever - options = newEmptyOptions(v) - } - - return v.callFunc(name, funcVal, options) -} - -// evalStructTag checks for the existence of a struct tag containing the -// name of the variable in the template. This allows for a template variable to -// be separated from the field in the struct. -func (v *evalVisitor) evalStructTag(ctx reflect.Value, name string) reflect.Value { - val := reflect.ValueOf(ctx.Interface()) - - for i := 0; i < val.NumField(); i++ { - field := val.Type().Field(i) - tag := field.Tag.Get("handlebars") - if tag == name { - return val.Field(i) - } - } - - return zero -} - -// findBlockParam returns node's block parameter -func (v *evalVisitor) findBlockParam(node *ast.PathExpression) (string, interface{}) { - if len(node.Parts) > 0 { - name := node.Parts[0] - if value := v.blockParam(name); value != nil { - return name, value - } - } - - return "", nil -} - -// evalPathExpression evaluates a path expression -func (v *evalVisitor) evalPathExpression(node *ast.PathExpression, exprRoot bool) interface{} { - var result interface{} - - if name, value := v.findBlockParam(node); value != nil { - // block parameter value - - // We push a new context so we can evaluate the path expression (note: this may be a bad idea). - // - // Example: - // {{#foo as |bar|}} - // {{bar.baz}} - // {{/foo}} - // - // With data: - // {"foo": {"baz": "bat"}} - newCtx := map[string]interface{}{name: value} - - v.pushCtx(reflect.ValueOf(newCtx)) - result = v.evalCtxPathExpression(node, exprRoot) - v.popCtx() - } else { - ctxTried := false - - if node.IsDataRoot() { - // context path - result = v.evalCtxPathExpression(node, exprRoot) - - ctxTried = true - } - - if (result == nil) && node.Data { - // if it is @root, then we tried to evaluate with root context but nothing was found - // so let's try with private data - - // private data - result = v.evalDataPathExpression(node, exprRoot) - } - - if (result == nil) && !ctxTried { - // context path - result = v.evalCtxPathExpression(node, exprRoot) - } - } - - return result -} - -// evalDataPathExpression evaluates a private data path expression -func (v *evalVisitor) evalDataPathExpression(node *ast.PathExpression, exprRoot bool) interface{} { - // find data frame - frame := v.dataFrame - for i := node.Depth; i > 0; i-- { - if frame.parent == nil { - return nil - } - frame = frame.parent - } - - // resolve data - // @note Can be changed to v.evalCtx() as context can't be an array - result, _ := v.evalCtxPath(reflect.ValueOf(frame.data), node.Parts, exprRoot) - return result -} - -// evalCtxPathExpression evaluates a context path expression -func (v *evalVisitor) evalCtxPathExpression(node *ast.PathExpression, exprRoot bool) interface{} { - v.at(node) - - if node.IsDataRoot() { - // `@root` - remove the first part - parts := node.Parts[1:len(node.Parts)] - - result, _ := v.evalCtxPath(v.rootCtx(), parts, exprRoot) - return result - } - - return v.evalDepthPath(node.Depth, node.Parts, exprRoot) -} - -// evalDepthPath iterates on contexts, starting at given depth, until there is one that resolve given path parts -func (v *evalVisitor) evalDepthPath(depth int, parts []string, exprRoot bool) interface{} { - var result interface{} - partResolved := false - - ctx := v.ancestorCtx(depth) - - for (result == nil) && ctx.IsValid() && (depth <= len(v.ctx) && !partResolved) { - // try with context - result, partResolved = v.evalCtxPath(ctx, parts, exprRoot) - - // As soon as we find the first part of a path, we must not try to resolve with parent context if result is finally `nil` - // Reference: "Dotted Names - Context Precedence" mustache test - if !partResolved && (result == nil) { - // try with previous context - depth++ - ctx = v.ancestorCtx(depth) - } - } - - return result -} - -// evalCtxPath evaluates path with given context -func (v *evalVisitor) evalCtxPath(ctx reflect.Value, parts []string, exprRoot bool) (interface{}, bool) { - var result interface{} - partResolved := false - - switch ctx.Kind() { - case reflect.Array, reflect.Slice: - // Array context - var results []interface{} - - for i := 0; i < ctx.Len(); i++ { - value, _ := v.evalPath(ctx.Index(i), parts, exprRoot) - if value.IsValid() { - results = append(results, value.Interface()) - } - } - - result = results - default: - // NOT array context - var value reflect.Value - - value, partResolved = v.evalPath(ctx, parts, exprRoot) - if value.IsValid() { - result = value.Interface() - } - } - - return result, partResolved -} - -// -// Helpers -// - -// isHelperCall returns true if given expression is a helper call -func (v *evalVisitor) isHelperCall(node *ast.Expression) bool { - if helperName := node.HelperName(); helperName != "" { - return v.findHelper(helperName) != zero - } - return false -} - -// findHelper finds given helper -func (v *evalVisitor) findHelper(name string) reflect.Value { - // check template helpers - if h := v.tpl.findHelper(name); h != zero { - return h - } - - // check global helpers - return findHelper(name) -} - -// callFunc calls function with given options -func (v *evalVisitor) callFunc(name string, funcVal reflect.Value, options *Options) reflect.Value { - params := options.Params() - - funcType := funcVal.Type() - - // @todo Is there a better way to do that ? - strType := reflect.TypeOf("") - boolType := reflect.TypeOf(true) - - // check parameters number - addOptions := false - numIn := funcType.NumIn() - - if numIn == len(params)+1 { - lastArgType := funcType.In(numIn - 1) - if reflect.TypeOf(options).AssignableTo(lastArgType) { - addOptions = true - } - } - - if !addOptions && (len(params) != numIn) { - v.errorf("Helper '%s' called with wrong number of arguments, needed %d but got %d", name, numIn, len(params)) - } - - // check and collect arguments - args := make([]reflect.Value, numIn) - for i, param := range params { - arg := reflect.ValueOf(param) - argType := funcType.In(i) - - if !arg.IsValid() { - if canBeNil(argType) { - arg = reflect.Zero(argType) - } else if argType.Kind() == reflect.String { - arg = reflect.ValueOf("") - } else { - // @todo Maybe we can panic on that - return reflect.Zero(strType) - } - } - - if !arg.Type().AssignableTo(argType) { - if strType.AssignableTo(argType) { - // convert parameter to string - arg = reflect.ValueOf(strValue(arg)) - } else if boolType.AssignableTo(argType) { - // convert parameter to bool - val, _ := isTrueValue(arg) - arg = reflect.ValueOf(val) - } else { - v.errorf("Helper %s called with argument %d with type %s but it should be %s", name, i, arg.Type(), argType) - } - } - - args[i] = arg - } - - if addOptions { - args[numIn-1] = reflect.ValueOf(options) - } - - result := funcVal.Call(args) - - return result[0] -} - -// callHelper invoqs helper function for given expression node -func (v *evalVisitor) callHelper(name string, helper reflect.Value, node *ast.Expression) interface{} { - result := v.callFunc(name, helper, v.helperOptions(node)) - if !result.IsValid() { - return nil - } - - // @todo We maybe want to ensure here that helper returned a string or a SafeString - return result.Interface() -} - -// helperOptions computes helper options argument from an expression -func (v *evalVisitor) helperOptions(node *ast.Expression) *Options { - var params []interface{} - var hash map[string]interface{} - - for _, paramNode := range node.Params { - param := paramNode.Accept(v) - params = append(params, param) - } - - if node.Hash != nil { - hash, _ = node.Hash.Accept(v).(map[string]interface{}) - } - - return newOptions(v, params, hash) -} - -// -// Partials -// - -// findPartial finds given partial -func (v *evalVisitor) findPartial(name string) *partial { - // check template partials - if p := v.tpl.findPartial(name); p != nil { - return p - } - - // check global partials - return findPartial(name) -} - -// partialContext computes partial context -func (v *evalVisitor) partialContext(node *ast.PartialStatement) reflect.Value { - if nb := len(node.Params); nb > 1 { - v.errorf("Unsupported number of partial arguments: %d", nb) - } - - if (len(node.Params) > 0) && (node.Hash != nil) { - v.errorf("Passing both context and named parameters to a partial is not allowed") - } - - if len(node.Params) == 1 { - return reflect.ValueOf(node.Params[0].Accept(v)) - } - - if node.Hash != nil { - hash, _ := node.Hash.Accept(v).(map[string]interface{}) - return reflect.ValueOf(hash) - } - - return zero -} - -// evalPartial evaluates a partial -func (v *evalVisitor) evalPartial(p *partial, node *ast.PartialStatement) string { - // get partial template - partialTpl, err := p.template() - if err != nil { - v.errPanic(err) - } - - // push partial context - ctx := v.partialContext(node) - if ctx.IsValid() { - v.pushCtx(ctx) - } - - // evaluate partial template - result, _ := partialTpl.program.Accept(v).(string) - - // ident partial - result = indentLines(result, node.Indent) - - if ctx.IsValid() { - v.popCtx() - } - - return result -} - -// indentLines indents all lines of given string -func indentLines(str string, indent string) string { - if indent == "" { - return str - } - - var indented []string - - lines := strings.Split(str, "\n") - for i, line := range lines { - if (i == (len(lines) - 1)) && (line == "") { - // input string ends with a new line - indented = append(indented, line) - } else { - indented = append(indented, indent+line) - } - } - - return strings.Join(indented, "\n") -} - -// -// Functions -// - -// wasFuncCall returns true if given expression was a function call -func (v *evalVisitor) wasFuncCall(node *ast.Expression) bool { - // check if expression was tagged as a function call - return v.exprFunc[node] -} - -// -// Visitor interface -// - -// Statements - -// VisitProgram implements corresponding Visitor interface method -func (v *evalVisitor) VisitProgram(node *ast.Program) interface{} { - v.at(node) - - buf := new(bytes.Buffer) - - for _, n := range node.Body { - if str := Str(n.Accept(v)); str != "" { - if _, err := buf.Write([]byte(str)); err != nil { - v.errPanic(err) - } - } - } - - return buf.String() -} - -// VisitMustache implements corresponding Visitor interface method -func (v *evalVisitor) VisitMustache(node *ast.MustacheStatement) interface{} { - v.at(node) - - // evaluate expression - expr := node.Expression.Accept(v) - - // check if this is a safe string - isSafe := isSafeString(expr) - - // get string value - str := Str(expr) - if !isSafe && !node.Unescaped { - // escape html - str = Escape(str) - } - - return str -} - -// VisitBlock implements corresponding Visitor interface method -func (v *evalVisitor) VisitBlock(node *ast.BlockStatement) interface{} { - v.at(node) - - v.pushBlock(node) - - var result interface{} - - // evaluate expression - expr := node.Expression.Accept(v) - - if v.isHelperCall(node.Expression) || v.wasFuncCall(node.Expression) { - // it is the responsability of the helper/function to evaluate block - result = expr - } else { - val := reflect.ValueOf(expr) - - truth, _ := isTrueValue(val) - if truth { - if node.Program != nil { - switch val.Kind() { - case reflect.Array, reflect.Slice: - concat := "" - - // Array context - for i := 0; i < val.Len(); i++ { - // Computes new private data frame - frame := v.dataFrame.newIterDataFrame(val.Len(), i, nil) - - // Evaluate program - concat += v.evalProgram(node.Program, val.Index(i).Interface(), frame, i) - } - - result = concat - default: - // NOT array - result = v.evalProgram(node.Program, expr, nil, nil) - } - } - } else if node.Inverse != nil { - result, _ = node.Inverse.Accept(v).(string) - } - } - - v.popBlock() - - return result -} - -// VisitPartial implements corresponding Visitor interface method -func (v *evalVisitor) VisitPartial(node *ast.PartialStatement) interface{} { - v.at(node) - - // partialName: helperName | sexpr - name, ok := ast.HelperNameStr(node.Name) - if !ok { - if subExpr, ok := node.Name.(*ast.SubExpression); ok { - name, _ = subExpr.Accept(v).(string) - } - } - - if name == "" { - v.errorf("Unexpected partial name: %q", node.Name) - } - - partial := v.findPartial(name) - if partial == nil { - v.errorf("Partial not found: %s", name) - } - - return v.evalPartial(partial, node) -} - -// VisitContent implements corresponding Visitor interface method -func (v *evalVisitor) VisitContent(node *ast.ContentStatement) interface{} { - v.at(node) - - // write content as is - return node.Value -} - -// VisitComment implements corresponding Visitor interface method -func (v *evalVisitor) VisitComment(node *ast.CommentStatement) interface{} { - v.at(node) - - // ignore comments - return "" -} - -// Expressions - -// VisitExpression implements corresponding Visitor interface method -func (v *evalVisitor) VisitExpression(node *ast.Expression) interface{} { - v.at(node) - - var result interface{} - done := false - - v.pushExpr(node) - - // helper call - if helperName := node.HelperName(); helperName != "" { - if helper := v.findHelper(helperName); helper != zero { - result = v.callHelper(helperName, helper, node) - done = true - } - } - - if !done { - // literal - if literal, ok := node.LiteralStr(); ok { - if val := v.evalField(v.curCtx(), literal, true); val.IsValid() { - result = val.Interface() - done = true - } - } - } - - if !done { - // field path - if path := node.FieldPath(); path != nil { - // @todo Find a cleaner way ! Don't break the pattern ! - // this is an exception to visitor pattern, because we need to pass the info - // that this path is at root of current expression - if val := v.evalPathExpression(path, true); val != nil { - result = val - } - } - } - - v.popExpr() - - return result -} - -// VisitSubExpression implements corresponding Visitor interface method -func (v *evalVisitor) VisitSubExpression(node *ast.SubExpression) interface{} { - v.at(node) - - return node.Expression.Accept(v) -} - -// VisitPath implements corresponding Visitor interface method -func (v *evalVisitor) VisitPath(node *ast.PathExpression) interface{} { - return v.evalPathExpression(node, false) -} - -// Literals - -// VisitString implements corresponding Visitor interface method -func (v *evalVisitor) VisitString(node *ast.StringLiteral) interface{} { - v.at(node) - - return node.Value -} - -// VisitBoolean implements corresponding Visitor interface method -func (v *evalVisitor) VisitBoolean(node *ast.BooleanLiteral) interface{} { - v.at(node) - - return node.Value -} - -// VisitNumber implements corresponding Visitor interface method -func (v *evalVisitor) VisitNumber(node *ast.NumberLiteral) interface{} { - v.at(node) - - return node.Number() -} - -// Miscellaneous - -// VisitHash implements corresponding Visitor interface method -func (v *evalVisitor) VisitHash(node *ast.Hash) interface{} { - v.at(node) - - result := make(map[string]interface{}) - - for _, pair := range node.Pairs { - if value := pair.Accept(v); value != nil { - result[pair.Key] = value - } - } - - return result -} - -// VisitHashPair implements corresponding Visitor interface method -func (v *evalVisitor) VisitHashPair(node *ast.HashPair) interface{} { - v.at(node) - - return node.Val.Accept(v) -} diff --git a/vendor/github.com/aymerick/raymond/helper.go b/vendor/github.com/aymerick/raymond/helper.go deleted file mode 100644 index 15c8309..0000000 --- a/vendor/github.com/aymerick/raymond/helper.go +++ /dev/null @@ -1,382 +0,0 @@ -package raymond - -import ( - "fmt" - "log" - "reflect" - "sync" -) - -// Options represents the options argument provided to helpers and context functions. -type Options struct { - // evaluation visitor - eval *evalVisitor - - // params - params []interface{} - hash map[string]interface{} -} - -// helpers stores all globally registered helpers -var helpers = make(map[string]reflect.Value) - -// protects global helpers -var helpersMutex sync.RWMutex - -func init() { - // register builtin helpers - RegisterHelper("if", ifHelper) - RegisterHelper("unless", unlessHelper) - RegisterHelper("with", withHelper) - RegisterHelper("each", eachHelper) - RegisterHelper("log", logHelper) - RegisterHelper("lookup", lookupHelper) - RegisterHelper("equal", equalHelper) -} - -// RegisterHelper registers a global helper. That helper will be available to all templates. -func RegisterHelper(name string, helper interface{}) { - helpersMutex.Lock() - defer helpersMutex.Unlock() - - if helpers[name] != zero { - panic(fmt.Errorf("Helper already registered: %s", name)) - } - - val := reflect.ValueOf(helper) - ensureValidHelper(name, val) - - helpers[name] = val -} - -// RegisterHelpers registers several global helpers. Those helpers will be available to all templates. -func RegisterHelpers(helpers map[string]interface{}) { - for name, helper := range helpers { - RegisterHelper(name, helper) - } -} - -// ensureValidHelper panics if given helper is not valid -func ensureValidHelper(name string, funcValue reflect.Value) { - if funcValue.Kind() != reflect.Func { - panic(fmt.Errorf("Helper must be a function: %s", name)) - } - - funcType := funcValue.Type() - - if funcType.NumOut() != 1 { - panic(fmt.Errorf("Helper function must return a string or a SafeString: %s", name)) - } - - // @todo Check if first returned value is a string, SafeString or interface{} ? -} - -// findHelper finds a globally registered helper -func findHelper(name string) reflect.Value { - helpersMutex.RLock() - defer helpersMutex.RUnlock() - - return helpers[name] -} - -// newOptions instanciates a new Options -func newOptions(eval *evalVisitor, params []interface{}, hash map[string]interface{}) *Options { - return &Options{ - eval: eval, - params: params, - hash: hash, - } -} - -// newEmptyOptions instanciates a new empty Options -func newEmptyOptions(eval *evalVisitor) *Options { - return &Options{ - eval: eval, - hash: make(map[string]interface{}), - } -} - -// -// Context Values -// - -// Value returns field value from current context. -func (options *Options) Value(name string) interface{} { - value := options.eval.evalField(options.eval.curCtx(), name, false) - if !value.IsValid() { - return nil - } - - return value.Interface() -} - -// ValueStr returns string representation of field value from current context. -func (options *Options) ValueStr(name string) string { - return Str(options.Value(name)) -} - -// Ctx returns current evaluation context. -func (options *Options) Ctx() interface{} { - return options.eval.curCtx().Interface() -} - -// -// Hash Arguments -// - -// HashProp returns hash property. -func (options *Options) HashProp(name string) interface{} { - return options.hash[name] -} - -// HashStr returns string representation of hash property. -func (options *Options) HashStr(name string) string { - return Str(options.hash[name]) -} - -// Hash returns entire hash. -func (options *Options) Hash() map[string]interface{} { - return options.hash -} - -// -// Parameters -// - -// Param returns parameter at given position. -func (options *Options) Param(pos int) interface{} { - if len(options.params) > pos { - return options.params[pos] - } - - return nil -} - -// ParamStr returns string representation of parameter at given position. -func (options *Options) ParamStr(pos int) string { - return Str(options.Param(pos)) -} - -// Params returns all parameters. -func (options *Options) Params() []interface{} { - return options.params -} - -// -// Private data -// - -// Data returns private data value. -func (options *Options) Data(name string) interface{} { - return options.eval.dataFrame.Get(name) -} - -// DataStr returns string representation of private data value. -func (options *Options) DataStr(name string) string { - return Str(options.eval.dataFrame.Get(name)) -} - -// DataFrame returns current private data frame. -func (options *Options) DataFrame() *DataFrame { - return options.eval.dataFrame -} - -// NewDataFrame instanciates a new data frame that is a copy of current evaluation data frame. -// -// Parent of returned data frame is set to current evaluation data frame. -func (options *Options) NewDataFrame() *DataFrame { - return options.eval.dataFrame.Copy() -} - -// newIterDataFrame instanciates a new data frame and set iteration specific vars -func (options *Options) newIterDataFrame(length int, i int, key interface{}) *DataFrame { - return options.eval.dataFrame.newIterDataFrame(length, i, key) -} - -// -// Evaluation -// - -// evalBlock evaluates block with given context, private data and iteration key -func (options *Options) evalBlock(ctx interface{}, data *DataFrame, key interface{}) string { - result := "" - - if block := options.eval.curBlock(); (block != nil) && (block.Program != nil) { - result = options.eval.evalProgram(block.Program, ctx, data, key) - } - - return result -} - -// Fn evaluates block with current evaluation context. -func (options *Options) Fn() string { - return options.evalBlock(nil, nil, nil) -} - -// FnCtxData evaluates block with given context and private data frame. -func (options *Options) FnCtxData(ctx interface{}, data *DataFrame) string { - return options.evalBlock(ctx, data, nil) -} - -// FnWith evaluates block with given context. -func (options *Options) FnWith(ctx interface{}) string { - return options.evalBlock(ctx, nil, nil) -} - -// FnData evaluates block with given private data frame. -func (options *Options) FnData(data *DataFrame) string { - return options.evalBlock(nil, data, nil) -} - -// Inverse evaluates "else block". -func (options *Options) Inverse() string { - result := "" - if block := options.eval.curBlock(); (block != nil) && (block.Inverse != nil) { - result, _ = block.Inverse.Accept(options.eval).(string) - } - - return result -} - -// Eval evaluates field for given context. -func (options *Options) Eval(ctx interface{}, field string) interface{} { - if ctx == nil { - return nil - } - - if field == "" { - return nil - } - - val := options.eval.evalField(reflect.ValueOf(ctx), field, false) - if !val.IsValid() { - return nil - } - - return val.Interface() -} - -// -// Misc -// - -// isIncludableZero returns true if 'includeZero' option is set and first param is the number 0 -func (options *Options) isIncludableZero() bool { - b, ok := options.HashProp("includeZero").(bool) - if ok && b { - nb, ok := options.Param(0).(int) - if ok && nb == 0 { - return true - } - } - - return false -} - -// -// Builtin helpers -// - -// #if block helper -func ifHelper(conditional interface{}, options *Options) interface{} { - if options.isIncludableZero() || IsTrue(conditional) { - return options.Fn() - } - - return options.Inverse() -} - -// #unless block helper -func unlessHelper(conditional interface{}, options *Options) interface{} { - if options.isIncludableZero() || IsTrue(conditional) { - return options.Inverse() - } - - return options.Fn() -} - -// #with block helper -func withHelper(context interface{}, options *Options) interface{} { - if IsTrue(context) { - return options.FnWith(context) - } - - return options.Inverse() -} - -// #each block helper -func eachHelper(context interface{}, options *Options) interface{} { - if !IsTrue(context) { - return options.Inverse() - } - - result := "" - - val := reflect.ValueOf(context) - switch val.Kind() { - case reflect.Array, reflect.Slice: - for i := 0; i < val.Len(); i++ { - // computes private data - data := options.newIterDataFrame(val.Len(), i, nil) - - // evaluates block - result += options.evalBlock(val.Index(i).Interface(), data, i) - } - case reflect.Map: - // note: a go hash is not ordered, so result may vary, this behaviour differs from the JS implementation - keys := val.MapKeys() - for i := 0; i < len(keys); i++ { - key := keys[i].Interface() - ctx := val.MapIndex(keys[i]).Interface() - - // computes private data - data := options.newIterDataFrame(len(keys), i, key) - - // evaluates block - result += options.evalBlock(ctx, data, key) - } - case reflect.Struct: - var exportedFields []int - - // collect exported fields only - for i := 0; i < val.NumField(); i++ { - if tField := val.Type().Field(i); tField.PkgPath == "" { - exportedFields = append(exportedFields, i) - } - } - - for i, fieldIndex := range exportedFields { - key := val.Type().Field(fieldIndex).Name - ctx := val.Field(fieldIndex).Interface() - - // computes private data - data := options.newIterDataFrame(len(exportedFields), i, key) - - // evaluates block - result += options.evalBlock(ctx, data, key) - } - } - - return result -} - -// #log helper -func logHelper(message string) interface{} { - log.Print(message) - return "" -} - -// #lookup helper -func lookupHelper(obj interface{}, field string, options *Options) interface{} { - return Str(options.Eval(obj, field)) -} - -// #equal helper -// Ref: https://github.com/aymerick/raymond/issues/7 -func equalHelper(a interface{}, b interface{}, options *Options) interface{} { - if Str(a) == Str(b) { - return options.Fn() - } - - return "" -} diff --git a/vendor/github.com/aymerick/raymond/lexer/lexer.go b/vendor/github.com/aymerick/raymond/lexer/lexer.go deleted file mode 100644 index 48899f8..0000000 --- a/vendor/github.com/aymerick/raymond/lexer/lexer.go +++ /dev/null @@ -1,639 +0,0 @@ -// Package lexer provides a handlebars tokenizer. -package lexer - -import ( - "fmt" - "regexp" - "strings" - "unicode" - "unicode/utf8" -) - -// References: -// - https://github.com/wycats/handlebars.js/blob/master/src/handlebars.l -// - https://github.com/golang/go/blob/master/src/text/template/parse/lex.go - -const ( - // Mustaches detection - escapedEscapedOpenMustache = "\\\\{{" - escapedOpenMustache = "\\{{" - openMustache = "{{" - closeMustache = "}}" - closeStripMustache = "~}}" - closeUnescapedStripMustache = "}~}}" -) - -const eof = -1 - -// lexFunc represents a function that returns the next lexer function. -type lexFunc func(*Lexer) lexFunc - -// Lexer is a lexical analyzer. -type Lexer struct { - input string // input to scan - name string // lexer name, used for testing purpose - tokens chan Token // channel of scanned tokens - nextFunc lexFunc // the next function to execute - - pos int // current byte position in input string - line int // current line position in input string - width int // size of last rune scanned from input string - start int // start position of the token we are scanning - - // the shameful contextual properties needed because `nextFunc` is not enough - closeComment *regexp.Regexp // regexp to scan close of current comment - rawBlock bool // are we parsing a raw block content ? -} - -var ( - lookheadChars = `[\s` + regexp.QuoteMeta("=~}/)|") + `]` - literalLookheadChars = `[\s` + regexp.QuoteMeta("~})") + `]` - - // characters not allowed in an identifier - unallowedIDChars = " \n\t!\"#%&'()*+,./;<=>@[\\]^`{|}~" - - // regular expressions - rID = regexp.MustCompile(`^[^` + regexp.QuoteMeta(unallowedIDChars) + `]+`) - rDotID = regexp.MustCompile(`^\.` + lookheadChars) - rTrue = regexp.MustCompile(`^true` + literalLookheadChars) - rFalse = regexp.MustCompile(`^false` + literalLookheadChars) - rOpenRaw = regexp.MustCompile(`^\{\{\{\{`) - rCloseRaw = regexp.MustCompile(`^\}\}\}\}`) - rOpenEndRaw = regexp.MustCompile(`^\{\{\{\{/`) - rOpenEndRawLookAhead = regexp.MustCompile(`\{\{\{\{/`) - rOpenUnescaped = regexp.MustCompile(`^\{\{~?\{`) - rCloseUnescaped = regexp.MustCompile(`^\}~?\}\}`) - rOpenBlock = regexp.MustCompile(`^\{\{~?#`) - rOpenEndBlock = regexp.MustCompile(`^\{\{~?/`) - rOpenPartial = regexp.MustCompile(`^\{\{~?>`) - // {{^}} or {{else}} - rInverse = regexp.MustCompile(`^(\{\{~?\^\s*~?\}\}|\{\{~?\s*else\s*~?\}\})`) - rOpenInverse = regexp.MustCompile(`^\{\{~?\^`) - rOpenInverseChain = regexp.MustCompile(`^\{\{~?\s*else`) - // {{ or {{& - rOpen = regexp.MustCompile(`^\{\{~?&?`) - rClose = regexp.MustCompile(`^~?\}\}`) - rOpenBlockParams = regexp.MustCompile(`^as\s+\|`) - // {{!-- ... --}} - rOpenCommentDash = regexp.MustCompile(`^\{\{~?!--\s*`) - rCloseCommentDash = regexp.MustCompile(`^\s*--~?\}\}`) - // {{! ... }} - rOpenComment = regexp.MustCompile(`^\{\{~?!\s*`) - rCloseComment = regexp.MustCompile(`^\s*~?\}\}`) -) - -// Scan scans given input. -// -// Tokens can then be fetched sequentially thanks to NextToken() function on returned lexer. -func Scan(input string) *Lexer { - return scanWithName(input, "") -} - -// scanWithName scans given input, with a name used for testing -// -// Tokens can then be fetched sequentially thanks to NextToken() function on returned lexer. -func scanWithName(input string, name string) *Lexer { - result := &Lexer{ - input: input, - name: name, - tokens: make(chan Token), - line: 1, - } - - go result.run() - - return result -} - -// Collect scans and collect all tokens. -// -// This should be used for debugging purpose only. You should use Scan() and lexer.NextToken() functions instead. -func Collect(input string) []Token { - var result []Token - - l := Scan(input) - for { - token := l.NextToken() - result = append(result, token) - - if token.Kind == TokenEOF || token.Kind == TokenError { - break - } - } - - return result -} - -// NextToken returns the next scanned token. -func (l *Lexer) NextToken() Token { - result := <-l.tokens - - return result -} - -// run starts lexical analysis -func (l *Lexer) run() { - for l.nextFunc = lexContent; l.nextFunc != nil; { - l.nextFunc = l.nextFunc(l) - } -} - -// next returns next character from input, or eof of there is nothing left to scan -func (l *Lexer) next() rune { - if l.pos >= len(l.input) { - l.width = 0 - return eof - } - - r, w := utf8.DecodeRuneInString(l.input[l.pos:]) - l.width = w - l.pos += l.width - - return r -} - -func (l *Lexer) produce(kind TokenKind, val string) { - l.tokens <- Token{kind, val, l.start, l.line} - - // scanning a new token - l.start = l.pos - - // update line number - l.line += strings.Count(val, "\n") -} - -// emit emits a new scanned token -func (l *Lexer) emit(kind TokenKind) { - l.produce(kind, l.input[l.start:l.pos]) -} - -// emitContent emits scanned content -func (l *Lexer) emitContent() { - if l.pos > l.start { - l.emit(TokenContent) - } -} - -// emitString emits a scanned string -func (l *Lexer) emitString(delimiter rune) { - str := l.input[l.start:l.pos] - - // replace escaped delimiters - str = strings.Replace(str, "\\"+string(delimiter), string(delimiter), -1) - - l.produce(TokenString, str) -} - -// peek returns but does not consume the next character in the input -func (l *Lexer) peek() rune { - r := l.next() - l.backup() - return r -} - -// backup steps back one character -// -// WARNING: Can only be called once per call of next -func (l *Lexer) backup() { - l.pos -= l.width -} - -// ignoreskips all characters that have been scanned up to current position -func (l *Lexer) ignore() { - l.start = l.pos -} - -// accept scans the next character if it is included in given string -func (l *Lexer) accept(valid string) bool { - if strings.IndexRune(valid, l.next()) >= 0 { - return true - } - - l.backup() - - return false -} - -// acceptRun scans all following characters that are part of given string -func (l *Lexer) acceptRun(valid string) { - for strings.IndexRune(valid, l.next()) >= 0 { - } - - l.backup() -} - -// errorf emits an error token -func (l *Lexer) errorf(format string, args ...interface{}) lexFunc { - l.tokens <- Token{TokenError, fmt.Sprintf(format, args...), l.start, l.line} - return nil -} - -// isString returns true if content at current scanning position starts with given string -func (l *Lexer) isString(str string) bool { - return strings.HasPrefix(l.input[l.pos:], str) -} - -// findRegexp returns the first string from current scanning position that matches given regular expression -func (l *Lexer) findRegexp(r *regexp.Regexp) string { - return r.FindString(l.input[l.pos:]) -} - -// indexRegexp returns the index of the first string from current scanning position that matches given regular expression -// -// It returns -1 if not found -func (l *Lexer) indexRegexp(r *regexp.Regexp) int { - loc := r.FindStringIndex(l.input[l.pos:]) - if loc == nil { - return -1 - } - return loc[0] -} - -// lexContent scans content (ie: not between mustaches) -func lexContent(l *Lexer) lexFunc { - var next lexFunc - - if l.rawBlock { - if i := l.indexRegexp(rOpenEndRawLookAhead); i != -1 { - // {{{{/ - l.rawBlock = false - l.pos += i - - next = lexOpenMustache - } else { - return l.errorf("Unclosed raw block") - } - } else if l.isString(escapedEscapedOpenMustache) { - // \\{{ - - // emit content with only one escaped escape - l.next() - l.emitContent() - - // ignore second escaped escape - l.next() - l.ignore() - - next = lexContent - } else if l.isString(escapedOpenMustache) { - // \{{ - next = lexEscapedOpenMustache - } else if str := l.findRegexp(rOpenCommentDash); str != "" { - // {{!-- - l.closeComment = rCloseCommentDash - - next = lexComment - } else if str := l.findRegexp(rOpenComment); str != "" { - // {{! - l.closeComment = rCloseComment - - next = lexComment - } else if l.isString(openMustache) { - // {{ - next = lexOpenMustache - } - - if next != nil { - // emit scanned content - l.emitContent() - - // scan next token - return next - } - - // scan next rune - if l.next() == eof { - // emit scanned content - l.emitContent() - - // this is over - l.emit(TokenEOF) - return nil - } - - // continue content scanning - return lexContent -} - -// lexEscapedOpenMustache scans \{{ -func lexEscapedOpenMustache(l *Lexer) lexFunc { - // ignore escape character - l.next() - l.ignore() - - // scan mustaches - for l.peek() == '{' { - l.next() - } - - return lexContent -} - -// lexOpenMustache scans {{ -func lexOpenMustache(l *Lexer) lexFunc { - var str string - var tok TokenKind - - nextFunc := lexExpression - - if str = l.findRegexp(rOpenEndRaw); str != "" { - tok = TokenOpenEndRawBlock - } else if str = l.findRegexp(rOpenRaw); str != "" { - tok = TokenOpenRawBlock - l.rawBlock = true - } else if str = l.findRegexp(rOpenUnescaped); str != "" { - tok = TokenOpenUnescaped - } else if str = l.findRegexp(rOpenBlock); str != "" { - tok = TokenOpenBlock - } else if str = l.findRegexp(rOpenEndBlock); str != "" { - tok = TokenOpenEndBlock - } else if str = l.findRegexp(rOpenPartial); str != "" { - tok = TokenOpenPartial - } else if str = l.findRegexp(rInverse); str != "" { - tok = TokenInverse - nextFunc = lexContent - } else if str = l.findRegexp(rOpenInverse); str != "" { - tok = TokenOpenInverse - } else if str = l.findRegexp(rOpenInverseChain); str != "" { - tok = TokenOpenInverseChain - } else if str = l.findRegexp(rOpen); str != "" { - tok = TokenOpen - } else { - // this is rotten - panic("Current pos MUST be an opening mustache") - } - - l.pos += len(str) - l.emit(tok) - - return nextFunc -} - -// lexCloseMustache scans }} or ~}} -func lexCloseMustache(l *Lexer) lexFunc { - var str string - var tok TokenKind - - if str = l.findRegexp(rCloseRaw); str != "" { - // }}}} - tok = TokenCloseRawBlock - } else if str = l.findRegexp(rCloseUnescaped); str != "" { - // }}} - tok = TokenCloseUnescaped - } else if str = l.findRegexp(rClose); str != "" { - // }} - tok = TokenClose - } else { - // this is rotten - panic("Current pos MUST be a closing mustache") - } - - l.pos += len(str) - l.emit(tok) - - return lexContent -} - -// lexExpression scans inside mustaches -func lexExpression(l *Lexer) lexFunc { - // search close mustache delimiter - if l.isString(closeMustache) || l.isString(closeStripMustache) || l.isString(closeUnescapedStripMustache) { - return lexCloseMustache - } - - // search some patterns before advancing scanning position - - // "as |" - if str := l.findRegexp(rOpenBlockParams); str != "" { - l.pos += len(str) - l.emit(TokenOpenBlockParams) - return lexExpression - } - - // .. - if l.isString("..") { - l.pos += len("..") - l.emit(TokenID) - return lexExpression - } - - // . - if str := l.findRegexp(rDotID); str != "" { - l.pos += len(".") - l.emit(TokenID) - return lexExpression - } - - // true - if str := l.findRegexp(rTrue); str != "" { - l.pos += len("true") - l.emit(TokenBoolean) - return lexExpression - } - - // false - if str := l.findRegexp(rFalse); str != "" { - l.pos += len("false") - l.emit(TokenBoolean) - return lexExpression - } - - // let's scan next character - switch r := l.next(); { - case r == eof: - return l.errorf("Unclosed expression") - case isIgnorable(r): - return lexIgnorable - case r == '(': - l.emit(TokenOpenSexpr) - case r == ')': - l.emit(TokenCloseSexpr) - case r == '=': - l.emit(TokenEquals) - case r == '@': - l.emit(TokenData) - case r == '"' || r == '\'': - l.backup() - return lexString - case r == '/' || r == '.': - l.emit(TokenSep) - case r == '|': - l.emit(TokenCloseBlockParams) - case r == '+' || r == '-' || (r >= '0' && r <= '9'): - l.backup() - return lexNumber - case r == '[': - return lexPathLiteral - case strings.IndexRune(unallowedIDChars, r) < 0: - l.backup() - return lexIdentifier - default: - return l.errorf("Unexpected character in expression: '%c'", r) - } - - return lexExpression -} - -// lexComment scans {{!-- or {{! -func lexComment(l *Lexer) lexFunc { - if str := l.findRegexp(l.closeComment); str != "" { - l.pos += len(str) - l.emit(TokenComment) - - return lexContent - } - - if r := l.next(); r == eof { - return l.errorf("Unclosed comment") - } - - return lexComment -} - -// lexIgnorable scans all following ignorable characters -func lexIgnorable(l *Lexer) lexFunc { - for isIgnorable(l.peek()) { - l.next() - } - l.ignore() - - return lexExpression -} - -// lexString scans a string -func lexString(l *Lexer) lexFunc { - // get string delimiter - delim := l.next() - var prev rune - - // ignore delimiter - l.ignore() - - for { - r := l.next() - if r == eof || r == '\n' { - return l.errorf("Unterminated string") - } - - if (r == delim) && (prev != '\\') { - break - } - - prev = r - } - - // remove end delimiter - l.backup() - - // emit string - l.emitString(delim) - - // skip end delimiter - l.next() - l.ignore() - - return lexExpression -} - -// lexNumber scans a number: decimal, octal, hex, float, or imaginary. This -// isn't a perfect number scanner - for instance it accepts "." and "0x0.2" -// and "089" - but when it's wrong the input is invalid and the parser (via -// strconv) will notice. -// -// NOTE: borrowed from https://github.com/golang/go/tree/master/src/text/template/parse/lex.go -func lexNumber(l *Lexer) lexFunc { - if !l.scanNumber() { - return l.errorf("bad number syntax: %q", l.input[l.start:l.pos]) - } - if sign := l.peek(); sign == '+' || sign == '-' { - // Complex: 1+2i. No spaces, must end in 'i'. - if !l.scanNumber() || l.input[l.pos-1] != 'i' { - return l.errorf("bad number syntax: %q", l.input[l.start:l.pos]) - } - l.emit(TokenNumber) - } else { - l.emit(TokenNumber) - } - return lexExpression -} - -// scanNumber scans a number -// -// NOTE: borrowed from https://github.com/golang/go/tree/master/src/text/template/parse/lex.go -func (l *Lexer) scanNumber() bool { - // Optional leading sign. - l.accept("+-") - - // Is it hex? - digits := "0123456789" - - if l.accept("0") && l.accept("xX") { - digits = "0123456789abcdefABCDEF" - } - - l.acceptRun(digits) - - if l.accept(".") { - l.acceptRun(digits) - } - - if l.accept("eE") { - l.accept("+-") - l.acceptRun("0123456789") - } - - // Is it imaginary? - l.accept("i") - - // Next thing mustn't be alphanumeric. - if isAlphaNumeric(l.peek()) { - l.next() - return false - } - - return true -} - -// lexIdentifier scans an ID -func lexIdentifier(l *Lexer) lexFunc { - str := l.findRegexp(rID) - if len(str) == 0 { - // this is rotten - panic("Identifier expected") - } - - l.pos += len(str) - l.emit(TokenID) - - return lexExpression -} - -// lexPathLiteral scans an [ID] -func lexPathLiteral(l *Lexer) lexFunc { - for { - r := l.next() - if r == eof || r == '\n' { - return l.errorf("Unterminated path literal") - } - - if r == ']' { - break - } - } - - l.emit(TokenID) - - return lexExpression -} - -// isIgnorable returns true if given character is ignorable (ie. whitespace of line feed) -func isIgnorable(r rune) bool { - return r == ' ' || r == '\t' || r == '\n' -} - -// isAlphaNumeric reports whether r is an alphabetic, digit, or underscore. -// -// NOTE borrowed from https://github.com/golang/go/tree/master/src/text/template/parse/lex.go -func isAlphaNumeric(r rune) bool { - return r == '_' || unicode.IsLetter(r) || unicode.IsDigit(r) -} diff --git a/vendor/github.com/aymerick/raymond/lexer/token.go b/vendor/github.com/aymerick/raymond/lexer/token.go deleted file mode 100644 index 13cf2e6..0000000 --- a/vendor/github.com/aymerick/raymond/lexer/token.go +++ /dev/null @@ -1,183 +0,0 @@ -package lexer - -import "fmt" - -const ( - // TokenError represents an error - TokenError TokenKind = iota - - // TokenEOF represents an End Of File - TokenEOF - - // - // Mustache delimiters - // - - // TokenOpen is the OPEN token - TokenOpen - - // TokenClose is the CLOSE token - TokenClose - - // TokenOpenRawBlock is the OPEN_RAW_BLOCK token - TokenOpenRawBlock - - // TokenCloseRawBlock is the CLOSE_RAW_BLOCK token - TokenCloseRawBlock - - // TokenOpenEndRawBlock is the END_RAW_BLOCK token - TokenOpenEndRawBlock - - // TokenOpenUnescaped is the OPEN_UNESCAPED token - TokenOpenUnescaped - - // TokenCloseUnescaped is the CLOSE_UNESCAPED token - TokenCloseUnescaped - - // TokenOpenBlock is the OPEN_BLOCK token - TokenOpenBlock - - // TokenOpenEndBlock is the OPEN_ENDBLOCK token - TokenOpenEndBlock - - // TokenInverse is the INVERSE token - TokenInverse - - // TokenOpenInverse is the OPEN_INVERSE token - TokenOpenInverse - - // TokenOpenInverseChain is the OPEN_INVERSE_CHAIN token - TokenOpenInverseChain - - // TokenOpenPartial is the OPEN_PARTIAL token - TokenOpenPartial - - // TokenComment is the COMMENT token - TokenComment - - // - // Inside mustaches - // - - // TokenOpenSexpr is the OPEN_SEXPR token - TokenOpenSexpr - - // TokenCloseSexpr is the CLOSE_SEXPR token - TokenCloseSexpr - - // TokenEquals is the EQUALS token - TokenEquals - - // TokenData is the DATA token - TokenData - - // TokenSep is the SEP token - TokenSep - - // TokenOpenBlockParams is the OPEN_BLOCK_PARAMS token - TokenOpenBlockParams - - // TokenCloseBlockParams is the CLOSE_BLOCK_PARAMS token - TokenCloseBlockParams - - // - // Tokens with content - // - - // TokenContent is the CONTENT token - TokenContent - - // TokenID is the ID token - TokenID - - // TokenString is the STRING token - TokenString - - // TokenNumber is the NUMBER token - TokenNumber - - // TokenBoolean is the BOOLEAN token - TokenBoolean -) - -const ( - // Option to generate token position in its string representation - dumpTokenPos = false - - // Option to generate values for all token kinds for their string representations - dumpAllTokensVal = true -) - -// TokenKind represents a Token type. -type TokenKind int - -// Token represents a scanned token. -type Token struct { - Kind TokenKind // Token kind - Val string // Token value - - Pos int // Byte position in input string - Line int // Line number in input string -} - -// tokenName permits to display token name given token type -var tokenName = map[TokenKind]string{ - TokenError: "Error", - TokenEOF: "EOF", - TokenContent: "Content", - TokenComment: "Comment", - TokenOpen: "Open", - TokenClose: "Close", - TokenOpenUnescaped: "OpenUnescaped", - TokenCloseUnescaped: "CloseUnescaped", - TokenOpenBlock: "OpenBlock", - TokenOpenEndBlock: "OpenEndBlock", - TokenOpenRawBlock: "OpenRawBlock", - TokenCloseRawBlock: "CloseRawBlock", - TokenOpenEndRawBlock: "OpenEndRawBlock", - TokenOpenBlockParams: "OpenBlockParams", - TokenCloseBlockParams: "CloseBlockParams", - TokenInverse: "Inverse", - TokenOpenInverse: "OpenInverse", - TokenOpenInverseChain: "OpenInverseChain", - TokenOpenPartial: "OpenPartial", - TokenOpenSexpr: "OpenSexpr", - TokenCloseSexpr: "CloseSexpr", - TokenID: "ID", - TokenEquals: "Equals", - TokenString: "String", - TokenNumber: "Number", - TokenBoolean: "Boolean", - TokenData: "Data", - TokenSep: "Sep", -} - -// String returns the token kind string representation for debugging. -func (k TokenKind) String() string { - s := tokenName[k] - if s == "" { - return fmt.Sprintf("Token-%d", int(k)) - } - return s -} - -// String returns the token string representation for debugging. -func (t Token) String() string { - result := "" - - if dumpTokenPos { - result += fmt.Sprintf("%d:", t.Pos) - } - - result += fmt.Sprintf("%s", t.Kind) - - if (dumpAllTokensVal || (t.Kind >= TokenContent)) && len(t.Val) > 0 { - if len(t.Val) > 100 { - result += fmt.Sprintf("{%.20q...}", t.Val) - } else { - result += fmt.Sprintf("{%q}", t.Val) - } - } - - return result -} diff --git a/vendor/github.com/aymerick/raymond/parser/parser.go b/vendor/github.com/aymerick/raymond/parser/parser.go deleted file mode 100644 index 22eed3c..0000000 --- a/vendor/github.com/aymerick/raymond/parser/parser.go +++ /dev/null @@ -1,846 +0,0 @@ -// Package parser provides a handlebars syntax analyser. It consumes the tokens provided by the lexer to build an AST. -package parser - -import ( - "fmt" - "regexp" - "runtime" - "strconv" - - "github.com/aymerick/raymond/ast" - "github.com/aymerick/raymond/lexer" -) - -// References: -// - https://github.com/wycats/handlebars.js/blob/master/src/handlebars.yy -// - https://github.com/golang/go/blob/master/src/text/template/parse/parse.go - -// parser is a syntax analyzer. -type parser struct { - // Lexer - lex *lexer.Lexer - - // Root node - root ast.Node - - // Tokens parsed but not consumed yet - tokens []*lexer.Token - - // All tokens have been retreieved from lexer - lexOver bool -} - -var ( - rOpenComment = regexp.MustCompile(`^\{\{~?!-?-?`) - rCloseComment = regexp.MustCompile(`-?-?~?\}\}$`) - rOpenAmp = regexp.MustCompile(`^\{\{~?&`) -) - -// new instanciates a new parser -func new(input string) *parser { - return &parser{ - lex: lexer.Scan(input), - } -} - -// Parse analyzes given input and returns the AST root node. -func Parse(input string) (result *ast.Program, err error) { - // recover error - defer errRecover(&err) - - parser := new(input) - - // parse - result = parser.parseProgram() - - // check last token - token := parser.shift() - if token.Kind != lexer.TokenEOF { - // Parsing ended before EOF - errToken(token, "Syntax error") - } - - // fix whitespaces - processWhitespaces(result) - - // named returned values - return -} - -// errRecover recovers parsing panic -func errRecover(errp *error) { - e := recover() - if e != nil { - switch err := e.(type) { - case runtime.Error: - panic(e) - case error: - *errp = err - default: - panic(e) - } - } -} - -// errPanic panics -func errPanic(err error, line int) { - panic(fmt.Errorf("Parse error on line %d:\n%s", line, err)) -} - -// errNode panics with given node infos -func errNode(node ast.Node, msg string) { - errPanic(fmt.Errorf("%s\nNode: %s", msg, node), node.Location().Line) -} - -// errNode panics with given Token infos -func errToken(tok *lexer.Token, msg string) { - errPanic(fmt.Errorf("%s\nToken: %s", msg, tok), tok.Line) -} - -// errNode panics because of an unexpected Token kind -func errExpected(expect lexer.TokenKind, tok *lexer.Token) { - errPanic(fmt.Errorf("Expecting %s, got: '%s'", expect, tok), tok.Line) -} - -// program : statement* -func (p *parser) parseProgram() *ast.Program { - result := ast.NewProgram(p.next().Pos, p.next().Line) - - for p.isStatement() { - result.AddStatement(p.parseStatement()) - } - - return result -} - -// statement : mustache | block | rawBlock | partial | content | COMMENT -func (p *parser) parseStatement() ast.Node { - var result ast.Node - - tok := p.next() - - switch tok.Kind { - case lexer.TokenOpen, lexer.TokenOpenUnescaped: - // mustache - result = p.parseMustache() - case lexer.TokenOpenBlock: - // block - result = p.parseBlock() - case lexer.TokenOpenInverse: - // block - result = p.parseInverse() - case lexer.TokenOpenRawBlock: - // rawBlock - result = p.parseRawBlock() - case lexer.TokenOpenPartial: - // partial - result = p.parsePartial() - case lexer.TokenContent: - // content - result = p.parseContent() - case lexer.TokenComment: - // COMMENT - result = p.parseComment() - } - - return result -} - -// isStatement returns true if next token starts a statement -func (p *parser) isStatement() bool { - if !p.have(1) { - return false - } - - switch p.next().Kind { - case lexer.TokenOpen, lexer.TokenOpenUnescaped, lexer.TokenOpenBlock, - lexer.TokenOpenInverse, lexer.TokenOpenRawBlock, lexer.TokenOpenPartial, - lexer.TokenContent, lexer.TokenComment: - return true - } - - return false -} - -// content : CONTENT -func (p *parser) parseContent() *ast.ContentStatement { - // CONTENT - tok := p.shift() - if tok.Kind != lexer.TokenContent { - // @todo This check can be removed if content is optional in a raw block - errExpected(lexer.TokenContent, tok) - } - - return ast.NewContentStatement(tok.Pos, tok.Line, tok.Val) -} - -// COMMENT -func (p *parser) parseComment() *ast.CommentStatement { - // COMMENT - tok := p.shift() - - value := rOpenComment.ReplaceAllString(tok.Val, "") - value = rCloseComment.ReplaceAllString(value, "") - - result := ast.NewCommentStatement(tok.Pos, tok.Line, value) - result.Strip = ast.NewStripForStr(tok.Val) - - return result -} - -// param* hash? -func (p *parser) parseExpressionParamsHash() ([]ast.Node, *ast.Hash) { - var params []ast.Node - var hash *ast.Hash - - // params* - if p.isParam() { - params = p.parseParams() - } - - // hash? - if p.isHashSegment() { - hash = p.parseHash() - } - - return params, hash -} - -// helperName param* hash? -func (p *parser) parseExpression(tok *lexer.Token) *ast.Expression { - result := ast.NewExpression(tok.Pos, tok.Line) - - // helperName - result.Path = p.parseHelperName() - - // param* hash? - result.Params, result.Hash = p.parseExpressionParamsHash() - - return result -} - -// rawBlock : openRawBlock content endRawBlock -// openRawBlock : OPEN_RAW_BLOCK helperName param* hash? CLOSE_RAW_BLOCK -// endRawBlock : OPEN_END_RAW_BLOCK helperName CLOSE_RAW_BLOCK -func (p *parser) parseRawBlock() *ast.BlockStatement { - // OPEN_RAW_BLOCK - tok := p.shift() - - result := ast.NewBlockStatement(tok.Pos, tok.Line) - - // helperName param* hash? - result.Expression = p.parseExpression(tok) - - openName := result.Expression.Canonical() - - // CLOSE_RAW_BLOCK - tok = p.shift() - if tok.Kind != lexer.TokenCloseRawBlock { - errExpected(lexer.TokenCloseRawBlock, tok) - } - - // content - // @todo Is content mandatory in a raw block ? - content := p.parseContent() - - program := ast.NewProgram(tok.Pos, tok.Line) - program.AddStatement(content) - - result.Program = program - - // OPEN_END_RAW_BLOCK - tok = p.shift() - if tok.Kind != lexer.TokenOpenEndRawBlock { - // should never happen as it is caught by lexer - errExpected(lexer.TokenOpenEndRawBlock, tok) - } - - // helperName - endID := p.parseHelperName() - - closeName, ok := ast.HelperNameStr(endID) - if !ok { - errNode(endID, "Erroneous closing expression") - } - - if openName != closeName { - errNode(endID, fmt.Sprintf("%s doesn't match %s", openName, closeName)) - } - - // CLOSE_RAW_BLOCK - tok = p.shift() - if tok.Kind != lexer.TokenCloseRawBlock { - errExpected(lexer.TokenCloseRawBlock, tok) - } - - return result -} - -// block : openBlock program inverseChain? closeBlock -func (p *parser) parseBlock() *ast.BlockStatement { - // openBlock - result, blockParams := p.parseOpenBlock() - - // program - program := p.parseProgram() - program.BlockParams = blockParams - result.Program = program - - // inverseChain? - if p.isInverseChain() { - result.Inverse = p.parseInverseChain() - } - - // closeBlock - p.parseCloseBlock(result) - - setBlockInverseStrip(result) - - return result -} - -// setBlockInverseStrip is called when parsing `block` (openBlock | openInverse) and `inverseChain` -// -// TODO: This was totally cargo culted ! CHECK THAT ! -// -// cf. prepareBlock() in: -// https://github.com/wycats/handlebars.js/blob/master/lib/handlebars/compiler/helper.js -func setBlockInverseStrip(block *ast.BlockStatement) { - if block.Inverse == nil { - return - } - - if block.Inverse.Chained { - b, _ := block.Inverse.Body[0].(*ast.BlockStatement) - b.CloseStrip = block.CloseStrip - } - - block.InverseStrip = block.Inverse.Strip -} - -// block : openInverse program inverseAndProgram? closeBlock -func (p *parser) parseInverse() *ast.BlockStatement { - // openInverse - result, blockParams := p.parseOpenBlock() - - // program - program := p.parseProgram() - - program.BlockParams = blockParams - result.Inverse = program - - // inverseAndProgram? - if p.isInverse() { - result.Program = p.parseInverseAndProgram() - } - - // closeBlock - p.parseCloseBlock(result) - - setBlockInverseStrip(result) - - return result -} - -// helperName param* hash? blockParams? -func (p *parser) parseOpenBlockExpression(tok *lexer.Token) (*ast.BlockStatement, []string) { - var blockParams []string - - result := ast.NewBlockStatement(tok.Pos, tok.Line) - - // helperName param* hash? - result.Expression = p.parseExpression(tok) - - // blockParams? - if p.isBlockParams() { - blockParams = p.parseBlockParams() - } - - // named returned values - return result, blockParams -} - -// inverseChain : openInverseChain program inverseChain? -// | inverseAndProgram -func (p *parser) parseInverseChain() *ast.Program { - if p.isInverse() { - // inverseAndProgram - return p.parseInverseAndProgram() - } - - result := ast.NewProgram(p.next().Pos, p.next().Line) - - // openInverseChain - block, blockParams := p.parseOpenBlock() - - // program - program := p.parseProgram() - - program.BlockParams = blockParams - block.Program = program - - // inverseChain? - if p.isInverseChain() { - block.Inverse = p.parseInverseChain() - } - - setBlockInverseStrip(block) - - result.Chained = true - result.AddStatement(block) - - return result -} - -// Returns true if current token starts an inverse chain -func (p *parser) isInverseChain() bool { - return p.isOpenInverseChain() || p.isInverse() -} - -// inverseAndProgram : INVERSE program -func (p *parser) parseInverseAndProgram() *ast.Program { - // INVERSE - tok := p.shift() - - // program - result := p.parseProgram() - result.Strip = ast.NewStripForStr(tok.Val) - - return result -} - -// openBlock : OPEN_BLOCK helperName param* hash? blockParams? CLOSE -// openInverse : OPEN_INVERSE helperName param* hash? blockParams? CLOSE -// openInverseChain: OPEN_INVERSE_CHAIN helperName param* hash? blockParams? CLOSE -func (p *parser) parseOpenBlock() (*ast.BlockStatement, []string) { - // OPEN_BLOCK | OPEN_INVERSE | OPEN_INVERSE_CHAIN - tok := p.shift() - - // helperName param* hash? blockParams? - result, blockParams := p.parseOpenBlockExpression(tok) - - // CLOSE - tokClose := p.shift() - if tokClose.Kind != lexer.TokenClose { - errExpected(lexer.TokenClose, tokClose) - } - - result.OpenStrip = ast.NewStrip(tok.Val, tokClose.Val) - - // named returned values - return result, blockParams -} - -// closeBlock : OPEN_ENDBLOCK helperName CLOSE -func (p *parser) parseCloseBlock(block *ast.BlockStatement) { - // OPEN_ENDBLOCK - tok := p.shift() - if tok.Kind != lexer.TokenOpenEndBlock { - errExpected(lexer.TokenOpenEndBlock, tok) - } - - // helperName - endID := p.parseHelperName() - - closeName, ok := ast.HelperNameStr(endID) - if !ok { - errNode(endID, "Erroneous closing expression") - } - - openName := block.Expression.Canonical() - if openName != closeName { - errNode(endID, fmt.Sprintf("%s doesn't match %s", openName, closeName)) - } - - // CLOSE - tokClose := p.shift() - if tokClose.Kind != lexer.TokenClose { - errExpected(lexer.TokenClose, tokClose) - } - - block.CloseStrip = ast.NewStrip(tok.Val, tokClose.Val) -} - -// mustache : OPEN helperName param* hash? CLOSE -// | OPEN_UNESCAPED helperName param* hash? CLOSE_UNESCAPED -func (p *parser) parseMustache() *ast.MustacheStatement { - // OPEN | OPEN_UNESCAPED - tok := p.shift() - - closeToken := lexer.TokenClose - if tok.Kind == lexer.TokenOpenUnescaped { - closeToken = lexer.TokenCloseUnescaped - } - - unescaped := false - if (tok.Kind == lexer.TokenOpenUnescaped) || (rOpenAmp.MatchString(tok.Val)) { - unescaped = true - } - - result := ast.NewMustacheStatement(tok.Pos, tok.Line, unescaped) - - // helperName param* hash? - result.Expression = p.parseExpression(tok) - - // CLOSE | CLOSE_UNESCAPED - tokClose := p.shift() - if tokClose.Kind != closeToken { - errExpected(closeToken, tokClose) - } - - result.Strip = ast.NewStrip(tok.Val, tokClose.Val) - - return result -} - -// partial : OPEN_PARTIAL partialName param* hash? CLOSE -func (p *parser) parsePartial() *ast.PartialStatement { - // OPEN_PARTIAL - tok := p.shift() - - result := ast.NewPartialStatement(tok.Pos, tok.Line) - - // partialName - result.Name = p.parsePartialName() - - // param* hash? - result.Params, result.Hash = p.parseExpressionParamsHash() - - // CLOSE - tokClose := p.shift() - if tokClose.Kind != lexer.TokenClose { - errExpected(lexer.TokenClose, tokClose) - } - - result.Strip = ast.NewStrip(tok.Val, tokClose.Val) - - return result -} - -// helperName | sexpr -func (p *parser) parseHelperNameOrSexpr() ast.Node { - if p.isSexpr() { - // sexpr - return p.parseSexpr() - } - - // helperName - return p.parseHelperName() -} - -// param : helperName | sexpr -func (p *parser) parseParam() ast.Node { - return p.parseHelperNameOrSexpr() -} - -// Returns true if next tokens represent a `param` -func (p *parser) isParam() bool { - return (p.isSexpr() || p.isHelperName()) && !p.isHashSegment() -} - -// param* -func (p *parser) parseParams() []ast.Node { - var result []ast.Node - - for p.isParam() { - result = append(result, p.parseParam()) - } - - return result -} - -// sexpr : OPEN_SEXPR helperName param* hash? CLOSE_SEXPR -func (p *parser) parseSexpr() *ast.SubExpression { - // OPEN_SEXPR - tok := p.shift() - - result := ast.NewSubExpression(tok.Pos, tok.Line) - - // helperName param* hash? - result.Expression = p.parseExpression(tok) - - // CLOSE_SEXPR - tok = p.shift() - if tok.Kind != lexer.TokenCloseSexpr { - errExpected(lexer.TokenCloseSexpr, tok) - } - - return result -} - -// hash : hashSegment+ -func (p *parser) parseHash() *ast.Hash { - var pairs []*ast.HashPair - - for p.isHashSegment() { - pairs = append(pairs, p.parseHashSegment()) - } - - firstLoc := pairs[0].Location() - - result := ast.NewHash(firstLoc.Pos, firstLoc.Line) - result.Pairs = pairs - - return result -} - -// returns true if next tokens represents a `hashSegment` -func (p *parser) isHashSegment() bool { - return p.have(2) && (p.next().Kind == lexer.TokenID) && (p.nextAt(1).Kind == lexer.TokenEquals) -} - -// hashSegment : ID EQUALS param -func (p *parser) parseHashSegment() *ast.HashPair { - // ID - tok := p.shift() - - // EQUALS - p.shift() - - // param - param := p.parseParam() - - result := ast.NewHashPair(tok.Pos, tok.Line) - result.Key = tok.Val - result.Val = param - - return result -} - -// blockParams : OPEN_BLOCK_PARAMS ID+ CLOSE_BLOCK_PARAMS -func (p *parser) parseBlockParams() []string { - var result []string - - // OPEN_BLOCK_PARAMS - tok := p.shift() - - // ID+ - for p.isID() { - result = append(result, p.shift().Val) - } - - if len(result) == 0 { - errExpected(lexer.TokenID, p.next()) - } - - // CLOSE_BLOCK_PARAMS - tok = p.shift() - if tok.Kind != lexer.TokenCloseBlockParams { - errExpected(lexer.TokenCloseBlockParams, tok) - } - - return result -} - -// helperName : path | dataName | STRING | NUMBER | BOOLEAN | UNDEFINED | NULL -func (p *parser) parseHelperName() ast.Node { - var result ast.Node - - tok := p.next() - - switch tok.Kind { - case lexer.TokenBoolean: - // BOOLEAN - p.shift() - result = ast.NewBooleanLiteral(tok.Pos, tok.Line, (tok.Val == "true"), tok.Val) - case lexer.TokenNumber: - // NUMBER - p.shift() - - val, isInt := parseNumber(tok) - result = ast.NewNumberLiteral(tok.Pos, tok.Line, val, isInt, tok.Val) - case lexer.TokenString: - // STRING - p.shift() - result = ast.NewStringLiteral(tok.Pos, tok.Line, tok.Val) - case lexer.TokenData: - // dataName - result = p.parseDataName() - default: - // path - result = p.parsePath(false) - } - - return result -} - -// parseNumber parses a number -func parseNumber(tok *lexer.Token) (result float64, isInt bool) { - var valInt int - var err error - - valInt, err = strconv.Atoi(tok.Val) - if err == nil { - isInt = true - - result = float64(valInt) - } else { - isInt = false - - result, err = strconv.ParseFloat(tok.Val, 64) - if err != nil { - errToken(tok, fmt.Sprintf("Failed to parse number: %s", tok.Val)) - } - } - - // named returned values - return -} - -// Returns true if next tokens represent a `helperName` -func (p *parser) isHelperName() bool { - switch p.next().Kind { - case lexer.TokenBoolean, lexer.TokenNumber, lexer.TokenString, lexer.TokenData, lexer.TokenID: - return true - } - - return false -} - -// partialName : helperName | sexpr -func (p *parser) parsePartialName() ast.Node { - return p.parseHelperNameOrSexpr() -} - -// dataName : DATA pathSegments -func (p *parser) parseDataName() *ast.PathExpression { - // DATA - p.shift() - - // pathSegments - return p.parsePath(true) -} - -// path : pathSegments -// pathSegments : pathSegments SEP ID -// | ID -func (p *parser) parsePath(data bool) *ast.PathExpression { - var tok *lexer.Token - - // ID - tok = p.shift() - if tok.Kind != lexer.TokenID { - errExpected(lexer.TokenID, tok) - } - - result := ast.NewPathExpression(tok.Pos, tok.Line, data) - result.Part(tok.Val) - - for p.isPathSep() { - // SEP - tok = p.shift() - result.Sep(tok.Val) - - // ID - tok = p.shift() - if tok.Kind != lexer.TokenID { - errExpected(lexer.TokenID, tok) - } - - result.Part(tok.Val) - - if len(result.Parts) > 0 { - switch tok.Val { - case "..", ".", "this": - errToken(tok, "Invalid path: "+result.Original) - } - } - } - - return result -} - -// Ensures there is token to parse at given index -func (p *parser) ensure(index int) { - if p.lexOver { - // nothing more to grab - return - } - - nb := index + 1 - - for len(p.tokens) < nb { - // fetch next token - tok := p.lex.NextToken() - - // queue it - p.tokens = append(p.tokens, &tok) - - if (tok.Kind == lexer.TokenEOF) || (tok.Kind == lexer.TokenError) { - p.lexOver = true - break - } - } -} - -// have returns true is there are a list given number of tokens to consume left -func (p *parser) have(nb int) bool { - p.ensure(nb - 1) - - return len(p.tokens) >= nb -} - -// nextAt returns next token at given index, without consuming it -func (p *parser) nextAt(index int) *lexer.Token { - p.ensure(index) - - return p.tokens[index] -} - -// next returns next token without consuming it -func (p *parser) next() *lexer.Token { - return p.nextAt(0) -} - -// shift returns next token and remove it from the tokens buffer -// -// Panics if next token is `TokenError` -func (p *parser) shift() *lexer.Token { - var result *lexer.Token - - p.ensure(0) - - result, p.tokens = p.tokens[0], p.tokens[1:] - - // check error token - if result.Kind == lexer.TokenError { - errToken(result, "Lexer error") - } - - return result -} - -// isToken returns true if next token is of given type -func (p *parser) isToken(kind lexer.TokenKind) bool { - return p.have(1) && p.next().Kind == kind -} - -// isSexpr returns true if next token starts a sexpr -func (p *parser) isSexpr() bool { - return p.isToken(lexer.TokenOpenSexpr) -} - -// isPathSep returns true if next token is a path separator -func (p *parser) isPathSep() bool { - return p.isToken(lexer.TokenSep) -} - -// isID returns true if next token is an ID -func (p *parser) isID() bool { - return p.isToken(lexer.TokenID) -} - -// isBlockParams returns true if next token starts a block params -func (p *parser) isBlockParams() bool { - return p.isToken(lexer.TokenOpenBlockParams) -} - -// isInverse returns true if next token starts an INVERSE sequence -func (p *parser) isInverse() bool { - return p.isToken(lexer.TokenInverse) -} - -// isOpenInverseChain returns true if next token is OPEN_INVERSE_CHAIN -func (p *parser) isOpenInverseChain() bool { - return p.isToken(lexer.TokenOpenInverseChain) -} diff --git a/vendor/github.com/aymerick/raymond/parser/whitespace.go b/vendor/github.com/aymerick/raymond/parser/whitespace.go deleted file mode 100644 index 8f8c2c4..0000000 --- a/vendor/github.com/aymerick/raymond/parser/whitespace.go +++ /dev/null @@ -1,360 +0,0 @@ -package parser - -import ( - "regexp" - - "github.com/aymerick/raymond/ast" -) - -// whitespaceVisitor walks through the AST to perform whitespace control -// -// The logic was shamelessly borrowed from: -// https://github.com/wycats/handlebars.js/blob/master/lib/handlebars/compiler/whitespace-control.js -type whitespaceVisitor struct { - isRootSeen bool -} - -var ( - rTrimLeft = regexp.MustCompile(`^[ \t]*\r?\n?`) - rTrimLeftMultiple = regexp.MustCompile(`^\s+`) - - rTrimRight = regexp.MustCompile(`[ \t]+$`) - rTrimRightMultiple = regexp.MustCompile(`\s+$`) - - rPrevWhitespace = regexp.MustCompile(`\r?\n\s*?$`) - rPrevWhitespaceStart = regexp.MustCompile(`(^|\r?\n)\s*?$`) - - rNextWhitespace = regexp.MustCompile(`^\s*?\r?\n`) - rNextWhitespaceEnd = regexp.MustCompile(`^\s*?(\r?\n|$)`) - - rPartialIndent = regexp.MustCompile(`([ \t]+$)`) -) - -// newWhitespaceVisitor instanciates a new whitespaceVisitor -func newWhitespaceVisitor() *whitespaceVisitor { - return &whitespaceVisitor{} -} - -// processWhitespaces performs whitespace control on given AST -// -// WARNING: It must be called only once on AST. -func processWhitespaces(node ast.Node) { - node.Accept(newWhitespaceVisitor()) -} - -func omitRightFirst(body []ast.Node, multiple bool) { - omitRight(body, -1, multiple) -} - -func omitRight(body []ast.Node, i int, multiple bool) { - if i+1 >= len(body) { - return - } - - current := body[i+1] - - node, ok := current.(*ast.ContentStatement) - if !ok { - return - } - - if !multiple && node.RightStripped { - return - } - - original := node.Value - - r := rTrimLeft - if multiple { - r = rTrimLeftMultiple - } - - node.Value = r.ReplaceAllString(node.Value, "") - - node.RightStripped = (original != node.Value) -} - -func omitLeftLast(body []ast.Node, multiple bool) { - omitLeft(body, len(body), multiple) -} - -func omitLeft(body []ast.Node, i int, multiple bool) bool { - if i-1 < 0 { - return false - } - - current := body[i-1] - - node, ok := current.(*ast.ContentStatement) - if !ok { - return false - } - - if !multiple && node.LeftStripped { - return false - } - - original := node.Value - - r := rTrimRight - if multiple { - r = rTrimRightMultiple - } - - node.Value = r.ReplaceAllString(node.Value, "") - - node.LeftStripped = (original != node.Value) - - return node.LeftStripped -} - -func isPrevWhitespace(body []ast.Node) bool { - return isPrevWhitespaceProgram(body, len(body), false) -} - -func isPrevWhitespaceProgram(body []ast.Node, i int, isRoot bool) bool { - if i < 1 { - return isRoot - } - - prev := body[i-1] - - if node, ok := prev.(*ast.ContentStatement); ok { - if (node.Value == "") && node.RightStripped { - // already stripped, so it may be an empty string not catched by regexp - return true - } - - r := rPrevWhitespaceStart - if (i > 1) || !isRoot { - r = rPrevWhitespace - } - - return r.MatchString(node.Value) - } - - return false -} - -func isNextWhitespace(body []ast.Node) bool { - return isNextWhitespaceProgram(body, -1, false) -} - -func isNextWhitespaceProgram(body []ast.Node, i int, isRoot bool) bool { - if i+1 >= len(body) { - return isRoot - } - - next := body[i+1] - - if node, ok := next.(*ast.ContentStatement); ok { - if (node.Value == "") && node.LeftStripped { - // already stripped, so it may be an empty string not catched by regexp - return true - } - - r := rNextWhitespaceEnd - if (i+2 > len(body)) || !isRoot { - r = rNextWhitespace - } - - return r.MatchString(node.Value) - } - - return false -} - -// -// Visitor interface -// - -func (v *whitespaceVisitor) VisitProgram(program *ast.Program) interface{} { - isRoot := !v.isRootSeen - v.isRootSeen = true - - body := program.Body - for i, current := range body { - strip, _ := current.Accept(v).(*ast.Strip) - if strip == nil { - continue - } - - _isPrevWhitespace := isPrevWhitespaceProgram(body, i, isRoot) - _isNextWhitespace := isNextWhitespaceProgram(body, i, isRoot) - - openStandalone := strip.OpenStandalone && _isPrevWhitespace - closeStandalone := strip.CloseStandalone && _isNextWhitespace - inlineStandalone := strip.InlineStandalone && _isPrevWhitespace && _isNextWhitespace - - if strip.Close { - omitRight(body, i, true) - } - - if strip.Open && (i > 0) { - omitLeft(body, i, true) - } - - if inlineStandalone { - omitRight(body, i, false) - - if omitLeft(body, i, false) { - // If we are on a standalone node, save the indent info for partials - if partial, ok := current.(*ast.PartialStatement); ok { - // Pull out the whitespace from the final line - if i > 0 { - if prevContent, ok := body[i-1].(*ast.ContentStatement); ok { - partial.Indent = rPartialIndent.FindString(prevContent.Original) - } - } - } - } - } - - if b, ok := current.(*ast.BlockStatement); ok { - if openStandalone { - prog := b.Program - if prog == nil { - prog = b.Inverse - } - - omitRightFirst(prog.Body, false) - - // Strip out the previous content node if it's whitespace only - omitLeft(body, i, false) - } - - if closeStandalone { - prog := b.Inverse - if prog == nil { - prog = b.Program - } - - // Always strip the next node - omitRight(body, i, false) - - omitLeftLast(prog.Body, false) - } - - } - } - - return nil -} - -func (v *whitespaceVisitor) VisitBlock(block *ast.BlockStatement) interface{} { - if block.Program != nil { - block.Program.Accept(v) - } - - if block.Inverse != nil { - block.Inverse.Accept(v) - } - - program := block.Program - inverse := block.Inverse - - if program == nil { - program = inverse - inverse = nil - } - - firstInverse := inverse - lastInverse := inverse - - if (inverse != nil) && inverse.Chained { - b, _ := inverse.Body[0].(*ast.BlockStatement) - firstInverse = b.Program - - for lastInverse.Chained { - b, _ := lastInverse.Body[len(lastInverse.Body)-1].(*ast.BlockStatement) - lastInverse = b.Program - } - } - - closeProg := firstInverse - if closeProg == nil { - closeProg = program - } - - strip := &ast.Strip{ - Open: (block.OpenStrip != nil) && block.OpenStrip.Open, - Close: (block.CloseStrip != nil) && block.CloseStrip.Close, - - OpenStandalone: isNextWhitespace(program.Body), - CloseStandalone: isPrevWhitespace(closeProg.Body), - } - - if (block.OpenStrip != nil) && block.OpenStrip.Close { - omitRightFirst(program.Body, true) - } - - if inverse != nil { - if block.InverseStrip != nil { - inverseStrip := block.InverseStrip - - if inverseStrip.Open { - omitLeftLast(program.Body, true) - } - - if inverseStrip.Close { - omitRightFirst(firstInverse.Body, true) - } - } - - if (block.CloseStrip != nil) && block.CloseStrip.Open { - omitLeftLast(lastInverse.Body, true) - } - - // Find standalone else statements - if isPrevWhitespace(program.Body) && isNextWhitespace(firstInverse.Body) { - omitLeftLast(program.Body, false) - - omitRightFirst(firstInverse.Body, false) - } - } else if (block.CloseStrip != nil) && block.CloseStrip.Open { - omitLeftLast(program.Body, true) - } - - return strip -} - -func (v *whitespaceVisitor) VisitMustache(mustache *ast.MustacheStatement) interface{} { - return mustache.Strip -} - -func _inlineStandalone(strip *ast.Strip) interface{} { - return &ast.Strip{ - Open: strip.Open, - Close: strip.Close, - InlineStandalone: true, - } -} - -func (v *whitespaceVisitor) VisitPartial(node *ast.PartialStatement) interface{} { - strip := node.Strip - if strip == nil { - strip = &ast.Strip{} - } - - return _inlineStandalone(strip) -} - -func (v *whitespaceVisitor) VisitComment(node *ast.CommentStatement) interface{} { - strip := node.Strip - if strip == nil { - strip = &ast.Strip{} - } - - return _inlineStandalone(strip) -} - -// NOOP -func (v *whitespaceVisitor) VisitContent(node *ast.ContentStatement) interface{} { return nil } -func (v *whitespaceVisitor) VisitExpression(node *ast.Expression) interface{} { return nil } -func (v *whitespaceVisitor) VisitSubExpression(node *ast.SubExpression) interface{} { return nil } -func (v *whitespaceVisitor) VisitPath(node *ast.PathExpression) interface{} { return nil } -func (v *whitespaceVisitor) VisitString(node *ast.StringLiteral) interface{} { return nil } -func (v *whitespaceVisitor) VisitBoolean(node *ast.BooleanLiteral) interface{} { return nil } -func (v *whitespaceVisitor) VisitNumber(node *ast.NumberLiteral) interface{} { return nil } -func (v *whitespaceVisitor) VisitHash(node *ast.Hash) interface{} { return nil } -func (v *whitespaceVisitor) VisitHashPair(node *ast.HashPair) interface{} { return nil } diff --git a/vendor/github.com/aymerick/raymond/partial.go b/vendor/github.com/aymerick/raymond/partial.go deleted file mode 100644 index 3299d02..0000000 --- a/vendor/github.com/aymerick/raymond/partial.go +++ /dev/null @@ -1,85 +0,0 @@ -package raymond - -import ( - "fmt" - "sync" -) - -// partial represents a partial template -type partial struct { - name string - source string - tpl *Template -} - -// partials stores all global partials -var partials map[string]*partial - -// protects global partials -var partialsMutex sync.RWMutex - -func init() { - partials = make(map[string]*partial) -} - -// newPartial instanciates a new partial -func newPartial(name string, source string, tpl *Template) *partial { - return &partial{ - name: name, - source: source, - tpl: tpl, - } -} - -// RegisterPartial registers a global partial. That partial will be available to all templates. -func RegisterPartial(name string, source string) { - partialsMutex.Lock() - defer partialsMutex.Unlock() - - if partials[name] != nil { - panic(fmt.Errorf("Partial already registered: %s", name)) - } - - partials[name] = newPartial(name, source, nil) -} - -// RegisterPartials registers several global partials. Those partials will be available to all templates. -func RegisterPartials(partials map[string]string) { - for name, p := range partials { - RegisterPartial(name, p) - } -} - -// RegisterPartialTemplate registers a global partial with given parsed template. That partial will be available to all templates. -func RegisterPartialTemplate(name string, tpl *Template) { - partialsMutex.Lock() - defer partialsMutex.Unlock() - - if partials[name] != nil { - panic(fmt.Errorf("Partial already registered: %s", name)) - } - - partials[name] = newPartial(name, "", tpl) -} - -// findPartial finds a registered global partial -func findPartial(name string) *partial { - partialsMutex.RLock() - defer partialsMutex.RUnlock() - - return partials[name] -} - -// template returns parsed partial template -func (p *partial) template() (*Template, error) { - if p.tpl == nil { - var err error - - p.tpl, err = Parse(p.source) - if err != nil { - return nil, err - } - } - - return p.tpl, nil -} diff --git a/vendor/github.com/aymerick/raymond/raymond.go b/vendor/github.com/aymerick/raymond/raymond.go deleted file mode 100644 index c6df6b3..0000000 --- a/vendor/github.com/aymerick/raymond/raymond.go +++ /dev/null @@ -1,28 +0,0 @@ -// Package raymond provides handlebars evaluation -package raymond - -// Render parses a template and evaluates it with given context -// -// Note that this function call is not optimal as your template is parsed everytime you call it. You should use Parse() function instead. -func Render(source string, ctx interface{}) (string, error) { - // parse template - tpl, err := Parse(source) - if err != nil { - return "", err - } - - // renders template - str, err := tpl.Exec(ctx) - if err != nil { - return "", err - } - - return str, nil -} - -// MustRender parses a template and evaluates it with given context. It panics on error. -// -// Note that this function call is not optimal as your template is parsed everytime you call it. You should use Parse() function instead. -func MustRender(source string, ctx interface{}) string { - return MustParse(source).MustExec(ctx) -} diff --git a/vendor/github.com/aymerick/raymond/raymond.png b/vendor/github.com/aymerick/raymond/raymond.png deleted file mode 100644 index 6a7c942e57561ce3462447a74560c48bdbb3fe10..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13661 zcmZ|019T_Bvp*Uen`~^`++brH-{2eD#>U#%`Nqb^cCxW;+qSK@zkBby|M%WGZ_erI z?&?ofb=CBl>Y1qtS5lBfM!-V=0|P^rmJ(C>S1bLez`^`G$DrL-{;QzOh2@38z-nU= z-wmPv^+}ASROG?HJgLCI{DZ*2UjLE&kHNrPS-`+f4Zy&7Q^CNn9Wq;$`Tq^TJ4gYY z!N3r||EGY1rDx)Rfq^er0yJGT<>h#d?QNM1P3(TMTK*}>EL2%Z%6VUxrRpet}Z{x$o`|~e~Gm!Z|Bh0K! zEX@Ba`yVU+f2h2o_O=dArq0g)^n{-4*JERCh@Tuhz*Df=I8w*S%g|Bv_|S^UiZG5r7Gi2wHTe^LLrSpb2b`F}5& z00P9a|GyQ&b}KC=3~&c;%z{rPSa2;-bXBXauTGc8lg`Ht2ogGP14ePb4=j^X#MBC! zlQ+G@KfeqpoVWLfJp268dymJyQpoIwfwhT3ZVE($g6*e5vJmzUdbGu|d^}0pY%4qa zIQq3DH>C+7Jd8QlxZ!n{?L6f>#mMk-#nee0KY<=!KJb0)_DKKeP5pl0-JgC^NJ^$$ zR^1|+@)L}cSNvUzXepfXp{SF&o+E3If8gW0@9--AZ6ze-4Jyy><=7VS26Hp8@U+vT zc!E#1-FfHJJDB^b-}A0jYgX0&uQh|)=ZJGD3LjqQdYwoL_$nodMOILj#8_U)r^mbU znns-Lc54AOfhd<>vL-20BT-6G_M?uAc}ZOc?Q5ZaUG^hF3!{_r1$=hmm~rRbR`@VC zaeyq^Q!24@`g(aq+=BpEhu)t@r*Mc2va;dY;c#ePQff$6_uZUb+nZ$)Mb-RwS$rD& zTO)}62qk?``cl^}$phESyFhb~hmJas=Q84*o7CxsWFlj88@1hZnJV{hrLX8RtuLI= zrx3vrL3xNT`1Dj;1jI6M3lhB>e5vQh?>$-=G%5cG8X9sndlk}7YLP7xMEyfj{Cmo zN>z*J#0$LXy?0x)vuqwlyJ$f=1BSB^5)(=;9J6Wnl}@JUZ|utlb@Sj$)4g{6q25F4 zL^Su~U0J@z1XGGqRtLMEv6M)&Y*xLVfui6MoiW)kNJ*+T;SshjF|OelIMM`iHSOhi zLbAQ-546CjeV-s#DP2l*dZWBEqM(fxRUe0!POS&JaR(G*`jUz*M98C)N7? z04r-43;$3@&wZce<)O+m?ymo!9l7!WMu>`{TUmW8&eN-CA{wdEp)XW}jMuGKI9%nW zz>p1_-n`9~!gkWI;=sUduZNHaDkSgR`wW`#sCSV2&Sv>neZg6^56xHnK54iS8d!?$ zuJpwT&@nkAFfV>nkv!B+LwlC9)+}5!=@&_$?;0{3g4lni&#aP1+~) zvm{tzMwpqgUBZ@kS#1Kv%U#Lp^Mfhe?|{8XIrFr3lPJ8m$W^)3kct1(Ta$giB>MNa zMp1Odeu}|$O1G;-ANDYg?1IfFG}?`KRuKDC9%0|Kv{sN9VPp$zY1w@y>`K&%70di{ ziT3zsvW}7Z$ zJMkP#Lj_dIh_x$hTq!BKsz9D5=eClZl($!^n`+PE=h3^n#Nj}39keKC-zd*rtws{Z zD);`nk26I4Kh>E`lrSA9+6sCQqiZ1Dli=Q1naYk)#TIBfdLji~7fm{oTz;$rMEsH5&Bua5&IDCdxdVWz>Rkw1! zzYjeCeQyRz$4(lH?|r&Is-1;{F%&khp8)0GjY;NYJ(6V^_fJIB%OA*DbpQ5yEd&zQ zKT-`J*PJ2fkRUZX_t~x7<^+LE?zo&RTlk^ft~jmb$AaNuw*JpC zRB6#Ipc596v^J76B^Jm#j|A;oO1GT$B7nLQxsm1?A}m6h4CPFsH-6M;kp(Tn1XX;e zC40YKe8fzbmL(Q9uEU&xQ8CKI#ORC2vD&9AQQ*s!mb3emri=|e@Foo{%`q#Jj$TTx zg)d^@d@WkeyJA$jq@h9}6EDE(sMHqfjn~lad+%fAXVgpsi!MuU?#ryTUS0)$uxl(q z{P4rkp64`-`wrORJJ__rhw61OCykT!iP?qe3 zbQpYEmb47(m55I#g*p3h56?)?=H5WfIUa5bHgzPM>vQh2zK>9QbEkF?JX-=!H2~wj z(0I{H>-U=qAT7+>598t;B|i&NCy}1%wbEiz{3+3sq2=ROAZFYXWng=Ou%6n-3$}V! z`#MO47_P47=6s0Q#Daa+?~oVR%s@)`fL7Ym6-(+gPdONp+?t-+(71^Ih@3<~3-LF& zSL%lnO~N-d$Pj^iUop1Q_N|}Jry#~b5S-nv=dXq@&M_+n^m(K81 z79ApW_@ozXr?qX*yf%af9!V6L<5zYQT=mJM6uY=2+eQ`pwpoO0#%Na+RoIN*p*Ruw zrMUTNacVfpF2V-zWk~eUeY@A36=yOimHa8=!}BhyH4a$oas@iL=|L0LRtLk+4g9Q` z3HRH+BR<9n?qy1e(T(Gxc$rYfOoDpPoKs^pw{~6I9a}hS#Rdm-L4ek4LtO~SnUr^d zsF>=s5&AWcIDmhtYKP9-Hg2>(P^8Um8@;XWuotnQ9@BV(HJNlpi0C{62j%Ahc zeprzOT~%{yJdPH8moA0+rv)LTc35CJ5t;q7mP<<4U`-vFqckw8n=K75XPUmnFOb3F zMok6ZIXGrvEr(gH_)zaaYpePk5!1szoC+*;U!Na){UqDj3|be8LNtC6Z40KxZ_8(3dLpzDwQK(_*e)3cSv{Rspte^`y5dt;JKx>T^+*>skPFrdLOvphu zIIn$j9Z1-S6KP>j&&e-9$>v;_#bC>#Yx}dcDQ;pgpQHG--d`x1q8#yVY{ZjeQ$K@+ zZ!bTlvtzxxhUKWI);mStN3RM}9(SxqP=IFfE~CI_4`w;CxJ2P64JU1Iuu_+p*gITP zZmW%9%;28CyhjMcP)UrKcOskucXpTp0)=+uud34MH?(DaQ*+iF$d-oSEZq`K(q5fJ zQ=02v5Z{Tumlh@B<|;#|)r|MmvV1~o%5|{O&k)_;~9wlDMEAEMZG~DJOcGJ%c8}n#AZC9mUHocU$DKe8ReOxP#b9LM!<-$+`4* z*&8|8-49OE5*#X!$N6Se&~zZLmIr@byH8Rq|Cx0^X{PG0v%(KL+;1fXIDL?{!s&w_ zw>+Ez2G%C&b$xKOVSa>;Mz;qDF~Q0qq^}lb30`u4{IMA z@2l7CJ~d$BNCY+meH@z6u*AWbbCq=B@)EKcX_87b1JqiW&>EWVOW2}5eO{I57?t58 z`VPk&6_XHk1EGkKR>A^8LU_O72oIJH1c)flNg4-cmeXfW{{4-DWxm8kMPnUTKIq;8 zAg{wK8a4J=5t$in3a_Hh1lK)cjim$N#IKF_#!!cT;DBu!9ouEU{>Emyf3z|$;)?G` z?9;);!$4LwP3pa^sY&pEjfn4Eet1ry-xpE>?^+y`uP;dm_5@fZq7_$YLKqZEU45Ohc*N2BlO6dUC@7ZT69)D1@bjOpQJDNH^uB0m>;lkvKcqtWxl z;kIQ`6%lk4N|8)T;r}>xlGV|p%Dx(qMa^Cdh18YP;T86iVUz&MwHj<3B+=lZj6Hmo z`{4~q$hQ*tK%nid1M2>>$Q2;%A8(Fb$H$MYMA@dV*}qZQqpG6eh{i>uw4-D{M9mz> z;d6`~3K?@nObr8p{;e})G78{b^$W7{ASh5pM3hnoPi9y675vcl zF@=2l=^j z@>=j?QuV2sifq8m;OUWrMht0PE8;fusQ2HyS^&Ji?6FZ3;J$hrSe=CV_)URO#gkUb zDduPtrU{2u0Sp`u0a4(?+gUgdyjWV$$mQlF?v@X%?(7(a7?3q-VU+a1trEZ6Vz#yU zusK0`APqAr=S1NgiE1Nleb7!hSR08KN-XJ6BeLtCEJu<kSt{PFz7lqw= zKf^7n4t<_`hsm)u)0J$1R*hFG|eBQb+aPkkmx-%hp-{X4+;syzV7G^{i^U9yjt z$&2!CBV1aTS$Ky719AartPbpOcTzSj^IQ!zG(i>htp4PV{1N=4y-7iY!PG9FB2X&f z-6dQx&oo5)cx(~1yxB8D zgBR2n4_eBrmw*DmYw-T=0D?Od$Abu_e0)uIevU~LPxv^mE(=@AQt>ppVN7j|EaU!7e1g2Bf zPg@$&@b=kjfG{-w?d3rq`L1d0ff7vXAuC@Nh{mbZ85lV49~P2Iezxc`Hh}*|0l|5( z$xgHOh%`o$=S6%m?RA)@vNX?x7U$~iErLRf3j)=$;{Ft1Ea$ad1YFz1$vK|)b5sbz z{y7|kEzGmb`tbk-1Q#`J{M`Z;+>6nTO(J_`3Dgqqbda(ClE|Jg-8Ym1*WfPG$c1YjhDZRQ?-BM0ZXm{V=?UGK%p0 z!9`4_bI;4{>^en0`4A<~Px2ENiEKZk>L^7DQ(M2#`8;BT;VI+3noAJv$)$D5xVuXB z7B@q}a2?FPZCGkDjDDjc6EYYU=*&HFIw)NssO|QJbp%O=zRxv?3k+OXO;{F85iEzO z5vqnUSU=~5G?1Qc?9bKM6JOQE1GzO`SnF}Y@jf6aH-CF^*19#YtdHh5+3M5!ZVWlBL?u_Qv;?{n`H%*7U&y0U!4(QeJD zn%>aJWsGuALqgIr1)13ev{M+1AJR+7=;i(BtS1Rz%}N5-(xcxB#^Fr1+%=f^;tvxz z^(swj+IC5Gd3N-6>pMhjASCV;uwIYp@6H~&-+`AC{}$!q~OR5*O@-ZCii(NglF*z-Ni_oPxyXzE>t{@~7ptyCTsLC$hcaNR`Fb@)zW0oHMsac=lJ%f{Se2NUnaRrqVZbmdxO^c zcMb5vK-h()*FW2>-hd{!J!l)CPjW@e?i1zB!IYHY#=lK36uzk|a(`02##48Z4;v3C z0HOFAa4mvB$rED6Xcj-awMG41b&f3pes71|8cr4x*^X2eikggZW1=pvOQR^EK7M>M zAPg$K4PFd=V?gr3kE77nG~)XE#3uE)BEi^1%cSIQACb+WeUyq02m z^BZWBOC8uwH9}@Qg1`vuy`h&4EQTx2kwJ824J)6+L+2N#G-OV|^ zDM^bw%4E@qXP^Jn3)@eiP)%`RDJ2tqid(ux{owtd8z?;~oIZCHWBh{LI2k;L?)tEk zR~7_PzT~7CWsZk3vOiHNK|q5gFmMDb6gO7HNYQaQkyKw-hSp?)WVze0D7SX#3sIid z@?<0wyIo?>8p+L5LdBDnq13P+#j~^Vr9fTaJT9kR|C|qBbfczRs6{x#J<~vb^+?4C zN$6wMKhRL1t8~S3VOy5Y{Y4CCa(Y-SL9g}&-2vD_oGj0oL4aC~5ZZMKUCNGC%mA52 zGZYxlzg7&&Pi*HQp~?ol0rxW@fE4ExsboCKRBl~0ifkk-APW;swD9fKg>PZDWtEWN z@bF8VBa4J@CUf7@yBSy~k7A1OhsdQ#C6eNVG$>c}Pv<0*sFp@W+>o^2+TFSWaBU%cSLr2%{_*soFXP0Sz!2(;&v4r z4WG}7i>FdKUs}2&b=3Ow)g>**DUSmpxq-lcREP zGUum9?T%2K45GlbCTl9rb6?~%XvA6tEN ziHKh=wU!1sRV)=U<(QKTU77>OuRSac;CCM9l2<6}5DFvcnkU@h*p}KLZR^$`hRn`Lb(L& zw+gJ(Lf;n0f@&}Zw;$zL9spsyxHhtvr8l8=2rq?@$sK(@&6xGX{+EG7V+9Qb6DNA< z*8+){J(Fi2x8{Xrmw)$}+Vs+Y{iL1|&A7o5VH3j{ySoc2|5MjmDb34i1)+U*s)HC1 z$V5~AeNi`Lc6#6`(@+}uB-SV_Hh#7U@dz!g+l(MBEopCf5olum(<5Y?*pq|{m>xHX zsX^*iYkN{Zh+{A;5* zLwm9R*n+b<=S)F?CUy+wNLU$-B#pg0qUCQS(?70q(vB1x6CXsBOcORKB%i>*7Cni1 z0CvtN5=R;tnn0~H$KK=Ka7yjp8#m9=v6q?S)P+{Fe7QzXYR0Y@Avb%5H=!V{^ zO)GUV?%@}@ZN60Vo`Y?b?iSD}1#I=5d1Z+p71#Vzmy`NiFqaU*63dvzo%fa$>HE<$ zO23sg3eO!iB@=b4*z>rU$A!AgX?1-sdNYNfU`LV1s7km-Q-c`*U8HUbduJ7uI+oC= z96Ds?!xq%1ozHJUU5IX5Sp)q;VKb-#D=tx8=g|8qO-Aw{ZtC3b>B9AS+PvgZ;Yu4k3+BY_ ze?f|1Oc8r&VMlnBgjL*W#(hdA?N}5s$2BjJOOGiWq--hhS6l={rM???HZNb>UDe`$ zKtgxY4pxf$K0yQep^PVwJVSAZ*E?%fCN><+g^T(t)7@CF=sJt>G`hn{j>+fgt)RoY z#pZJ=RPOL}o!OVc)p`=E%a1VR$9u6s@VTLp_4mZqIZ-^mPW}_n&MoMk9gj4)H#IM zq7Ds76r7B^It`{RhlHYLuySt;P8r>fd!JH;HwaQL4x}V_iiAKVoRx29F=MXI1mrZN zzJ)N&6GE74H>98RAc|*Gkb1{`7|WonejgyobJFu6T(9;tNrzhUM1skiD=gEE6u*@p zX&x3BuGFJfUFw))HhFwwSLi?r@W0`xh?LyvGkSP{?^RJE2j`y}do6WAx9WqF6us$y zB3sJ#vv5(+u&`dKBQ;aEsGKn(pJE>3flGeK5|>jdS31 z+-=9slGQ!iAGdt5k<9rSao~5X629eEELL31VIG7ETY@xmkn2Ig2zFoYK&I_(GZJ{% zhQzOdrA{YC_xx1r?T2`@u38KPVU8oXZ7G#DEcMWieZz_V_CC%ZCFjJ>hI^7wiblqg z{uNrAIaAZNkIs7dZ!_@9!S{J8{^K@h>^72#G8HR+hBoH{rNBxE-fGO&;{cA{ z2D$&+h>qztV}V%-m^_uL6G6_?@iE4XX>ZB!umn~X2aT7>mhj6p^(Xqo8mgOzlg)7r z?!P1lIeGbXaf*%VBl*~HwK)o3?Lha~4dfvtf7gI@*AWBE+o+jh3zw}#mU}g%R5&hD_KuvTkqE3(;{GD_+*jRdnzue zJ99s8)%)F+tjU~PY3Pe^w}I^yLK>gI@NXpv^mLBNE`~HM$>K3>?7CF;`jtQ%2?{yX z;^5(5m3^7(5mPr2Uvi;AOz&ddiMfcOORI@h;)v*~n~($XF(Sm99EI#P28 z!g}=6W6nC3+l#4i=OH(W_mpPooiexZwMDyRLs1$*-PaPO{3fp6OujEUI|BumF-Wh- zq~IgjS}t#m9|ykcyT)iHCRR2s@R%@C2r+l^Jf$Q|xx8jN2N6GA03wR~44+@0QY|n& z@;!=8=QS=akHdxbE$W|lp>8{R!6Vb7xPnb+i?$|L4u9%b#Ej=fNnaw8XK=Wsn#bY4wOD-9_K@7*?Uj z4End4A0@X)CsPC%AEs!uFjLqK(&vb^k|E6 z9|)MIsdUd3NIfoE*(yXgNRAPEqh!zpU!w}}8!w#jAMbo-=@poeWbCSNx5_ub@@e!z zFM|W@(eSZ>6y5L~FAu?(ZQbrRgzST@asQfm#-SRy_J|c z?&)a$MnY56DY?2)-(IFnU4e8dlz%a5PY(8{ydER``IcWX|}Fg#rMQ)c8#fX@&W;|AkDS5QMoev_i4=od z$fgzq{XnDD0n@)wGvi?6BuDfzKy{JsW>M8ZC%>OF%E~?iPRLXOGojmHpj-)AF9T-< zs2|i5@Ym?K3vBBIM4%Ek-1*%+?f!b&q{7cg2smeF-Zcjg@H~3IOWN({V}8xQj=b!c z-CpnKMvFUUU^^xOWLRlt1_ocz?oo@eh%)?6>a8L3RO>oae>-NYIC6?k~mei{yiBHtOE5W4&Qor=Eunsw241JCp$N5^ca9kdsc|C zLH2UyWNf-tznzI;PN*}ja3A3#3QQyTKn{urdL!F4vPWZ784Fa&SGwCFt+?kbpYi>M zprWBMIP(|`)6{p&T}E;xjl=r@GDYkuV}@Wo_Z{&%qXUGO&#a5v+eJonYYMb1`Jk?s zaK*7C4PAP|4U=Z0HCor8G&oURxFt)I!#za-Gm=>(jlv%jm#AKb=aQn|4|M~$)C*1* z5eAaVSJmzPwKi~-iqu_nNUwn3PinT@)CbdvzM@Xvo7QTy?8;p%E*bKKI*Rd^zs0}Y z{o5sz?AH0ro6NK+LL7C%jpRA2)-8`TDra)d0Z^{K54 zA<2an^=2aC(M)T(yah&6p@?R+%IAS6&+j?&{TiN|`pL}4qS*O-#ytk>cV;F>#6^Q{ z$@;AvDv;LY?hl(We67Rwwm{3?<&~6%SMxZiwlJ~qyu2-ETmZv|x_U_(pej9-@1&Fz zZue?N|Lsa5Q;3+!>t5>V&b8hoJS$I+<1;OMW6C}u!>%rcOmRn3F2GZAY(b(77<~6< ztGeZ*&Hk>L|FtbI^lF}g%jqB>-#WTf{kOQxetDu9)%F`(o2FQbt^aM5jp1}eKLVK= z*NIT$af@Am5|kCpZzhCIudR+-^PD#hjPM(|mz1_HX72VU?tEi$vI_;D_;PB9I-N5XMmxun&JgmNlF-wI z`an?o;~=17=41~_^D|7Ao!oQ5y6*O=vdNy2cBb#Ja*v`Vf9!)q1(Bc4{Xwuasl>zqQVJ<)~QhNGtw zlvS3O-&{iZj>qreP1w(S3GVnGhr}!2;U^RfheY7<_(E+PX}sw8(pC;qpO&+NY-YSh zYhH^v?|H-e7M8flj-{8n`IWaG_Htf=ewhZn+R({sT{+?&Ytv^CeW1R)Rr>{hzsHd!K0LF>jyae~sWa<~PbW3*_@4^p#>hTR^Ef~;A6=9QSd6vcvQIr|o%!1} z6}v-s#UZv$R7%d#FRlN$srHlo99ckNRc&Nf&{BvNs_a~W8+W+8?BYAEBKRwu{G_-_ zxiGw(`)&b~L{&-ddqiukcg^sJ_CI|M{-&#c{A32A8s^ zIKz~LBbht2u*+WPb4UA&nR|Rxy%{slo||F8Dxtenhgs`oP5Qq4nvI>uVp*41T}O12oHmT<$vxQF=Nk zt?*#GGrRo>I(|tJj0SfL%=!09Iap+wbx@HlkX@>bgX=sm*B^>8_r7m9H}|<9JB)wla5l+j+LWI4O+Pzq_)_|dl$hhp3O7Y zQ(oFFxZoYqh*N{$_Ad_z`Sv!FIj{t;<+}auAnFsG$N3_y&gsDFu05o2^G`+svbiqB zQrFo}nuMo#{%la*j$wiaOLTGV$xf);#<#=*uX6}GcA#ea77es&U=Owi*luMpqF|eV}!E-E-Iq`L}ZT9SZ!z>iO zj@;vhYB^6W+qOwE14x@+KUgtwg?sB-+_^{=Y zamMLz)pgdteI8!3>yyDLPkY1*H^r8(X-rqJ6+f_TBMe+T`xCmZvOS=!7vlaqziOH4 zqUjb9;_^AK2-RQPthII5vrQFmvpJNqvPB-oedVbrU~I8=ZvS0h3*!^vgxvm_A>j;h{K@1yuXP@SgFT^VNmkN=3jKR+)oSAE2T6kBr35>T~thKZ+|mw*~`8n zLFA(po!8p)p{uv@;DR3Dd~%J~mnvf>8mISq9Dcfb1K*l6stlxXsSjRkmrSc4Z;klz zi2?MEh{V)6z^IVyB<~{#BAZ=IbN>F|m%Q4wSMC(1S!lIpo1u?=i{V&I57}tv>KJW0 znRWhYs}JgQO?kQa84H{VvTcE8vy8?A{QIsbj6z25y5eMJH@oGaAP62LL7sx4EC~a9 z@c8w%R8;k120>O*S}RUf49gldw6c=~S+W?hlQBn&q zLJnCbW{_S?DK_qVMoL<3Bf5KA)HjPOj*iNDI$c#S&#GuwhBBhYTa#inF^?lW$?I5p z9rLtfY;;8if__L(K}XT=#ax5qFWNbv(mgk*KR)ihC9gQTSc!BxKM|VQY!HsEl*Pu5 zx8ELUs&IN9z;1oT-Me6Tu*Ca+m9kHI4Uep_sU((x>R z)?UtZ&!^!HvKdvTALq3sE%zmaGpUAbqFZ>!5@^Q><>W-$&66YsdHH%)-#=C)&fJ81 z{82-&BKv7vBy@`-k!Ll7ftE?gd`VGiA*Sxa#2tPT!SSIg!!9M7r>rB-ypwMhGhvd9 zw=Y zFZadN(nQ>J6z_w>LW&Hbbic+d=C&N(Vy}2?-*rnlh9X{pYvhO`QJF4`w?AI57-S7S z$@|MD&K_Q2boe>dX7je-@t^IhUQAorj&L1iOJNW<{3>5@y?9Q6y&y-}l>)a=jwV0q zkMknZm0~gTl9)yNDAUHk(_8(*?$b^H9CY2xq(GYojkCki5j(byuW+gP!9?Dp>C@4k zt19|c!|GZJ&)f*^kvXbB?$wiaMutHngJm!$kynI|KyIMrei>m2S?|`%?3k00)4HI; zbKKYT;n($QhSthJk`tzOo=7%M;889a0e5nZj69>Nuk+i-KousjRQ6L0qKa3uk3jjb z=saM*NktcE;B>3cXpau9j%=)#T>`0~^hUi!NyF@RmZRggXN61DLiHV9|7JE%6kFhB zoc*IAs%9NOLi{C%d;98kf~gKh(^0e~2&nl-^MnB3p$^x2EvC}bcE|`Ge?%e-@jFd6 z&9{PO#f(Z{)wS>Hsz-aOv763H^rMke$IN?w!y%n6^#<>#QiS9?M>f>m+_a@8zudH& zY_%Ee1@1@Et3H@3v$FB7%sDSI|K)O;TL7P4|77Shj^I8Hn~@{m)NrynNqt`D6F)Jx z?AP^TcRoJc2jqPZZMCu2Xw9>Qn!6OQF17V@GTqaA*?daPe=#zgGfaNRV|!}ij$S?V ds^)$9Dk#_i;U!=Y|K}$rX>kRyDiMR<{}%w$L^%Ke diff --git a/vendor/github.com/aymerick/raymond/string.go b/vendor/github.com/aymerick/raymond/string.go deleted file mode 100644 index 7194769..0000000 --- a/vendor/github.com/aymerick/raymond/string.go +++ /dev/null @@ -1,84 +0,0 @@ -package raymond - -import ( - "fmt" - "reflect" - "strconv" -) - -// SafeString represents a string that must not be escaped. -// -// A SafeString can be returned by helpers to disable escaping. -type SafeString string - -// isSafeString returns true if argument is a SafeString -func isSafeString(value interface{}) bool { - if _, ok := value.(SafeString); ok { - return true - } - return false -} - -// Str returns string representation of any basic type value. -func Str(value interface{}) string { - return strValue(reflect.ValueOf(value)) -} - -// strValue returns string representation of a reflect.Value -func strValue(value reflect.Value) string { - result := "" - - ival, ok := printableValue(value) - if !ok { - panic(fmt.Errorf("Can't print value: %q", value)) - } - - val := reflect.ValueOf(ival) - - switch val.Kind() { - case reflect.Array, reflect.Slice: - for i := 0; i < val.Len(); i++ { - result += strValue(val.Index(i)) - } - case reflect.Bool: - result = "false" - if val.Bool() { - result = "true" - } - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - result = fmt.Sprintf("%d", ival) - case reflect.Float32, reflect.Float64: - result = strconv.FormatFloat(val.Float(), 'f', -1, 64) - case reflect.Invalid: - result = "" - default: - result = fmt.Sprintf("%s", ival) - } - - return result -} - -// printableValue returns the, possibly indirected, interface value inside v that -// is best for a call to formatted printer. -// -// NOTE: borrowed from https://github.com/golang/go/tree/master/src/text/template/exec.go -func printableValue(v reflect.Value) (interface{}, bool) { - if v.Kind() == reflect.Ptr { - v, _ = indirect(v) // fmt.Fprint handles nil. - } - if !v.IsValid() { - return "", true - } - - if !v.Type().Implements(errorType) && !v.Type().Implements(fmtStringerType) { - if v.CanAddr() && (reflect.PtrTo(v.Type()).Implements(errorType) || reflect.PtrTo(v.Type()).Implements(fmtStringerType)) { - v = v.Addr() - } else { - switch v.Kind() { - case reflect.Chan, reflect.Func: - return nil, false - } - } - } - return v.Interface(), true -} diff --git a/vendor/github.com/aymerick/raymond/template.go b/vendor/github.com/aymerick/raymond/template.go deleted file mode 100644 index f16ed2f..0000000 --- a/vendor/github.com/aymerick/raymond/template.go +++ /dev/null @@ -1,248 +0,0 @@ -package raymond - -import ( - "fmt" - "io/ioutil" - "reflect" - "runtime" - "sync" - - "github.com/aymerick/raymond/ast" - "github.com/aymerick/raymond/parser" -) - -// Template represents a handlebars template. -type Template struct { - source string - program *ast.Program - helpers map[string]reflect.Value - partials map[string]*partial - mutex sync.RWMutex // protects helpers and partials -} - -// newTemplate instanciate a new template without parsing it -func newTemplate(source string) *Template { - return &Template{ - source: source, - helpers: make(map[string]reflect.Value), - partials: make(map[string]*partial), - } -} - -// Parse instanciates a template by parsing given source. -func Parse(source string) (*Template, error) { - tpl := newTemplate(source) - - // parse template - if err := tpl.parse(); err != nil { - return nil, err - } - - return tpl, nil -} - -// MustParse instanciates a template by parsing given source. It panics on error. -func MustParse(source string) *Template { - result, err := Parse(source) - if err != nil { - panic(err) - } - return result -} - -// ParseFile reads given file and returns parsed template. -func ParseFile(filePath string) (*Template, error) { - b, err := ioutil.ReadFile(filePath) - if err != nil { - return nil, err - } - - return Parse(string(b)) -} - -// parse parses the template -// -// It can be called several times, the parsing will be done only once. -func (tpl *Template) parse() error { - if tpl.program == nil { - var err error - - tpl.program, err = parser.Parse(tpl.source) - if err != nil { - return err - } - } - - return nil -} - -// Clone returns a copy of that template. -func (tpl *Template) Clone() *Template { - result := newTemplate(tpl.source) - - result.program = tpl.program - - tpl.mutex.RLock() - defer tpl.mutex.RUnlock() - - for name, helper := range tpl.helpers { - result.RegisterHelper(name, helper.Interface()) - } - - for name, partial := range tpl.partials { - result.addPartial(name, partial.source, partial.tpl) - } - - return result -} - -func (tpl *Template) findHelper(name string) reflect.Value { - tpl.mutex.RLock() - defer tpl.mutex.RUnlock() - - return tpl.helpers[name] -} - -// RegisterHelper registers a helper for that template. -func (tpl *Template) RegisterHelper(name string, helper interface{}) { - tpl.mutex.Lock() - defer tpl.mutex.Unlock() - - if tpl.helpers[name] != zero { - panic(fmt.Sprintf("Helper %s already registered", name)) - } - - val := reflect.ValueOf(helper) - ensureValidHelper(name, val) - - tpl.helpers[name] = val -} - -// RegisterHelpers registers several helpers for that template. -func (tpl *Template) RegisterHelpers(helpers map[string]interface{}) { - for name, helper := range helpers { - tpl.RegisterHelper(name, helper) - } -} - -func (tpl *Template) addPartial(name string, source string, template *Template) { - tpl.mutex.Lock() - defer tpl.mutex.Unlock() - - if tpl.partials[name] != nil { - panic(fmt.Sprintf("Partial %s already registered", name)) - } - - tpl.partials[name] = newPartial(name, source, template) -} - -func (tpl *Template) findPartial(name string) *partial { - tpl.mutex.RLock() - defer tpl.mutex.RUnlock() - - return tpl.partials[name] -} - -// RegisterPartial registers a partial for that template. -func (tpl *Template) RegisterPartial(name string, source string) { - tpl.addPartial(name, source, nil) -} - -// RegisterPartials registers several partials for that template. -func (tpl *Template) RegisterPartials(partials map[string]string) { - for name, partial := range partials { - tpl.RegisterPartial(name, partial) - } -} - -// RegisterPartialFile reads given file and registers its content as a partial with given name. -func (tpl *Template) RegisterPartialFile(filePath string, name string) error { - b, err := ioutil.ReadFile(filePath) - if err != nil { - return err - } - - tpl.RegisterPartial(name, string(b)) - - return nil -} - -// RegisterPartialFiles reads several files and registers them as partials, the filename base is used as the partial name. -func (tpl *Template) RegisterPartialFiles(filePaths ...string) error { - if len(filePaths) == 0 { - return nil - } - - for _, filePath := range filePaths { - name := fileBase(filePath) - - if err := tpl.RegisterPartialFile(filePath, name); err != nil { - return err - } - } - - return nil -} - -// RegisterPartialTemplate registers an already parsed partial for that template. -func (tpl *Template) RegisterPartialTemplate(name string, template *Template) { - tpl.addPartial(name, "", template) -} - -// Exec evaluates template with given context. -func (tpl *Template) Exec(ctx interface{}) (result string, err error) { - return tpl.ExecWith(ctx, nil) -} - -// MustExec evaluates template with given context. It panics on error. -func (tpl *Template) MustExec(ctx interface{}) string { - result, err := tpl.Exec(ctx) - if err != nil { - panic(err) - } - return result -} - -// ExecWith evaluates template with given context and private data frame. -func (tpl *Template) ExecWith(ctx interface{}, privData *DataFrame) (result string, err error) { - defer errRecover(&err) - - // parses template if necessary - err = tpl.parse() - if err != nil { - return - } - - // setup visitor - v := newEvalVisitor(tpl, ctx, privData) - - // visit AST - result, _ = tpl.program.Accept(v).(string) - - // named return values - return -} - -// errRecover recovers evaluation panic -func errRecover(errp *error) { - e := recover() - if e != nil { - switch err := e.(type) { - case runtime.Error: - panic(e) - case error: - *errp = err - default: - panic(e) - } - } -} - -// PrintAST returns string representation of parsed template. -func (tpl *Template) PrintAST() string { - if err := tpl.parse(); err != nil { - return fmt.Sprintf("PARSER ERROR: %s", err) - } - - return ast.Print(tpl.program) -} diff --git a/vendor/github.com/aymerick/raymond/utils.go b/vendor/github.com/aymerick/raymond/utils.go deleted file mode 100644 index 3deaaf3..0000000 --- a/vendor/github.com/aymerick/raymond/utils.go +++ /dev/null @@ -1,85 +0,0 @@ -package raymond - -import ( - "path" - "reflect" -) - -// indirect returns the item at the end of indirection, and a bool to indicate if it's nil. -// We indirect through pointers and empty interfaces (only) because -// non-empty interfaces have methods we might need. -// -// NOTE: borrowed from https://github.com/golang/go/tree/master/src/text/template/exec.go -func indirect(v reflect.Value) (rv reflect.Value, isNil bool) { - for ; v.Kind() == reflect.Ptr || v.Kind() == reflect.Interface; v = v.Elem() { - if v.IsNil() { - return v, true - } - if v.Kind() == reflect.Interface && v.NumMethod() > 0 { - break - } - } - return v, false -} - -// IsTrue returns true if obj is a truthy value. -func IsTrue(obj interface{}) bool { - thruth, ok := isTrueValue(reflect.ValueOf(obj)) - if !ok { - return false - } - return thruth -} - -// isTrueValue reports whether the value is 'true', in the sense of not the zero of its type, -// and whether the value has a meaningful truth value -// -// NOTE: borrowed from https://github.com/golang/go/tree/master/src/text/template/exec.go -func isTrueValue(val reflect.Value) (truth, ok bool) { - if !val.IsValid() { - // Something like var x interface{}, never set. It's a form of nil. - return false, true - } - switch val.Kind() { - case reflect.Array, reflect.Map, reflect.Slice, reflect.String: - truth = val.Len() > 0 - case reflect.Bool: - truth = val.Bool() - case reflect.Complex64, reflect.Complex128: - truth = val.Complex() != 0 - case reflect.Chan, reflect.Func, reflect.Ptr, reflect.Interface: - truth = !val.IsNil() - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - truth = val.Int() != 0 - case reflect.Float32, reflect.Float64: - truth = val.Float() != 0 - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - truth = val.Uint() != 0 - case reflect.Struct: - truth = true // Struct values are always true. - default: - return - } - return truth, true -} - -// canBeNil reports whether an untyped nil can be assigned to the type. See reflect.Zero. -// -// NOTE: borrowed from https://github.com/golang/go/tree/master/src/text/template/exec.go -func canBeNil(typ reflect.Type) bool { - switch typ.Kind() { - case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice: - return true - } - return false -} - -// fileBase returns base file name -// -// example: /foo/bar/baz.png => baz -func fileBase(filePath string) string { - fileName := path.Base(filePath) - fileExt := path.Ext(filePath) - - return fileName[:len(fileName)-len(fileExt)] -} 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 2bbbd8e..0000000 --- a/vendor/github.com/urfave/cli/README.md +++ /dev/null @@ -1,1381 +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` -or `CommandsByName` 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`", - }, - } - - app.Commands = []cli.Command{ - { - Name: "complete", - Aliases: []string{"c"}, - Usage: "complete a task on the list", - Action: func(c *cli.Context) error { - return nil - }, - }, - { - Name: "add", - Aliases: []string{"a"}, - Usage: "add a task to the list", - Action: func(c *cli.Context) error { - return nil - }, - }, - } - - sort.Sort(cli.FlagsByName(app.Flags)) - sort.Sort(cli.CommandsByName(app.Commands)) - - 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: - {{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 51fc45d..0000000 --- a/vendor/github.com/urfave/cli/app.go +++ /dev/null @@ -1,497 +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{} - // Carries a function which returns app specific info. - ExtraInfo func() map[string]string - // CustomAppHelpTemplate the text template for app help topic. - // cli.go uses text/template to render templates. You can - // render custom help text by setting this variable. - CustomAppHelpTemplate string - - 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 { - 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 90c07eb..0000000 --- a/vendor/github.com/urfave/cli/cli.go +++ /dev/null @@ -1,22 +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") -// return nil -// } -// -// 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 23de294..0000000 --- a/vendor/github.com/urfave/cli/command.go +++ /dev/null @@ -1,304 +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 - - // CustomHelpTemplate 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. - CustomHelpTemplate string -} - -type CommandsByName []Command - -func (c CommandsByName) Len() int { - return len(c) -} - -func (c CommandsByName) Less(i, j int) bool { - return c[i].Name < c[j].Name -} - -func (c CommandsByName) Swap(i, j int) { - c[i], c[j] = c[j], c[i] -} - -// 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) - context.Command = c - if checkCommandCompletions(context, c.Name) { - return nil - } - - if err != nil { - if c.OnUsageError != nil { - err := c.OnUsageError(context, err, false) - HandleExitCoder(err) - return err - } - fmt.Fprintln(context.App.Writer, "Incorrect Usage:", err.Error()) - fmt.Fprintln(context.App.Writer) - ShowCommandHelp(context, 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 { - ShowCommandHelp(context, c.Name) - HandleExitCoder(err) - return err - } - } - - if c.Action == nil { - c.Action = helpSubcommand.Action - } - - 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 - } - - app.Usage = c.Usage - app.Description = c.Description - app.ArgsUsage = c.ArgsUsage - - // set CommandNotFound - app.CommandNotFound = ctx.App.CommandNotFound - app.CustomAppHelpTemplate = c.CustomHelpTemplate - - // 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.ErrWriter = ctx.App.ErrWriter - - 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 - } - app.OnUsageError = c.OnUsageError - - 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 db94191..0000000 --- a/vendor/github.com/urfave/cli/context.go +++ /dev/null @@ -1,278 +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 { - c.setFlags = nil - 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 { - globalContext(c).setFlags = nil - 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 562b295..0000000 --- a/vendor/github.com/urfave/cli/errors.go +++ /dev/null @@ -1,115 +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 and calls OsExiter with the last exit code. -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 { - code := handleMultiError(multiErr) - OsExiter(code) - return - } -} - -func handleMultiError(multiErr MultiError) int { - code := 1 - for _, merr := range multiErr.Errors { - if multiErr2, ok := merr.(MultiError); ok { - code = handleMultiError(multiErr2) - } else { - fmt.Fprintln(ErrWriter, merr) - if exitErr, ok := merr.(ExitCoder); ok { - code = exitErr.ExitCode() - } - } - } - return code -} 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 877ff35..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 Flag = BoolFlag{ - Name: "generate-bash-completion", - Hidden: true, -} - -// VersionFlag prints the version for the application -var VersionFlag Flag = 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 Flag = 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 { - field := flagValue(flag).FieldByName("Hidden") - if !field.IsValid() || !field.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 := "" - - if val := fv.FieldByName("Value"); 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 100755 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 57ec98d..0000000 --- a/vendor/github.com/urfave/cli/help.go +++ /dev/null @@ -1,338 +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: - {{if .UsageText}}{{.UsageText}}{{else}}{{.HelpName}}{{if .VisibleFlags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{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}} - {{if .Description}}{{.Description}}{{else}}{{.Usage}}{{end}} - -USAGE: - {{if .UsageText}}{{.UsageText}}{{else}}{{.HelpName}} command{{if .VisibleFlags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{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{}) - -// Prints help for the App or Command with custom template function. -type helpPrinterCustom func(w io.Writer, templ string, data interface{}, customFunc map[string]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 - -// HelpPrinterCustom is same as HelpPrinter but -// takes a custom function for template function map. -var HelpPrinterCustom helpPrinterCustom = printHelpCustom - -// VersionPrinter prints the version for the App -var VersionPrinter = printVersion - -// ShowAppHelpAndExit - Prints the list of subcommands for the app and exits with exit code. -func ShowAppHelpAndExit(c *Context, exitCode int) { - ShowAppHelp(c) - os.Exit(exitCode) -} - -// ShowAppHelp is an action that displays the help. -func ShowAppHelp(c *Context) (err error) { - if c.App.CustomAppHelpTemplate == "" { - HelpPrinter(c.App.Writer, AppHelpTemplate, c.App) - return - } - customAppData := func() map[string]interface{} { - if c.App.ExtraInfo == nil { - return nil - } - return map[string]interface{}{ - "ExtraInfo": c.App.ExtraInfo, - } - } - HelpPrinterCustom(c.App.Writer, c.App.CustomAppHelpTemplate, c.App, customAppData()) - 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) - } - } -} - -// ShowCommandHelpAndExit - exits with code after showing help -func ShowCommandHelpAndExit(c *Context, command string, code int) { - ShowCommandHelp(c, command) - os.Exit(code) -} - -// 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) { - if c.CustomHelpTemplate != "" { - HelpPrinterCustom(ctx.App.Writer, c.CustomHelpTemplate, c, nil) - } else { - 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 printHelpCustom(out io.Writer, templ string, data interface{}, customFunc map[string]interface{}) { - funcMap := template.FuncMap{ - "join": strings.Join, - } - if customFunc != nil { - for key, value := range customFunc { - funcMap[key] = value - } - } - - 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 printHelp(out io.Writer, templ string, data interface{}) { - printHelpCustom(out, templ, data, nil) -} - -func checkVersion(c *Context) bool { - found := false - if VersionFlag.GetName() != "" { - eachName(VersionFlag.GetName(), func(name string) { - if c.GlobalBool(name) || c.Bool(name) { - found = true - } - }) - } - return found -} - -func checkHelp(c *Context) bool { - found := false - if HelpFlag.GetName() != "" { - eachName(HelpFlag.GetName(), 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.GetName() { - 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 100755 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/vendor.json b/vendor/vendor.json deleted file mode 100644 index 906a4b9..0000000 --- a/vendor/vendor.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "comment": "", - "ignore": "test", - "package": [ - { - "checksumSHA1": "PZ4KJai7DnuJ2YNJ2v2l2BseB1g=", - "path": "github.com/aymerick/raymond", - "revision": "72acac2207479d21dd45898c2a4264246c818148", - "revisionTime": "2016-12-09T22:07:24Z" - }, - { - "checksumSHA1": "Rvn+RH9pwFno1w6W+mhWsj/PxlA=", - "path": "github.com/aymerick/raymond/ast", - "revision": "72acac2207479d21dd45898c2a4264246c818148", - "revisionTime": "2016-12-09T22:07:24Z" - }, - { - "checksumSHA1": "5SJwPK0MYtJt5YiE1BNc9Wl3+S0=", - "path": "github.com/aymerick/raymond/lexer", - "revision": "72acac2207479d21dd45898c2a4264246c818148", - "revisionTime": "2016-12-09T22:07:24Z" - }, - { - "checksumSHA1": "TCu/8QBP8TApLjSt13a7Qjnyxrs=", - "path": "github.com/aymerick/raymond/parser", - "revision": "72acac2207479d21dd45898c2a4264246c818148", - "revisionTime": "2016-12-09T22:07:24Z" - }, - { - "checksumSHA1": "9LeR7BH4PSu8LRDZ8bY7QY1HXJE=", - "path": "github.com/urfave/cli", - "revision": "4b90d79a682b4bf685762c7452db20f2a676ecb2", - "revisionTime": "2017-07-06T19:46:25Z" - } - ], - "rootPath": "github.com/drone-plugins/drone-webhook" -}