various updates (embed templates). already WIP
This commit is contained in:
parent
923461cec1
commit
898110de47
16
.gitignore
vendored
Normal file
16
.gitignore
vendored
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
# ---> Go
|
||||||
|
# Binaries for programs and plugins
|
||||||
|
*.exe
|
||||||
|
*.exe~
|
||||||
|
*.dll
|
||||||
|
*.so
|
||||||
|
*.dylib
|
||||||
|
|
||||||
|
# Test binary, build with `go test -c`
|
||||||
|
*.test
|
||||||
|
|
||||||
|
# Output of the go coverage tool, specifically when used with LiteIDE
|
||||||
|
*.out
|
||||||
|
|
||||||
|
*.ini
|
||||||
|
dip
|
30
README.md
30
README.md
@ -4,16 +4,38 @@ dip is a small webservice designed to return public ip address
|
|||||||
|
|
||||||
## Howto
|
## Howto
|
||||||
|
|
||||||
## Build
|
### Build
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
go build -mod vendor
|
go build -mod vendor
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Play
|
||||||
|
|
||||||
|
Query webservice with html output
|
||||||
|
curl http://localhost:8080/
|
||||||
|
|
||||||
|
Query webservice with json output
|
||||||
|
curl http://localhost:8080/json
|
||||||
|
|
||||||
|
## Todo
|
||||||
|
|
||||||
|
- Add tests
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
BSD
|
```text
|
||||||
|
Copyright (c) 2019 PaulBSD
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
## Authors
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
Copyright © Paul Lecuq 2019
|
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
The views and conclusions contained in the software and documentation are those of the authors and should not be interpreted as representing official policies, either expressed or implied, of the fuelprices project.
|
||||||
|
```
|
17
dip.go
17
dip.go
@ -4,22 +4,31 @@ import (
|
|||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/gobuffalo/packr"
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
e := echo.New()
|
e := echo.New()
|
||||||
|
e.HideBanner = true
|
||||||
flag.Usage = Usage
|
|
||||||
|
|
||||||
var host, port string
|
var host, port string
|
||||||
|
var templatesbox packr.Box
|
||||||
|
//var staticbox packr.Box
|
||||||
|
|
||||||
|
flag.Usage = Usage
|
||||||
flag.StringVar(&host, "host", "[::]", "Listen host")
|
flag.StringVar(&host, "host", "[::]", "Listen host")
|
||||||
flag.StringVar(&port, "port", "8080", "Listen port")
|
flag.StringVar(&port, "port", "8080", "Listen port")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
e.GET("/", DipAsIndex)
|
templatesbox = packr.NewBox("templates")
|
||||||
e.GET("/json", DipAsJSON)
|
//staticbox = packr.NewBox("static")
|
||||||
|
|
||||||
|
builttemplates, _ := BuildTemplates(templatesbox)
|
||||||
|
e.Renderer = builttemplates
|
||||||
|
|
||||||
|
e.GET("/", Dip)
|
||||||
|
e.GET("/test", Static)
|
||||||
|
|
||||||
e.Logger.Fatal(e.Start(fmt.Sprintf("%s:%s", host, port)))
|
e.Logger.Fatal(e.Start(fmt.Sprintf("%s:%s", host, port)))
|
||||||
}
|
}
|
||||||
|
49
functions.go
49
functions.go
@ -4,7 +4,9 @@ import (
|
|||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
"github.com/likexian/whois-go"
|
"github.com/likexian/whois-go"
|
||||||
@ -32,40 +34,29 @@ func GetIPInfo(c echo.Context) (ip IP, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// DipAsIndex ...
|
// Dip return webpage
|
||||||
func DipAsIndex(c echo.Context) (err error) {
|
func Dip(c echo.Context) (err error) {
|
||||||
var ip IP
|
var ip IP
|
||||||
|
|
||||||
ip, err = GetIPInfo(c)
|
ip, err = GetIPInfo(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.HTML(500, fmt.Sprintf(
|
return c.Render(http.StatusInternalServerError, "error.html", nil)
|
||||||
`<html>
|
|
||||||
<body>
|
|
||||||
<h1>Error occured: %s</h1>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
`, err))
|
|
||||||
}
|
|
||||||
return c.HTML(200, fmt.Sprintf(
|
|
||||||
`<html>
|
|
||||||
<body>
|
|
||||||
<h1>IP: %s</h1>
|
|
||||||
<h2>Reverse DNS: %s</h2>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
`, ip.IP, ip.Hostname))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DipAsJSON ...
|
if strings.Contains(c.Request().Header.Get(echo.HeaderAccept), echo.MIMETextHTML) {
|
||||||
func DipAsJSON(c echo.Context) (err error) {
|
return c.Render(http.StatusOK, "index.html", ip)
|
||||||
var ip IP
|
} else {
|
||||||
ip, err = GetIPInfo(c)
|
return c.JSON(http.StatusOK, ip)
|
||||||
if err != nil {
|
|
||||||
return c.JSON(500, fmt.Sprintf("Error occured: %s", err))
|
|
||||||
}
|
}
|
||||||
return c.JSON(200, ip)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// CheckIPAddress ...
|
// Static returns static files
|
||||||
|
func Static(c echo.Context) (err error) {
|
||||||
|
//static := c.Param("static")
|
||||||
|
return c.Render(http.StatusOK, "static/js/uikit-icons.js", "")
|
||||||
|
}
|
||||||
|
|
||||||
|
// CheckIPAddress check if ip is an IP address, return err if there's an error
|
||||||
func (ip *IP) CheckIPAddress() (err error) {
|
func (ip *IP) CheckIPAddress() (err error) {
|
||||||
addr := net.ParseIP(ip.IP)
|
addr := net.ParseIP(ip.IP)
|
||||||
if addr == nil {
|
if addr == nil {
|
||||||
@ -84,9 +75,9 @@ func (ip *IP) GetHostname() (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetWhois not implemened yet
|
// GetWhois not implemented yet
|
||||||
func (ip *IP) GetWhois() (err error) {
|
func (ip *IP) GetWhois() (err error) {
|
||||||
resultraw, err := whois.Whois("exemple.com")
|
resultraw, err := whois.Whois("example.com")
|
||||||
//resultraw, err := whois.Whois(ip.IP)
|
//resultraw, err := whois.Whois(ip.IP)
|
||||||
fmt.Println(resultraw)
|
fmt.Println(resultraw)
|
||||||
result, err := whoisparser.Parse(resultraw)
|
result, err := whoisparser.Parse(resultraw)
|
||||||
@ -103,7 +94,7 @@ func Usage() {
|
|||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// IP ...
|
// IP defines dip main struct
|
||||||
type IP struct {
|
type IP struct {
|
||||||
IP string `json:"ip"`
|
IP string `json:"ip"`
|
||||||
Hostname string `json:"hostname"`
|
Hostname string `json:"hostname"`
|
||||||
|
1
go.mod
1
go.mod
@ -3,6 +3,7 @@ module dip
|
|||||||
go 1.13
|
go 1.13
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/gobuffalo/packr v1.30.1
|
||||||
github.com/labstack/echo/v4 v4.1.11
|
github.com/labstack/echo/v4 v4.1.11
|
||||||
github.com/likexian/whois-go v1.3.1
|
github.com/likexian/whois-go v1.3.1
|
||||||
github.com/likexian/whois-parser-go v1.10.2
|
github.com/likexian/whois-parser-go v1.10.2
|
||||||
|
60
go.sum
60
go.sum
@ -1,6 +1,35 @@
|
|||||||
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
|
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||||
|
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||||
|
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
|
||||||
|
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||||
|
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
|
||||||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||||
|
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||||
|
github.com/gobuffalo/envy v1.7.0 h1:GlXgaiBkmrYMHco6t4j7SacKO4XUjvh5pwXh0f4uxXU=
|
||||||
|
github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI=
|
||||||
|
github.com/gobuffalo/logger v1.0.0/go.mod h1:2zbswyIUa45I+c+FLXuWl9zSWEiVuthsk8ze5s8JvPs=
|
||||||
|
github.com/gobuffalo/packd v0.3.0 h1:eMwymTkA1uXsqxS0Tpoop3Lc0u3kTfiMBE6nKtQU4g4=
|
||||||
|
github.com/gobuffalo/packd v0.3.0/go.mod h1:zC7QkmNkYVGKPw4tHpBQ+ml7W/3tIebgeo1b36chA3Q=
|
||||||
|
github.com/gobuffalo/packr v1.30.1 h1:hu1fuVR3fXEZR7rXNW3h8rqSML8EVAf6KNm0NKO/wKg=
|
||||||
|
github.com/gobuffalo/packr v1.30.1/go.mod h1:ljMyFO2EcrnzsHsN99cvbq055Y9OhRrIaviy289eRuk=
|
||||||
|
github.com/gobuffalo/packr/v2 v2.5.1/go.mod h1:8f9c96ITobJlPzI44jj+4tHnEKNt0xXWSVlXRN9X1Iw=
|
||||||
|
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||||
|
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||||
|
github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc=
|
||||||
|
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
|
||||||
|
github.com/karrick/godirwalk v1.10.12/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA=
|
||||||
|
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
|
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
|
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||||
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
|
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||||
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
github.com/labstack/echo/v4 v4.1.11 h1:z0BZoArY4FqdpUEl+wlHp4hnr/oSR6MTmQmv8OHSoww=
|
github.com/labstack/echo/v4 v4.1.11 h1:z0BZoArY4FqdpUEl+wlHp4hnr/oSR6MTmQmv8OHSoww=
|
||||||
github.com/labstack/echo/v4 v4.1.11/go.mod h1:i541M3Fj6f76NZtHSj7TXnyM8n2gaodfvfxNnFqi74g=
|
github.com/labstack/echo/v4 v4.1.11/go.mod h1:i541M3Fj6f76NZtHSj7TXnyM8n2gaodfvfxNnFqi74g=
|
||||||
github.com/labstack/gommon v0.3.0 h1:JEeO0bvc78PKdyHxloTKiF8BD5iGrH8T6MSeGvSgob0=
|
github.com/labstack/gommon v0.3.0 h1:JEeO0bvc78PKdyHxloTKiF8BD5iGrH8T6MSeGvSgob0=
|
||||||
@ -11,32 +40,59 @@ github.com/likexian/whois-go v1.3.1 h1:aKk3ZSwE5X4UHHXf6tzHbzc2BN6ih4DsrXQ6qk667
|
|||||||
github.com/likexian/whois-go v1.3.1/go.mod h1:6aBrKuJZ66dDhXG7/BiZ6uxPzmBocgapf+04i4VjXdU=
|
github.com/likexian/whois-go v1.3.1/go.mod h1:6aBrKuJZ66dDhXG7/BiZ6uxPzmBocgapf+04i4VjXdU=
|
||||||
github.com/likexian/whois-parser-go v1.10.2 h1:j4qDwPuv7Qnmg3CcSEAywqcTnXCFETMAMn+jhRkTaJs=
|
github.com/likexian/whois-parser-go v1.10.2 h1:j4qDwPuv7Qnmg3CcSEAywqcTnXCFETMAMn+jhRkTaJs=
|
||||||
github.com/likexian/whois-parser-go v1.10.2/go.mod h1:I3zHrhbq4XRmc3nn4xtWNafclqmZXJzW7tSx9KXlCwk=
|
github.com/likexian/whois-parser-go v1.10.2/go.mod h1:I3zHrhbq4XRmc3nn4xtWNafclqmZXJzW7tSx9KXlCwk=
|
||||||
|
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||||
github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU=
|
github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU=
|
||||||
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||||
github.com/mattn/go-isatty v0.0.9 h1:d5US/mDsogSGW37IV293h//ZFaeajb69h+EHFsv2xGg=
|
github.com/mattn/go-isatty v0.0.9 h1:d5US/mDsogSGW37IV293h//ZFaeajb69h+EHFsv2xGg=
|
||||||
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
|
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
|
||||||
|
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||||
|
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||||
|
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||||
|
github.com/rogpeppe/go-internal v1.3.0 h1:RR9dF3JtopPvtkroDZuVD7qquD0bnHlKSqaQhgwt8yk=
|
||||||
|
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||||
|
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||||
|
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||||
|
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
||||||
|
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||||
|
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
|
||||||
|
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||||
|
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||||
|
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||||
|
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
||||||
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||||
github.com/valyala/fasttemplate v1.0.1 h1:tY9CJiPnMXf1ERmG2EyK7gNUd+c6RKGD0IfU8WdUSz8=
|
github.com/valyala/fasttemplate v1.0.1 h1:tY9CJiPnMXf1ERmG2EyK7gNUd+c6RKGD0IfU8WdUSz8=
|
||||||
github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
|
github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
|
||||||
|
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||||
|
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 h1:HuIa8hRrWRSrqYzx1qI49NNxhdi2PrY7gxVSq1JjLDc=
|
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 h1:HuIa8hRrWRSrqYzx1qI49NNxhdi2PrY7gxVSq1JjLDc=
|
||||||
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392 h1:ACG4HJsFiNMf47Y4PeRoebLNy/2lXT9EtprMuTFWt1M=
|
golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392 h1:ACG4HJsFiNMf47Y4PeRoebLNy/2lXT9EtprMuTFWt1M=
|
||||||
golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY=
|
golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY=
|
||||||
|
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3 h1:0GoQqolDA55aaLxZyTzK/Y2ePZzZTUrRacwib7cNsYQ=
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3 h1:0GoQqolDA55aaLxZyTzK/Y2ePZzZTUrRacwib7cNsYQ=
|
||||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190923162816-aa69164e4478 h1:l5EDrHhldLYb3ZRHDUhXF7Om7MvYXnkV9/iQNo1lX6g=
|
golang.org/x/net v0.0.0-20190923162816-aa69164e4478 h1:l5EDrHhldLYb3ZRHDUhXF7Om7MvYXnkV9/iQNo1lX6g=
|
||||||
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20190515120540-06a5c4944438/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a h1:aYOabOQFp6Vj6W1F80affTUvO9UxmJRx8K0gsfABByQ=
|
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a h1:aYOabOQFp6Vj6W1F80affTUvO9UxmJRx8K0gsfABByQ=
|
||||||
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
@ -47,7 +103,11 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
|||||||
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
||||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20190624180213-70d37148ca0c/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||||
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
12410
static/css/uikit-rtl.css
Normal file
12410
static/css/uikit-rtl.css
Normal file
File diff suppressed because it is too large
Load Diff
1
static/css/uikit-rtl.min.css
vendored
Normal file
1
static/css/uikit-rtl.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
12410
static/css/uikit.css
Normal file
12410
static/css/uikit.css
Normal file
File diff suppressed because it is too large
Load Diff
1
static/css/uikit.min.css
vendored
Normal file
1
static/css/uikit.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
167
static/js/uikit-icons.js
Normal file
167
static/js/uikit-icons.js
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
/*! UIkit 3.2.7 | http://www.getuikit.com | (c) 2014 - 2019 YOOtheme | MIT License */
|
||||||
|
|
||||||
|
(function (global, factory) {
|
||||||
|
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
|
||||||
|
typeof define === 'function' && define.amd ? define('uikiticons', factory) :
|
||||||
|
(global = global || self, global.UIkitIcons = factory());
|
||||||
|
}(this, (function () { 'use strict';
|
||||||
|
|
||||||
|
function plugin(UIkit) {
|
||||||
|
|
||||||
|
if (plugin.installed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
UIkit.icon.add({
|
||||||
|
"500px": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M9.624,11.866c-0.141,0.132,0.479,0.658,0.662,0.418c0.051-0.046,0.607-0.61,0.662-0.664c0,0,0.738,0.719,0.814,0.719 c0.1,0,0.207-0.055,0.322-0.17c0.27-0.269,0.135-0.416,0.066-0.495l-0.631-0.616l0.658-0.668c0.146-0.156,0.021-0.314-0.1-0.449 c-0.182-0.18-0.359-0.226-0.471-0.125l-0.656,0.654l-0.654-0.654c-0.033-0.034-0.08-0.045-0.124-0.045 c-0.079,0-0.191,0.068-0.307,0.181c-0.202,0.202-0.247,0.351-0.133,0.462l0.665,0.665L9.624,11.866z\"/><path d=\"M11.066,2.884c-1.061,0-2.185,0.248-3.011,0.604c-0.087,0.034-0.141,0.106-0.15,0.205C7.893,3.784,7.919,3.909,7.982,4.066 c0.05,0.136,0.187,0.474,0.452,0.372c0.844-0.326,1.779-0.507,2.633-0.507c0.963,0,1.9,0.191,2.781,0.564 c0.695,0.292,1.357,0.719,2.078,1.34c0.051,0.044,0.105,0.068,0.164,0.068c0.143,0,0.273-0.137,0.389-0.271 c0.191-0.214,0.324-0.395,0.135-0.575c-0.686-0.654-1.436-1.138-2.363-1.533C13.24,3.097,12.168,2.884,11.066,2.884z\"/><path d=\"M16.43,15.747c-0.092-0.028-0.242,0.05-0.309,0.119l0,0c-0.652,0.652-1.42,1.169-2.268,1.521 c-0.877,0.371-1.814,0.551-2.779,0.551c-0.961,0-1.896-0.189-2.775-0.564c-0.848-0.36-1.612-0.879-2.268-1.53 c-0.682-0.688-1.196-1.455-1.529-2.268c-0.325-0.799-0.471-1.643-0.471-1.643c-0.045-0.24-0.258-0.249-0.567-0.203 c-0.128,0.021-0.519,0.079-0.483,0.36v0.01c0.105,0.644,0.289,1.284,0.545,1.895c0.417,0.969,1.002,1.849,1.756,2.604 c0.757,0.754,1.636,1.34,2.604,1.757C8.901,18.785,9.97,19,11.088,19c1.104,0,2.186-0.215,3.188-0.645 c1.838-0.896,2.604-1.757,2.604-1.757c0.182-0.204,0.227-0.317-0.1-0.643C16.779,15.956,16.525,15.774,16.43,15.747z\"/><path d=\"M5.633,13.287c0.293,0.71,0.723,1.341,1.262,1.882c0.54,0.54,1.172,0.971,1.882,1.264c0.731,0.303,1.509,0.461,2.298,0.461 c0.801,0,1.578-0.158,2.297-0.461c0.711-0.293,1.344-0.724,1.883-1.264c0.543-0.541,0.971-1.172,1.264-1.882 c0.314-0.721,0.463-1.5,0.463-2.298c0-0.79-0.148-1.569-0.463-2.289c-0.293-0.699-0.721-1.329-1.264-1.881 c-0.539-0.541-1.172-0.959-1.867-1.263c-0.721-0.303-1.5-0.461-2.299-0.461c-0.802,0-1.613,0.159-2.322,0.461 c-0.577,0.25-1.544,0.867-2.119,1.454v0.012V2.108h8.16C15.1,2.104,15.1,1.69,15.1,1.552C15.1,1.417,15.1,1,14.809,1H5.915 C5.676,1,5.527,1.192,5.527,1.384v6.84c0,0.214,0.273,0.372,0.529,0.428c0.5,0.105,0.614-0.056,0.737-0.224l0,0 c0.18-0.273,0.776-0.884,0.787-0.894c0.901-0.905,2.117-1.408,3.416-1.408c1.285,0,2.5,0.501,3.412,1.408 c0.914,0.914,1.408,2.122,1.408,3.405c0,1.288-0.508,2.496-1.408,3.405c-0.9,0.896-2.152,1.406-3.438,1.406 c-0.877,0-1.711-0.229-2.433-0.671v-4.158c0-0.553,0.237-1.151,0.643-1.614c0.462-0.519,1.094-0.799,1.782-0.799 c0.664,0,1.293,0.253,1.758,0.715c0.459,0.459,0.709,1.071,0.709,1.723c0,1.385-1.094,2.468-2.488,2.468 c-0.273,0-0.769-0.121-0.781-0.125c-0.281-0.087-0.405,0.306-0.438,0.436c-0.159,0.496,0.079,0.585,0.123,0.607 c0.452,0.137,0.743,0.157,1.129,0.157c1.973,0,3.572-1.6,3.572-3.57c0-1.964-1.6-3.552-3.572-3.552c-0.97,0-1.872,0.36-2.546,1.038 c-0.656,0.631-1.027,1.487-1.027,2.322v3.438v-0.011c-0.372-0.42-0.732-1.041-0.981-1.682c-0.102-0.248-0.315-0.202-0.607-0.113 c-0.135,0.035-0.519,0.157-0.44,0.439C5.372,12.799,5.577,13.164,5.633,13.287z\"/></svg>",
|
||||||
|
"album": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><rect x=\"5\" y=\"2\" width=\"10\" height=\"1\"/><rect x=\"3\" y=\"4\" width=\"14\" height=\"1\"/><rect fill=\"none\" stroke=\"#000\" x=\"1.5\" y=\"6.5\" width=\"17\" height=\"11\"/></svg>",
|
||||||
|
"arrow-down": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><polygon points=\"10.5,16.08 5.63,10.66 6.37,10 10.5,14.58 14.63,10 15.37,10.66\"/><line fill=\"none\" stroke=\"#000\" x1=\"10.5\" y1=\"4\" x2=\"10.5\" y2=\"15\"/></svg>",
|
||||||
|
"arrow-left": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><polyline fill=\"none\" stroke=\"#000\" points=\"10 14 5 9.5 10 5\"/><line fill=\"none\" stroke=\"#000\" x1=\"16\" y1=\"9.5\" x2=\"5\" y2=\"9.52\"/></svg>",
|
||||||
|
"arrow-right": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><polyline fill=\"none\" stroke=\"#000\" points=\"10 5 15 9.5 10 14\"/><line fill=\"none\" stroke=\"#000\" x1=\"4\" y1=\"9.5\" x2=\"15\" y2=\"9.5\"/></svg>",
|
||||||
|
"arrow-up": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><polygon points=\"10.5,4 15.37,9.4 14.63,10.08 10.5,5.49 6.37,10.08 5.63,9.4\"/><line fill=\"none\" stroke=\"#000\" x1=\"10.5\" y1=\"16\" x2=\"10.5\" y2=\"5\"/></svg>",
|
||||||
|
"ban": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><circle fill=\"none\" stroke=\"#000\" stroke-width=\"1.1\" cx=\"10\" cy=\"10\" r=\"9\"/><line fill=\"none\" stroke=\"#000\" stroke-width=\"1.1\" x1=\"4\" y1=\"3.5\" x2=\"16\" y2=\"16.5\"/></svg>",
|
||||||
|
"behance": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M9.5,10.6c-0.4-0.5-0.9-0.9-1.6-1.1c1.7-1,2.2-3.2,0.7-4.7C7.8,4,6.3,4,5.2,4C3.5,4,1.7,4,0,4v12c1.7,0,3.4,0,5.2,0 c1,0,2.1,0,3.1-0.5C10.2,14.6,10.5,12.3,9.5,10.6L9.5,10.6z M5.6,6.1c1.8,0,1.8,2.7-0.1,2.7c-1,0-2,0-2.9,0V6.1H5.6z M2.6,13.8v-3.1 c1.1,0,2.1,0,3.2,0c2.1,0,2.1,3.2,0.1,3.2L2.6,13.8z\"/><path d=\"M19.9,10.9C19.7,9.2,18.7,7.6,17,7c-4.2-1.3-7.3,3.4-5.3,7.1c0.9,1.7,2.8,2.3,4.7,2.1c1.7-0.2,2.9-1.3,3.4-2.9h-2.2 c-0.4,1.3-2.4,1.5-3.5,0.6c-0.4-0.4-0.6-1.1-0.6-1.7H20C20,11.7,19.9,10.9,19.9,10.9z M13.5,10.6c0-1.6,2.3-2.7,3.5-1.4 c0.4,0.4,0.5,0.9,0.6,1.4H13.5L13.5,10.6z\"/><rect x=\"13\" y=\"4\" width=\"5\" height=\"1.4\"/></svg>",
|
||||||
|
"bell": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path fill=\"none\" stroke=\"#000\" stroke-width=\"1.1\" d=\"M17,15.5 L3,15.5 C2.99,14.61 3.79,13.34 4.1,12.51 C4.58,11.3 4.72,10.35 5.19,7.01 C5.54,4.53 5.89,3.2 7.28,2.16 C8.13,1.56 9.37,1.5 9.81,1.5 L9.96,1.5 C9.96,1.5 11.62,1.41 12.67,2.17 C14.08,3.2 14.42,4.54 14.77,7.02 C15.26,10.35 15.4,11.31 15.87,12.52 C16.2,13.34 17.01,14.61 17,15.5 L17,15.5 Z\"/><path fill=\"none\" stroke=\"#000\" d=\"M12.39,16 C12.39,17.37 11.35,18.43 9.91,18.43 C8.48,18.43 7.42,17.37 7.42,16\"/></svg>",
|
||||||
|
"bold": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M5,15.3 C5.66,15.3 5.9,15 5.9,14.53 L5.9,5.5 C5.9,4.92 5.56,4.7 5,4.7 L5,4 L8.95,4 C12.6,4 13.7,5.37 13.7,6.9 C13.7,7.87 13.14,9.17 10.86,9.59 L10.86,9.7 C13.25,9.86 14.29,11.28 14.3,12.54 C14.3,14.47 12.94,16 9,16 L5,16 L5,15.3 Z M9,9.3 C11.19,9.3 11.8,8.5 11.85,7 C11.85,5.65 11.3,4.8 9,4.8 L7.67,4.8 L7.67,9.3 L9,9.3 Z M9.185,15.22 C11.97,15 12.39,14 12.4,12.58 C12.4,11.15 11.39,10 9,10 L7.67,10 L7.67,15 L9.18,15 Z\"/></svg>",
|
||||||
|
"bolt": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M4.74,20 L7.73,12 L3,12 L15.43,1 L12.32,9 L17.02,9 L4.74,20 L4.74,20 L4.74,20 Z M9.18,11 L7.1,16.39 L14.47,10 L10.86,10 L12.99,4.67 L5.61,11 L9.18,11 L9.18,11 L9.18,11 Z\"/></svg>",
|
||||||
|
"bookmark": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><polygon fill=\"none\" stroke=\"#000\" points=\"5.5 1.5 15.5 1.5 15.5 17.5 10.5 12.5 5.5 17.5\"/></svg>",
|
||||||
|
"calendar": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M 2,3 2,17 18,17 18,3 2,3 Z M 17,16 3,16 3,8 17,8 17,16 Z M 17,7 3,7 3,4 17,4 17,7 Z\"/><rect width=\"1\" height=\"3\" x=\"6\" y=\"2\"/><rect width=\"1\" height=\"3\" x=\"13\" y=\"2\"/></svg>",
|
||||||
|
"camera": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><circle fill=\"none\" stroke=\"#000\" stroke-width=\"1.1\" cx=\"10\" cy=\"10.8\" r=\"3.8\"/><path fill=\"none\" stroke=\"#000\" d=\"M1,4.5 C0.7,4.5 0.5,4.7 0.5,5 L0.5,17 C0.5,17.3 0.7,17.5 1,17.5 L19,17.5 C19.3,17.5 19.5,17.3 19.5,17 L19.5,5 C19.5,4.7 19.3,4.5 19,4.5 L13.5,4.5 L13.5,2.9 C13.5,2.6 13.3,2.5 13,2.5 L7,2.5 C6.7,2.5 6.5,2.6 6.5,2.9 L6.5,4.5 L1,4.5 L1,4.5 Z\"/></svg>",
|
||||||
|
"cart": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><circle cx=\"7.3\" cy=\"17.3\" r=\"1.4\"/><circle cx=\"13.3\" cy=\"17.3\" r=\"1.4\"/><polyline fill=\"none\" stroke=\"#000\" points=\"0 2 3.2 4 5.3 12.5 16 12.5 18 6.5 8 6.5\"/></svg>",
|
||||||
|
"check": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><polyline fill=\"none\" stroke=\"#000\" stroke-width=\"1.1\" points=\"4,10 8,15 17,4\"/></svg>",
|
||||||
|
"chevron-double-left": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><polyline fill=\"none\" stroke=\"#000\" stroke-width=\"1.03\" points=\"10 14 6 10 10 6\"/><polyline fill=\"none\" stroke=\"#000\" stroke-width=\"1.03\" points=\"14 14 10 10 14 6\"/></svg>",
|
||||||
|
"chevron-double-right": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><polyline fill=\"none\" stroke=\"#000\" stroke-width=\"1.03\" points=\"10 6 14 10 10 14\"/><polyline fill=\"none\" stroke=\"#000\" stroke-width=\"1.03\" points=\"6 6 10 10 6 14\"/></svg>",
|
||||||
|
"chevron-down": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><polyline fill=\"none\" stroke=\"#000\" stroke-width=\"1.03\" points=\"16 7 10 13 4 7\"/></svg>",
|
||||||
|
"chevron-left": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><polyline fill=\"none\" stroke=\"#000\" stroke-width=\"1.03\" points=\"13 16 7 10 13 4\"/></svg>",
|
||||||
|
"chevron-right": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><polyline fill=\"none\" stroke=\"#000\" stroke-width=\"1.03\" points=\"7 4 13 10 7 16\"/></svg>",
|
||||||
|
"chevron-up": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><polyline fill=\"none\" stroke=\"#000\" stroke-width=\"1.03\" points=\"4 13 10 7 16 13\"/></svg>",
|
||||||
|
"clock": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><circle fill=\"none\" stroke=\"#000\" stroke-width=\"1.1\" cx=\"10\" cy=\"10\" r=\"9\"/><rect x=\"9\" y=\"4\" width=\"1\" height=\"7\"/><path fill=\"none\" stroke=\"#000\" stroke-width=\"1.1\" d=\"M13.018,14.197 L9.445,10.625\"/></svg>",
|
||||||
|
"close": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path fill=\"none\" stroke=\"#000\" stroke-width=\"1.06\" d=\"M16,16 L4,4\"/><path fill=\"none\" stroke=\"#000\" stroke-width=\"1.06\" d=\"M16,4 L4,16\"/></svg>",
|
||||||
|
"cloud-download": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path fill=\"none\" stroke=\"#000\" stroke-width=\"1.1\" d=\"M6.5,14.61 L3.75,14.61 C1.96,14.61 0.5,13.17 0.5,11.39 C0.5,9.76 1.72,8.41 3.3,8.2 C3.38,5.31 5.75,3 8.68,3 C11.19,3 13.31,4.71 13.89,7.02 C14.39,6.8 14.93,6.68 15.5,6.68 C17.71,6.68 19.5,8.45 19.5,10.64 C19.5,12.83 17.71,14.6 15.5,14.6 L12.5,14.6\"/><polyline fill=\"none\" stroke=\"#000\" points=\"11.75 16 9.5 18.25 7.25 16\"/><path fill=\"none\" stroke=\"#000\" d=\"M9.5,18 L9.5,9.5\"/></svg>",
|
||||||
|
"cloud-upload": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path fill=\"none\" stroke=\"#000\" stroke-width=\"1.1\" d=\"M6.5,14.61 L3.75,14.61 C1.96,14.61 0.5,13.17 0.5,11.39 C0.5,9.76 1.72,8.41 3.31,8.2 C3.38,5.31 5.75,3 8.68,3 C11.19,3 13.31,4.71 13.89,7.02 C14.39,6.8 14.93,6.68 15.5,6.68 C17.71,6.68 19.5,8.45 19.5,10.64 C19.5,12.83 17.71,14.6 15.5,14.6 L12.5,14.6\"/><polyline fill=\"none\" stroke=\"#000\" points=\"7.25 11.75 9.5 9.5 11.75 11.75\"/><path fill=\"none\" stroke=\"#000\" d=\"M9.5,18 L9.5,9.5\"/></svg>",
|
||||||
|
"code": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><polyline fill=\"none\" stroke=\"#000\" stroke-width=\"1.01\" points=\"13,4 19,10 13,16\"/><polyline fill=\"none\" stroke=\"#000\" stroke-width=\"1.01\" points=\"7,4 1,10 7,16\"/></svg>",
|
||||||
|
"cog": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><circle fill=\"none\" stroke=\"#000\" cx=\"9.997\" cy=\"10\" r=\"3.31\"/><path fill=\"none\" stroke=\"#000\" d=\"M18.488,12.285 L16.205,16.237 C15.322,15.496 14.185,15.281 13.303,15.791 C12.428,16.289 12.047,17.373 12.246,18.5 L7.735,18.5 C7.938,17.374 7.553,16.299 6.684,15.791 C5.801,15.27 4.655,15.492 3.773,16.237 L1.5,12.285 C2.573,11.871 3.317,10.999 3.317,9.991 C3.305,8.98 2.573,8.121 1.5,7.716 L3.765,3.784 C4.645,4.516 5.794,4.738 6.687,4.232 C7.555,3.722 7.939,2.637 7.735,1.5 L12.263,1.5 C12.072,2.637 12.441,3.71 13.314,4.22 C14.206,4.73 15.343,4.516 16.225,3.794 L18.487,7.714 C17.404,8.117 16.661,8.988 16.67,10.009 C16.672,11.018 17.415,11.88 18.488,12.285 L18.488,12.285 Z\"/></svg>",
|
||||||
|
"comment": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6,18.71 L6,14 L1,14 L1,1 L19,1 L19,14 L10.71,14 L6,18.71 L6,18.71 Z M2,13 L7,13 L7,16.29 L10.29,13 L18,13 L18,2 L2,2 L2,13 L2,13 Z\"/></svg>",
|
||||||
|
"commenting": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><polygon fill=\"none\" stroke=\"#000\" points=\"1.5,1.5 18.5,1.5 18.5,13.5 10.5,13.5 6.5,17.5 6.5,13.5 1.5,13.5\"/><circle cx=\"10\" cy=\"8\" r=\"1\"/><circle cx=\"6\" cy=\"8\" r=\"1\"/><circle cx=\"14\" cy=\"8\" r=\"1\"/></svg>",
|
||||||
|
"comments": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><polyline fill=\"none\" stroke=\"#000\" points=\"2 0.5 19.5 0.5 19.5 13\"/><path d=\"M5,19.71 L5,15 L0,15 L0,2 L18,2 L18,15 L9.71,15 L5,19.71 L5,19.71 L5,19.71 Z M1,14 L6,14 L6,17.29 L9.29,14 L17,14 L17,3 L1,3 L1,14 L1,14 L1,14 Z\"/></svg>",
|
||||||
|
"copy": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><rect fill=\"none\" stroke=\"#000\" x=\"3.5\" y=\"2.5\" width=\"12\" height=\"16\"/><polyline fill=\"none\" stroke=\"#000\" points=\"5 0.5 17.5 0.5 17.5 17\"/></svg>",
|
||||||
|
"credit-card": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><rect fill=\"none\" stroke=\"#000\" x=\"1.5\" y=\"4.5\" width=\"17\" height=\"12\"/><rect x=\"1\" y=\"7\" width=\"18\" height=\"3\"/></svg>",
|
||||||
|
"database": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><ellipse fill=\"none\" stroke=\"#000\" cx=\"10\" cy=\"4.64\" rx=\"7.5\" ry=\"3.14\"/><path fill=\"none\" stroke=\"#000\" d=\"M17.5,8.11 C17.5,9.85 14.14,11.25 10,11.25 C5.86,11.25 2.5,9.84 2.5,8.11\"/><path fill=\"none\" stroke=\"#000\" d=\"M17.5,11.25 C17.5,12.99 14.14,14.39 10,14.39 C5.86,14.39 2.5,12.98 2.5,11.25\"/><path fill=\"none\" stroke=\"#000\" d=\"M17.49,4.64 L17.5,14.36 C17.5,16.1 14.14,17.5 10,17.5 C5.86,17.5 2.5,16.09 2.5,14.36 L2.5,4.64\"/></svg>",
|
||||||
|
"desktop": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><rect x=\"8\" y=\"15\" width=\"1\" height=\"2\"/><rect x=\"11\" y=\"15\" width=\"1\" height=\"2\"/><rect x=\"5\" y=\"16\" width=\"10\" height=\"1\"/><rect fill=\"none\" stroke=\"#000\" x=\"1.5\" y=\"3.5\" width=\"17\" height=\"11\"/></svg>",
|
||||||
|
"download": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><polyline fill=\"none\" stroke=\"#000\" points=\"14,10 9.5,14.5 5,10\"/><rect x=\"3\" y=\"17\" width=\"13\" height=\"1\"/><line fill=\"none\" stroke=\"#000\" x1=\"9.5\" y1=\"13.91\" x2=\"9.5\" y2=\"3\"/></svg>",
|
||||||
|
"dribbble": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path fill=\"none\" stroke=\"#000\" stroke-width=\"1.4\" d=\"M1.3,8.9c0,0,5,0.1,8.6-1c1.4-0.4,2.6-0.9,4-1.9 c1.4-1.1,2.5-2.5,2.5-2.5\"/><path fill=\"none\" stroke=\"#000\" stroke-width=\"1.4\" d=\"M3.9,16.6c0,0,1.7-2.8,3.5-4.2 c1.8-1.3,4-2,5.7-2.2C16,10,19,10.6,19,10.6\"/><path fill=\"none\" stroke=\"#000\" stroke-width=\"1.4\" d=\"M6.9,1.6c0,0,3.3,4.6,4.2,6.8 c0.4,0.9,1.3,3.1,1.9,5.2c0.6,2,0.9,4.4,0.9,4.4\"/><circle fill=\"none\" stroke=\"#000\" stroke-width=\"1.4\" cx=\"10\" cy=\"10\" r=\"9\"/></svg>",
|
||||||
|
"etsy": "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\"><path d=\"M8,4.26C8,4.07,8,4,8.31,4h4.46c.79,0,1.22.67,1.53,1.91l.25,1h.76c.14-2.82.26-4,.26-4S13.65,3,12.52,3H6.81L3.75,2.92v.84l1,.2c.73.11.9.27,1,1,0,0,.06,2,.06,5.17s-.06,5.14-.06,5.14c0,.59-.23.81-1,.94l-1,.2v.84l3.06-.1h5.11c1.15,0,3.82.1,3.82.1,0-.7.45-3.88.51-4.22h-.73l-.76,1.69a2.25,2.25,0,0,1-2.45,1.47H9.4c-1,0-1.44-.4-1.44-1.24V10.44s2.16,0,2.86.06c.55,0,.85.19,1.06,1l.23,1H13L12.9,9.94,13,7.41h-.85l-.28,1.13c-.16.74-.28.84-1,1-1,.1-2.89.09-2.89.09Z\"/></svg>",
|
||||||
|
"expand": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><polygon points=\"13 2 18 2 18 7 17 7 17 3 13 3\"/><polygon points=\"2 13 3 13 3 17 7 17 7 18 2 18\"/><path fill=\"none\" stroke=\"#000\" stroke-width=\"1.1\" d=\"M11,9 L17,3\"/><path fill=\"none\" stroke=\"#000\" stroke-width=\"1.1\" d=\"M3,17 L9,11\"/></svg>",
|
||||||
|
"facebook": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M11,10h2.6l0.4-3H11V5.3c0-0.9,0.2-1.5,1.5-1.5H14V1.1c-0.3,0-1-0.1-2.1-0.1C9.6,1,8,2.4,8,5v2H5.5v3H8v8h3V10z\"/></svg>",
|
||||||
|
"file-edit": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path fill=\"none\" stroke=\"#000\" d=\"M18.65,1.68 C18.41,1.45 18.109,1.33 17.81,1.33 C17.499,1.33 17.209,1.45 16.98,1.68 L8.92,9.76 L8,12.33 L10.55,11.41 L18.651,3.34 C19.12,2.87 19.12,2.15 18.65,1.68 L18.65,1.68 L18.65,1.68 Z\"/><polyline fill=\"none\" stroke=\"#000\" points=\"16.5 8.482 16.5 18.5 3.5 18.5 3.5 1.5 14.211 1.5\"/></svg>",
|
||||||
|
"file-pdf": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><rect fill=\"none\" stroke=\"#000\" width=\"13\" height=\"17\" x=\"3.5\" y=\"1.5\"/><path d=\"M14.65 11.67c-.48.3-1.37-.19-1.79-.37a4.65 4.65 0 0 1 1.49.06c.35.1.36.28.3.31zm-6.3.06l.43-.79a14.7 14.7 0 0 0 .75-1.64 5.48 5.48 0 0 0 1.25 1.55l.2.15a16.36 16.36 0 0 0-2.63.73zM9.5 5.32c.2 0 .32.5.32.97a1.99 1.99 0 0 1-.23 1.04 5.05 5.05 0 0 1-.17-1.3s0-.71.08-.71zm-3.9 9a4.35 4.35 0 0 1 1.21-1.46l.24-.22a4.35 4.35 0 0 1-1.46 1.68zm9.23-3.3a2.05 2.05 0 0 0-1.32-.3 11.07 11.07 0 0 0-1.58.11 4.09 4.09 0 0 1-.74-.5 5.39 5.39 0 0 1-1.32-2.06 10.37 10.37 0 0 0 .28-2.62 1.83 1.83 0 0 0-.07-.25.57.57 0 0 0-.52-.4H9.4a.59.59 0 0 0-.6.38 6.95 6.95 0 0 0 .37 3.14c-.26.63-1 2.12-1 2.12-.3.58-.57 1.08-.82 1.5l-.8.44A3.11 3.11 0 0 0 5 14.16a.39.39 0 0 0 .15.42l.24.13c1.15.56 2.28-1.74 2.66-2.42a23.1 23.1 0 0 1 3.59-.85 4.56 4.56 0 0 0 2.91.8.5.5 0 0 0 .3-.21 1.1 1.1 0 0 0 .12-.75.84.84 0 0 0-.14-.25z\"/></svg>",
|
||||||
|
"file-text": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><rect fill=\"none\" stroke=\"#000\" width=\"13\" height=\"17\" x=\"3.5\" y=\"1.5\"/><line fill=\"none\" stroke=\"#000\" x1=\"6\" x2=\"12\" y1=\"12.5\" y2=\"12.5\"/><line fill=\"none\" stroke=\"#000\" x1=\"6\" x2=\"14\" y1=\"8.5\" y2=\"8.5\"/><line fill=\"none\" stroke=\"#000\" x1=\"6\" x2=\"14\" y1=\"6.5\" y2=\"6.5\"/><line fill=\"none\" stroke=\"#000\" x1=\"6\" x2=\"14\" y1=\"10.5\" y2=\"10.5\"/></svg>",
|
||||||
|
"file": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><rect fill=\"none\" stroke=\"#000\" x=\"3.5\" y=\"1.5\" width=\"13\" height=\"17\"/></svg>",
|
||||||
|
"flickr": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><circle cx=\"5.5\" cy=\"9.5\" r=\"3.5\"/><circle cx=\"14.5\" cy=\"9.5\" r=\"3.5\"/></svg>",
|
||||||
|
"folder": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><polygon fill=\"none\" stroke=\"#000\" points=\"9.5 5.5 8.5 3.5 1.5 3.5 1.5 16.5 18.5 16.5 18.5 5.5\"/></svg>",
|
||||||
|
"forward": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M2.47,13.11 C4.02,10.02 6.27,7.85 9.04,6.61 C9.48,6.41 10.27,6.13 11,5.91 L11,2 L18.89,9 L11,16 L11,12.13 C9.25,12.47 7.58,13.19 6.02,14.25 C3.03,16.28 1.63,18.54 1.63,18.54 C1.63,18.54 1.38,15.28 2.47,13.11 L2.47,13.11 Z M5.3,13.53 C6.92,12.4 9.04,11.4 12,10.92 L12,13.63 L17.36,9 L12,4.25 L12,6.8 C11.71,6.86 10.86,7.02 9.67,7.49 C6.79,8.65 4.58,10.96 3.49,13.08 C3.18,13.7 2.68,14.87 2.49,16 C3.28,15.05 4.4,14.15 5.3,13.53 L5.3,13.53 Z\"/></svg>",
|
||||||
|
"foursquare": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M15.23,2 C15.96,2 16.4,2.41 16.5,2.86 C16.57,3.15 16.56,3.44 16.51,3.73 C16.46,4.04 14.86,11.72 14.75,12.03 C14.56,12.56 14.16,12.82 13.61,12.83 C13.03,12.84 11.09,12.51 10.69,13 C10.38,13.38 7.79,16.39 6.81,17.53 C6.61,17.76 6.4,17.96 6.08,17.99 C5.68,18.04 5.29,17.87 5.17,17.45 C5.12,17.28 5.1,17.09 5.1,16.91 C5.1,12.4 4.86,7.81 5.11,3.31 C5.17,2.5 5.81,2.12 6.53,2 L15.23,2 L15.23,2 Z M9.76,11.42 C9.94,11.19 10.17,11.1 10.45,11.1 L12.86,11.1 C13.12,11.1 13.31,10.94 13.36,10.69 C13.37,10.64 13.62,9.41 13.74,8.83 C13.81,8.52 13.53,8.28 13.27,8.28 C12.35,8.29 11.42,8.28 10.5,8.28 C9.84,8.28 9.83,7.69 9.82,7.21 C9.8,6.85 10.13,6.55 10.5,6.55 C11.59,6.56 12.67,6.55 13.76,6.55 C14.03,6.55 14.23,6.4 14.28,6.14 C14.34,5.87 14.67,4.29 14.67,4.29 C14.67,4.29 14.82,3.74 14.19,3.74 L7.34,3.74 C7,3.75 6.84,4.02 6.84,4.33 C6.84,7.58 6.85,14.95 6.85,14.99 C6.87,15 8.89,12.51 9.76,11.42 L9.76,11.42 Z\"/></svg>",
|
||||||
|
"future": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><polyline points=\"19 2 18 2 18 6 14 6 14 7 19 7 19 2\"/><path fill=\"none\" stroke=\"#000\" stroke-width=\"1.1\" d=\"M18,6.548 C16.709,3.29 13.354,1 9.6,1 C4.6,1 0.6,5 0.6,10 C0.6,15 4.6,19 9.6,19 C14.6,19 18.6,15 18.6,10\"/><rect x=\"9\" y=\"4\" width=\"1\" height=\"7\"/><path d=\"M13.018,14.197 L9.445,10.625\" fill=\"none\" stroke=\"#000\" stroke-width=\"1.1\"/></svg>",
|
||||||
|
"git-branch": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><circle fill=\"none\" stroke=\"#000\" stroke-width=\"1.2\" cx=\"7\" cy=\"3\" r=\"2\"/><circle fill=\"none\" stroke=\"#000\" stroke-width=\"1.2\" cx=\"14\" cy=\"6\" r=\"2\"/><circle fill=\"none\" stroke=\"#000\" stroke-width=\"1.2\" cx=\"7\" cy=\"17\" r=\"2\"/><path fill=\"none\" stroke=\"#000\" stroke-width=\"2\" d=\"M14,8 C14,10.41 12.43,10.87 10.56,11.25 C9.09,11.54 7,12.06 7,15 L7,5\"/></svg>",
|
||||||
|
"git-fork": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><circle fill=\"none\" stroke=\"#000\" stroke-width=\"1.2\" cx=\"5.79\" cy=\"2.79\" r=\"1.79\"/><circle fill=\"none\" stroke=\"#000\" stroke-width=\"1.2\" cx=\"14.19\" cy=\"2.79\" r=\"1.79\"/><circle fill=\"none\" stroke=\"#000\" stroke-width=\"1.2\" cx=\"10.03\" cy=\"16.79\" r=\"1.79\"/><path fill=\"none\" stroke=\"#000\" stroke-width=\"2\" d=\"M5.79,4.57 L5.79,6.56 C5.79,9.19 10.03,10.22 10.03,13.31 C10.03,14.86 10.04,14.55 10.04,14.55 C10.04,14.37 10.04,14.86 10.04,13.31 C10.04,10.22 14.2,9.19 14.2,6.56 L14.2,4.57\"/></svg>",
|
||||||
|
"github-alt": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10,0.5 C4.75,0.5 0.5,4.76 0.5,10.01 C0.5,15.26 4.75,19.51 10,19.51 C15.24,19.51 19.5,15.26 19.5,10.01 C19.5,4.76 15.25,0.5 10,0.5 L10,0.5 Z M12.81,17.69 C12.81,17.69 12.81,17.7 12.79,17.69 C12.47,17.75 12.35,17.59 12.35,17.36 L12.35,16.17 C12.35,15.45 12.09,14.92 11.58,14.56 C12.2,14.51 12.77,14.39 13.26,14.21 C13.87,13.98 14.36,13.69 14.74,13.29 C15.42,12.59 15.76,11.55 15.76,10.17 C15.76,9.25 15.45,8.46 14.83,7.8 C15.1,7.08 15.07,6.29 14.75,5.44 L14.51,5.42 C14.34,5.4 14.06,5.46 13.67,5.61 C13.25,5.78 12.79,6.03 12.31,6.35 C11.55,6.16 10.81,6.05 10.09,6.05 C9.36,6.05 8.61,6.15 7.88,6.35 C7.28,5.96 6.75,5.68 6.26,5.54 C6.07,5.47 5.9,5.44 5.78,5.44 L5.42,5.44 C5.06,6.29 5.04,7.08 5.32,7.8 C4.7,8.46 4.4,9.25 4.4,10.17 C4.4,11.94 4.96,13.16 6.08,13.84 C6.53,14.13 7.05,14.32 7.69,14.43 C8.03,14.5 8.32,14.54 8.55,14.55 C8.07,14.89 7.82,15.42 7.82,16.16 L7.82,17.51 C7.8,17.69 7.7,17.8 7.51,17.8 C4.21,16.74 1.82,13.65 1.82,10.01 C1.82,5.5 5.49,1.83 10,1.83 C14.5,1.83 18.17,5.5 18.17,10.01 C18.18,13.53 15.94,16.54 12.81,17.69 L12.81,17.69 Z\"/></svg>",
|
||||||
|
"github": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10,1 C5.03,1 1,5.03 1,10 C1,13.98 3.58,17.35 7.16,18.54 C7.61,18.62 7.77,18.34 7.77,18.11 C7.77,17.9 7.76,17.33 7.76,16.58 C5.26,17.12 4.73,15.37 4.73,15.37 C4.32,14.33 3.73,14.05 3.73,14.05 C2.91,13.5 3.79,13.5 3.79,13.5 C4.69,13.56 5.17,14.43 5.17,14.43 C5.97,15.8 7.28,15.41 7.79,15.18 C7.87,14.6 8.1,14.2 8.36,13.98 C6.36,13.75 4.26,12.98 4.26,9.53 C4.26,8.55 4.61,7.74 5.19,7.11 C5.1,6.88 4.79,5.97 5.28,4.73 C5.28,4.73 6.04,4.49 7.75,5.65 C8.47,5.45 9.24,5.35 10,5.35 C10.76,5.35 11.53,5.45 12.25,5.65 C13.97,4.48 14.72,4.73 14.72,4.73 C15.21,5.97 14.9,6.88 14.81,7.11 C15.39,7.74 15.73,8.54 15.73,9.53 C15.73,12.99 13.63,13.75 11.62,13.97 C11.94,14.25 12.23,14.8 12.23,15.64 C12.23,16.84 12.22,17.81 12.22,18.11 C12.22,18.35 12.38,18.63 12.84,18.54 C16.42,17.35 19,13.98 19,10 C19,5.03 14.97,1 10,1 L10,1 Z\"/></svg>",
|
||||||
|
"gitter": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><rect x=\"3.5\" y=\"1\" width=\"1.531\" height=\"11.471\"/><rect x=\"7.324\" y=\"4.059\" width=\"1.529\" height=\"15.294\"/><rect x=\"11.148\" y=\"4.059\" width=\"1.527\" height=\"15.294\"/><rect x=\"14.971\" y=\"4.059\" width=\"1.529\" height=\"8.412\"/></svg>",
|
||||||
|
"google-plus": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M12.9,9c0,2.7-0.6,5-3.2,6.3c-3.7,1.8-8.1,0.2-9.4-3.6C-1.1,7.6,1.9,3.3,6.1,3c1.7-0.1,3.2,0.3,4.6,1.3 c0.1,0.1,0.3,0.2,0.4,0.4c-0.5,0.5-1.2,1-1.7,1.6c-1-0.8-2.1-1.1-3.5-0.9C5,5.6,4.2,6,3.6,6.7c-1.3,1.3-1.5,3.4-0.5,5 c1,1.7,2.6,2.3,4.6,1.9c1.4-0.3,2.4-1.2,2.6-2.6H6.9V9H12.9z\"/><polygon points=\"20,9 20,11 18,11 18,13 16,13 16,11 14,11 14,9 16,9 16,7 18,7 18,9\"/></svg>",
|
||||||
|
"google": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M17.86,9.09 C18.46,12.12 17.14,16.05 13.81,17.56 C9.45,19.53 4.13,17.68 2.47,12.87 C0.68,7.68 4.22,2.42 9.5,2.03 C11.57,1.88 13.42,2.37 15.05,3.65 C15.22,3.78 15.37,3.93 15.61,4.14 C14.9,4.81 14.23,5.45 13.5,6.14 C12.27,5.08 10.84,4.72 9.28,4.98 C8.12,5.17 7.16,5.76 6.37,6.63 C4.88,8.27 4.62,10.86 5.76,12.82 C6.95,14.87 9.17,15.8 11.57,15.25 C13.27,14.87 14.76,13.33 14.89,11.75 L10.51,11.75 L10.51,9.09 L17.86,9.09 L17.86,9.09 Z\"/></svg>",
|
||||||
|
"grid": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><rect x=\"2\" y=\"2\" width=\"3\" height=\"3\"/><rect x=\"8\" y=\"2\" width=\"3\" height=\"3\"/><rect x=\"14\" y=\"2\" width=\"3\" height=\"3\"/><rect x=\"2\" y=\"8\" width=\"3\" height=\"3\"/><rect x=\"8\" y=\"8\" width=\"3\" height=\"3\"/><rect x=\"14\" y=\"8\" width=\"3\" height=\"3\"/><rect x=\"2\" y=\"14\" width=\"3\" height=\"3\"/><rect x=\"8\" y=\"14\" width=\"3\" height=\"3\"/><rect x=\"14\" y=\"14\" width=\"3\" height=\"3\"/></svg>",
|
||||||
|
"happy": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><circle cx=\"13\" cy=\"7\" r=\"1\"/><circle cx=\"7\" cy=\"7\" r=\"1\"/><circle fill=\"none\" stroke=\"#000\" cx=\"10\" cy=\"10\" r=\"8.5\"/><path fill=\"none\" stroke=\"#000\" d=\"M14.6,11.4 C13.9,13.3 12.1,14.5 10,14.5 C7.9,14.5 6.1,13.3 5.4,11.4\"/></svg>",
|
||||||
|
"hashtag": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M15.431,8 L15.661,7 L12.911,7 L13.831,3 L12.901,3 L11.98,7 L9.29,7 L10.21,3 L9.281,3 L8.361,7 L5.23,7 L5,8 L8.13,8 L7.21,12 L4.23,12 L4,13 L6.98,13 L6.061,17 L6.991,17 L7.911,13 L10.601,13 L9.681,17 L10.611,17 L11.531,13 L14.431,13 L14.661,12 L11.76,12 L12.681,8 L15.431,8 Z M10.831,12 L8.141,12 L9.061,8 L11.75,8 L10.831,12 Z\"/></svg>",
|
||||||
|
"heart": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path fill=\"none\" stroke=\"#000\" stroke-width=\"1.03\" d=\"M10,4 C10,4 8.1,2 5.74,2 C3.38,2 1,3.55 1,6.73 C1,8.84 2.67,10.44 2.67,10.44 L10,18 L17.33,10.44 C17.33,10.44 19,8.84 19,6.73 C19,3.55 16.62,2 14.26,2 C11.9,2 10,4 10,4 L10,4 Z\"/></svg>",
|
||||||
|
"history": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><polyline fill=\"#000\" points=\"1 2 2 2 2 6 6 6 6 7 1 7 1 2\"/><path fill=\"none\" stroke=\"#000\" stroke-width=\"1.1\" d=\"M2.1,6.548 C3.391,3.29 6.746,1 10.5,1 C15.5,1 19.5,5 19.5,10 C19.5,15 15.5,19 10.5,19 C5.5,19 1.5,15 1.5,10\"/><rect x=\"9\" y=\"4\" width=\"1\" height=\"7\"/><path fill=\"none\" stroke=\"#000\" stroke-width=\"1.1\" d=\"M13.018,14.197 L9.445,10.625\"/></svg>",
|
||||||
|
"home": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><polygon points=\"18.65 11.35 10 2.71 1.35 11.35 0.65 10.65 10 1.29 19.35 10.65\"/><polygon points=\"15 4 18 4 18 7 17 7 17 5 15 5\"/><polygon points=\"3 11 4 11 4 18 7 18 7 12 12 12 12 18 16 18 16 11 17 11 17 19 11 19 11 13 8 13 8 19 3 19\"/></svg>",
|
||||||
|
"image": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><circle cx=\"16.1\" cy=\"6.1\" r=\"1.1\"/><rect fill=\"none\" stroke=\"#000\" x=\".5\" y=\"2.5\" width=\"19\" height=\"15\"/><polyline fill=\"none\" stroke=\"#000\" stroke-width=\"1.01\" points=\"4,13 8,9 13,14\"/><polyline fill=\"none\" stroke=\"#000\" stroke-width=\"1.01\" points=\"11,12 12.5,10.5 16,14\"/></svg>",
|
||||||
|
"info": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M12.13,11.59 C11.97,12.84 10.35,14.12 9.1,14.16 C6.17,14.2 9.89,9.46 8.74,8.37 C9.3,8.16 10.62,7.83 10.62,8.81 C10.62,9.63 10.12,10.55 9.88,11.32 C8.66,15.16 12.13,11.15 12.14,11.18 C12.16,11.21 12.16,11.35 12.13,11.59 C12.08,11.95 12.16,11.35 12.13,11.59 L12.13,11.59 Z M11.56,5.67 C11.56,6.67 9.36,7.15 9.36,6.03 C9.36,5 11.56,4.54 11.56,5.67 L11.56,5.67 Z\"/><circle fill=\"none\" stroke=\"#000\" stroke-width=\"1.1\" cx=\"10\" cy=\"10\" r=\"9\"/></svg>",
|
||||||
|
"instagram": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M13.55,1H6.46C3.45,1,1,3.44,1,6.44v7.12c0,3,2.45,5.44,5.46,5.44h7.08c3.02,0,5.46-2.44,5.46-5.44V6.44 C19.01,3.44,16.56,1,13.55,1z M17.5,14c0,1.93-1.57,3.5-3.5,3.5H6c-1.93,0-3.5-1.57-3.5-3.5V6c0-1.93,1.57-3.5,3.5-3.5h8 c1.93,0,3.5,1.57,3.5,3.5V14z\"/><circle cx=\"14.87\" cy=\"5.26\" r=\"1.09\"/><path d=\"M10.03,5.45c-2.55,0-4.63,2.06-4.63,4.6c0,2.55,2.07,4.61,4.63,4.61c2.56,0,4.63-2.061,4.63-4.61 C14.65,7.51,12.58,5.45,10.03,5.45L10.03,5.45L10.03,5.45z M10.08,13c-1.66,0-3-1.34-3-2.99c0-1.65,1.34-2.99,3-2.99s3,1.34,3,2.99 C13.08,11.66,11.74,13,10.08,13L10.08,13L10.08,13z\"/></svg>",
|
||||||
|
"italic": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M12.63,5.48 L10.15,14.52 C10,15.08 10.37,15.25 11.92,15.3 L11.72,16 L6,16 L6.2,15.31 C7.78,15.26 8.19,15.09 8.34,14.53 L10.82,5.49 C10.97,4.92 10.63,4.76 9.09,4.71 L9.28,4 L15,4 L14.81,4.69 C13.23,4.75 12.78,4.91 12.63,5.48 L12.63,5.48 Z\"/></svg>",
|
||||||
|
"joomla": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M7.8,13.4l1.7-1.7L5.9,8c-0.6-0.5-0.6-1.5,0-2c0.6-0.6,1.4-0.6,2,0l1.7-1.7c-1-1-2.3-1.3-3.6-1C5.8,2.2,4.8,1.4,3.7,1.4 c-1.3,0-2.3,1-2.3,2.3c0,1.1,0.8,2,1.8,2.3c-0.4,1.3-0.1,2.8,1,3.8L7.8,13.4L7.8,13.4z\"/><path d=\"M10.2,4.3c1-1,2.5-1.4,3.8-1c0.2-1.1,1.1-2,2.3-2c1.3,0,2.3,1,2.3,2.3c0,1.2-0.9,2.2-2,2.3c0.4,1.3,0,2.8-1,3.8L13.9,8 c0.6-0.5,0.6-1.5,0-2c-0.5-0.6-1.5-0.6-2,0L8.2,9.7L6.5,8\"/><path d=\"M14.1,16.8c-1.3,0.4-2.8,0.1-3.8-1l1.7-1.7c0.6,0.6,1.5,0.6,2,0c0.5-0.6,0.6-1.5,0-2l-3.7-3.7L12,6.7l3.7,3.7 c1,1,1.3,2.4,1,3.6c1.1,0.2,2,1.1,2,2.3c0,1.3-1,2.3-2.3,2.3C15.2,18.6,14.3,17.8,14.1,16.8\"/><path d=\"M13.2,12.2l-3.7,3.7c-1,1-2.4,1.3-3.6,1c-0.2,1-1.2,1.8-2.2,1.8c-1.3,0-2.3-1-2.3-2.3c0-1.1,0.8-2,1.8-2.3 c-0.3-1.3,0-2.7,1-3.7l1.7,1.7c-0.6,0.6-0.6,1.5,0,2c0.6,0.6,1.4,0.6,2,0l3.7-3.7\"/></svg>",
|
||||||
|
"laptop": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><rect y=\"16\" width=\"20\" height=\"1\"/><rect fill=\"none\" stroke=\"#000\" x=\"2.5\" y=\"4.5\" width=\"15\" height=\"10\"/></svg>",
|
||||||
|
"lifesaver": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10,0.5 C4.76,0.5 0.5,4.76 0.5,10 C0.5,15.24 4.76,19.5 10,19.5 C15.24,19.5 19.5,15.24 19.5,10 C19.5,4.76 15.24,0.5 10,0.5 L10,0.5 Z M10,1.5 C11.49,1.5 12.89,1.88 14.11,2.56 L11.85,4.82 C11.27,4.61 10.65,4.5 10,4.5 C9.21,4.5 8.47,4.67 7.79,4.96 L5.58,2.75 C6.87,1.95 8.38,1.5 10,1.5 L10,1.5 Z M4.96,7.8 C4.67,8.48 4.5,9.21 4.5,10 C4.5,10.65 4.61,11.27 4.83,11.85 L2.56,14.11 C1.88,12.89 1.5,11.49 1.5,10 C1.5,8.38 1.95,6.87 2.75,5.58 L4.96,7.79 L4.96,7.8 L4.96,7.8 Z M10,18.5 C8.25,18.5 6.62,17.97 5.27,17.06 L7.46,14.87 C8.22,15.27 9.08,15.5 10,15.5 C10.79,15.5 11.53,15.33 12.21,15.04 L14.42,17.25 C13.13,18.05 11.62,18.5 10,18.5 L10,18.5 Z M10,14.5 C7.52,14.5 5.5,12.48 5.5,10 C5.5,7.52 7.52,5.5 10,5.5 C12.48,5.5 14.5,7.52 14.5,10 C14.5,12.48 12.48,14.5 10,14.5 L10,14.5 Z M15.04,12.21 C15.33,11.53 15.5,10.79 15.5,10 C15.5,9.08 15.27,8.22 14.87,7.46 L17.06,5.27 C17.97,6.62 18.5,8.25 18.5,10 C18.5,11.62 18.05,13.13 17.25,14.42 L15.04,12.21 L15.04,12.21 Z\"/></svg>",
|
||||||
|
"link": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path fill=\"none\" stroke=\"#000\" stroke-width=\"1.1\" d=\"M10.625,12.375 L7.525,15.475 C6.825,16.175 5.925,16.175 5.225,15.475 L4.525,14.775 C3.825,14.074 3.825,13.175 4.525,12.475 L7.625,9.375\"/><path fill=\"none\" stroke=\"#000\" stroke-width=\"1.1\" d=\"M9.325,7.375 L12.425,4.275 C13.125,3.575 14.025,3.575 14.724,4.275 L15.425,4.975 C16.125,5.675 16.125,6.575 15.425,7.275 L12.325,10.375\"/><path fill=\"none\" stroke=\"#000\" stroke-width=\"1.1\" d=\"M7.925,11.875 L11.925,7.975\"/></svg>",
|
||||||
|
"linkedin": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M5.77,17.89 L5.77,7.17 L2.21,7.17 L2.21,17.89 L5.77,17.89 L5.77,17.89 Z M3.99,5.71 C5.23,5.71 6.01,4.89 6.01,3.86 C5.99,2.8 5.24,2 4.02,2 C2.8,2 2,2.8 2,3.85 C2,4.88 2.77,5.7 3.97,5.7 L3.99,5.7 L3.99,5.71 L3.99,5.71 Z\"/><path d=\"M7.75,17.89 L11.31,17.89 L11.31,11.9 C11.31,11.58 11.33,11.26 11.43,11.03 C11.69,10.39 12.27,9.73 13.26,9.73 C14.55,9.73 15.06,10.71 15.06,12.15 L15.06,17.89 L18.62,17.89 L18.62,11.74 C18.62,8.45 16.86,6.92 14.52,6.92 C12.6,6.92 11.75,7.99 11.28,8.73 L11.3,8.73 L11.3,7.17 L7.75,7.17 C7.79,8.17 7.75,17.89 7.75,17.89 L7.75,17.89 L7.75,17.89 Z\"/></svg>",
|
||||||
|
"list": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><rect x=\"6\" y=\"4\" width=\"12\" height=\"1\"/><rect x=\"6\" y=\"9\" width=\"12\" height=\"1\"/><rect x=\"6\" y=\"14\" width=\"12\" height=\"1\"/><rect x=\"2\" y=\"4\" width=\"2\" height=\"1\"/><rect x=\"2\" y=\"9\" width=\"2\" height=\"1\"/><rect x=\"2\" y=\"14\" width=\"2\" height=\"1\"/></svg>",
|
||||||
|
"location": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path fill=\"none\" stroke=\"#000\" stroke-width=\"1.01\" d=\"M10,0.5 C6.41,0.5 3.5,3.39 3.5,6.98 C3.5,11.83 10,19 10,19 C10,19 16.5,11.83 16.5,6.98 C16.5,3.39 13.59,0.5 10,0.5 L10,0.5 Z\"/><circle fill=\"none\" stroke=\"#000\" cx=\"10\" cy=\"6.8\" r=\"2.3\"/></svg>",
|
||||||
|
"lock": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><rect fill=\"none\" stroke=\"#000\" height=\"10\" width=\"13\" y=\"8.5\" x=\"3.5\"/><path fill=\"none\" stroke=\"#000\" d=\"M6.5,8 L6.5,4.88 C6.5,3.01 8.07,1.5 10,1.5 C11.93,1.5 13.5,3.01 13.5,4.88 L13.5,8\"/></svg>",
|
||||||
|
"mail": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><polyline fill=\"none\" stroke=\"#000\" points=\"1.4,6.5 10,11 18.6,6.5\"/><path d=\"M 1,4 1,16 19,16 19,4 1,4 Z M 18,15 2,15 2,5 18,5 18,15 Z\"/></svg>",
|
||||||
|
"menu": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><rect x=\"2\" y=\"4\" width=\"16\" height=\"1\"/><rect x=\"2\" y=\"9\" width=\"16\" height=\"1\"/><rect x=\"2\" y=\"14\" width=\"16\" height=\"1\"/></svg>",
|
||||||
|
"microphone": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><line fill=\"none\" stroke=\"#000\" x1=\"10\" x2=\"10\" y1=\"16.44\" y2=\"18.5\"/><line fill=\"none\" stroke=\"#000\" x1=\"7\" x2=\"13\" y1=\"18.5\" y2=\"18.5\"/><path fill=\"none\" stroke=\"#000\" stroke-width=\"1.1\" d=\"M13.5 4.89v5.87a3.5 3.5 0 0 1-7 0V4.89a3.5 3.5 0 0 1 7 0z\"/><path fill=\"none\" stroke=\"#000\" stroke-width=\"1.1\" d=\"M15.5 10.36V11a5.5 5.5 0 0 1-11 0v-.6\"/></svg>",
|
||||||
|
"minus-circle": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><circle fill=\"none\" stroke=\"#000\" stroke-width=\"1.1\" cx=\"9.5\" cy=\"9.5\" r=\"9\"/><line fill=\"none\" stroke=\"#000\" x1=\"5\" y1=\"9.5\" x2=\"14\" y2=\"9.5\"/></svg>",
|
||||||
|
"minus": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><rect height=\"1\" width=\"18\" y=\"9\" x=\"1\"/></svg>",
|
||||||
|
"more-vertical": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><circle cx=\"10\" cy=\"3\" r=\"2\"/><circle cx=\"10\" cy=\"10\" r=\"2\"/><circle cx=\"10\" cy=\"17\" r=\"2\"/></svg>",
|
||||||
|
"more": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><circle cx=\"3\" cy=\"10\" r=\"2\"/><circle cx=\"10\" cy=\"10\" r=\"2\"/><circle cx=\"17\" cy=\"10\" r=\"2\"/></svg>",
|
||||||
|
"move": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><polygon points=\"4,5 1,5 1,9 2,9 2,6 4,6\"/><polygon points=\"1,16 2,16 2,18 4,18 4,19 1,19\"/><polygon points=\"14,16 14,19 11,19 11,18 13,18 13,16\"/><rect fill=\"none\" stroke=\"#000\" x=\"5.5\" y=\"1.5\" width=\"13\" height=\"13\"/><rect x=\"1\" y=\"11\" width=\"1\" height=\"3\"/><rect x=\"6\" y=\"18\" width=\"3\" height=\"1\"/></svg>",
|
||||||
|
"nut": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><polygon fill=\"none\" stroke=\"#000\" points=\"2.5,5.7 10,1.3 17.5,5.7 17.5,14.3 10,18.7 2.5,14.3\"/><circle fill=\"none\" stroke=\"#000\" cx=\"10\" cy=\"10\" r=\"3.5\"/></svg>",
|
||||||
|
"pagekit": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><polygon points=\"3,1 17,1 17,16 10,16 10,13 14,13 14,4 6,4 6,16 10,16 10,19 3,19\"/></svg>",
|
||||||
|
"paint-bucket": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10.21,1 L0,11.21 L8.1,19.31 L18.31,9.1 L10.21,1 L10.21,1 Z M16.89,9.1 L15,11 L1.7,11 L10.21,2.42 L16.89,9.1 Z\"/><path fill=\"none\" stroke=\"#000\" stroke-width=\"1.1\" d=\"M6.42,2.33 L11.7,7.61\"/><path d=\"M18.49,12 C18.49,12 20,14.06 20,15.36 C20,16.28 19.24,17 18.49,17 L18.49,17 C17.74,17 17,16.28 17,15.36 C17,14.06 18.49,12 18.49,12 L18.49,12 Z\"/></svg>",
|
||||||
|
"pencil": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path fill=\"none\" stroke=\"#000\" d=\"M17.25,6.01 L7.12,16.1 L3.82,17.2 L5.02,13.9 L15.12,3.88 C15.71,3.29 16.66,3.29 17.25,3.88 C17.83,4.47 17.83,5.42 17.25,6.01 L17.25,6.01 Z\"/><path fill=\"none\" stroke=\"#000\" d=\"M15.98,7.268 L13.851,5.148\"/></svg>",
|
||||||
|
"phone-landscape": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path fill=\"none\" stroke=\"#000\" d=\"M17,5.5 C17.8,5.5 18.5,6.2 18.5,7 L18.5,14 C18.5,14.8 17.8,15.5 17,15.5 L3,15.5 C2.2,15.5 1.5,14.8 1.5,14 L1.5,7 C1.5,6.2 2.2,5.5 3,5.5 L17,5.5 L17,5.5 L17,5.5 Z\"/><circle cx=\"3.8\" cy=\"10.5\" r=\".8\"/></svg>",
|
||||||
|
"phone": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path fill=\"none\" stroke=\"#000\" d=\"M15.5,17 C15.5,17.8 14.8,18.5 14,18.5 L7,18.5 C6.2,18.5 5.5,17.8 5.5,17 L5.5,3 C5.5,2.2 6.2,1.5 7,1.5 L14,1.5 C14.8,1.5 15.5,2.2 15.5,3 L15.5,17 L15.5,17 L15.5,17 Z\"/><circle cx=\"10.5\" cy=\"16.5\" r=\".8\"/></svg>",
|
||||||
|
"pinterest": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10.21,1 C5.5,1 3,4.16 3,7.61 C3,9.21 3.85,11.2 5.22,11.84 C5.43,11.94 5.54,11.89 5.58,11.69 C5.62,11.54 5.8,10.8 5.88,10.45 C5.91,10.34 5.89,10.24 5.8,10.14 C5.36,9.59 5,8.58 5,7.65 C5,5.24 6.82,2.91 9.93,2.91 C12.61,2.91 14.49,4.74 14.49,7.35 C14.49,10.3 13,12.35 11.06,12.35 C9.99,12.35 9.19,11.47 9.44,10.38 C9.75,9.08 10.35,7.68 10.35,6.75 C10.35,5.91 9.9,5.21 8.97,5.21 C7.87,5.21 6.99,6.34 6.99,7.86 C6.99,8.83 7.32,9.48 7.32,9.48 C7.32,9.48 6.24,14.06 6.04,14.91 C5.7,16.35 6.08,18.7 6.12,18.9 C6.14,19.01 6.26,19.05 6.33,18.95 C6.44,18.81 7.74,16.85 8.11,15.44 C8.24,14.93 8.79,12.84 8.79,12.84 C9.15,13.52 10.19,14.09 11.29,14.09 C14.58,14.09 16.96,11.06 16.96,7.3 C16.94,3.7 14,1 10.21,1\"/></svg>",
|
||||||
|
"play-circle": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><polygon fill=\"none\" stroke=\"#000\" stroke-width=\"1.1\" points=\"8.5 7 13.5 10 8.5 13\"/><circle fill=\"none\" stroke=\"#000\" stroke-width=\"1.1\" cx=\"10\" cy=\"10\" r=\"9\"/></svg>",
|
||||||
|
"play": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><polygon fill=\"none\" stroke=\"#000\" points=\"6.5,5 14.5,10 6.5,15\"/></svg>",
|
||||||
|
"plus-circle": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><circle fill=\"none\" stroke=\"#000\" stroke-width=\"1.1\" cx=\"9.5\" cy=\"9.5\" r=\"9\"/><line fill=\"none\" stroke=\"#000\" x1=\"9.5\" y1=\"5\" x2=\"9.5\" y2=\"14\"/><line fill=\"none\" stroke=\"#000\" x1=\"5\" y1=\"9.5\" x2=\"14\" y2=\"9.5\"/></svg>",
|
||||||
|
"plus": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><rect x=\"9\" y=\"1\" width=\"1\" height=\"17\"/><rect x=\"1\" y=\"9\" width=\"17\" height=\"1\"/></svg>",
|
||||||
|
"print": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><polyline fill=\"none\" stroke=\"#000\" points=\"4.5 13.5 1.5 13.5 1.5 6.5 18.5 6.5 18.5 13.5 15.5 13.5\"/><polyline fill=\"none\" stroke=\"#000\" points=\"15.5 6.5 15.5 2.5 4.5 2.5 4.5 6.5\"/><rect fill=\"none\" stroke=\"#000\" width=\"11\" height=\"6\" x=\"4.5\" y=\"11.5\"/><rect width=\"8\" height=\"1\" x=\"6\" y=\"13\"/><rect width=\"8\" height=\"1\" x=\"6\" y=\"15\"/></svg>",
|
||||||
|
"pull": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><polygon points=\"6.85,8 9.5,10.6 12.15,8 12.85,8.7 9.5,12 6.15,8.7\"/><line fill=\"none\" stroke=\"#000\" x1=\"9.5\" y1=\"11\" x2=\"9.5\" y2=\"2\"/><polyline fill=\"none\" stroke=\"#000\" points=\"6,5.5 3.5,5.5 3.5,18.5 15.5,18.5 15.5,5.5 13,5.5\"/></svg>",
|
||||||
|
"push": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><polygon points=\"12.15,4 9.5,1.4 6.85,4 6.15,3.3 9.5,0 12.85,3.3\"/><line fill=\"none\" stroke=\"#000\" x1=\"9.5\" y1=\"10\" x2=\"9.5\" y2=\"1\"/><polyline fill=\"none\" stroke=\"#000\" points=\"6 5.5 3.5 5.5 3.5 18.5 15.5 18.5 15.5 5.5 13 5.5\"/></svg>",
|
||||||
|
"question": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><circle fill=\"none\" stroke=\"#000\" stroke-width=\"1.1\" cx=\"10\" cy=\"10\" r=\"9\"/><circle cx=\"10.44\" cy=\"14.42\" r=\"1.05\"/><path fill=\"none\" stroke=\"#000\" stroke-width=\"1.2\" d=\"M8.17,7.79 C8.17,4.75 12.72,4.73 12.72,7.72 C12.72,8.67 11.81,9.15 11.23,9.75 C10.75,10.24 10.51,10.73 10.45,11.4 C10.44,11.53 10.43,11.64 10.43,11.75\"/></svg>",
|
||||||
|
"quote-right": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M17.27,7.79 C17.27,9.45 16.97,10.43 15.99,12.02 C14.98,13.64 13,15.23 11.56,15.97 L11.1,15.08 C12.34,14.2 13.14,13.51 14.02,11.82 C14.27,11.34 14.41,10.92 14.49,10.54 C14.3,10.58 14.09,10.6 13.88,10.6 C12.06,10.6 10.59,9.12 10.59,7.3 C10.59,5.48 12.06,4 13.88,4 C15.39,4 16.67,5.02 17.05,6.42 C17.19,6.82 17.27,7.27 17.27,7.79 L17.27,7.79 Z\"/><path d=\"M8.68,7.79 C8.68,9.45 8.38,10.43 7.4,12.02 C6.39,13.64 4.41,15.23 2.97,15.97 L2.51,15.08 C3.75,14.2 4.55,13.51 5.43,11.82 C5.68,11.34 5.82,10.92 5.9,10.54 C5.71,10.58 5.5,10.6 5.29,10.6 C3.47,10.6 2,9.12 2,7.3 C2,5.48 3.47,4 5.29,4 C6.8,4 8.08,5.02 8.46,6.42 C8.6,6.82 8.68,7.27 8.68,7.79 L8.68,7.79 Z\"/></svg>",
|
||||||
|
"receiver": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path fill=\"none\" stroke=\"#000\" stroke-width=\"1.01\" d=\"M6.189,13.611C8.134,15.525 11.097,18.239 13.867,18.257C16.47,18.275 18.2,16.241 18.2,16.241L14.509,12.551L11.539,13.639L6.189,8.29L7.313,5.355L3.76,1.8C3.76,1.8 1.732,3.537 1.7,6.092C1.667,8.809 4.347,11.738 6.189,13.611\"/></svg>",
|
||||||
|
"reddit": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M19 9.05a2.56 2.56 0 0 0-2.56-2.56 2.59 2.59 0 0 0-1.88.82 10.63 10.63 0 0 0-4.14-1v-.08c.58-1.62 1.58-3.89 2.7-4.1.38-.08.77.12 1.19.57a1.15 1.15 0 0 0-.06.37 1.48 1.48 0 1 0 1.51-1.45 1.43 1.43 0 0 0-.76.19A2.29 2.29 0 0 0 12.91 1c-2.11.43-3.39 4.38-3.63 5.19 0 0 0 .11-.06.11a10.65 10.65 0 0 0-3.75 1A2.56 2.56 0 0 0 1 9.05a2.42 2.42 0 0 0 .72 1.76A5.18 5.18 0 0 0 1.24 13c0 3.66 3.92 6.64 8.73 6.64s8.74-3 8.74-6.64a5.23 5.23 0 0 0-.46-2.13A2.58 2.58 0 0 0 19 9.05zm-16.88 0a1.44 1.44 0 0 1 2.27-1.19 7.68 7.68 0 0 0-2.07 1.91 1.33 1.33 0 0 1-.2-.72zM10 18.4c-4.17 0-7.55-2.4-7.55-5.4S5.83 7.53 10 7.53 17.5 10 17.5 13s-3.38 5.4-7.5 5.4zm7.69-8.61a7.62 7.62 0 0 0-2.09-1.91 1.41 1.41 0 0 1 .84-.28 1.47 1.47 0 0 1 1.44 1.45 1.34 1.34 0 0 1-.21.72z\"/><path d=\"M6.69 12.58a1.39 1.39 0 1 1 1.39-1.39 1.38 1.38 0 0 1-1.38 1.39z\"/><path d=\"M14.26 11.2a1.39 1.39 0 1 1-1.39-1.39 1.39 1.39 0 0 1 1.39 1.39z\"/><path d=\"M13.09 14.88a.54.54 0 0 1-.09.77 5.3 5.3 0 0 1-3.26 1.19 5.61 5.61 0 0 1-3.4-1.22.55.55 0 1 1 .73-.83 4.09 4.09 0 0 0 5.25 0 .56.56 0 0 1 .77.09z\"/></svg>",
|
||||||
|
"refresh": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path fill=\"none\" stroke=\"#000\" stroke-width=\"1.1\" d=\"M17.08,11.15 C17.09,11.31 17.1,11.47 17.1,11.64 C17.1,15.53 13.94,18.69 10.05,18.69 C6.16,18.68 3,15.53 3,11.63 C3,7.74 6.16,4.58 10.05,4.58 C10.9,4.58 11.71,4.73 12.46,5\"/><polyline fill=\"none\" stroke=\"#000\" points=\"9.9 2 12.79 4.89 9.79 7.9\"/></svg>",
|
||||||
|
"reply": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M17.7,13.11 C16.12,10.02 13.84,7.85 11.02,6.61 C10.57,6.41 9.75,6.13 9,5.91 L9,2 L1,9 L9,16 L9,12.13 C10.78,12.47 12.5,13.19 14.09,14.25 C17.13,16.28 18.56,18.54 18.56,18.54 C18.56,18.54 18.81,15.28 17.7,13.11 L17.7,13.11 Z M14.82,13.53 C13.17,12.4 11.01,11.4 8,10.92 L8,13.63 L2.55,9 L8,4.25 L8,6.8 C8.3,6.86 9.16,7.02 10.37,7.49 C13.3,8.65 15.54,10.96 16.65,13.08 C16.97,13.7 17.48,14.86 17.68,16 C16.87,15.05 15.73,14.15 14.82,13.53 L14.82,13.53 Z\"/></svg>",
|
||||||
|
"rss": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><circle cx=\"3.12\" cy=\"16.8\" r=\"1.85\"/><path fill=\"none\" stroke=\"#000\" stroke-width=\"1.1\" d=\"M1.5,8.2 C1.78,8.18 2.06,8.16 2.35,8.16 C7.57,8.16 11.81,12.37 11.81,17.57 C11.81,17.89 11.79,18.19 11.76,18.5\"/><path fill=\"none\" stroke=\"#000\" stroke-width=\"1.1\" d=\"M1.5,2.52 C1.78,2.51 2.06,2.5 2.35,2.5 C10.72,2.5 17.5,9.24 17.5,17.57 C17.5,17.89 17.49,18.19 17.47,18.5\"/></svg>",
|
||||||
|
"search": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><circle fill=\"none\" stroke=\"#000\" stroke-width=\"1.1\" cx=\"9\" cy=\"9\" r=\"7\"/><path fill=\"none\" stroke=\"#000\" stroke-width=\"1.1\" d=\"M14,14 L18,18 L14,14 Z\"/></svg>",
|
||||||
|
"server": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><rect x=\"3\" y=\"3\" width=\"1\" height=\"2\"/><rect x=\"5\" y=\"3\" width=\"1\" height=\"2\"/><rect x=\"7\" y=\"3\" width=\"1\" height=\"2\"/><rect x=\"16\" y=\"3\" width=\"1\" height=\"1\"/><rect x=\"16\" y=\"10\" width=\"1\" height=\"1\"/><circle fill=\"none\" stroke=\"#000\" cx=\"9.9\" cy=\"17.4\" r=\"1.4\"/><rect x=\"3\" y=\"10\" width=\"1\" height=\"2\"/><rect x=\"5\" y=\"10\" width=\"1\" height=\"2\"/><rect x=\"9.5\" y=\"14\" width=\"1\" height=\"2\"/><rect x=\"3\" y=\"17\" width=\"6\" height=\"1\"/><rect x=\"11\" y=\"17\" width=\"6\" height=\"1\"/><rect fill=\"none\" stroke=\"#000\" x=\"1.5\" y=\"1.5\" width=\"17\" height=\"5\"/><rect fill=\"none\" stroke=\"#000\" x=\"1.5\" y=\"8.5\" width=\"17\" height=\"5\"/></svg>",
|
||||||
|
"settings": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><ellipse fill=\"none\" stroke=\"#000\" cx=\"6.11\" cy=\"3.55\" rx=\"2.11\" ry=\"2.15\"/><ellipse fill=\"none\" stroke=\"#000\" cx=\"6.11\" cy=\"15.55\" rx=\"2.11\" ry=\"2.15\"/><circle fill=\"none\" stroke=\"#000\" cx=\"13.15\" cy=\"9.55\" r=\"2.15\"/><rect x=\"1\" y=\"3\" width=\"3\" height=\"1\"/><rect x=\"10\" y=\"3\" width=\"8\" height=\"1\"/><rect x=\"1\" y=\"9\" width=\"8\" height=\"1\"/><rect x=\"15\" y=\"9\" width=\"3\" height=\"1\"/><rect x=\"1\" y=\"15\" width=\"3\" height=\"1\"/><rect x=\"10\" y=\"15\" width=\"8\" height=\"1\"/></svg>",
|
||||||
|
"shrink": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><polygon points=\"11 4 12 4 12 8 16 8 16 9 11 9\"/><polygon points=\"4 11 9 11 9 16 8 16 8 12 4 12\"/><path fill=\"none\" stroke=\"#000\" stroke-width=\"1.1\" d=\"M12,8 L18,2\"/><path fill=\"none\" stroke=\"#000\" stroke-width=\"1.1\" d=\"M2,18 L8,12\"/></svg>",
|
||||||
|
"sign-in": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><polygon points=\"7 2 17 2 17 17 7 17 7 16 16 16 16 3 7 3\"/><polygon points=\"9.1 13.4 8.5 12.8 11.28 10 4 10 4 9 11.28 9 8.5 6.2 9.1 5.62 13 9.5\"/></svg>",
|
||||||
|
"sign-out": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><polygon points=\"13.1 13.4 12.5 12.8 15.28 10 8 10 8 9 15.28 9 12.5 6.2 13.1 5.62 17 9.5\"/><polygon points=\"13 2 3 2 3 17 13 17 13 16 4 16 4 3 13 3\"/></svg>",
|
||||||
|
"social": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><line fill=\"none\" stroke=\"#000\" stroke-width=\"1.1\" x1=\"13.4\" y1=\"14\" x2=\"6.3\" y2=\"10.7\"/><line fill=\"none\" stroke=\"#000\" stroke-width=\"1.1\" x1=\"13.5\" y1=\"5.5\" x2=\"6.5\" y2=\"8.8\"/><circle fill=\"none\" stroke=\"#000\" stroke-width=\"1.1\" cx=\"15.5\" cy=\"4.6\" r=\"2.3\"/><circle fill=\"none\" stroke=\"#000\" stroke-width=\"1.1\" cx=\"15.5\" cy=\"14.8\" r=\"2.3\"/><circle fill=\"none\" stroke=\"#000\" stroke-width=\"1.1\" cx=\"4.5\" cy=\"9.8\" r=\"2.3\"/></svg>",
|
||||||
|
"soundcloud": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M17.2,9.4c-0.4,0-0.8,0.1-1.101,0.2c-0.199-2.5-2.399-4.5-5-4.5c-0.6,0-1.2,0.1-1.7,0.3C9.2,5.5,9.1,5.6,9.1,5.6V15h8 c1.601,0,2.801-1.2,2.801-2.8C20,10.7,18.7,9.4,17.2,9.4L17.2,9.4z\"/><rect x=\"6\" y=\"6.5\" width=\"1.5\" height=\"8.5\"/><rect x=\"3\" y=\"8\" width=\"1.5\" height=\"7\"/><rect y=\"10\" width=\"1.5\" height=\"5\"/></svg>",
|
||||||
|
"star": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><polygon fill=\"none\" stroke=\"#000\" stroke-width=\"1.01\" points=\"10 2 12.63 7.27 18.5 8.12 14.25 12.22 15.25 18 10 15.27 4.75 18 5.75 12.22 1.5 8.12 7.37 7.27\"/></svg>",
|
||||||
|
"strikethrough": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6,13.02 L6.65,13.02 C7.64,15.16 8.86,16.12 10.41,16.12 C12.22,16.12 12.92,14.93 12.92,13.89 C12.92,12.55 11.99,12.03 9.74,11.23 C8.05,10.64 6.23,10.11 6.23,7.83 C6.23,5.5 8.09,4.09 10.4,4.09 C11.44,4.09 12.13,4.31 12.72,4.54 L13.33,4 L13.81,4 L13.81,7.59 L13.16,7.59 C12.55,5.88 11.52,4.89 10.07,4.89 C8.84,4.89 7.89,5.69 7.89,7.03 C7.89,8.29 8.89,8.78 10.88,9.45 C12.57,10.03 14.38,10.6 14.38,12.91 C14.38,14.75 13.27,16.93 10.18,16.93 C9.18,16.93 8.17,16.69 7.46,16.39 L6.52,17 L6,17 L6,13.02 L6,13.02 Z\"/><rect x=\"3\" y=\"10\" width=\"15\" height=\"1\"/></svg>",
|
||||||
|
"table": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><rect x=\"1\" y=\"3\" width=\"18\" height=\"1\"/><rect x=\"1\" y=\"7\" width=\"18\" height=\"1\"/><rect x=\"1\" y=\"11\" width=\"18\" height=\"1\"/><rect x=\"1\" y=\"15\" width=\"18\" height=\"1\"/></svg>",
|
||||||
|
"tablet-landscape": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path fill=\"none\" stroke=\"#000\" d=\"M1.5,5 C1.5,4.2 2.2,3.5 3,3.5 L17,3.5 C17.8,3.5 18.5,4.2 18.5,5 L18.5,16 C18.5,16.8 17.8,17.5 17,17.5 L3,17.5 C2.2,17.5 1.5,16.8 1.5,16 L1.5,5 L1.5,5 L1.5,5 Z\"/><circle cx=\"3.7\" cy=\"10.5\" r=\".8\"/></svg>",
|
||||||
|
"tablet": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path fill=\"none\" stroke=\"#000\" d=\"M5,18.5 C4.2,18.5 3.5,17.8 3.5,17 L3.5,3 C3.5,2.2 4.2,1.5 5,1.5 L16,1.5 C16.8,1.5 17.5,2.2 17.5,3 L17.5,17 C17.5,17.8 16.8,18.5 16,18.5 L5,18.5 L5,18.5 L5,18.5 Z\"/><circle cx=\"10.5\" cy=\"16.3\" r=\".8\"/></svg>",
|
||||||
|
"tag": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path fill=\"none\" stroke=\"#000\" stroke-width=\"1.1\" d=\"M17.5,3.71 L17.5,7.72 C17.5,7.96 17.4,8.2 17.21,8.39 L8.39,17.2 C7.99,17.6 7.33,17.6 6.93,17.2 L2.8,13.07 C2.4,12.67 2.4,12.01 2.8,11.61 L11.61,2.8 C11.81,2.6 12.08,2.5 12.34,2.5 L16.19,2.5 C16.52,2.5 16.86,2.63 17.11,2.88 C17.35,3.11 17.48,3.4 17.5,3.71 L17.5,3.71 Z\"/><circle cx=\"14\" cy=\"6\" r=\"1\"/></svg>",
|
||||||
|
"thumbnails": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><rect fill=\"none\" stroke=\"#000\" x=\"3.5\" y=\"3.5\" width=\"5\" height=\"5\"/><rect fill=\"none\" stroke=\"#000\" x=\"11.5\" y=\"3.5\" width=\"5\" height=\"5\"/><rect fill=\"none\" stroke=\"#000\" x=\"11.5\" y=\"11.5\" width=\"5\" height=\"5\"/><rect fill=\"none\" stroke=\"#000\" x=\"3.5\" y=\"11.5\" width=\"5\" height=\"5\"/></svg>",
|
||||||
|
"trash": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><polyline fill=\"none\" stroke=\"#000\" points=\"6.5 3 6.5 1.5 13.5 1.5 13.5 3\"/><polyline fill=\"none\" stroke=\"#000\" points=\"4.5 4 4.5 18.5 15.5 18.5 15.5 4\"/><rect x=\"8\" y=\"7\" width=\"1\" height=\"9\"/><rect x=\"11\" y=\"7\" width=\"1\" height=\"9\"/><rect x=\"2\" y=\"3\" width=\"16\" height=\"1\"/></svg>",
|
||||||
|
"triangle-down": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><polygon points=\"5 7 15 7 10 12\"/></svg>",
|
||||||
|
"triangle-left": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><polygon points=\"12 5 7 10 12 15\"/></svg>",
|
||||||
|
"triangle-right": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><polygon points=\"8 5 13 10 8 15\"/></svg>",
|
||||||
|
"triangle-up": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><polygon points=\"5 13 10 8 15 13\"/></svg>",
|
||||||
|
"tripadvisor": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M19.021,7.866C19.256,6.862,20,5.854,20,5.854h-3.346C14.781,4.641,12.504,4,9.98,4C7.363,4,4.999,4.651,3.135,5.876H0\tc0,0,0.738,0.987,0.976,1.988c-0.611,0.837-0.973,1.852-0.973,2.964c0,2.763,2.249,5.009,5.011,5.009\tc1.576,0,2.976-0.737,3.901-1.879l1.063,1.599l1.075-1.615c0.475,0.611,1.1,1.111,1.838,1.451c1.213,0.547,2.574,0.612,3.825,0.15\tc2.589-0.963,3.913-3.852,2.964-6.439c-0.175-0.463-0.4-0.876-0.675-1.238H19.021z M16.38,14.594\tc-1.002,0.371-2.088,0.328-3.06-0.119c-0.688-0.317-1.252-0.817-1.657-1.438c-0.164-0.25-0.313-0.52-0.417-0.811\tc-0.124-0.328-0.186-0.668-0.217-1.014c-0.063-0.689,0.037-1.396,0.339-2.043c0.448-0.971,1.251-1.71,2.25-2.079\tc2.075-0.765,4.375,0.3,5.14,2.366c0.762,2.066-0.301,4.37-2.363,5.134L16.38,14.594L16.38,14.594z M8.322,13.066\tc-0.72,1.059-1.935,1.76-3.309,1.76c-2.207,0-4.001-1.797-4.001-3.996c0-2.203,1.795-4.002,4.001-4.002\tc2.204,0,3.999,1.8,3.999,4.002c0,0.137-0.024,0.261-0.04,0.396c-0.067,0.678-0.284,1.313-0.648,1.853v-0.013H8.322z M2.472,10.775\tc0,1.367,1.112,2.479,2.476,2.479c1.363,0,2.472-1.11,2.472-2.479c0-1.359-1.11-2.468-2.472-2.468\tC3.584,8.306,2.473,9.416,2.472,10.775L2.472,10.775z M12.514,10.775c0,1.367,1.104,2.479,2.471,2.479\tc1.363,0,2.474-1.108,2.474-2.479c0-1.359-1.11-2.468-2.474-2.468c-1.364,0-2.477,1.109-2.477,2.468H12.514z M3.324,10.775\tc0-0.893,0.726-1.618,1.614-1.618c0.889,0,1.625,0.727,1.625,1.618c0,0.898-0.725,1.627-1.625,1.627\tc-0.901,0-1.625-0.729-1.625-1.627H3.324z M13.354,10.775c0-0.893,0.726-1.618,1.627-1.618c0.886,0,1.61,0.727,1.61,1.618\tc0,0.898-0.726,1.627-1.626,1.627s-1.625-0.729-1.625-1.627H13.354z M9.977,4.875c1.798,0,3.425,0.324,4.849,0.968\tc-0.535,0.015-1.061,0.108-1.586,0.3c-1.264,0.463-2.264,1.388-2.815,2.604c-0.262,0.551-0.398,1.133-0.448,1.72\tC9.79,7.905,7.677,5.873,5.076,5.82C6.501,5.208,8.153,4.875,9.94,4.875H9.977z\"/></svg>",
|
||||||
|
"tumblr": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6.885,8.598c0,0,0,3.393,0,4.996c0,0.282,0,0.66,0.094,0.942c0.377,1.509,1.131,2.545,2.545,3.11 c1.319,0.472,2.356,0.472,3.676,0c0.565-0.188,1.132-0.659,1.132-0.659l-0.849-2.263c0,0-1.036,0.378-1.603,0.283 c-0.565-0.094-1.226-0.66-1.226-1.508c0-1.603,0-4.902,0-4.902h2.828V5.771h-2.828V2H8.205c0,0-0.094,0.66-0.188,0.942 C7.828,3.791,7.262,4.733,6.603,5.394C5.848,6.147,5,6.43,5,6.43v2.168H6.885z\"/></svg>",
|
||||||
|
"tv": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><rect x=\"7\" y=\"16\" width=\"6\" height=\"1\"/><rect fill=\"none\" stroke=\"#000\" x=\".5\" y=\"3.5\" width=\"19\" height=\"11\"/></svg>",
|
||||||
|
"twitter": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M19,4.74 C18.339,5.029 17.626,5.229 16.881,5.32 C17.644,4.86 18.227,4.139 18.503,3.28 C17.79,3.7 17.001,4.009 16.159,4.17 C15.485,3.45 14.526,3 13.464,3 C11.423,3 9.771,4.66 9.771,6.7 C9.771,6.99 9.804,7.269 9.868,7.539 C6.795,7.38 4.076,5.919 2.254,3.679 C1.936,4.219 1.754,4.86 1.754,5.539 C1.754,6.82 2.405,7.95 3.397,8.61 C2.79,8.589 2.22,8.429 1.723,8.149 L1.723,8.189 C1.723,9.978 2.997,11.478 4.686,11.82 C4.376,11.899 4.049,11.939 3.713,11.939 C3.475,11.939 3.245,11.919 3.018,11.88 C3.49,13.349 4.852,14.419 6.469,14.449 C5.205,15.429 3.612,16.019 1.882,16.019 C1.583,16.019 1.29,16.009 1,15.969 C2.635,17.019 4.576,17.629 6.662,17.629 C13.454,17.629 17.17,12 17.17,7.129 C17.17,6.969 17.166,6.809 17.157,6.649 C17.879,6.129 18.504,5.478 19,4.74\"/></svg>",
|
||||||
|
"uikit": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><polygon points=\"14.4,3.1 11.3,5.1 15,7.3 15,12.9 10,15.7 5,12.9 5,8.5 2,6.8 2,14.8 9.9,19.5 18,14.8 18,5.3\"/><polygon points=\"9.8,4.2 6.7,2.4 9.8,0.4 12.9,2.3\"/></svg>",
|
||||||
|
"unlock": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><rect fill=\"none\" stroke=\"#000\" x=\"3.5\" y=\"8.5\" width=\"13\" height=\"10\"/><path fill=\"none\" stroke=\"#000\" d=\"M6.5,8.5 L6.5,4.9 C6.5,3 8.1,1.5 10,1.5 C11.9,1.5 13.5,3 13.5,4.9\"/></svg>",
|
||||||
|
"upload": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><polyline fill=\"none\" stroke=\"#000\" points=\"5 8 9.5 3.5 14 8\"/><rect x=\"3\" y=\"17\" width=\"13\" height=\"1\"/><line fill=\"none\" stroke=\"#000\" x1=\"9.5\" y1=\"15\" x2=\"9.5\" y2=\"4\"/></svg>",
|
||||||
|
"user": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><circle fill=\"none\" stroke=\"#000\" stroke-width=\"1.1\" cx=\"9.9\" cy=\"6.4\" r=\"4.4\"/><path fill=\"none\" stroke=\"#000\" stroke-width=\"1.1\" d=\"M1.5,19 C2.3,14.5 5.8,11.2 10,11.2 C14.2,11.2 17.7,14.6 18.5,19.2\"/></svg>",
|
||||||
|
"users": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><circle fill=\"none\" stroke=\"#000\" stroke-width=\"1.1\" cx=\"7.7\" cy=\"8.6\" r=\"3.5\"/><path fill=\"none\" stroke=\"#000\" stroke-width=\"1.1\" d=\"M1,18.1 C1.7,14.6 4.4,12.1 7.6,12.1 C10.9,12.1 13.7,14.8 14.3,18.3\"/><path fill=\"none\" stroke=\"#000\" stroke-width=\"1.1\" d=\"M11.4,4 C12.8,2.4 15.4,2.8 16.3,4.7 C17.2,6.6 15.7,8.9 13.6,8.9 C16.5,8.9 18.8,11.3 19.2,14.1\"/></svg>",
|
||||||
|
"video-camera": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><polygon fill=\"none\" stroke=\"#000\" points=\"17.5 6.9 17.5 13.1 13.5 10.4 13.5 14.5 2.5 14.5 2.5 5.5 13.5 5.5 13.5 9.6 17.5 6.9\"/></svg>",
|
||||||
|
"vimeo": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M2.065,7.59C1.84,7.367,1.654,7.082,1.468,6.838c-0.332-0.42-0.137-0.411,0.274-0.772c1.026-0.91,2.004-1.896,3.127-2.688 c1.017-0.713,2.365-1.173,3.286-0.039c0.849,1.045,0.869,2.629,1.084,3.891c0.215,1.309,0.421,2.648,0.88,3.901 c0.127,0.352,0.37,1.018,0.81,1.074c0.567,0.078,1.145-0.917,1.408-1.289c0.684-0.987,1.611-2.317,1.494-3.587 c-0.115-1.349-1.572-1.095-2.482-0.773c0.146-1.514,1.555-3.216,2.912-3.792c1.439-0.597,3.579-0.587,4.302,1.036 c0.772,1.759,0.078,3.802-0.763,5.396c-0.918,1.731-2.1,3.333-3.363,4.829c-1.114,1.329-2.432,2.787-4.093,3.422 c-1.897,0.723-3.021-0.686-3.667-2.318c-0.705-1.777-1.056-3.771-1.565-5.621C4.898,8.726,4.644,7.836,4.136,7.191 C3.473,6.358,2.72,7.141,2.065,7.59C1.977,7.502,2.115,7.551,2.065,7.59L2.065,7.59z\"/></svg>",
|
||||||
|
"warning": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><circle cx=\"10\" cy=\"14\" r=\"1\"/><circle fill=\"none\" stroke=\"#000\" stroke-width=\"1.1\" cx=\"10\" cy=\"10\" r=\"9\"/><path d=\"M10.97,7.72 C10.85,9.54 10.56,11.29 10.56,11.29 C10.51,11.87 10.27,12 9.99,12 C9.69,12 9.49,11.87 9.43,11.29 C9.43,11.29 9.16,9.54 9.03,7.72 C8.96,6.54 9.03,6 9.03,6 C9.03,5.45 9.46,5.02 9.99,5 C10.53,5.01 10.97,5.44 10.97,6 C10.97,6 11.04,6.54 10.97,7.72 L10.97,7.72 Z\"/></svg>",
|
||||||
|
"whatsapp": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M16.7,3.3c-1.8-1.8-4.1-2.8-6.7-2.8c-5.2,0-9.4,4.2-9.4,9.4c0,1.7,0.4,3.3,1.3,4.7l-1.3,4.9l5-1.3c1.4,0.8,2.9,1.2,4.5,1.2 l0,0l0,0c5.2,0,9.4-4.2,9.4-9.4C19.5,7.4,18.5,5,16.7,3.3 M10.1,17.7L10.1,17.7c-1.4,0-2.8-0.4-4-1.1l-0.3-0.2l-3,0.8l0.8-2.9 l-0.2-0.3c-0.8-1.2-1.2-2.7-1.2-4.2c0-4.3,3.5-7.8,7.8-7.8c2.1,0,4.1,0.8,5.5,2.3c1.5,1.5,2.3,3.4,2.3,5.5 C17.9,14.2,14.4,17.7,10.1,17.7 M14.4,11.9c-0.2-0.1-1.4-0.7-1.6-0.8c-0.2-0.1-0.4-0.1-0.5,0.1c-0.2,0.2-0.6,0.8-0.8,0.9 c-0.1,0.2-0.3,0.2-0.5,0.1c-0.2-0.1-1-0.4-1.9-1.2c-0.7-0.6-1.2-1.4-1.3-1.6c-0.1-0.2,0-0.4,0.1-0.5C8,8.8,8.1,8.7,8.2,8.5 c0.1-0.1,0.2-0.2,0.2-0.4c0.1-0.2,0-0.3,0-0.4C8.4,7.6,7.9,6.5,7.7,6C7.5,5.5,7.3,5.6,7.2,5.6c-0.1,0-0.3,0-0.4,0 c-0.2,0-0.4,0.1-0.6,0.3c-0.2,0.2-0.8,0.8-0.8,2c0,1.2,0.8,2.3,1,2.4c0.1,0.2,1.7,2.5,4,3.5c0.6,0.2,1,0.4,1.3,0.5 c0.6,0.2,1.1,0.2,1.5,0.1c0.5-0.1,1.4-0.6,1.6-1.1c0.2-0.5,0.2-1,0.1-1.1C14.8,12.1,14.6,12,14.4,11.9\"/></svg>",
|
||||||
|
"wordpress": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10,0.5c-5.2,0-9.5,4.3-9.5,9.5s4.3,9.5,9.5,9.5c5.2,0,9.5-4.3,9.5-9.5S15.2,0.5,10,0.5L10,0.5L10,0.5z M15.6,3.9h-0.1 c-0.8,0-1.4,0.7-1.4,1.5c0,0.7,0.4,1.3,0.8,1.9c0.3,0.6,0.7,1.3,0.7,2.3c0,0.7-0.3,1.5-0.6,2.7L14.1,15l-3-8.9 c0.5,0,0.9-0.1,0.9-0.1C12.5,6,12.5,5.3,12,5.4c0,0-1.3,0.1-2.2,0.1C9,5.5,7.7,5.4,7.7,5.4C7.2,5.3,7.2,6,7.6,6c0,0,0.4,0.1,0.9,0.1 l1.3,3.5L8,15L5,6.1C5.5,6.1,5.9,6,5.9,6C6.4,6,6.3,5.3,5.9,5.4c0,0-1.3,0.1-2.2,0.1c-0.2,0-0.3,0-0.5,0c1.5-2.2,4-3.7,6.9-3.7 C12.2,1.7,14.1,2.6,15.6,3.9L15.6,3.9L15.6,3.9z M2.5,6.6l3.9,10.8c-2.7-1.3-4.6-4.2-4.6-7.4C1.8,8.8,2,7.6,2.5,6.6L2.5,6.6L2.5,6.6 z M10.2,10.7l2.5,6.9c0,0,0,0.1,0.1,0.1C11.9,18,11,18.2,10,18.2c-0.8,0-1.6-0.1-2.3-0.3L10.2,10.7L10.2,10.7L10.2,10.7z M14.2,17.1 l2.5-7.3c0.5-1.2,0.6-2.1,0.6-2.9c0-0.3,0-0.6-0.1-0.8c0.6,1.2,1,2.5,1,4C18.3,13,16.6,15.7,14.2,17.1L14.2,17.1L14.2,17.1z\"/></svg>",
|
||||||
|
"world": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path fill=\"none\" stroke=\"#000\" d=\"M1,10.5 L19,10.5\"/><path fill=\"none\" stroke=\"#000\" d=\"M2.35,15.5 L17.65,15.5\"/><path fill=\"none\" stroke=\"#000\" d=\"M2.35,5.5 L17.523,5.5\"/><path fill=\"none\" stroke=\"#000\" d=\"M10,19.46 L9.98,19.46 C7.31,17.33 5.61,14.141 5.61,10.58 C5.61,7.02 7.33,3.83 10,1.7 C10.01,1.7 9.99,1.7 10,1.7 L10,1.7 C12.67,3.83 14.4,7.02 14.4,10.58 C14.4,14.141 12.67,17.33 10,19.46 L10,19.46 L10,19.46 L10,19.46 Z\"/><circle fill=\"none\" stroke=\"#000\" cx=\"10\" cy=\"10.5\" r=\"9\"/></svg>",
|
||||||
|
"xing": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M4.4,4.56 C4.24,4.56 4.11,4.61 4.05,4.72 C3.98,4.83 3.99,4.97 4.07,5.12 L5.82,8.16 L5.82,8.17 L3.06,13.04 C2.99,13.18 2.99,13.33 3.06,13.44 C3.12,13.55 3.24,13.62 3.4,13.62 L6,13.62 C6.39,13.62 6.57,13.36 6.71,13.12 C6.71,13.12 9.41,8.35 9.51,8.16 C9.49,8.14 7.72,5.04 7.72,5.04 C7.58,4.81 7.39,4.56 6.99,4.56 L4.4,4.56 L4.4,4.56 Z\"/><path d=\"M15.3,1 C14.91,1 14.74,1.25 14.6,1.5 C14.6,1.5 9.01,11.42 8.82,11.74 C8.83,11.76 12.51,18.51 12.51,18.51 C12.64,18.74 12.84,19 13.23,19 L15.82,19 C15.98,19 16.1,18.94 16.16,18.83 C16.23,18.72 16.23,18.57 16.16,18.43 L12.5,11.74 L12.5,11.72 L18.25,1.56 C18.32,1.42 18.32,1.27 18.25,1.16 C18.21,1.06 18.08,1 17.93,1 L15.3,1 L15.3,1 Z\"/></svg>",
|
||||||
|
"yelp": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M17.175,14.971c-0.112,0.77-1.686,2.767-2.406,3.054c-0.246,0.1-0.487,0.076-0.675-0.069\tc-0.122-0.096-2.446-3.859-2.446-3.859c-0.194-0.293-0.157-0.682,0.083-0.978c0.234-0.284,0.581-0.393,0.881-0.276\tc0.016,0.01,4.21,1.394,4.332,1.482c0.178,0.148,0.263,0.379,0.225,0.646L17.175,14.971L17.175,14.971z M11.464,10.789\tc-0.203-0.307-0.199-0.666,0.009-0.916c0,0,2.625-3.574,2.745-3.657c0.203-0.135,0.452-0.141,0.69-0.025\tc0.691,0.335,2.085,2.405,2.167,3.199v0.027c0.024,0.271-0.082,0.491-0.273,0.623c-0.132,0.083-4.43,1.155-4.43,1.155\tc-0.322,0.096-0.68-0.06-0.882-0.381L11.464,10.789z M9.475,9.563C9.32,9.609,8.848,9.757,8.269,8.817c0,0-3.916-6.16-4.007-6.351\tc-0.057-0.212,0.011-0.455,0.202-0.65C5.047,1.211,8.21,0.327,9.037,0.529c0.27,0.069,0.457,0.238,0.522,0.479\tc0.047,0.266,0.433,5.982,0.488,7.264C10.098,9.368,9.629,9.517,9.475,9.563z M9.927,19.066c-0.083,0.225-0.273,0.373-0.54,0.421\tc-0.762,0.13-3.15-0.751-3.647-1.342c-0.096-0.131-0.155-0.262-0.167-0.394c-0.011-0.095,0-0.189,0.036-0.272\tc0.061-0.155,2.917-3.538,2.917-3.538c0.214-0.272,0.595-0.355,0.952-0.213c0.345,0.13,0.56,0.428,0.536,0.749\tC10.014,14.479,9.977,18.923,9.927,19.066z M3.495,13.912c-0.235-0.009-0.444-0.148-0.568-0.382c-0.089-0.17-0.151-0.453-0.19-0.794\tC2.63,11.701,2.761,10.144,3.07,9.648c0.145-0.226,0.357-0.345,0.592-0.336c0.154,0,4.255,1.667,4.255,1.667\tc0.321,0.118,0.521,0.453,0.5,0.833c-0.023,0.37-0.236,0.655-0.551,0.738L3.495,13.912z\"/></svg>",
|
||||||
|
"youtube": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M15,4.1c1,0.1,2.3,0,3,0.8c0.8,0.8,0.9,2.1,0.9,3.1C19,9.2,19,10.9,19,12c-0.1,1.1,0,2.4-0.5,3.4c-0.5,1.1-1.4,1.5-2.5,1.6 c-1.2,0.1-8.6,0.1-11,0c-1.1-0.1-2.4-0.1-3.2-1c-0.7-0.8-0.7-2-0.8-3C1,11.8,1,10.1,1,8.9c0-1.1,0-2.4,0.5-3.4C2,4.5,3,4.3,4.1,4.2 C5.3,4.1,12.6,4,15,4.1z M8,7.5v6l5.5-3L8,7.5z\"/></svg>"
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof window !== 'undefined' && window.UIkit) {
|
||||||
|
window.UIkit.use(plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
return plugin;
|
||||||
|
|
||||||
|
})));
|
3
static/js/uikit-icons.min.js
vendored
Normal file
3
static/js/uikit-icons.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
12173
static/js/uikit.js
Normal file
12173
static/js/uikit.js
Normal file
File diff suppressed because it is too large
Load Diff
3
static/js/uikit.min.js
vendored
Normal file
3
static/js/uikit.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
45
templates.go
Normal file
45
templates.go
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"html/template"
|
||||||
|
"io"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/gobuffalo/packr"
|
||||||
|
"github.com/labstack/echo/v4"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Template is a template struct
|
||||||
|
type Template struct {
|
||||||
|
templates *template.Template
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render is a method that render templates
|
||||||
|
func (t *Template) Render(w io.Writer, name string, data interface{}, c echo.Context) error {
|
||||||
|
if strings.HasSuffix(name, ".html") {
|
||||||
|
c.Response().Header().Set(echo.HeaderContentType, echo.MIMETextHTMLCharsetUTF8)
|
||||||
|
} else if strings.HasSuffix(name, ".js") {
|
||||||
|
c.Response().Header().Set(echo.HeaderContentType, echo.MIMETextPlain)
|
||||||
|
} else if strings.HasSuffix(name, ".css") {
|
||||||
|
c.Response().Header().Set(echo.HeaderContentType, echo.MIMETextPlain)
|
||||||
|
}
|
||||||
|
return t.templates.ExecuteTemplate(w, name, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// BuildTemplates converts packr packages to html/template
|
||||||
|
func BuildTemplates(box packr.Box) (builttemplates *Template, err error) {
|
||||||
|
tmpl := template.New("template")
|
||||||
|
|
||||||
|
for _, filename := range box.List() {
|
||||||
|
fmt.Println(filename)
|
||||||
|
tmplContent, _ := box.FindString(filename)
|
||||||
|
tmpl.New(filename).Parse(tmplContent)
|
||||||
|
}
|
||||||
|
|
||||||
|
builttemplate := &Template{
|
||||||
|
templates: tmpl,
|
||||||
|
}
|
||||||
|
|
||||||
|
return builttemplate, nil
|
||||||
|
}
|
0
templates/admin.html
Normal file
0
templates/admin.html
Normal file
8
templates/error.html
Normal file
8
templates/error.html
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Public IP Address</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Error</h1>
|
||||||
|
</body>
|
||||||
|
</html>
|
5
templates/head.html
Normal file
5
templates/head.html
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<link rel="stylesheet" href="css/uikit.min.css" />
|
||||||
|
<script src="js/uikit.min.js"></script>
|
||||||
|
<script src="js/uikit-icons.min.js"></script>
|
10
templates/index.html
Normal file
10
templates/index.html
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Public IP Address</title>
|
||||||
|
{{ template "head.html" .}}
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>IP: {{ .IP }}</h1>
|
||||||
|
<h2>Reverse DNS: {{ .Hostname }}</h2>
|
||||||
|
</body>
|
||||||
|
</html>
|
30
vendor/github.com/gobuffalo/envy/.gitignore
generated
vendored
Normal file
30
vendor/github.com/gobuffalo/envy/.gitignore
generated
vendored
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
*.log
|
||||||
|
.DS_Store
|
||||||
|
doc
|
||||||
|
tmp
|
||||||
|
pkg
|
||||||
|
*.gem
|
||||||
|
*.pid
|
||||||
|
coverage
|
||||||
|
coverage.data
|
||||||
|
build/*
|
||||||
|
*.pbxuser
|
||||||
|
*.mode1v3
|
||||||
|
.svn
|
||||||
|
profile
|
||||||
|
.console_history
|
||||||
|
.sass-cache/*
|
||||||
|
.rake_tasks~
|
||||||
|
*.log.lck
|
||||||
|
solr/
|
||||||
|
.jhw-cache/
|
||||||
|
jhw.*
|
||||||
|
*.sublime*
|
||||||
|
node_modules/
|
||||||
|
dist/
|
||||||
|
generated/
|
||||||
|
.vendor/
|
||||||
|
bin/*
|
||||||
|
gin-bin
|
||||||
|
.idea/
|
||||||
|
.env
|
3
vendor/github.com/gobuffalo/envy/.gometalinter.json
generated
vendored
Normal file
3
vendor/github.com/gobuffalo/envy/.gometalinter.json
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"Enable": ["vet", "golint", "goimports", "deadcode", "gotype", "ineffassign", "misspell", "nakedret", "unconvert", "megacheck", "varcheck"]
|
||||||
|
}
|
8
vendor/github.com/gobuffalo/envy/LICENSE.txt
generated
vendored
Normal file
8
vendor/github.com/gobuffalo/envy/LICENSE.txt
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
The MIT License (MIT)
|
||||||
|
Copyright (c) 2018 Mark Bates
|
||||||
|
|
||||||
|
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.
|
46
vendor/github.com/gobuffalo/envy/Makefile
generated
vendored
Normal file
46
vendor/github.com/gobuffalo/envy/Makefile
generated
vendored
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
TAGS ?= "sqlite"
|
||||||
|
GO_BIN ?= go
|
||||||
|
|
||||||
|
install:
|
||||||
|
packr2
|
||||||
|
$(GO_BIN) install -v .
|
||||||
|
|
||||||
|
deps:
|
||||||
|
$(GO_BIN) get github.com/gobuffalo/release
|
||||||
|
$(GO_BIN) get github.com/gobuffalo/packr/v2/packr2
|
||||||
|
$(GO_BIN) get -tags ${TAGS} -t ./...
|
||||||
|
ifeq ($(GO111MODULE),on)
|
||||||
|
$(GO_BIN) mod tidy
|
||||||
|
endif
|
||||||
|
|
||||||
|
build:
|
||||||
|
packr2
|
||||||
|
$(GO_BIN) build -v .
|
||||||
|
|
||||||
|
test:
|
||||||
|
packr2
|
||||||
|
$(GO_BIN) test -tags ${TAGS} ./...
|
||||||
|
|
||||||
|
ci-test:
|
||||||
|
$(GO_BIN) test -tags ${TAGS} -race ./...
|
||||||
|
|
||||||
|
lint:
|
||||||
|
gometalinter --vendor ./... --deadline=1m --skip=internal
|
||||||
|
|
||||||
|
update:
|
||||||
|
$(GO_BIN) get -u -tags ${TAGS}
|
||||||
|
ifeq ($(GO111MODULE),on)
|
||||||
|
$(GO_BIN) mod tidy
|
||||||
|
endif
|
||||||
|
packr2
|
||||||
|
make test
|
||||||
|
make install
|
||||||
|
ifeq ($(GO111MODULE),on)
|
||||||
|
$(GO_BIN) mod tidy
|
||||||
|
endif
|
||||||
|
|
||||||
|
release-test:
|
||||||
|
$(GO_BIN) test -tags ${TAGS} -race ./...
|
||||||
|
|
||||||
|
release:
|
||||||
|
release -y -f version.go
|
93
vendor/github.com/gobuffalo/envy/README.md
generated
vendored
Normal file
93
vendor/github.com/gobuffalo/envy/README.md
generated
vendored
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
# envy
|
||||||
|
[![Build Status](https://travis-ci.org/gobuffalo/envy.svg?branch=master)](https://travis-ci.org/gobuffalo/envy)
|
||||||
|
|
||||||
|
Envy makes working with ENV variables in Go trivial.
|
||||||
|
|
||||||
|
* Get ENV variables with default values.
|
||||||
|
* Set ENV variables safely without affecting the underlying system.
|
||||||
|
* Temporarily change ENV vars; useful for testing.
|
||||||
|
* Map all of the key/values in the ENV.
|
||||||
|
* Loads .env files (by using [godotenv](https://github.com/joho/godotenv/))
|
||||||
|
* More!
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
```text
|
||||||
|
$ go get -u github.com/gobuffalo/envy
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```go
|
||||||
|
func Test_Get(t *testing.T) {
|
||||||
|
r := require.New(t)
|
||||||
|
r.NotZero(os.Getenv("GOPATH"))
|
||||||
|
r.Equal(os.Getenv("GOPATH"), envy.Get("GOPATH", "foo"))
|
||||||
|
r.Equal("bar", envy.Get("IDONTEXIST", "bar"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_MustGet(t *testing.T) {
|
||||||
|
r := require.New(t)
|
||||||
|
r.NotZero(os.Getenv("GOPATH"))
|
||||||
|
v, err := envy.MustGet("GOPATH")
|
||||||
|
r.NoError(err)
|
||||||
|
r.Equal(os.Getenv("GOPATH"), v)
|
||||||
|
|
||||||
|
_, err = envy.MustGet("IDONTEXIST")
|
||||||
|
r.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_Set(t *testing.T) {
|
||||||
|
r := require.New(t)
|
||||||
|
_, err := envy.MustGet("FOO")
|
||||||
|
r.Error(err)
|
||||||
|
|
||||||
|
envy.Set("FOO", "foo")
|
||||||
|
r.Equal("foo", envy.Get("FOO", "bar"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_Temp(t *testing.T) {
|
||||||
|
r := require.New(t)
|
||||||
|
|
||||||
|
_, err := envy.MustGet("BAR")
|
||||||
|
r.Error(err)
|
||||||
|
|
||||||
|
envy.Temp(func() {
|
||||||
|
envy.Set("BAR", "foo")
|
||||||
|
r.Equal("foo", envy.Get("BAR", "bar"))
|
||||||
|
_, err = envy.MustGet("BAR")
|
||||||
|
r.NoError(err)
|
||||||
|
})
|
||||||
|
|
||||||
|
_, err = envy.MustGet("BAR")
|
||||||
|
r.Error(err)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
## .env files support
|
||||||
|
|
||||||
|
Envy now supports loading `.env` files by using the [godotenv library](https://github.com/joho/godotenv/).
|
||||||
|
That means one can use and define multiple `.env` files which will be loaded on-demand. By default, no env files will be loaded. To load one or more, you need to call the `envy.Load` function in one of the following ways:
|
||||||
|
|
||||||
|
```go
|
||||||
|
envy.Load() // 1
|
||||||
|
|
||||||
|
envy.Load("MY_ENV_FILE") // 2
|
||||||
|
|
||||||
|
envy.Load(".env", ".env.prod") // 3
|
||||||
|
|
||||||
|
envy.Load(".env", "NON_EXISTING_FILE") // 4
|
||||||
|
|
||||||
|
// 5
|
||||||
|
envy.Load(".env")
|
||||||
|
envy.Load("NON_EXISTING_FILE")
|
||||||
|
|
||||||
|
// 6
|
||||||
|
envy.Load(".env", "NON_EXISTING_FILE", ".env.prod")
|
||||||
|
```
|
||||||
|
|
||||||
|
1. Will load the default `.env` file
|
||||||
|
2. Will load the file `MY_ENV_FILE`, **but not** `.env`
|
||||||
|
3. Will load the file `.env`, and after that will load the `.env.prod` file. If any variable is redefined in `. env.prod` it will be overwritten (will contain the `env.prod` value)
|
||||||
|
4. Will load the `.env` file and return an error as the second file does not exist. The values in `.env` will be loaded and available.
|
||||||
|
5. Same as 4
|
||||||
|
6. Will load the `.env` file and return an error as the second file does not exist. The values in `.env` will be loaded and available, **but the ones in** `.env.prod` **won't**.
|
14
vendor/github.com/gobuffalo/envy/SHOULDERS.md
generated
vendored
Normal file
14
vendor/github.com/gobuffalo/envy/SHOULDERS.md
generated
vendored
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
# github.com/gobuffalo/envy Stands on the Shoulders of Giants
|
||||||
|
|
||||||
|
github.com/gobuffalo/envy does not try to reinvent the wheel! Instead, it uses the already great wheels developed by the Go community and puts them all together in the best way possible. Without these giants, this project would not be possible. Please make sure to check them out and thank them for all of their hard work.
|
||||||
|
|
||||||
|
Thank you to the following **GIANTS**:
|
||||||
|
|
||||||
|
|
||||||
|
* [github.com/davecgh/go-spew](https://godoc.org/github.com/davecgh/go-spew)
|
||||||
|
|
||||||
|
* [github.com/joho/godotenv](https://godoc.org/github.com/joho/godotenv)
|
||||||
|
|
||||||
|
* [github.com/rogpeppe/go-internal](https://godoc.org/github.com/rogpeppe/go-internal)
|
||||||
|
|
||||||
|
* [github.com/stretchr/testify](https://godoc.org/github.com/stretchr/testify)
|
59
vendor/github.com/gobuffalo/envy/azure-pipelines.yml
generated
vendored
Normal file
59
vendor/github.com/gobuffalo/envy/azure-pipelines.yml
generated
vendored
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
variables:
|
||||||
|
GOBIN: "$(GOPATH)/bin" # Go binaries path
|
||||||
|
GOPATH: "$(system.defaultWorkingDirectory)/gopath" # Go workspace path
|
||||||
|
modulePath: "$(GOPATH)/src/github.com/$(build.repository.name)" # Path to the module"s code
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
- job: Windows
|
||||||
|
pool:
|
||||||
|
vmImage: "vs2017-win2016"
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
go 1.9:
|
||||||
|
go_version: "1.9"
|
||||||
|
go 1.10:
|
||||||
|
go_version: "1.10"
|
||||||
|
go 1.11 (on):
|
||||||
|
go_version: "1.11"
|
||||||
|
GO111MODULE: "on"
|
||||||
|
go 1.11 (off):
|
||||||
|
go_version: "1.11"
|
||||||
|
GO111MODULE: "off"
|
||||||
|
steps:
|
||||||
|
- template: azure-tests.yml
|
||||||
|
|
||||||
|
- job: macOS
|
||||||
|
pool:
|
||||||
|
vmImage: "macOS-10.13"
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
go 1.9:
|
||||||
|
go_version: "1.9"
|
||||||
|
go 1.10:
|
||||||
|
go_version: "1.10"
|
||||||
|
go 1.11 (on):
|
||||||
|
go_version: "1.11"
|
||||||
|
GO111MODULE: "on"
|
||||||
|
go 1.11 (off):
|
||||||
|
go_version: "1.11"
|
||||||
|
GO111MODULE: "off"
|
||||||
|
steps:
|
||||||
|
- template: azure-tests.yml
|
||||||
|
|
||||||
|
- job: Linux
|
||||||
|
pool:
|
||||||
|
vmImage: "ubuntu-16.04"
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
go 1.9:
|
||||||
|
go_version: "1.9"
|
||||||
|
go 1.10:
|
||||||
|
go_version: "1.10"
|
||||||
|
go 1.11 (on):
|
||||||
|
go_version: "1.11"
|
||||||
|
GO111MODULE: "on"
|
||||||
|
go 1.11 (off):
|
||||||
|
go_version: "1.11"
|
||||||
|
GO111MODULE: "off"
|
||||||
|
steps:
|
||||||
|
- template: azure-tests.yml
|
19
vendor/github.com/gobuffalo/envy/azure-tests.yml
generated
vendored
Normal file
19
vendor/github.com/gobuffalo/envy/azure-tests.yml
generated
vendored
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
steps:
|
||||||
|
- task: GoTool@0
|
||||||
|
inputs:
|
||||||
|
version: $(go_version)
|
||||||
|
- task: Bash@3
|
||||||
|
inputs:
|
||||||
|
targetType: inline
|
||||||
|
script: |
|
||||||
|
mkdir -p "$(GOBIN)"
|
||||||
|
mkdir -p "$(GOPATH)/pkg"
|
||||||
|
mkdir -p "$(modulePath)"
|
||||||
|
shopt -s extglob
|
||||||
|
mv !(gopath) "$(modulePath)"
|
||||||
|
displayName: "Setup Go Workspace"
|
||||||
|
- script: |
|
||||||
|
go get -t -v ./...
|
||||||
|
go test -race ./...
|
||||||
|
workingDirectory: "$(modulePath)"
|
||||||
|
displayName: "Tests"
|
11
vendor/github.com/gobuffalo/envy/azure.sh
generated
vendored
Normal file
11
vendor/github.com/gobuffalo/envy/azure.sh
generated
vendored
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -xe
|
||||||
|
|
||||||
|
cat >> .env << EOF
|
||||||
|
# This is a comment
|
||||||
|
# We can use equal or colon notation
|
||||||
|
DIR: root
|
||||||
|
FLAVOUR: none
|
||||||
|
INSIDE_FOLDER=false
|
||||||
|
EOF
|
5
vendor/github.com/gobuffalo/envy/env
generated
vendored
Normal file
5
vendor/github.com/gobuffalo/envy/env
generated
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# This is a comment
|
||||||
|
# We can use equal or colon notation
|
||||||
|
DIR: root
|
||||||
|
FLAVOUR: none
|
||||||
|
INSIDE_FOLDER=false
|
276
vendor/github.com/gobuffalo/envy/envy.go
generated
vendored
Normal file
276
vendor/github.com/gobuffalo/envy/envy.go
generated
vendored
Normal file
@ -0,0 +1,276 @@
|
|||||||
|
/*
|
||||||
|
package envy makes working with ENV variables in Go trivial.
|
||||||
|
|
||||||
|
* Get ENV variables with default values.
|
||||||
|
* Set ENV variables safely without affecting the underlying system.
|
||||||
|
* Temporarily change ENV vars; useful for testing.
|
||||||
|
* Map all of the key/values in the ENV.
|
||||||
|
* Loads .env files (by using [godotenv](https://github.com/joho/godotenv/))
|
||||||
|
* More!
|
||||||
|
*/
|
||||||
|
package envy
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/joho/godotenv"
|
||||||
|
"github.com/rogpeppe/go-internal/modfile"
|
||||||
|
)
|
||||||
|
|
||||||
|
var gil = &sync.RWMutex{}
|
||||||
|
var env = map[string]string{}
|
||||||
|
|
||||||
|
// GO111MODULE is ENV for turning mods on/off
|
||||||
|
const GO111MODULE = "GO111MODULE"
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
Load()
|
||||||
|
loadEnv()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load the ENV variables to the env map
|
||||||
|
func loadEnv() {
|
||||||
|
gil.Lock()
|
||||||
|
defer gil.Unlock()
|
||||||
|
|
||||||
|
if os.Getenv("GO_ENV") == "" {
|
||||||
|
// if the flag "test.v" is *defined*, we're running as a unit test. Note that we don't care
|
||||||
|
// about v.Value (verbose test mode); we just want to know if the test environment has defined
|
||||||
|
// it. It's also possible that the flags are not yet fully parsed (i.e. flag.Parsed() == false),
|
||||||
|
// so we could not depend on v.Value anyway.
|
||||||
|
//
|
||||||
|
if v := flag.Lookup("test.v"); v != nil {
|
||||||
|
env["GO_ENV"] = "test"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// set the GOPATH if using >= 1.8 and the GOPATH isn't set
|
||||||
|
if os.Getenv("GOPATH") == "" {
|
||||||
|
out, err := exec.Command("go", "env", "GOPATH").Output()
|
||||||
|
if err == nil {
|
||||||
|
gp := strings.TrimSpace(string(out))
|
||||||
|
os.Setenv("GOPATH", gp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, e := range os.Environ() {
|
||||||
|
pair := strings.Split(e, "=")
|
||||||
|
env[pair[0]] = os.Getenv(pair[0])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mods returns true if module support is enabled, false otherwise
|
||||||
|
// See https://github.com/golang/go/wiki/Modules#how-to-install-and-activate-module-support for details
|
||||||
|
func Mods() bool {
|
||||||
|
go111 := Get(GO111MODULE, "")
|
||||||
|
|
||||||
|
if !InGoPath() {
|
||||||
|
return go111 != "off"
|
||||||
|
}
|
||||||
|
|
||||||
|
return go111 == "on"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reload the ENV variables. Useful if
|
||||||
|
// an external ENV manager has been used
|
||||||
|
func Reload() {
|
||||||
|
env = map[string]string{}
|
||||||
|
loadEnv()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load .env files. Files will be loaded in the same order that are received.
|
||||||
|
// Redefined vars will override previously existing values.
|
||||||
|
// IE: envy.Load(".env", "test_env/.env") will result in DIR=test_env
|
||||||
|
// If no arg passed, it will try to load a .env file.
|
||||||
|
func Load(files ...string) error {
|
||||||
|
|
||||||
|
// If no files received, load the default one
|
||||||
|
if len(files) == 0 {
|
||||||
|
err := godotenv.Overload()
|
||||||
|
if err == nil {
|
||||||
|
Reload()
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// We received a list of files
|
||||||
|
for _, file := range files {
|
||||||
|
|
||||||
|
// Check if it exists or we can access
|
||||||
|
if _, err := os.Stat(file); err != nil {
|
||||||
|
// It does not exist or we can not access.
|
||||||
|
// Return and stop loading
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// It exists and we have permission. Load it
|
||||||
|
if err := godotenv.Overload(file); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reload the env so all new changes are noticed
|
||||||
|
Reload()
|
||||||
|
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get a value from the ENV. If it doesn't exist the
|
||||||
|
// default value will be returned.
|
||||||
|
func Get(key string, value string) string {
|
||||||
|
gil.RLock()
|
||||||
|
defer gil.RUnlock()
|
||||||
|
if v, ok := env[key]; ok {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get a value from the ENV. If it doesn't exist
|
||||||
|
// an error will be returned
|
||||||
|
func MustGet(key string) (string, error) {
|
||||||
|
gil.RLock()
|
||||||
|
defer gil.RUnlock()
|
||||||
|
if v, ok := env[key]; ok {
|
||||||
|
return v, nil
|
||||||
|
}
|
||||||
|
return "", fmt.Errorf("could not find ENV var with %s", key)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set a value into the ENV. This is NOT permanent. It will
|
||||||
|
// only affect values accessed through envy.
|
||||||
|
func Set(key string, value string) {
|
||||||
|
gil.Lock()
|
||||||
|
defer gil.Unlock()
|
||||||
|
env[key] = value
|
||||||
|
}
|
||||||
|
|
||||||
|
// MustSet the value into the underlying ENV, as well as envy.
|
||||||
|
// This may return an error if there is a problem setting the
|
||||||
|
// underlying ENV value.
|
||||||
|
func MustSet(key string, value string) error {
|
||||||
|
gil.Lock()
|
||||||
|
defer gil.Unlock()
|
||||||
|
err := os.Setenv(key, value)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
env[key] = value
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Map all of the keys/values set in envy.
|
||||||
|
func Map() map[string]string {
|
||||||
|
gil.RLock()
|
||||||
|
defer gil.RUnlock()
|
||||||
|
cp := map[string]string{}
|
||||||
|
for k, v := range env {
|
||||||
|
cp[k] = v
|
||||||
|
}
|
||||||
|
return cp
|
||||||
|
}
|
||||||
|
|
||||||
|
// Temp makes a copy of the values and allows operation on
|
||||||
|
// those values temporarily during the run of the function.
|
||||||
|
// At the end of the function run the copy is discarded and
|
||||||
|
// the original values are replaced. This is useful for testing.
|
||||||
|
// Warning: This function is NOT safe to use from a goroutine or
|
||||||
|
// from code which may access any Get or Set function from a goroutine
|
||||||
|
func Temp(f func()) {
|
||||||
|
oenv := env
|
||||||
|
env = map[string]string{}
|
||||||
|
for k, v := range oenv {
|
||||||
|
env[k] = v
|
||||||
|
}
|
||||||
|
defer func() { env = oenv }()
|
||||||
|
f()
|
||||||
|
}
|
||||||
|
|
||||||
|
func GoPath() string {
|
||||||
|
return Get("GOPATH", "")
|
||||||
|
}
|
||||||
|
|
||||||
|
func GoBin() string {
|
||||||
|
return Get("GO_BIN", "go")
|
||||||
|
}
|
||||||
|
|
||||||
|
func InGoPath() bool {
|
||||||
|
pwd, _ := os.Getwd()
|
||||||
|
for _, p := range GoPaths() {
|
||||||
|
if strings.HasPrefix(pwd, p) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// GoPaths returns all possible GOPATHS that are set.
|
||||||
|
func GoPaths() []string {
|
||||||
|
gp := Get("GOPATH", "")
|
||||||
|
if runtime.GOOS == "windows" {
|
||||||
|
return strings.Split(gp, ";") // Windows uses a different separator
|
||||||
|
}
|
||||||
|
return strings.Split(gp, ":")
|
||||||
|
}
|
||||||
|
|
||||||
|
func importPath(path string) string {
|
||||||
|
path = strings.TrimPrefix(path, "/private")
|
||||||
|
for _, gopath := range GoPaths() {
|
||||||
|
srcpath := filepath.Join(gopath, "src")
|
||||||
|
rel, err := filepath.Rel(srcpath, path)
|
||||||
|
if err == nil {
|
||||||
|
return filepath.ToSlash(rel)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// fallback to trim
|
||||||
|
rel := strings.TrimPrefix(path, filepath.Join(GoPath(), "src"))
|
||||||
|
rel = strings.TrimPrefix(rel, string(filepath.Separator))
|
||||||
|
return filepath.ToSlash(rel)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CurrentModule will attempt to return the module name from `go.mod` if
|
||||||
|
// modules are enabled.
|
||||||
|
// If modules are not enabled it will fallback to using CurrentPackage instead.
|
||||||
|
func CurrentModule() (string, error) {
|
||||||
|
if !Mods() {
|
||||||
|
return CurrentPackage(), nil
|
||||||
|
}
|
||||||
|
moddata, err := ioutil.ReadFile("go.mod")
|
||||||
|
if err != nil {
|
||||||
|
return "", errors.New("go.mod cannot be read or does not exist while go module is enabled")
|
||||||
|
}
|
||||||
|
packagePath := modfile.ModulePath(moddata)
|
||||||
|
if packagePath == "" {
|
||||||
|
return "", errors.New("go.mod is malformed")
|
||||||
|
}
|
||||||
|
return packagePath, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CurrentPackage attempts to figure out the current package name from the PWD
|
||||||
|
// Use CurrentModule for a more accurate package name.
|
||||||
|
func CurrentPackage() string {
|
||||||
|
if Mods() {
|
||||||
|
}
|
||||||
|
pwd, _ := os.Getwd()
|
||||||
|
return importPath(pwd)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Environ() []string {
|
||||||
|
gil.RLock()
|
||||||
|
defer gil.RUnlock()
|
||||||
|
var e []string
|
||||||
|
for k, v := range env {
|
||||||
|
e = append(e, fmt.Sprintf("%s=%s", k, v))
|
||||||
|
}
|
||||||
|
return e
|
||||||
|
}
|
8
vendor/github.com/gobuffalo/envy/go.mod
generated
vendored
Normal file
8
vendor/github.com/gobuffalo/envy/go.mod
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
module github.com/gobuffalo/envy
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
|
github.com/joho/godotenv v1.3.0
|
||||||
|
github.com/rogpeppe/go-internal v1.1.0
|
||||||
|
github.com/stretchr/testify v1.3.0
|
||||||
|
)
|
17
vendor/github.com/gobuffalo/envy/go.sum
generated
vendored
Normal file
17
vendor/github.com/gobuffalo/envy/go.sum
generated
vendored
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc=
|
||||||
|
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
|
||||||
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/rogpeppe/go-internal v1.1.0 h1:g0fH8RicVgNl+zVZDCDfbdWxAWoAEJyI7I3TZYXFiig=
|
||||||
|
github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||||
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
||||||
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
3
vendor/github.com/gobuffalo/envy/version.go
generated
vendored
Normal file
3
vendor/github.com/gobuffalo/envy/version.go
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
package envy
|
||||||
|
|
||||||
|
const Version = "v1.7.0"
|
29
vendor/github.com/gobuffalo/packd/.gitignore
generated
vendored
Normal file
29
vendor/github.com/gobuffalo/packd/.gitignore
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
*.log
|
||||||
|
.DS_Store
|
||||||
|
doc
|
||||||
|
tmp
|
||||||
|
pkg
|
||||||
|
*.gem
|
||||||
|
*.pid
|
||||||
|
coverage
|
||||||
|
coverage.data
|
||||||
|
build/*
|
||||||
|
*.pbxuser
|
||||||
|
*.mode1v3
|
||||||
|
.svn
|
||||||
|
profile
|
||||||
|
.console_history
|
||||||
|
.sass-cache/*
|
||||||
|
.rake_tasks~
|
||||||
|
*.log.lck
|
||||||
|
solr/
|
||||||
|
.jhw-cache/
|
||||||
|
jhw.*
|
||||||
|
*.sublime*
|
||||||
|
node_modules/
|
||||||
|
dist/
|
||||||
|
generated/
|
||||||
|
.vendor/
|
||||||
|
bin/*
|
||||||
|
gin-bin
|
||||||
|
.idea/
|
3
vendor/github.com/gobuffalo/packd/.gometalinter.json
generated
vendored
Normal file
3
vendor/github.com/gobuffalo/packd/.gometalinter.json
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"Enable": ["vet", "golint", "goimports", "deadcode", "gotype", "ineffassign", "misspell", "nakedret", "unconvert", "megacheck", "varcheck"]
|
||||||
|
}
|
21
vendor/github.com/gobuffalo/packd/LICENSE
generated
vendored
Normal file
21
vendor/github.com/gobuffalo/packd/LICENSE
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2019 Mark Bates
|
||||||
|
|
||||||
|
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.
|
61
vendor/github.com/gobuffalo/packd/Makefile
generated
vendored
Normal file
61
vendor/github.com/gobuffalo/packd/Makefile
generated
vendored
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
TAGS ?= ""
|
||||||
|
GO_BIN ?= "go"
|
||||||
|
|
||||||
|
install:
|
||||||
|
$(GO_BIN) install -tags ${TAGS} -v .
|
||||||
|
make tidy
|
||||||
|
|
||||||
|
tidy:
|
||||||
|
ifeq ($(GO111MODULE),on)
|
||||||
|
$(GO_BIN) mod tidy
|
||||||
|
else
|
||||||
|
echo skipping go mod tidy
|
||||||
|
endif
|
||||||
|
|
||||||
|
deps:
|
||||||
|
$(GO_BIN) get -tags ${TAGS} -t ./...
|
||||||
|
make tidy
|
||||||
|
|
||||||
|
build:
|
||||||
|
$(GO_BIN) build -v .
|
||||||
|
make tidy
|
||||||
|
|
||||||
|
test:
|
||||||
|
$(GO_BIN) test -cover -tags ${TAGS} ./...
|
||||||
|
make tidy
|
||||||
|
|
||||||
|
ci-deps:
|
||||||
|
$(GO_BIN) get -tags ${TAGS} -t ./...
|
||||||
|
|
||||||
|
ci-test:
|
||||||
|
$(GO_BIN) test -tags ${TAGS} -race ./...
|
||||||
|
|
||||||
|
lint:
|
||||||
|
go get github.com/golangci/golangci-lint/cmd/golangci-lint
|
||||||
|
golangci-lint run --enable-all
|
||||||
|
make tidy
|
||||||
|
|
||||||
|
update:
|
||||||
|
ifeq ($(GO111MODULE),on)
|
||||||
|
rm go.*
|
||||||
|
$(GO_BIN) mod init
|
||||||
|
$(GO_BIN) mod tidy
|
||||||
|
else
|
||||||
|
$(GO_BIN) get -u -tags ${TAGS}
|
||||||
|
endif
|
||||||
|
make test
|
||||||
|
make install
|
||||||
|
make tidy
|
||||||
|
|
||||||
|
release-test:
|
||||||
|
$(GO_BIN) test -tags ${TAGS} -race ./...
|
||||||
|
make tidy
|
||||||
|
|
||||||
|
release:
|
||||||
|
$(GO_BIN) get github.com/gobuffalo/release
|
||||||
|
make tidy
|
||||||
|
release -y -f version.go --skip-packr
|
||||||
|
make tidy
|
||||||
|
|
||||||
|
|
||||||
|
|
24
vendor/github.com/gobuffalo/packd/README.md
generated
vendored
Normal file
24
vendor/github.com/gobuffalo/packd/README.md
generated
vendored
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<p align="center"><img src="https://github.com/gobuffalo/buffalo/blob/master/logo.svg" width="360"></p>
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
|
<a href="https://godoc.org/github.com/gobuffalo/packd"><img src="https://godoc.org/github.com/gobuffalo/packd?status.svg" alt="GoDoc" /></a>
|
||||||
|
<a href="https://travis-ci.org/gobuffalo/packd"><img src="https://travis-ci.org/gobuffalo/packd.svg?branch=master" alt="Build Status" /></a>
|
||||||
|
<a href="https://goreportcard.com/report/github.com/gobuffalo/packd"><img src="https://goreportcard.com/badge/github.com/gobuffalo/packd" alt="Go Report Card" /></a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
# github.com/gobuffalo/packd
|
||||||
|
|
||||||
|
This is a collection of interfaces designed to make using [github.com/gobuffalo/packr](https://github.com/gobuffalo/packr) easier, and to make the transition between v1 and v2 as seamless as possible.
|
||||||
|
|
||||||
|
They can, and should, be used for testing, alternate Box implementations, etc...
|
||||||
|
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ go get -u -v github.com/gobuffalo/packd
|
||||||
|
```
|
||||||
|
|
||||||
|
## Memory Box
|
||||||
|
|
||||||
|
The [`packd#MemoryBox`](https://godoc.org/github.com/gobuffalo/packd#MemoryBox) is a complete, thread-safe, implementation of [`packd#Box`](https://godoc.org/github.com/gobuffalo/packd#Box)
|
10
vendor/github.com/gobuffalo/packd/SHOULDERS.md
generated
vendored
Normal file
10
vendor/github.com/gobuffalo/packd/SHOULDERS.md
generated
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# github.com/gobuffalo/packd Stands on the Shoulders of Giants
|
||||||
|
|
||||||
|
github.com/gobuffalo/packd does not try to reinvent the wheel! Instead, it uses the already great wheels developed by the Go community and puts them all together in the best way possible. Without these giants, this project would not be possible. Please make sure to check them out and thank them for all of their hard work.
|
||||||
|
|
||||||
|
Thank you to the following **GIANTS**:
|
||||||
|
|
||||||
|
|
||||||
|
* [github.com/davecgh/go-spew](https://godoc.org/github.com/davecgh/go-spew)
|
||||||
|
|
||||||
|
* [github.com/stretchr/testify](https://godoc.org/github.com/stretchr/testify)
|
71
vendor/github.com/gobuffalo/packd/azure-pipelines.yml
generated
vendored
Normal file
71
vendor/github.com/gobuffalo/packd/azure-pipelines.yml
generated
vendored
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
variables:
|
||||||
|
GOBIN: "$(GOPATH)/bin" # Go binaries path
|
||||||
|
GOPATH: "$(system.defaultWorkingDirectory)/gopath" # Go workspace path
|
||||||
|
modulePath: "$(GOPATH)/src/github.com/$(build.repository.name)" # Path to the module"s code
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
- job: Windows
|
||||||
|
pool:
|
||||||
|
vmImage: "vs2017-win2016"
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
go 1.10:
|
||||||
|
go_version: "1.10"
|
||||||
|
go 1.11 (on):
|
||||||
|
go_version: "1.11.5"
|
||||||
|
GO111MODULE: "on"
|
||||||
|
go 1.11 (off):
|
||||||
|
go_version: "1.11.5"
|
||||||
|
GO111MODULE: "off"
|
||||||
|
go 1.12 (on):
|
||||||
|
go_version: "1.12"
|
||||||
|
GO111MODULE: "on"
|
||||||
|
go 1.12 (off):
|
||||||
|
go_version: "1.12"
|
||||||
|
GO111MODULE: "off"
|
||||||
|
steps:
|
||||||
|
- template: azure-tests.yml
|
||||||
|
|
||||||
|
- job: macOS
|
||||||
|
pool:
|
||||||
|
vmImage: "macOS-10.13"
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
go 1.10:
|
||||||
|
go_version: "1.10"
|
||||||
|
go 1.11 (on):
|
||||||
|
go_version: "1.11.5"
|
||||||
|
GO111MODULE: "on"
|
||||||
|
go 1.11 (off):
|
||||||
|
go_version: "1.11.5"
|
||||||
|
GO111MODULE: "off"
|
||||||
|
go 1.12 (on):
|
||||||
|
go_version: "1.12"
|
||||||
|
GO111MODULE: "on"
|
||||||
|
go 1.12 (off):
|
||||||
|
go_version: "1.12"
|
||||||
|
GO111MODULE: "off"
|
||||||
|
steps:
|
||||||
|
- template: azure-tests.yml
|
||||||
|
|
||||||
|
- job: Linux
|
||||||
|
pool:
|
||||||
|
vmImage: "ubuntu-16.04"
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
go 1.10:
|
||||||
|
go_version: "1.10"
|
||||||
|
go 1.11 (on):
|
||||||
|
go_version: "1.11.5"
|
||||||
|
GO111MODULE: "on"
|
||||||
|
go 1.11 (off):
|
||||||
|
go_version: "1.11.5"
|
||||||
|
GO111MODULE: "off"
|
||||||
|
go 1.12 (on):
|
||||||
|
go_version: "1.12"
|
||||||
|
GO111MODULE: "on"
|
||||||
|
go 1.12 (off):
|
||||||
|
go_version: "1.12"
|
||||||
|
GO111MODULE: "off"
|
||||||
|
steps:
|
||||||
|
- template: azure-tests.yml
|
19
vendor/github.com/gobuffalo/packd/azure-tests.yml
generated
vendored
Normal file
19
vendor/github.com/gobuffalo/packd/azure-tests.yml
generated
vendored
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
steps:
|
||||||
|
- task: GoTool@0
|
||||||
|
inputs:
|
||||||
|
version: $(go_version)
|
||||||
|
- task: Bash@3
|
||||||
|
inputs:
|
||||||
|
targetType: inline
|
||||||
|
script: |
|
||||||
|
mkdir -p "$(GOBIN)"
|
||||||
|
mkdir -p "$(GOPATH)/pkg"
|
||||||
|
mkdir -p "$(modulePath)"
|
||||||
|
shopt -s extglob
|
||||||
|
mv !(gopath) "$(modulePath)"
|
||||||
|
displayName: "Setup Go Workspace"
|
||||||
|
- script: |
|
||||||
|
go get -t -v ./...
|
||||||
|
go test -race ./...
|
||||||
|
workingDirectory: "$(modulePath)"
|
||||||
|
displayName: "Tests"
|
126
vendor/github.com/gobuffalo/packd/file.go
generated
vendored
Normal file
126
vendor/github.com/gobuffalo/packd/file.go
generated
vendored
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
package packd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ File = &virtualFile{}
|
||||||
|
var _ io.Reader = &virtualFile{}
|
||||||
|
var _ io.Writer = &virtualFile{}
|
||||||
|
var _ fmt.Stringer = &virtualFile{}
|
||||||
|
|
||||||
|
type virtualFile struct {
|
||||||
|
io.Reader
|
||||||
|
name string
|
||||||
|
info fileInfo
|
||||||
|
original []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f virtualFile) Name() string {
|
||||||
|
return f.name
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *virtualFile) Seek(offset int64, whence int) (int64, error) {
|
||||||
|
return f.Reader.(*bytes.Reader).Seek(offset, whence)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f virtualFile) FileInfo() (os.FileInfo, error) {
|
||||||
|
return f.info, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *virtualFile) Close() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f virtualFile) Readdir(count int) ([]os.FileInfo, error) {
|
||||||
|
return []os.FileInfo{f.info}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f virtualFile) Stat() (os.FileInfo, error) {
|
||||||
|
return f.info, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f virtualFile) String() string {
|
||||||
|
return string(f.original)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read reads the next len(p) bytes from the virtualFile and
|
||||||
|
// rewind read offset to 0 when it met EOF.
|
||||||
|
func (f *virtualFile) Read(p []byte) (int, error) {
|
||||||
|
i, err := f.Reader.Read(p)
|
||||||
|
|
||||||
|
if i == 0 || err == io.EOF {
|
||||||
|
f.Seek(0, io.SeekStart)
|
||||||
|
}
|
||||||
|
return i, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write copies byte slice p to content of virtualFile.
|
||||||
|
func (f *virtualFile) Write(p []byte) (int, error) {
|
||||||
|
return f.write(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
// write copies byte slice or data from io.Reader to content of the
|
||||||
|
// virtualFile and update related information of the virtualFile.
|
||||||
|
func (f *virtualFile) write(d interface{}) (c int, err error) {
|
||||||
|
bb := &bytes.Buffer{}
|
||||||
|
switch d.(type) {
|
||||||
|
case []byte:
|
||||||
|
c, err = bb.Write(d.([]byte))
|
||||||
|
case io.Reader:
|
||||||
|
if d != nil {
|
||||||
|
i64, e := io.Copy(bb, d.(io.Reader))
|
||||||
|
c = int(i64)
|
||||||
|
err = e
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
err = fmt.Errorf("unknown type of argument")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return c, err
|
||||||
|
}
|
||||||
|
|
||||||
|
f.info.size = int64(c)
|
||||||
|
f.info.modTime = time.Now()
|
||||||
|
f.original = bb.Bytes()
|
||||||
|
f.Reader = bytes.NewReader(f.original)
|
||||||
|
return c, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewFile returns a new "virtual" file
|
||||||
|
func NewFile(name string, r io.Reader) (File, error) {
|
||||||
|
return buildFile(name, r)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewDir returns a new "virtual" directory
|
||||||
|
func NewDir(name string) (File, error) {
|
||||||
|
v, err := buildFile(name, nil)
|
||||||
|
if err != nil {
|
||||||
|
return v, err
|
||||||
|
}
|
||||||
|
v.info.isDir = true
|
||||||
|
return v, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildFile(name string, r io.Reader) (*virtualFile, error) {
|
||||||
|
vf := &virtualFile{
|
||||||
|
name: name,
|
||||||
|
info: fileInfo{
|
||||||
|
Path: name,
|
||||||
|
modTime: time.Now(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
|
if r != nil {
|
||||||
|
_, err = vf.write(r)
|
||||||
|
} else {
|
||||||
|
_, err = vf.write([]byte{}) // for safety
|
||||||
|
}
|
||||||
|
return vf, err
|
||||||
|
}
|
39
vendor/github.com/gobuffalo/packd/file_info.go
generated
vendored
Normal file
39
vendor/github.com/gobuffalo/packd/file_info.go
generated
vendored
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
package packd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ os.FileInfo = fileInfo{}
|
||||||
|
|
||||||
|
type fileInfo struct {
|
||||||
|
Path string
|
||||||
|
size int64
|
||||||
|
modTime time.Time
|
||||||
|
isDir bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f fileInfo) Name() string {
|
||||||
|
return f.Path
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f fileInfo) Size() int64 {
|
||||||
|
return f.size
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f fileInfo) Mode() os.FileMode {
|
||||||
|
return 0444
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f fileInfo) ModTime() time.Time {
|
||||||
|
return f.modTime
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f fileInfo) IsDir() bool {
|
||||||
|
return f.isDir
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f fileInfo) Sys() interface{} {
|
||||||
|
return nil
|
||||||
|
}
|
8
vendor/github.com/gobuffalo/packd/go.mod
generated
vendored
Normal file
8
vendor/github.com/gobuffalo/packd/go.mod
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
module github.com/gobuffalo/packd
|
||||||
|
|
||||||
|
go 1.12
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
|
github.com/stretchr/testify v1.3.0
|
||||||
|
)
|
9
vendor/github.com/gobuffalo/packd/go.sum
generated
vendored
Normal file
9
vendor/github.com/gobuffalo/packd/go.sum
generated
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||||
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
||||||
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
83
vendor/github.com/gobuffalo/packd/interfaces.go
generated
vendored
Normal file
83
vendor/github.com/gobuffalo/packd/interfaces.go
generated
vendored
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
package packd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
type WalkFunc func(string, File) error
|
||||||
|
|
||||||
|
// Box represents the entirety of the necessary
|
||||||
|
// interfaces to form a "full" box.
|
||||||
|
// github.com/gobuffalo/packr#Box is an example of this interface.
|
||||||
|
type Box interface {
|
||||||
|
HTTPBox
|
||||||
|
Lister
|
||||||
|
Addable
|
||||||
|
Finder
|
||||||
|
Walkable
|
||||||
|
Haser
|
||||||
|
}
|
||||||
|
|
||||||
|
type Haser interface {
|
||||||
|
Has(string) bool
|
||||||
|
}
|
||||||
|
|
||||||
|
type Walker interface {
|
||||||
|
Walk(wf WalkFunc) error
|
||||||
|
}
|
||||||
|
|
||||||
|
type Walkable interface {
|
||||||
|
Walker
|
||||||
|
WalkPrefix(prefix string, wf WalkFunc) error
|
||||||
|
}
|
||||||
|
|
||||||
|
type Finder interface {
|
||||||
|
Find(string) ([]byte, error)
|
||||||
|
FindString(name string) (string, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type HTTPBox interface {
|
||||||
|
Open(name string) (http.File, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type Lister interface {
|
||||||
|
List() []string
|
||||||
|
}
|
||||||
|
|
||||||
|
type Addable interface {
|
||||||
|
AddString(path string, t string) error
|
||||||
|
AddBytes(path string, t []byte) error
|
||||||
|
}
|
||||||
|
|
||||||
|
type SimpleFile interface {
|
||||||
|
fmt.Stringer
|
||||||
|
io.Reader
|
||||||
|
io.Writer
|
||||||
|
Name() string
|
||||||
|
}
|
||||||
|
|
||||||
|
type HTTPFile interface {
|
||||||
|
SimpleFile
|
||||||
|
io.Closer
|
||||||
|
io.Seeker
|
||||||
|
Readdir(count int) ([]os.FileInfo, error)
|
||||||
|
Stat() (os.FileInfo, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type File interface {
|
||||||
|
HTTPFile
|
||||||
|
FileInfo() (os.FileInfo, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// LegacyBox represents deprecated methods
|
||||||
|
// that older Box implementations might have had.
|
||||||
|
// github.com/gobuffalo/packr v1 is an example of a LegacyBox.
|
||||||
|
type LegacyBox interface {
|
||||||
|
String(name string) string
|
||||||
|
MustString(name string) (string, error)
|
||||||
|
Bytes(name string) []byte
|
||||||
|
MustBytes(name string) ([]byte, error)
|
||||||
|
}
|
29
vendor/github.com/gobuffalo/packd/internal/takeon/github.com/markbates/errx/.gitignore
generated
vendored
Normal file
29
vendor/github.com/gobuffalo/packd/internal/takeon/github.com/markbates/errx/.gitignore
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
*.log
|
||||||
|
.DS_Store
|
||||||
|
doc
|
||||||
|
tmp
|
||||||
|
pkg
|
||||||
|
*.gem
|
||||||
|
*.pid
|
||||||
|
coverage
|
||||||
|
coverage.data
|
||||||
|
build/*
|
||||||
|
*.pbxuser
|
||||||
|
*.mode1v3
|
||||||
|
.svn
|
||||||
|
profile
|
||||||
|
.console_history
|
||||||
|
.sass-cache/*
|
||||||
|
.rake_tasks~
|
||||||
|
*.log.lck
|
||||||
|
solr/
|
||||||
|
.jhw-cache/
|
||||||
|
jhw.*
|
||||||
|
*.sublime*
|
||||||
|
node_modules/
|
||||||
|
dist/
|
||||||
|
generated/
|
||||||
|
.vendor/
|
||||||
|
bin/*
|
||||||
|
gin-bin
|
||||||
|
.idea/
|
21
vendor/github.com/gobuffalo/packd/internal/takeon/github.com/markbates/errx/LICENSE
generated
vendored
Normal file
21
vendor/github.com/gobuffalo/packd/internal/takeon/github.com/markbates/errx/LICENSE
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2019 Mark Bates
|
||||||
|
|
||||||
|
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.
|
61
vendor/github.com/gobuffalo/packd/internal/takeon/github.com/markbates/errx/Makefile
generated
vendored
Normal file
61
vendor/github.com/gobuffalo/packd/internal/takeon/github.com/markbates/errx/Makefile
generated
vendored
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
TAGS ?= ""
|
||||||
|
GO_BIN ?= "go"
|
||||||
|
|
||||||
|
install:
|
||||||
|
$(GO_BIN) install -tags ${TAGS} -v .
|
||||||
|
make tidy
|
||||||
|
|
||||||
|
tidy:
|
||||||
|
ifeq ($(GO111MODULE),on)
|
||||||
|
$(GO_BIN) mod tidy
|
||||||
|
else
|
||||||
|
echo skipping go mod tidy
|
||||||
|
endif
|
||||||
|
|
||||||
|
deps:
|
||||||
|
$(GO_BIN) get -tags ${TAGS} -t ./...
|
||||||
|
make tidy
|
||||||
|
|
||||||
|
build:
|
||||||
|
$(GO_BIN) build -v .
|
||||||
|
make tidy
|
||||||
|
|
||||||
|
test:
|
||||||
|
$(GO_BIN) test -cover -tags ${TAGS} ./...
|
||||||
|
make tidy
|
||||||
|
|
||||||
|
ci-deps:
|
||||||
|
$(GO_BIN) get -tags ${TAGS} -t ./...
|
||||||
|
|
||||||
|
ci-test:
|
||||||
|
$(GO_BIN) test -tags ${TAGS} -race ./...
|
||||||
|
|
||||||
|
lint:
|
||||||
|
go get github.com/golangci/golangci-lint/cmd/golangci-lint
|
||||||
|
golangci-lint run --enable-all
|
||||||
|
make tidy
|
||||||
|
|
||||||
|
update:
|
||||||
|
ifeq ($(GO111MODULE),on)
|
||||||
|
rm go.*
|
||||||
|
$(GO_BIN) mod init
|
||||||
|
$(GO_BIN) mod tidy
|
||||||
|
else
|
||||||
|
$(GO_BIN) get -u -tags ${TAGS}
|
||||||
|
endif
|
||||||
|
make test
|
||||||
|
make install
|
||||||
|
make tidy
|
||||||
|
|
||||||
|
release-test:
|
||||||
|
$(GO_BIN) test -tags ${TAGS} -race ./...
|
||||||
|
make tidy
|
||||||
|
|
||||||
|
release:
|
||||||
|
$(GO_BIN) get github.com/gobuffalo/release
|
||||||
|
make tidy
|
||||||
|
release -y -f version.go --skip-packr
|
||||||
|
make tidy
|
||||||
|
|
||||||
|
|
||||||
|
|
6
vendor/github.com/gobuffalo/packd/internal/takeon/github.com/markbates/errx/SHOULDERS.md
generated
vendored
Normal file
6
vendor/github.com/gobuffalo/packd/internal/takeon/github.com/markbates/errx/SHOULDERS.md
generated
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
# github.com/markbates/errx Stands on the Shoulders of Giants
|
||||||
|
|
||||||
|
github.com/markbates/errx does not try to reinvent the wheel! Instead, it uses the already great wheels developed by the Go community and puts them all together in the best way possible. Without these giants, this project would not be possible. Please make sure to check them out and thank them for all of their hard work.
|
||||||
|
|
||||||
|
Thank you to the following **GIANTS**:
|
||||||
|
|
71
vendor/github.com/gobuffalo/packd/internal/takeon/github.com/markbates/errx/azure-pipelines.yml
generated
vendored
Normal file
71
vendor/github.com/gobuffalo/packd/internal/takeon/github.com/markbates/errx/azure-pipelines.yml
generated
vendored
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
variables:
|
||||||
|
GOBIN: "$(GOPATH)/bin" # Go binaries path
|
||||||
|
GOPATH: "$(system.defaultWorkingDirectory)/gopath" # Go workspace path
|
||||||
|
modulePath: "$(GOPATH)/src/github.com/$(build.repository.name)" # Path to the module"s code
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
- job: Windows
|
||||||
|
pool:
|
||||||
|
vmImage: "vs2017-win2016"
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
go 1.10:
|
||||||
|
go_version: "1.10"
|
||||||
|
go 1.11 (on):
|
||||||
|
go_version: "1.11.5"
|
||||||
|
GO111MODULE: "on"
|
||||||
|
go 1.11 (off):
|
||||||
|
go_version: "1.11.5"
|
||||||
|
GO111MODULE: "off"
|
||||||
|
go 1.12 (on):
|
||||||
|
go_version: "1.12"
|
||||||
|
GO111MODULE: "on"
|
||||||
|
go 1.12 (off):
|
||||||
|
go_version: "1.12"
|
||||||
|
GO111MODULE: "off"
|
||||||
|
steps:
|
||||||
|
- template: azure-tests.yml
|
||||||
|
|
||||||
|
- job: macOS
|
||||||
|
pool:
|
||||||
|
vmImage: "macOS-10.13"
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
go 1.10:
|
||||||
|
go_version: "1.10"
|
||||||
|
go 1.11 (on):
|
||||||
|
go_version: "1.11.5"
|
||||||
|
GO111MODULE: "on"
|
||||||
|
go 1.11 (off):
|
||||||
|
go_version: "1.11.5"
|
||||||
|
GO111MODULE: "off"
|
||||||
|
go 1.12 (on):
|
||||||
|
go_version: "1.12"
|
||||||
|
GO111MODULE: "on"
|
||||||
|
go 1.12 (off):
|
||||||
|
go_version: "1.12"
|
||||||
|
GO111MODULE: "off"
|
||||||
|
steps:
|
||||||
|
- template: azure-tests.yml
|
||||||
|
|
||||||
|
- job: Linux
|
||||||
|
pool:
|
||||||
|
vmImage: "ubuntu-16.04"
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
go 1.10:
|
||||||
|
go_version: "1.10"
|
||||||
|
go 1.11 (on):
|
||||||
|
go_version: "1.11.5"
|
||||||
|
GO111MODULE: "on"
|
||||||
|
go 1.11 (off):
|
||||||
|
go_version: "1.11.5"
|
||||||
|
GO111MODULE: "off"
|
||||||
|
go 1.12 (on):
|
||||||
|
go_version: "1.12"
|
||||||
|
GO111MODULE: "on"
|
||||||
|
go 1.12 (off):
|
||||||
|
go_version: "1.12"
|
||||||
|
GO111MODULE: "off"
|
||||||
|
steps:
|
||||||
|
- template: azure-tests.yml
|
19
vendor/github.com/gobuffalo/packd/internal/takeon/github.com/markbates/errx/azure-tests.yml
generated
vendored
Normal file
19
vendor/github.com/gobuffalo/packd/internal/takeon/github.com/markbates/errx/azure-tests.yml
generated
vendored
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
steps:
|
||||||
|
- task: GoTool@0
|
||||||
|
inputs:
|
||||||
|
version: $(go_version)
|
||||||
|
- task: Bash@3
|
||||||
|
inputs:
|
||||||
|
targetType: inline
|
||||||
|
script: |
|
||||||
|
mkdir -p "$(GOBIN)"
|
||||||
|
mkdir -p "$(GOPATH)/pkg"
|
||||||
|
mkdir -p "$(modulePath)"
|
||||||
|
shopt -s extglob
|
||||||
|
mv !(gopath) "$(modulePath)"
|
||||||
|
displayName: "Setup Go Workspace"
|
||||||
|
- script: |
|
||||||
|
go get -t -v ./...
|
||||||
|
go test -race ./...
|
||||||
|
workingDirectory: "$(modulePath)"
|
||||||
|
displayName: "Tests"
|
23
vendor/github.com/gobuffalo/packd/internal/takeon/github.com/markbates/errx/errx.go
generated
vendored
Normal file
23
vendor/github.com/gobuffalo/packd/internal/takeon/github.com/markbates/errx/errx.go
generated
vendored
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
package errx
|
||||||
|
|
||||||
|
// go2 errors
|
||||||
|
type Wrapper interface {
|
||||||
|
Unwrap() error
|
||||||
|
}
|
||||||
|
|
||||||
|
// pkg/errors
|
||||||
|
type Causer interface {
|
||||||
|
Cause() error
|
||||||
|
}
|
||||||
|
|
||||||
|
func Unwrap(err error) error {
|
||||||
|
switch e := err.(type) {
|
||||||
|
case Wrapper:
|
||||||
|
return e.Unwrap()
|
||||||
|
case Causer:
|
||||||
|
return e.Cause()
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var Cause = Unwrap
|
4
vendor/github.com/gobuffalo/packd/internal/takeon/github.com/markbates/errx/version.go
generated
vendored
Normal file
4
vendor/github.com/gobuffalo/packd/internal/takeon/github.com/markbates/errx/version.go
generated
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
package errx
|
||||||
|
|
||||||
|
// Version of errx
|
||||||
|
const Version = "v1.0.0"
|
70
vendor/github.com/gobuffalo/packd/map.go
generated
vendored
Normal file
70
vendor/github.com/gobuffalo/packd/map.go
generated
vendored
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
package packd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"sort"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ByteMap wraps sync.Map and uses the following types:
|
||||||
|
// key: string
|
||||||
|
// value: []byte
|
||||||
|
type ByteMap struct {
|
||||||
|
data sync.Map
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete the key from the map
|
||||||
|
func (m *ByteMap) Delete(key string) {
|
||||||
|
m.data.Delete(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load the key from the map.
|
||||||
|
// Returns []byte or bool.
|
||||||
|
// A false return indicates either the key was not found
|
||||||
|
// or the value is not of type []byte
|
||||||
|
func (m *ByteMap) Load(key string) ([]byte, bool) {
|
||||||
|
i, ok := m.data.Load(key)
|
||||||
|
if !ok {
|
||||||
|
return []byte(``), false
|
||||||
|
}
|
||||||
|
s, ok := i.([]byte)
|
||||||
|
return s, ok
|
||||||
|
}
|
||||||
|
|
||||||
|
// LoadOrStore will return an existing key or
|
||||||
|
// store the value if not already in the map
|
||||||
|
func (m *ByteMap) LoadOrStore(key string, value []byte) ([]byte, bool) {
|
||||||
|
i, _ := m.data.LoadOrStore(key, value)
|
||||||
|
s, ok := i.([]byte)
|
||||||
|
return s, ok
|
||||||
|
}
|
||||||
|
|
||||||
|
// Range over the []byte values in the map
|
||||||
|
func (m *ByteMap) Range(f func(key string, value []byte) bool) {
|
||||||
|
m.data.Range(func(k, v interface{}) bool {
|
||||||
|
key, ok := k.(string)
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
value, ok := v.([]byte)
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return f(key, value)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store a []byte in the map
|
||||||
|
func (m *ByteMap) Store(key string, value []byte) {
|
||||||
|
m.data.Store(key, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keys returns a list of keys in the map
|
||||||
|
func (m *ByteMap) Keys() []string {
|
||||||
|
var keys []string
|
||||||
|
m.Range(func(key string, value []byte) bool {
|
||||||
|
keys = append(keys, key)
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
sort.Strings(keys)
|
||||||
|
return keys
|
||||||
|
}
|
156
vendor/github.com/gobuffalo/packd/memory_box.go
generated
vendored
Normal file
156
vendor/github.com/gobuffalo/packd/memory_box.go
generated
vendored
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
package packd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"sort"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/gobuffalo/packd/internal/takeon/github.com/markbates/errx"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ Addable = NewMemoryBox()
|
||||||
|
var _ Finder = NewMemoryBox()
|
||||||
|
var _ Lister = NewMemoryBox()
|
||||||
|
var _ HTTPBox = NewMemoryBox()
|
||||||
|
var _ Haser = NewMemoryBox()
|
||||||
|
var _ Walkable = NewMemoryBox()
|
||||||
|
var _ Box = NewMemoryBox()
|
||||||
|
|
||||||
|
// MemoryBox is a thread-safe, in-memory, implementation of the Box interface.
|
||||||
|
type MemoryBox struct {
|
||||||
|
files *ByteMap
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MemoryBox) Has(path string) bool {
|
||||||
|
_, ok := m.files.Load(path)
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MemoryBox) List() []string {
|
||||||
|
var names []string
|
||||||
|
m.files.Range(func(key string, value []byte) bool {
|
||||||
|
names = append(names, key)
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
|
||||||
|
sort.Strings(names)
|
||||||
|
return names
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MemoryBox) Open(path string) (http.File, error) {
|
||||||
|
cpath := strings.TrimPrefix(path, "/")
|
||||||
|
|
||||||
|
if filepath.Ext(cpath) == "" {
|
||||||
|
// it's a directory
|
||||||
|
return NewDir(path)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(cpath) == 0 {
|
||||||
|
cpath = "index.html"
|
||||||
|
}
|
||||||
|
|
||||||
|
b, err := m.Find(cpath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
cpath = filepath.FromSlash(cpath)
|
||||||
|
|
||||||
|
f, err := NewFile(cpath, bytes.NewReader(b))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return f, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MemoryBox) FindString(path string) (string, error) {
|
||||||
|
bb, err := m.Find(path)
|
||||||
|
return string(bb), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MemoryBox) Find(path string) (ret []byte, e error) {
|
||||||
|
res, ok := m.files.Load(path)
|
||||||
|
if !ok {
|
||||||
|
|
||||||
|
var b []byte
|
||||||
|
lpath := strings.ToLower(path)
|
||||||
|
err := m.Walk(func(p string, file File) error {
|
||||||
|
lp := strings.ToLower(p)
|
||||||
|
if lp != lpath {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
res := file.String()
|
||||||
|
b = []byte(res)
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return b, os.ErrNotExist
|
||||||
|
}
|
||||||
|
if len(b) == 0 {
|
||||||
|
return b, os.ErrNotExist
|
||||||
|
}
|
||||||
|
return b, nil
|
||||||
|
}
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MemoryBox) AddString(path string, t string) error {
|
||||||
|
return m.AddBytes(path, []byte(t))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MemoryBox) AddBytes(path string, t []byte) error {
|
||||||
|
m.files.Store(path, t)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MemoryBox) Walk(wf WalkFunc) error {
|
||||||
|
var err error
|
||||||
|
m.files.Range(func(path string, b []byte) bool {
|
||||||
|
var f File
|
||||||
|
f, err = NewFile(path, bytes.NewReader(b))
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
err = wf(path, f)
|
||||||
|
if err != nil {
|
||||||
|
if errx.Unwrap(err) == filepath.SkipDir {
|
||||||
|
err = nil
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
|
||||||
|
if errx.Unwrap(err) == filepath.SkipDir {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MemoryBox) WalkPrefix(pre string, wf WalkFunc) error {
|
||||||
|
return m.Walk(func(path string, file File) error {
|
||||||
|
if strings.HasPrefix(path, pre) {
|
||||||
|
return wf(path, file)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MemoryBox) Remove(path string) {
|
||||||
|
m.files.Delete(path)
|
||||||
|
m.files.Delete(strings.ToLower(path))
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewMemoryBox returns a configured *MemoryBox
|
||||||
|
func NewMemoryBox() *MemoryBox {
|
||||||
|
return &MemoryBox{
|
||||||
|
files: &ByteMap{},
|
||||||
|
}
|
||||||
|
}
|
43
vendor/github.com/gobuffalo/packd/skip_walker.go
generated
vendored
Normal file
43
vendor/github.com/gobuffalo/packd/skip_walker.go
generated
vendored
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
package packd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
var CommonSkipPrefixes = []string{".", "_", "node_modules", "vendor"}
|
||||||
|
|
||||||
|
// SkipWalker will walk the Walker and call the WalkFunc for files who's directories
|
||||||
|
// do no match any of the skipPrefixes. If no skipPrefixes are passed, then
|
||||||
|
// CommonSkipPrefixes is used
|
||||||
|
func SkipWalker(walker Walker, skipPrefixes []string, wf WalkFunc) error {
|
||||||
|
if len(skipPrefixes) == 0 {
|
||||||
|
skipPrefixes = append(skipPrefixes, CommonSkipPrefixes...)
|
||||||
|
}
|
||||||
|
return walker.Walk(func(path string, file File) error {
|
||||||
|
fi, err := file.FileInfo()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
path = strings.Replace(path, "\\", "/", -1)
|
||||||
|
|
||||||
|
parts := strings.Split(path, "/")
|
||||||
|
if !fi.IsDir() {
|
||||||
|
parts = parts[:len(parts)-1]
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, base := range parts {
|
||||||
|
if base != "." {
|
||||||
|
for _, skip := range skipPrefixes {
|
||||||
|
skip = strings.ToLower(skip)
|
||||||
|
lbase := strings.ToLower(base)
|
||||||
|
if strings.HasPrefix(lbase, skip) {
|
||||||
|
return filepath.SkipDir
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return wf(path, file)
|
||||||
|
})
|
||||||
|
}
|
4
vendor/github.com/gobuffalo/packd/version.go
generated
vendored
Normal file
4
vendor/github.com/gobuffalo/packd/version.go
generated
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
package packd
|
||||||
|
|
||||||
|
// Version of packd
|
||||||
|
const Version = "v0.3.0"
|
20
vendor/github.com/gobuffalo/packr/.codeclimate.yml
generated
vendored
Normal file
20
vendor/github.com/gobuffalo/packr/.codeclimate.yml
generated
vendored
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
---
|
||||||
|
engines:
|
||||||
|
golint:
|
||||||
|
enabled: true
|
||||||
|
checks:
|
||||||
|
GoLint/Naming/MixedCaps:
|
||||||
|
enabled: false
|
||||||
|
govet:
|
||||||
|
enabled: true
|
||||||
|
gofmt:
|
||||||
|
enabled: true
|
||||||
|
fixme:
|
||||||
|
enabled: true
|
||||||
|
ratings:
|
||||||
|
paths:
|
||||||
|
- "**.go"
|
||||||
|
exclude_paths:
|
||||||
|
- "**/*_test.go"
|
||||||
|
- "*_test.go"
|
||||||
|
- "fixtures/"
|
36
vendor/github.com/gobuffalo/packr/.gitignore
generated
vendored
Normal file
36
vendor/github.com/gobuffalo/packr/.gitignore
generated
vendored
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
*.log
|
||||||
|
./packr2
|
||||||
|
.DS_Store
|
||||||
|
doc
|
||||||
|
tmp
|
||||||
|
pkg
|
||||||
|
*.gem
|
||||||
|
*.pid
|
||||||
|
coverage
|
||||||
|
coverage.data
|
||||||
|
build/*
|
||||||
|
*.pbxuser
|
||||||
|
*.mode1v3
|
||||||
|
.svn
|
||||||
|
profile
|
||||||
|
.console_history
|
||||||
|
.sass-cache/*
|
||||||
|
.rake_tasks~
|
||||||
|
*.log.lck
|
||||||
|
solr/
|
||||||
|
.jhw-cache/
|
||||||
|
jhw.*
|
||||||
|
*.sublime*
|
||||||
|
node_modules/
|
||||||
|
dist/
|
||||||
|
generated/
|
||||||
|
.vendor/
|
||||||
|
bin/*
|
||||||
|
gin-bin
|
||||||
|
/packr_darwin_amd64
|
||||||
|
/packr_linux_amd64
|
||||||
|
.vscode/
|
||||||
|
debug.test
|
||||||
|
.grifter/
|
||||||
|
*-packr.go
|
||||||
|
|
3
vendor/github.com/gobuffalo/packr/.gometalinter.json
generated
vendored
Normal file
3
vendor/github.com/gobuffalo/packr/.gometalinter.json
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"Enable": ["vet", "golint", "goimports", "deadcode", "gotype", "ineffassign", "misspell", "nakedret", "unconvert", "megacheck", "varcheck"]
|
||||||
|
}
|
32
vendor/github.com/gobuffalo/packr/.goreleaser.yml
generated
vendored
Normal file
32
vendor/github.com/gobuffalo/packr/.goreleaser.yml
generated
vendored
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
# Code generated by github.com/gobuffalo/release. DO NOT EDIT.
|
||||||
|
# Edit .goreleaser.yml.plush instead
|
||||||
|
|
||||||
|
builds:
|
||||||
|
-
|
||||||
|
goos:
|
||||||
|
- darwin
|
||||||
|
- linux
|
||||||
|
- windows
|
||||||
|
env:
|
||||||
|
- CGO_ENABLED=0
|
||||||
|
main: ./packr/main.go
|
||||||
|
binary: packr
|
||||||
|
|
||||||
|
checksum:
|
||||||
|
name_template: 'checksums.txt'
|
||||||
|
|
||||||
|
snapshot:
|
||||||
|
name_template: "{{ .Tag }}-next"
|
||||||
|
|
||||||
|
changelog:
|
||||||
|
sort: asc
|
||||||
|
filters:
|
||||||
|
exclude:
|
||||||
|
- '^docs:'
|
||||||
|
- '^test:'
|
||||||
|
|
||||||
|
brew:
|
||||||
|
github:
|
||||||
|
owner: gobuffalo
|
||||||
|
name: homebrew-tap
|
||||||
|
|
29
vendor/github.com/gobuffalo/packr/.goreleaser.yml.plush
generated
vendored
Normal file
29
vendor/github.com/gobuffalo/packr/.goreleaser.yml.plush
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
builds:
|
||||||
|
-
|
||||||
|
goos:
|
||||||
|
- darwin
|
||||||
|
- linux
|
||||||
|
- windows
|
||||||
|
env:
|
||||||
|
- CGO_ENABLED=0
|
||||||
|
main: ./packr/main.go
|
||||||
|
binary: packr
|
||||||
|
|
||||||
|
checksum:
|
||||||
|
name_template: 'checksums.txt'
|
||||||
|
|
||||||
|
snapshot:
|
||||||
|
name_template: "{{ .Tag }}-next"
|
||||||
|
|
||||||
|
changelog:
|
||||||
|
sort: asc
|
||||||
|
filters:
|
||||||
|
exclude:
|
||||||
|
- '^docs:'
|
||||||
|
- '^test:'
|
||||||
|
<%= if (brew) { %>
|
||||||
|
brew:
|
||||||
|
github:
|
||||||
|
owner: gobuffalo
|
||||||
|
name: homebrew-tap
|
||||||
|
<% } %>
|
8
vendor/github.com/gobuffalo/packr/LICENSE.txt
generated
vendored
Normal file
8
vendor/github.com/gobuffalo/packr/LICENSE.txt
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
The MIT License (MIT)
|
||||||
|
Copyright (c) 2016 Mark Bates
|
||||||
|
|
||||||
|
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.
|
64
vendor/github.com/gobuffalo/packr/Makefile
generated
vendored
Normal file
64
vendor/github.com/gobuffalo/packr/Makefile
generated
vendored
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
TAGS ?= "sqlite"
|
||||||
|
GO_BIN ?= go
|
||||||
|
|
||||||
|
install: deps
|
||||||
|
echo "installing packr v1"
|
||||||
|
packr
|
||||||
|
$(GO_BIN) install -v ./packr
|
||||||
|
|
||||||
|
tidy:
|
||||||
|
ifeq ($(GO111MODULE),on)
|
||||||
|
$(GO_BIN) mod tidy
|
||||||
|
else
|
||||||
|
echo skipping go mod tidy
|
||||||
|
endif
|
||||||
|
|
||||||
|
deps:
|
||||||
|
rm -rf packrd
|
||||||
|
rm -rf v2/packrd
|
||||||
|
$(GO_BIN) get github.com/gobuffalo/release
|
||||||
|
$(GO_BIN) get -tags ${TAGS} -t ./...
|
||||||
|
$(GO_BIN) install -v ./packr
|
||||||
|
packr clean
|
||||||
|
make tidy
|
||||||
|
|
||||||
|
build: deps
|
||||||
|
packr
|
||||||
|
$(GO_BIN) build -v .
|
||||||
|
make tidy
|
||||||
|
|
||||||
|
test:
|
||||||
|
packr clean
|
||||||
|
$(GO_BIN) test -tags ${TAGS} ./...
|
||||||
|
packr clean
|
||||||
|
|
||||||
|
ci-deps:
|
||||||
|
rm -rf packrd
|
||||||
|
rm -rf v2/packrd
|
||||||
|
$(GO_BIN) get -tags ${TAGS} -t ./...
|
||||||
|
$(GO_BIN) install -v ./packr
|
||||||
|
packr clean
|
||||||
|
make tidy
|
||||||
|
|
||||||
|
ci-test:
|
||||||
|
$(GO_BIN) test -v -tags ${TAGS} -race ./...
|
||||||
|
make tidy
|
||||||
|
cd ./v2 && make ci-test
|
||||||
|
|
||||||
|
lint:
|
||||||
|
gometalinter --vendor ./... --deadline=1m --skip=internal
|
||||||
|
|
||||||
|
update:
|
||||||
|
$(GO_BIN) get -u -tags ${TAGS}
|
||||||
|
make tidy
|
||||||
|
packr
|
||||||
|
make test
|
||||||
|
make install
|
||||||
|
make tidy
|
||||||
|
|
||||||
|
release-test:
|
||||||
|
$(GO_BIN) test -tags ${TAGS} -race ./...
|
||||||
|
|
||||||
|
release:
|
||||||
|
release -y -f version.go
|
||||||
|
make tidy
|
205
vendor/github.com/gobuffalo/packr/README.md
generated
vendored
Normal file
205
vendor/github.com/gobuffalo/packr/README.md
generated
vendored
Normal file
@ -0,0 +1,205 @@
|
|||||||
|
# packr (v1)
|
||||||
|
|
||||||
|
[![GoDoc](https://godoc.org/github.com/gobuffalo/packr?status.svg)](https://godoc.org/github.com/gobuffalo/packr)
|
||||||
|
|
||||||
|
## Packr has been updated to `v2`! Please read the `./v2/README.md` file for more details.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Packr is a simple solution for bundling static assets inside of Go binaries. Most importantly it does it in a way that is friendly to developers while they are developing.
|
||||||
|
|
||||||
|
## Intro Video
|
||||||
|
|
||||||
|
To get an idea of the what and why of packr, please enjoy this short video: [https://vimeo.com/219863271](https://vimeo.com/219863271).
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
To install Packr utility
|
||||||
|
|
||||||
|
```text
|
||||||
|
$ go get -u github.com/gobuffalo/packr/packr
|
||||||
|
```
|
||||||
|
|
||||||
|
To get the dependency
|
||||||
|
|
||||||
|
```text
|
||||||
|
$ go get -u github.com/gobuffalo/packr
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
### In Code
|
||||||
|
|
||||||
|
The first step in using Packr is to create a new box. A box represents a folder on disk. Once you have a box you can get `string` or `[]byte` representations of the file.
|
||||||
|
|
||||||
|
```go
|
||||||
|
// set up a new box by giving it a (relative) path to a folder on disk:
|
||||||
|
box := packr.NewBox("./templates")
|
||||||
|
|
||||||
|
// Get the string representation of a file, or an error if it doesn't exist:
|
||||||
|
html, err := box.FindString("index.html")
|
||||||
|
|
||||||
|
// Get the []byte representation of a file, or an error if it doesn't exist:
|
||||||
|
html, err := box.FindBytes("index.html")
|
||||||
|
```
|
||||||
|
|
||||||
|
### What is a Box?
|
||||||
|
|
||||||
|
A box represents a folder, and any sub-folders, on disk that you want to have access to in your binary. When compiling a binary using the `packr` CLI the contents of the folder will be converted into Go files that can be compiled inside of a "standard" go binary. Inside of the compiled binary the files will be read from memory. When working locally the files will be read directly off of disk. This is a seamless switch that doesn't require any special attention on your part.
|
||||||
|
|
||||||
|
#### Example
|
||||||
|
|
||||||
|
Assume the follow directory structure:
|
||||||
|
|
||||||
|
```
|
||||||
|
├── main.go
|
||||||
|
└── templates
|
||||||
|
├── admin
|
||||||
|
│ └── index.html
|
||||||
|
└── index.html
|
||||||
|
```
|
||||||
|
|
||||||
|
The following program will read the `./templates/admin/index.html` file and print it out.
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/gobuffalo/packr"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
box := packr.NewBox("./templates")
|
||||||
|
|
||||||
|
s, err := box.FindString("admin/index.html")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
fmt.Println(s)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Development Made Easy
|
||||||
|
|
||||||
|
In order to get static files into a Go binary, those files must first be converted to Go code. To do that, Packr, ships with a few tools to help build binaries. See below.
|
||||||
|
|
||||||
|
During development, however, it is painful to have to keep running a tool to compile those files.
|
||||||
|
|
||||||
|
Packr uses the following resolution rules when looking for a file:
|
||||||
|
|
||||||
|
1. Look for the file in-memory (inside a Go binary)
|
||||||
|
1. Look for the file on disk (during development)
|
||||||
|
|
||||||
|
Because Packr knows how to fall through to the file system, developers don't need to worry about constantly compiling their static files into a binary. They can work unimpeded.
|
||||||
|
|
||||||
|
Packr takes file resolution a step further. When declaring a new box you use a relative path, `./templates`. When Packr receives this call it calculates out the absolute path to that directory. By doing this it means you can be guaranteed that Packr can find your files correctly, even if you're not running in the directory that the box was created in. This helps with the problem of testing, where Go changes the `pwd` for each package, making relative paths difficult to work with. This is not a problem when using Packr.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Usage with HTTP
|
||||||
|
|
||||||
|
A box implements the [`http.FileSystem`](https://golang.org/pkg/net/http/#FileSystem) interface, meaning it can be used to serve static files.
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/gobuffalo/packr"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
box := packr.NewBox("./templates")
|
||||||
|
|
||||||
|
http.Handle("/", http.FileServer(box))
|
||||||
|
http.ListenAndServe(":3000", nil)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Building a Binary (the easy way)
|
||||||
|
|
||||||
|
When it comes time to build, or install, your Go binary, simply use `packr build` or `packr install` just as you would `go build` or `go install`. All flags for the `go` tool are supported and everything works the way you expect, the only difference is your static assets are now bundled in the generated binary. If you want more control over how this happens, looking at the following section on building binaries (the hard way).
|
||||||
|
|
||||||
|
## Building a Binary (the hard way)
|
||||||
|
|
||||||
|
Before you build your Go binary, run the `packr` command first. It will look for all the boxes in your code and then generate `.go` files that pack the static files into bytes that can be bundled into the Go binary.
|
||||||
|
|
||||||
|
```
|
||||||
|
$ packr
|
||||||
|
```
|
||||||
|
|
||||||
|
Then run your `go build command` like normal.
|
||||||
|
|
||||||
|
*NOTE*: It is not recommended to check-in these generated `-packr.go` files. They can be large, and can easily become out of date if not careful. It is recommended that you always run `packr clean` after running the `packr` tool.
|
||||||
|
|
||||||
|
#### Cleaning Up
|
||||||
|
|
||||||
|
When you're done it is recommended that you run the `packr clean` command. This will remove all of the generated files that Packr created for you.
|
||||||
|
|
||||||
|
```
|
||||||
|
$ packr clean
|
||||||
|
```
|
||||||
|
|
||||||
|
Why do you want to do this? Packr first looks to the information stored in these generated files, if the information isn't there it looks to disk. This makes it easy to work with in development.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Building/Moving a portable release
|
||||||
|
|
||||||
|
When it comes to building multiple releases you typically want that release to be built in a specific directory.
|
||||||
|
|
||||||
|
For example: `./releases`
|
||||||
|
|
||||||
|
However, because passing a `.go` file requires absolute paths, we must compile the release in the appropriate absolute path.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
GOOS=linux GOARCH=amd64 packr build
|
||||||
|
```
|
||||||
|
|
||||||
|
Now your `project_name` binary will be built at the root of your project dir. Great!
|
||||||
|
|
||||||
|
All that is left to do is to move that binary to your release dir:
|
||||||
|
|
||||||
|
Linux/macOS/Windows (bash)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mv ./project_name ./releases
|
||||||
|
```
|
||||||
|
|
||||||
|
Windows (cmd):
|
||||||
|
|
||||||
|
```cmd
|
||||||
|
move ./project_name ./releases
|
||||||
|
```
|
||||||
|
|
||||||
|
Powershell:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
Move-Item -Path .\project_name -Destination .\releases\
|
||||||
|
```
|
||||||
|
|
||||||
|
If you _target_ for Windows when building don't forget that it's `project_name.exe`
|
||||||
|
|
||||||
|
Now you can make multiple releases and all of your needed static files will be available!
|
||||||
|
|
||||||
|
#### Summing it up:
|
||||||
|
|
||||||
|
Example Script for building to 3 common targets:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
GOOS=darwin GOARCH=amd64 packr build && mv ./project_name ./releases/darwin-project_name \
|
||||||
|
&& GOOS=linux GOARCH=amd64 packr build && mv ./project_name ./releases/linux-project_name \
|
||||||
|
&& GOOS=windows GOARCH=386 packr build && mv ./project_name.exe ./releases/project_name.exe \
|
||||||
|
&& packr clean
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Debugging
|
||||||
|
|
||||||
|
The `packr` command passes all arguments down to the underlying `go` command, this includes the `-v` flag to print out `go build` information. Packr looks for the `-v` flag, and will turn on its own verbose logging. This is very useful for trying to understand what the `packr` command is doing when it is run.
|
18
vendor/github.com/gobuffalo/packr/SHOULDERS.md
generated
vendored
Normal file
18
vendor/github.com/gobuffalo/packr/SHOULDERS.md
generated
vendored
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# github.com/gobuffalo/packr Stands on the Shoulders of Giants
|
||||||
|
|
||||||
|
github.com/gobuffalo/packr does not try to reinvent the wheel! Instead, it uses the already great wheels developed by the Go community and puts them all together in the best way possible. Without these giants, this project would not be possible. Please make sure to check them out and thank them for all of their hard work.
|
||||||
|
|
||||||
|
Thank you to the following **GIANTS**:
|
||||||
|
|
||||||
|
|
||||||
|
* [github.com/gobuffalo/envy](https://godoc.org/github.com/gobuffalo/envy)
|
||||||
|
|
||||||
|
* [github.com/gobuffalo/packd](https://godoc.org/github.com/gobuffalo/packd)
|
||||||
|
|
||||||
|
* [github.com/gobuffalo/packr/v2](https://godoc.org/github.com/gobuffalo/packr/v2)
|
||||||
|
|
||||||
|
* [github.com/spf13/cobra](https://godoc.org/github.com/spf13/cobra)
|
||||||
|
|
||||||
|
* [github.com/stretchr/testify](https://godoc.org/github.com/stretchr/testify)
|
||||||
|
|
||||||
|
* [golang.org/x/sync](https://godoc.org/golang.org/x/sync)
|
71
vendor/github.com/gobuffalo/packr/azure-pipelines.yml
generated
vendored
Normal file
71
vendor/github.com/gobuffalo/packr/azure-pipelines.yml
generated
vendored
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
variables:
|
||||||
|
GOBIN: "$(GOPATH)/bin" # Go binaries path
|
||||||
|
GOPATH: "$(system.defaultWorkingDirectory)/gopath" # Go workspace path
|
||||||
|
modulePath: "$(GOPATH)/src/github.com/$(build.repository.name)" # Path to the module"s code
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
- job: Windows
|
||||||
|
pool:
|
||||||
|
vmImage: "vs2017-win2016"
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
go 1.10:
|
||||||
|
go_version: "1.10"
|
||||||
|
go 1.11 (on):
|
||||||
|
go_version: "1.11.5"
|
||||||
|
GO111MODULE: "on"
|
||||||
|
go 1.11 (off):
|
||||||
|
go_version: "1.11.5"
|
||||||
|
GO111MODULE: "off"
|
||||||
|
go 1.12 (on):
|
||||||
|
go_version: "1.12"
|
||||||
|
GO111MODULE: "on"
|
||||||
|
go 1.12 (off):
|
||||||
|
go_version: "1.12"
|
||||||
|
GO111MODULE: "off"
|
||||||
|
steps:
|
||||||
|
- template: azure-tests.yml
|
||||||
|
|
||||||
|
- job: macOS
|
||||||
|
pool:
|
||||||
|
vmImage: "macOS-10.13"
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
go 1.10:
|
||||||
|
go_version: "1.10"
|
||||||
|
go 1.11 (on):
|
||||||
|
go_version: "1.11.5"
|
||||||
|
GO111MODULE: "on"
|
||||||
|
go 1.11 (off):
|
||||||
|
go_version: "1.11.5"
|
||||||
|
GO111MODULE: "off"
|
||||||
|
go 1.12 (on):
|
||||||
|
go_version: "1.12"
|
||||||
|
GO111MODULE: "on"
|
||||||
|
go 1.12 (off):
|
||||||
|
go_version: "1.12"
|
||||||
|
GO111MODULE: "off"
|
||||||
|
steps:
|
||||||
|
- template: azure-tests.yml
|
||||||
|
|
||||||
|
- job: Linux
|
||||||
|
pool:
|
||||||
|
vmImage: "ubuntu-16.04"
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
go 1.10:
|
||||||
|
go_version: "1.10"
|
||||||
|
go 1.11 (on):
|
||||||
|
go_version: "1.11.5"
|
||||||
|
GO111MODULE: "on"
|
||||||
|
go 1.11 (off):
|
||||||
|
go_version: "1.11.5"
|
||||||
|
GO111MODULE: "off"
|
||||||
|
go 1.12 (on):
|
||||||
|
go_version: "1.12"
|
||||||
|
GO111MODULE: "on"
|
||||||
|
go 1.12 (off):
|
||||||
|
go_version: "1.12"
|
||||||
|
GO111MODULE: "off"
|
||||||
|
steps:
|
||||||
|
- template: azure-tests.yml
|
24
vendor/github.com/gobuffalo/packr/azure-tests.yml
generated
vendored
Normal file
24
vendor/github.com/gobuffalo/packr/azure-tests.yml
generated
vendored
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
steps:
|
||||||
|
- task: GoTool@0
|
||||||
|
inputs:
|
||||||
|
version: $(go_version)
|
||||||
|
- task: Bash@3
|
||||||
|
inputs:
|
||||||
|
targetType: inline
|
||||||
|
script: |
|
||||||
|
mkdir -p "$(GOBIN)"
|
||||||
|
mkdir -p "$(GOPATH)/pkg"
|
||||||
|
mkdir -p "$(modulePath)"
|
||||||
|
shopt -s extglob
|
||||||
|
mv !(gopath) "$(modulePath)"
|
||||||
|
displayName: "Setup Go Workspace"
|
||||||
|
- script: |
|
||||||
|
go get -t -v ./...
|
||||||
|
go test -race ./...
|
||||||
|
go install -v ./packr
|
||||||
|
cd v2
|
||||||
|
go get -t -v ./...
|
||||||
|
go test -race ./...
|
||||||
|
go install -v ./packr2
|
||||||
|
workingDirectory: "$(modulePath)"
|
||||||
|
displayName: "Tests"
|
228
vendor/github.com/gobuffalo/packr/box.go
generated
vendored
Normal file
228
vendor/github.com/gobuffalo/packr/box.go
generated
vendored
Normal file
@ -0,0 +1,228 @@
|
|||||||
|
package packr
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"compress/gzip"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"path"
|
||||||
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/gobuffalo/packd"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// ErrResOutsideBox gets returned in case of the requested resources being outside the box
|
||||||
|
ErrResOutsideBox = fmt.Errorf("Can't find a resource outside the box")
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ packd.Box = Box{}
|
||||||
|
var _ packd.HTTPBox = Box{}
|
||||||
|
var _ packd.Lister = Box{}
|
||||||
|
var _ packd.Addable = Box{}
|
||||||
|
var _ packd.Walkable = Box{}
|
||||||
|
var _ packd.Finder = Box{}
|
||||||
|
var _ packd.LegacyBox = Box{}
|
||||||
|
|
||||||
|
// NewBox returns a Box that can be used to
|
||||||
|
// retrieve files from either disk or the embedded
|
||||||
|
// binary.
|
||||||
|
func NewBox(path string) Box {
|
||||||
|
var cd string
|
||||||
|
if !filepath.IsAbs(path) {
|
||||||
|
_, filename, _, _ := runtime.Caller(1)
|
||||||
|
cd = filepath.Dir(filename)
|
||||||
|
}
|
||||||
|
|
||||||
|
// this little hack courtesy of the `-cover` flag!!
|
||||||
|
cov := filepath.Join("_test", "_obj_test")
|
||||||
|
cd = strings.Replace(cd, string(filepath.Separator)+cov, "", 1)
|
||||||
|
if !filepath.IsAbs(cd) && cd != "" {
|
||||||
|
cd = filepath.Join(GoPath(), "src", cd)
|
||||||
|
}
|
||||||
|
|
||||||
|
return Box{
|
||||||
|
Path: path,
|
||||||
|
callingDir: cd,
|
||||||
|
data: map[string][]byte{},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Box represent a folder on a disk you want to
|
||||||
|
// have access to in the built Go binary.
|
||||||
|
type Box struct {
|
||||||
|
Path string
|
||||||
|
callingDir string
|
||||||
|
data map[string][]byte
|
||||||
|
directories map[string]bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddString converts t to a byteslice and delegates to AddBytes to add to b.data
|
||||||
|
func (b Box) AddString(path string, t string) error {
|
||||||
|
b.AddBytes(path, []byte(t))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddBytes sets t in b.data by the given path
|
||||||
|
func (b Box) AddBytes(path string, t []byte) error {
|
||||||
|
b.data[path] = t
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: Use FindString instead.
|
||||||
|
func (b Box) String(name string) string {
|
||||||
|
bb, _ := b.FindString(name)
|
||||||
|
return bb
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: Use FindString instead.
|
||||||
|
func (b Box) MustString(name string) (string, error) {
|
||||||
|
return b.FindString(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: Use Find instead.
|
||||||
|
func (b Box) Bytes(name string) []byte {
|
||||||
|
bb, _ := b.Find(name)
|
||||||
|
return bb
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: Use Find instead.
|
||||||
|
func (b Box) MustBytes(name string) ([]byte, error) {
|
||||||
|
return b.Find(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindString returns either the string of the requested
|
||||||
|
// file or an error if it can not be found.
|
||||||
|
func (b Box) FindString(name string) (string, error) {
|
||||||
|
bb, err := b.Find(name)
|
||||||
|
return string(bb), err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find returns either the byte slice of the requested
|
||||||
|
// file or an error if it can not be found.
|
||||||
|
func (b Box) Find(name string) ([]byte, error) {
|
||||||
|
f, err := b.find(name)
|
||||||
|
if err == nil {
|
||||||
|
bb := &bytes.Buffer{}
|
||||||
|
bb.ReadFrom(f)
|
||||||
|
return bb.Bytes(), err
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Has returns true if the resource exists in the box
|
||||||
|
func (b Box) Has(name string) bool {
|
||||||
|
_, err := b.find(name)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b Box) decompress(bb []byte) []byte {
|
||||||
|
reader, err := gzip.NewReader(bytes.NewReader(bb))
|
||||||
|
if err != nil {
|
||||||
|
return bb
|
||||||
|
}
|
||||||
|
defer reader.Close()
|
||||||
|
|
||||||
|
data, err := ioutil.ReadAll(reader)
|
||||||
|
if err != nil {
|
||||||
|
return bb
|
||||||
|
}
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b Box) find(name string) (File, error) {
|
||||||
|
if bb, ok := b.data[name]; ok {
|
||||||
|
return packd.NewFile(name, bytes.NewReader(bb))
|
||||||
|
}
|
||||||
|
|
||||||
|
if b.directories == nil {
|
||||||
|
b.indexDirectories()
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanName := filepath.ToSlash(filepath.Clean(name))
|
||||||
|
// Ensure name is not outside the box
|
||||||
|
if strings.HasPrefix(cleanName, "../") {
|
||||||
|
return nil, ErrResOutsideBox
|
||||||
|
}
|
||||||
|
// Absolute name is considered as relative to the box root
|
||||||
|
cleanName = strings.TrimPrefix(cleanName, "/")
|
||||||
|
|
||||||
|
if _, ok := data[b.Path]; ok {
|
||||||
|
if bb, ok := data[b.Path][cleanName]; ok {
|
||||||
|
bb = b.decompress(bb)
|
||||||
|
return packd.NewFile(cleanName, bytes.NewReader(bb))
|
||||||
|
}
|
||||||
|
if _, ok := b.directories[cleanName]; ok {
|
||||||
|
return packd.NewDir(cleanName)
|
||||||
|
}
|
||||||
|
if filepath.Ext(cleanName) != "" {
|
||||||
|
// The Handler created by http.FileSystem checks for those errors and
|
||||||
|
// returns http.StatusNotFound instead of http.StatusInternalServerError.
|
||||||
|
return nil, os.ErrNotExist
|
||||||
|
}
|
||||||
|
return nil, os.ErrNotExist
|
||||||
|
}
|
||||||
|
|
||||||
|
// Not found in the box virtual fs, try to get it from the file system
|
||||||
|
cleanName = filepath.FromSlash(cleanName)
|
||||||
|
p := filepath.Join(b.callingDir, b.Path, cleanName)
|
||||||
|
return fileFor(p, cleanName)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Open returns a File using the http.File interface
|
||||||
|
func (b Box) Open(name string) (http.File, error) {
|
||||||
|
return b.find(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// List shows "What's in the box?"
|
||||||
|
func (b Box) List() []string {
|
||||||
|
var keys []string
|
||||||
|
|
||||||
|
if b.data == nil || len(b.data) == 0 {
|
||||||
|
b.Walk(func(path string, info File) error {
|
||||||
|
finfo, _ := info.FileInfo()
|
||||||
|
if !finfo.IsDir() {
|
||||||
|
keys = append(keys, finfo.Name())
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
for k := range b.data {
|
||||||
|
keys = append(keys, k)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return keys
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Box) indexDirectories() {
|
||||||
|
b.directories = map[string]bool{}
|
||||||
|
if _, ok := data[b.Path]; ok {
|
||||||
|
for name := range data[b.Path] {
|
||||||
|
prefix, _ := path.Split(name)
|
||||||
|
// Even on Windows the suffix appears to be a /
|
||||||
|
prefix = strings.TrimSuffix(prefix, "/")
|
||||||
|
b.directories[prefix] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func fileFor(p string, name string) (File, error) {
|
||||||
|
fi, err := os.Stat(p)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if fi.IsDir() {
|
||||||
|
return packd.NewDir(p)
|
||||||
|
}
|
||||||
|
if bb, err := ioutil.ReadFile(p); err == nil {
|
||||||
|
return packd.NewFile(name, bytes.NewReader(bb))
|
||||||
|
}
|
||||||
|
return nil, os.ErrNotExist
|
||||||
|
}
|
13
vendor/github.com/gobuffalo/packr/env.go
generated
vendored
Normal file
13
vendor/github.com/gobuffalo/packr/env.go
generated
vendored
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
package packr
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gobuffalo/envy"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GoPath returns the current GOPATH env var
|
||||||
|
// or if it's missing, the default.
|
||||||
|
var GoPath = envy.GoPath
|
||||||
|
|
||||||
|
// GoBin returns the current GO_BIN env var
|
||||||
|
// or if it's missing, a default of "go"
|
||||||
|
var GoBin = envy.GoBin
|
5
vendor/github.com/gobuffalo/packr/file.go
generated
vendored
Normal file
5
vendor/github.com/gobuffalo/packr/file.go
generated
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
package packr
|
||||||
|
|
||||||
|
import "github.com/gobuffalo/packd"
|
||||||
|
|
||||||
|
type File = packd.File
|
12
vendor/github.com/gobuffalo/packr/go.mod
generated
vendored
Normal file
12
vendor/github.com/gobuffalo/packr/go.mod
generated
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
module github.com/gobuffalo/packr
|
||||||
|
|
||||||
|
go 1.12
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/gobuffalo/envy v1.7.0
|
||||||
|
github.com/gobuffalo/packd v0.3.0
|
||||||
|
github.com/gobuffalo/packr/v2 v2.5.1
|
||||||
|
github.com/spf13/cobra v0.0.5
|
||||||
|
github.com/stretchr/testify v1.3.0
|
||||||
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58
|
||||||
|
)
|
79
vendor/github.com/gobuffalo/packr/go.sum
generated
vendored
Normal file
79
vendor/github.com/gobuffalo/packr/go.sum
generated
vendored
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
|
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||||
|
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||||
|
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
|
||||||
|
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||||
|
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
|
||||||
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||||
|
github.com/gobuffalo/envy v1.7.0 h1:GlXgaiBkmrYMHco6t4j7SacKO4XUjvh5pwXh0f4uxXU=
|
||||||
|
github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI=
|
||||||
|
github.com/gobuffalo/logger v1.0.0 h1:xw9Ko9EcC5iAFprrjJ6oZco9UpzS5MQ4jAwghsLHdy4=
|
||||||
|
github.com/gobuffalo/logger v1.0.0/go.mod h1:2zbswyIUa45I+c+FLXuWl9zSWEiVuthsk8ze5s8JvPs=
|
||||||
|
github.com/gobuffalo/packd v0.3.0 h1:eMwymTkA1uXsqxS0Tpoop3Lc0u3kTfiMBE6nKtQU4g4=
|
||||||
|
github.com/gobuffalo/packd v0.3.0/go.mod h1:zC7QkmNkYVGKPw4tHpBQ+ml7W/3tIebgeo1b36chA3Q=
|
||||||
|
github.com/gobuffalo/packr/v2 v2.5.1 h1:TFOeY2VoGamPjQLiNDT3mn//ytzk236VMO2j7iHxJR4=
|
||||||
|
github.com/gobuffalo/packr/v2 v2.5.1/go.mod h1:8f9c96ITobJlPzI44jj+4tHnEKNt0xXWSVlXRN9X1Iw=
|
||||||
|
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||||
|
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
|
||||||
|
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||||
|
github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc=
|
||||||
|
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
|
||||||
|
github.com/karrick/godirwalk v1.10.12 h1:BqUm+LuJcXjGv1d2mj3gBiQyrQ57a0rYoAmhvJQ7RDU=
|
||||||
|
github.com/karrick/godirwalk v1.10.12/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA=
|
||||||
|
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
|
github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s=
|
||||||
|
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
|
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||||
|
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||||
|
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||||
|
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||||
|
github.com/rogpeppe/go-internal v1.3.0 h1:RR9dF3JtopPvtkroDZuVD7qquD0bnHlKSqaQhgwt8yk=
|
||||||
|
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||||
|
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||||
|
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
|
||||||
|
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||||
|
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
||||||
|
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||||
|
github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s=
|
||||||
|
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
|
||||||
|
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||||
|
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
|
||||||
|
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||||
|
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
|
||||||
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
|
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
||||||
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
|
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
||||||
|
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||||
|
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4 h1:ydJNl0ENAG67pFbB+9tfhiL2pYqLhfoaZFw/cjLhY4A=
|
||||||
|
golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
|
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU=
|
||||||
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20190515120540-06a5c4944438 h1:khxRGsvPk4n2y8I/mLLjp7e5dMTJmH75wvqS6nMwUtY=
|
||||||
|
golang.org/x/sys v0.0.0-20190515120540-06a5c4944438/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
golang.org/x/tools v0.0.0-20190624180213-70d37148ca0c h1:KfpJVdWhuRqNk4XVXzjXf2KAV4TBEP77SYdFGjeGuIE=
|
||||||
|
golang.org/x/tools v0.0.0-20190624180213-70d37148ca0c/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||||
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
74
vendor/github.com/gobuffalo/packr/packr.go
generated
vendored
Normal file
74
vendor/github.com/gobuffalo/packr/packr.go
generated
vendored
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
package packr
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"compress/gzip"
|
||||||
|
"encoding/json"
|
||||||
|
"runtime"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
var gil = &sync.Mutex{}
|
||||||
|
var data = map[string]map[string][]byte{}
|
||||||
|
|
||||||
|
// PackBytes packs bytes for a file into a box.
|
||||||
|
func PackBytes(box string, name string, bb []byte) {
|
||||||
|
gil.Lock()
|
||||||
|
defer gil.Unlock()
|
||||||
|
if _, ok := data[box]; !ok {
|
||||||
|
data[box] = map[string][]byte{}
|
||||||
|
}
|
||||||
|
data[box][name] = bb
|
||||||
|
}
|
||||||
|
|
||||||
|
// PackBytesGzip packets the gzipped compressed bytes into a box.
|
||||||
|
func PackBytesGzip(box string, name string, bb []byte) error {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
w := gzip.NewWriter(&buf)
|
||||||
|
_, err := w.Write(bb)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = w.Close()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
PackBytes(box, name, buf.Bytes())
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// PackJSONBytes packs JSON encoded bytes for a file into a box.
|
||||||
|
func PackJSONBytes(box string, name string, jbb string) error {
|
||||||
|
var bb []byte
|
||||||
|
err := json.Unmarshal([]byte(jbb), &bb)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
PackBytes(box, name, bb)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnpackBytes unpacks bytes for specific box.
|
||||||
|
func UnpackBytes(box string) {
|
||||||
|
gil.Lock()
|
||||||
|
defer gil.Unlock()
|
||||||
|
delete(data, box)
|
||||||
|
}
|
||||||
|
|
||||||
|
func osPaths(paths ...string) []string {
|
||||||
|
if runtime.GOOS == "windows" {
|
||||||
|
for i, path := range paths {
|
||||||
|
paths[i] = strings.Replace(path, "/", "\\", -1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return paths
|
||||||
|
}
|
||||||
|
|
||||||
|
func osPath(path string) string {
|
||||||
|
if runtime.GOOS == "windows" {
|
||||||
|
return strings.Replace(path, "/", "\\", -1)
|
||||||
|
}
|
||||||
|
return path
|
||||||
|
}
|
3
vendor/github.com/gobuffalo/packr/version.go
generated
vendored
Normal file
3
vendor/github.com/gobuffalo/packr/version.go
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
package packr
|
||||||
|
|
||||||
|
const Version = "v1.30.1"
|
63
vendor/github.com/gobuffalo/packr/walk.go
generated
vendored
Normal file
63
vendor/github.com/gobuffalo/packr/walk.go
generated
vendored
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
package packr
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/gobuffalo/packd"
|
||||||
|
)
|
||||||
|
|
||||||
|
type WalkFunc = packd.WalkFunc
|
||||||
|
|
||||||
|
// Walk will traverse the box and call the WalkFunc for each file in the box/folder.
|
||||||
|
func (b Box) Walk(wf WalkFunc) error {
|
||||||
|
if data[b.Path] == nil {
|
||||||
|
base, err := filepath.EvalSymlinks(filepath.Join(b.callingDir, b.Path))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return filepath.Walk(base, func(path string, info os.FileInfo, err error) error {
|
||||||
|
cleanName, err := filepath.Rel(base, path)
|
||||||
|
if err != nil {
|
||||||
|
cleanName = strings.TrimPrefix(path, base)
|
||||||
|
}
|
||||||
|
cleanName = filepath.ToSlash(filepath.Clean(cleanName))
|
||||||
|
cleanName = strings.TrimPrefix(cleanName, "/")
|
||||||
|
cleanName = filepath.FromSlash(cleanName)
|
||||||
|
if info == nil || info.IsDir() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
file, err := fileFor(path, cleanName)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return wf(cleanName, file)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
for n := range data[b.Path] {
|
||||||
|
f, err := b.find(n)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = wf(n, f)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// WalkPrefix will call box.Walk and call the WalkFunc when it finds paths that have a matching prefix
|
||||||
|
func (b Box) WalkPrefix(prefix string, wf WalkFunc) error {
|
||||||
|
opre := osPath(prefix)
|
||||||
|
return b.Walk(func(path string, f File) error {
|
||||||
|
if strings.HasPrefix(osPath(path), opre) {
|
||||||
|
if err := wf(path, f); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
1
vendor/github.com/joho/godotenv/.gitignore
generated
vendored
Normal file
1
vendor/github.com/joho/godotenv/.gitignore
generated
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
.DS_Store
|
8
vendor/github.com/joho/godotenv/.travis.yml
generated
vendored
Normal file
8
vendor/github.com/joho/godotenv/.travis.yml
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
language: go
|
||||||
|
|
||||||
|
go:
|
||||||
|
- 1.x
|
||||||
|
|
||||||
|
os:
|
||||||
|
- linux
|
||||||
|
- osx
|
23
vendor/github.com/joho/godotenv/LICENCE
generated
vendored
Normal file
23
vendor/github.com/joho/godotenv/LICENCE
generated
vendored
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
Copyright (c) 2013 John Barton
|
||||||
|
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
163
vendor/github.com/joho/godotenv/README.md
generated
vendored
Normal file
163
vendor/github.com/joho/godotenv/README.md
generated
vendored
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
# GoDotEnv [![Build Status](https://travis-ci.org/joho/godotenv.svg?branch=master)](https://travis-ci.org/joho/godotenv) [![Build status](https://ci.appveyor.com/api/projects/status/9v40vnfvvgde64u4?svg=true)](https://ci.appveyor.com/project/joho/godotenv) [![Go Report Card](https://goreportcard.com/badge/github.com/joho/godotenv)](https://goreportcard.com/report/github.com/joho/godotenv)
|
||||||
|
|
||||||
|
A Go (golang) port of the Ruby dotenv project (which loads env vars from a .env file)
|
||||||
|
|
||||||
|
From the original Library:
|
||||||
|
|
||||||
|
> Storing configuration in the environment is one of the tenets of a twelve-factor app. Anything that is likely to change between deployment environments–such as resource handles for databases or credentials for external services–should be extracted from the code into environment variables.
|
||||||
|
>
|
||||||
|
> But it is not always practical to set environment variables on development machines or continuous integration servers where multiple projects are run. Dotenv load variables from a .env file into ENV when the environment is bootstrapped.
|
||||||
|
|
||||||
|
It can be used as a library (for loading in env for your own daemons etc) or as a bin command.
|
||||||
|
|
||||||
|
There is test coverage and CI for both linuxish and windows environments, but I make no guarantees about the bin version working on windows.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
As a library
|
||||||
|
|
||||||
|
```shell
|
||||||
|
go get github.com/joho/godotenv
|
||||||
|
```
|
||||||
|
|
||||||
|
or if you want to use it as a bin command
|
||||||
|
```shell
|
||||||
|
go get github.com/joho/godotenv/cmd/godotenv
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
Add your application configuration to your `.env` file in the root of your project:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
S3_BUCKET=YOURS3BUCKET
|
||||||
|
SECRET_KEY=YOURSECRETKEYGOESHERE
|
||||||
|
```
|
||||||
|
|
||||||
|
Then in your Go app you can do something like
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/joho/godotenv"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
err := godotenv.Load()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("Error loading .env file")
|
||||||
|
}
|
||||||
|
|
||||||
|
s3Bucket := os.Getenv("S3_BUCKET")
|
||||||
|
secretKey := os.Getenv("SECRET_KEY")
|
||||||
|
|
||||||
|
// now do something with s3 or whatever
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
If you're even lazier than that, you can just take advantage of the autoload package which will read in `.env` on import
|
||||||
|
|
||||||
|
```go
|
||||||
|
import _ "github.com/joho/godotenv/autoload"
|
||||||
|
```
|
||||||
|
|
||||||
|
While `.env` in the project root is the default, you don't have to be constrained, both examples below are 100% legit
|
||||||
|
|
||||||
|
```go
|
||||||
|
_ = godotenv.Load("somerandomfile")
|
||||||
|
_ = godotenv.Load("filenumberone.env", "filenumbertwo.env")
|
||||||
|
```
|
||||||
|
|
||||||
|
If you want to be really fancy with your env file you can do comments and exports (below is a valid env file)
|
||||||
|
|
||||||
|
```shell
|
||||||
|
# I am a comment and that is OK
|
||||||
|
SOME_VAR=someval
|
||||||
|
FOO=BAR # comments at line end are OK too
|
||||||
|
export BAR=BAZ
|
||||||
|
```
|
||||||
|
|
||||||
|
Or finally you can do YAML(ish) style
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
FOO: bar
|
||||||
|
BAR: baz
|
||||||
|
```
|
||||||
|
|
||||||
|
as a final aside, if you don't want godotenv munging your env you can just get a map back instead
|
||||||
|
|
||||||
|
```go
|
||||||
|
var myEnv map[string]string
|
||||||
|
myEnv, err := godotenv.Read()
|
||||||
|
|
||||||
|
s3Bucket := myEnv["S3_BUCKET"]
|
||||||
|
```
|
||||||
|
|
||||||
|
... or from an `io.Reader` instead of a local file
|
||||||
|
|
||||||
|
```go
|
||||||
|
reader := getRemoteFile()
|
||||||
|
myEnv, err := godotenv.Parse(reader)
|
||||||
|
```
|
||||||
|
|
||||||
|
... or from a `string` if you so desire
|
||||||
|
|
||||||
|
```go
|
||||||
|
content := getRemoteFileContent()
|
||||||
|
myEnv, err := godotenv.Unmarshal(content)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Command Mode
|
||||||
|
|
||||||
|
Assuming you've installed the command as above and you've got `$GOPATH/bin` in your `$PATH`
|
||||||
|
|
||||||
|
```
|
||||||
|
godotenv -f /some/path/to/.env some_command with some args
|
||||||
|
```
|
||||||
|
|
||||||
|
If you don't specify `-f` it will fall back on the default of loading `.env` in `PWD`
|
||||||
|
|
||||||
|
### Writing Env Files
|
||||||
|
|
||||||
|
Godotenv can also write a map representing the environment to a correctly-formatted and escaped file
|
||||||
|
|
||||||
|
```go
|
||||||
|
env, err := godotenv.Unmarshal("KEY=value")
|
||||||
|
err := godotenv.Write(env, "./.env")
|
||||||
|
```
|
||||||
|
|
||||||
|
... or to a string
|
||||||
|
|
||||||
|
```go
|
||||||
|
env, err := godotenv.Unmarshal("KEY=value")
|
||||||
|
content, err := godotenv.Marshal(env)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
Contributions are most welcome! The parser itself is pretty stupidly naive and I wouldn't be surprised if it breaks with edge cases.
|
||||||
|
|
||||||
|
*code changes without tests will not be accepted*
|
||||||
|
|
||||||
|
1. Fork it
|
||||||
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
||||||
|
3. Commit your changes (`git commit -am 'Added some feature'`)
|
||||||
|
4. Push to the branch (`git push origin my-new-feature`)
|
||||||
|
5. Create new Pull Request
|
||||||
|
|
||||||
|
## Releases
|
||||||
|
|
||||||
|
Releases should follow [Semver](http://semver.org/) though the first couple of releases are `v1` and `v1.1`.
|
||||||
|
|
||||||
|
Use [annotated tags for all releases](https://github.com/joho/godotenv/issues/30). Example `git tag -a v1.2.1`
|
||||||
|
|
||||||
|
## CI
|
||||||
|
|
||||||
|
Linux: [![Build Status](https://travis-ci.org/joho/godotenv.svg?branch=master)](https://travis-ci.org/joho/godotenv) Windows: [![Build status](https://ci.appveyor.com/api/projects/status/9v40vnfvvgde64u4)](https://ci.appveyor.com/project/joho/godotenv)
|
||||||
|
|
||||||
|
## Who?
|
||||||
|
|
||||||
|
The original library [dotenv](https://github.com/bkeepers/dotenv) was written by [Brandon Keepers](http://opensoul.org/), and this port was done by [John Barton](https://johnbarton.co/) based off the tests/fixtures in the original library.
|
346
vendor/github.com/joho/godotenv/godotenv.go
generated
vendored
Normal file
346
vendor/github.com/joho/godotenv/godotenv.go
generated
vendored
Normal file
@ -0,0 +1,346 @@
|
|||||||
|
// Package godotenv is a go port of the ruby dotenv library (https://github.com/bkeepers/dotenv)
|
||||||
|
//
|
||||||
|
// Examples/readme can be found on the github page at https://github.com/joho/godotenv
|
||||||
|
//
|
||||||
|
// The TL;DR is that you make a .env file that looks something like
|
||||||
|
//
|
||||||
|
// SOME_ENV_VAR=somevalue
|
||||||
|
//
|
||||||
|
// and then in your go code you can call
|
||||||
|
//
|
||||||
|
// godotenv.Load()
|
||||||
|
//
|
||||||
|
// and all the env vars declared in .env will be available through os.Getenv("SOME_ENV_VAR")
|
||||||
|
package godotenv
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"regexp"
|
||||||
|
"sort"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
const doubleQuoteSpecialChars = "\\\n\r\"!$`"
|
||||||
|
|
||||||
|
// Load will read your env file(s) and load them into ENV for this process.
|
||||||
|
//
|
||||||
|
// Call this function as close as possible to the start of your program (ideally in main)
|
||||||
|
//
|
||||||
|
// If you call Load without any args it will default to loading .env in the current path
|
||||||
|
//
|
||||||
|
// You can otherwise tell it which files to load (there can be more than one) like
|
||||||
|
//
|
||||||
|
// godotenv.Load("fileone", "filetwo")
|
||||||
|
//
|
||||||
|
// It's important to note that it WILL NOT OVERRIDE an env variable that already exists - consider the .env file to set dev vars or sensible defaults
|
||||||
|
func Load(filenames ...string) (err error) {
|
||||||
|
filenames = filenamesOrDefault(filenames)
|
||||||
|
|
||||||
|
for _, filename := range filenames {
|
||||||
|
err = loadFile(filename, false)
|
||||||
|
if err != nil {
|
||||||
|
return // return early on a spazout
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Overload will read your env file(s) and load them into ENV for this process.
|
||||||
|
//
|
||||||
|
// Call this function as close as possible to the start of your program (ideally in main)
|
||||||
|
//
|
||||||
|
// If you call Overload without any args it will default to loading .env in the current path
|
||||||
|
//
|
||||||
|
// You can otherwise tell it which files to load (there can be more than one) like
|
||||||
|
//
|
||||||
|
// godotenv.Overload("fileone", "filetwo")
|
||||||
|
//
|
||||||
|
// It's important to note this WILL OVERRIDE an env variable that already exists - consider the .env file to forcefilly set all vars.
|
||||||
|
func Overload(filenames ...string) (err error) {
|
||||||
|
filenames = filenamesOrDefault(filenames)
|
||||||
|
|
||||||
|
for _, filename := range filenames {
|
||||||
|
err = loadFile(filename, true)
|
||||||
|
if err != nil {
|
||||||
|
return // return early on a spazout
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read all env (with same file loading semantics as Load) but return values as
|
||||||
|
// a map rather than automatically writing values into env
|
||||||
|
func Read(filenames ...string) (envMap map[string]string, err error) {
|
||||||
|
filenames = filenamesOrDefault(filenames)
|
||||||
|
envMap = make(map[string]string)
|
||||||
|
|
||||||
|
for _, filename := range filenames {
|
||||||
|
individualEnvMap, individualErr := readFile(filename)
|
||||||
|
|
||||||
|
if individualErr != nil {
|
||||||
|
err = individualErr
|
||||||
|
return // return early on a spazout
|
||||||
|
}
|
||||||
|
|
||||||
|
for key, value := range individualEnvMap {
|
||||||
|
envMap[key] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse reads an env file from io.Reader, returning a map of keys and values.
|
||||||
|
func Parse(r io.Reader) (envMap map[string]string, err error) {
|
||||||
|
envMap = make(map[string]string)
|
||||||
|
|
||||||
|
var lines []string
|
||||||
|
scanner := bufio.NewScanner(r)
|
||||||
|
for scanner.Scan() {
|
||||||
|
lines = append(lines, scanner.Text())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = scanner.Err(); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, fullLine := range lines {
|
||||||
|
if !isIgnoredLine(fullLine) {
|
||||||
|
var key, value string
|
||||||
|
key, value, err = parseLine(fullLine, envMap)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
envMap[key] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//Unmarshal reads an env file from a string, returning a map of keys and values.
|
||||||
|
func Unmarshal(str string) (envMap map[string]string, err error) {
|
||||||
|
return Parse(strings.NewReader(str))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exec loads env vars from the specified filenames (empty map falls back to default)
|
||||||
|
// then executes the cmd specified.
|
||||||
|
//
|
||||||
|
// Simply hooks up os.Stdin/err/out to the command and calls Run()
|
||||||
|
//
|
||||||
|
// If you want more fine grained control over your command it's recommended
|
||||||
|
// that you use `Load()` or `Read()` and the `os/exec` package yourself.
|
||||||
|
func Exec(filenames []string, cmd string, cmdArgs []string) error {
|
||||||
|
Load(filenames...)
|
||||||
|
|
||||||
|
command := exec.Command(cmd, cmdArgs...)
|
||||||
|
command.Stdin = os.Stdin
|
||||||
|
command.Stdout = os.Stdout
|
||||||
|
command.Stderr = os.Stderr
|
||||||
|
return command.Run()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write serializes the given environment and writes it to a file
|
||||||
|
func Write(envMap map[string]string, filename string) error {
|
||||||
|
content, error := Marshal(envMap)
|
||||||
|
if error != nil {
|
||||||
|
return error
|
||||||
|
}
|
||||||
|
file, error := os.Create(filename)
|
||||||
|
if error != nil {
|
||||||
|
return error
|
||||||
|
}
|
||||||
|
_, err := file.WriteString(content)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Marshal outputs the given environment as a dotenv-formatted environment file.
|
||||||
|
// Each line is in the format: KEY="VALUE" where VALUE is backslash-escaped.
|
||||||
|
func Marshal(envMap map[string]string) (string, error) {
|
||||||
|
lines := make([]string, 0, len(envMap))
|
||||||
|
for k, v := range envMap {
|
||||||
|
lines = append(lines, fmt.Sprintf(`%s="%s"`, k, doubleQuoteEscape(v)))
|
||||||
|
}
|
||||||
|
sort.Strings(lines)
|
||||||
|
return strings.Join(lines, "\n"), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func filenamesOrDefault(filenames []string) []string {
|
||||||
|
if len(filenames) == 0 {
|
||||||
|
return []string{".env"}
|
||||||
|
}
|
||||||
|
return filenames
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadFile(filename string, overload bool) error {
|
||||||
|
envMap, err := readFile(filename)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
currentEnv := map[string]bool{}
|
||||||
|
rawEnv := os.Environ()
|
||||||
|
for _, rawEnvLine := range rawEnv {
|
||||||
|
key := strings.Split(rawEnvLine, "=")[0]
|
||||||
|
currentEnv[key] = true
|
||||||
|
}
|
||||||
|
|
||||||
|
for key, value := range envMap {
|
||||||
|
if !currentEnv[key] || overload {
|
||||||
|
os.Setenv(key, value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func readFile(filename string) (envMap map[string]string, err error) {
|
||||||
|
file, err := os.Open(filename)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
return Parse(file)
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseLine(line string, envMap map[string]string) (key string, value string, err error) {
|
||||||
|
if len(line) == 0 {
|
||||||
|
err = errors.New("zero length string")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// ditch the comments (but keep quoted hashes)
|
||||||
|
if strings.Contains(line, "#") {
|
||||||
|
segmentsBetweenHashes := strings.Split(line, "#")
|
||||||
|
quotesAreOpen := false
|
||||||
|
var segmentsToKeep []string
|
||||||
|
for _, segment := range segmentsBetweenHashes {
|
||||||
|
if strings.Count(segment, "\"") == 1 || strings.Count(segment, "'") == 1 {
|
||||||
|
if quotesAreOpen {
|
||||||
|
quotesAreOpen = false
|
||||||
|
segmentsToKeep = append(segmentsToKeep, segment)
|
||||||
|
} else {
|
||||||
|
quotesAreOpen = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(segmentsToKeep) == 0 || quotesAreOpen {
|
||||||
|
segmentsToKeep = append(segmentsToKeep, segment)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
line = strings.Join(segmentsToKeep, "#")
|
||||||
|
}
|
||||||
|
|
||||||
|
firstEquals := strings.Index(line, "=")
|
||||||
|
firstColon := strings.Index(line, ":")
|
||||||
|
splitString := strings.SplitN(line, "=", 2)
|
||||||
|
if firstColon != -1 && (firstColon < firstEquals || firstEquals == -1) {
|
||||||
|
//this is a yaml-style line
|
||||||
|
splitString = strings.SplitN(line, ":", 2)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(splitString) != 2 {
|
||||||
|
err = errors.New("Can't separate key from value")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse the key
|
||||||
|
key = splitString[0]
|
||||||
|
if strings.HasPrefix(key, "export") {
|
||||||
|
key = strings.TrimPrefix(key, "export")
|
||||||
|
}
|
||||||
|
key = strings.Trim(key, " ")
|
||||||
|
|
||||||
|
// Parse the value
|
||||||
|
value = parseValue(splitString[1], envMap)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseValue(value string, envMap map[string]string) string {
|
||||||
|
|
||||||
|
// trim
|
||||||
|
value = strings.Trim(value, " ")
|
||||||
|
|
||||||
|
// check if we've got quoted values or possible escapes
|
||||||
|
if len(value) > 1 {
|
||||||
|
rs := regexp.MustCompile(`\A'(.*)'\z`)
|
||||||
|
singleQuotes := rs.FindStringSubmatch(value)
|
||||||
|
|
||||||
|
rd := regexp.MustCompile(`\A"(.*)"\z`)
|
||||||
|
doubleQuotes := rd.FindStringSubmatch(value)
|
||||||
|
|
||||||
|
if singleQuotes != nil || doubleQuotes != nil {
|
||||||
|
// pull the quotes off the edges
|
||||||
|
value = value[1 : len(value)-1]
|
||||||
|
}
|
||||||
|
|
||||||
|
if doubleQuotes != nil {
|
||||||
|
// expand newlines
|
||||||
|
escapeRegex := regexp.MustCompile(`\\.`)
|
||||||
|
value = escapeRegex.ReplaceAllStringFunc(value, func(match string) string {
|
||||||
|
c := strings.TrimPrefix(match, `\`)
|
||||||
|
switch c {
|
||||||
|
case "n":
|
||||||
|
return "\n"
|
||||||
|
case "r":
|
||||||
|
return "\r"
|
||||||
|
default:
|
||||||
|
return match
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// unescape characters
|
||||||
|
e := regexp.MustCompile(`\\([^$])`)
|
||||||
|
value = e.ReplaceAllString(value, "$1")
|
||||||
|
}
|
||||||
|
|
||||||
|
if singleQuotes == nil {
|
||||||
|
value = expandVariables(value, envMap)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
|
func expandVariables(v string, m map[string]string) string {
|
||||||
|
r := regexp.MustCompile(`(\\)?(\$)(\()?\{?([A-Z0-9_]+)?\}?`)
|
||||||
|
|
||||||
|
return r.ReplaceAllStringFunc(v, func(s string) string {
|
||||||
|
submatch := r.FindStringSubmatch(s)
|
||||||
|
|
||||||
|
if submatch == nil {
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
if submatch[1] == "\\" || submatch[2] == "(" {
|
||||||
|
return submatch[0][1:]
|
||||||
|
} else if submatch[4] != "" {
|
||||||
|
return m[submatch[4]]
|
||||||
|
}
|
||||||
|
return s
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func isIgnoredLine(line string) bool {
|
||||||
|
trimmedLine := strings.Trim(line, " \n\t")
|
||||||
|
return len(trimmedLine) == 0 || strings.HasPrefix(trimmedLine, "#")
|
||||||
|
}
|
||||||
|
|
||||||
|
func doubleQuoteEscape(line string) string {
|
||||||
|
for _, c := range doubleQuoteSpecialChars {
|
||||||
|
toReplace := "\\" + string(c)
|
||||||
|
if c == '\n' {
|
||||||
|
toReplace = `\n`
|
||||||
|
}
|
||||||
|
if c == '\r' {
|
||||||
|
toReplace = `\r`
|
||||||
|
}
|
||||||
|
line = strings.Replace(line, string(c), toReplace, -1)
|
||||||
|
}
|
||||||
|
return line
|
||||||
|
}
|
27
vendor/github.com/rogpeppe/go-internal/LICENSE
generated
vendored
Normal file
27
vendor/github.com/rogpeppe/go-internal/LICENSE
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
Copyright (c) 2018 The Go Authors. All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the following disclaimer
|
||||||
|
in the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
* Neither the name of Google Inc. nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
47
vendor/github.com/rogpeppe/go-internal/modfile/gopkgin.go
generated
vendored
Normal file
47
vendor/github.com/rogpeppe/go-internal/modfile/gopkgin.go
generated
vendored
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
// Copyright 2018 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// TODO: Figure out what gopkg.in should do.
|
||||||
|
|
||||||
|
package modfile
|
||||||
|
|
||||||
|
import "strings"
|
||||||
|
|
||||||
|
// ParseGopkgIn splits gopkg.in import paths into their constituent parts
|
||||||
|
func ParseGopkgIn(path string) (root, repo, major, subdir string, ok bool) {
|
||||||
|
if !strings.HasPrefix(path, "gopkg.in/") {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
f := strings.Split(path, "/")
|
||||||
|
if len(f) >= 2 {
|
||||||
|
if elem, v, ok := dotV(f[1]); ok {
|
||||||
|
root = strings.Join(f[:2], "/")
|
||||||
|
repo = "github.com/go-" + elem + "/" + elem
|
||||||
|
major = v
|
||||||
|
subdir = strings.Join(f[2:], "/")
|
||||||
|
return root, repo, major, subdir, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(f) >= 3 {
|
||||||
|
if elem, v, ok := dotV(f[2]); ok {
|
||||||
|
root = strings.Join(f[:3], "/")
|
||||||
|
repo = "github.com/" + f[1] + "/" + elem
|
||||||
|
major = v
|
||||||
|
subdir = strings.Join(f[3:], "/")
|
||||||
|
return root, repo, major, subdir, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func dotV(name string) (elem, v string, ok bool) {
|
||||||
|
i := len(name) - 1
|
||||||
|
for i >= 0 && '0' <= name[i] && name[i] <= '9' {
|
||||||
|
i--
|
||||||
|
}
|
||||||
|
if i <= 2 || i+1 >= len(name) || name[i-1] != '.' || name[i] != 'v' || name[i+1] == '0' && len(name) != i+2 {
|
||||||
|
return "", "", false
|
||||||
|
}
|
||||||
|
return name[:i-1], name[i:], true
|
||||||
|
}
|
164
vendor/github.com/rogpeppe/go-internal/modfile/print.go
generated
vendored
Normal file
164
vendor/github.com/rogpeppe/go-internal/modfile/print.go
generated
vendored
Normal file
@ -0,0 +1,164 @@
|
|||||||
|
// Copyright 2018 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Package modfile implements parsing and formatting for
|
||||||
|
// go.mod files.
|
||||||
|
package modfile
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Format(f *FileSyntax) []byte {
|
||||||
|
pr := &printer{}
|
||||||
|
pr.file(f)
|
||||||
|
return pr.Bytes()
|
||||||
|
}
|
||||||
|
|
||||||
|
// A printer collects the state during printing of a file or expression.
|
||||||
|
type printer struct {
|
||||||
|
bytes.Buffer // output buffer
|
||||||
|
comment []Comment // pending end-of-line comments
|
||||||
|
margin int // left margin (indent), a number of tabs
|
||||||
|
}
|
||||||
|
|
||||||
|
// printf prints to the buffer.
|
||||||
|
func (p *printer) printf(format string, args ...interface{}) {
|
||||||
|
fmt.Fprintf(p, format, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// indent returns the position on the current line, in bytes, 0-indexed.
|
||||||
|
func (p *printer) indent() int {
|
||||||
|
b := p.Bytes()
|
||||||
|
n := 0
|
||||||
|
for n < len(b) && b[len(b)-1-n] != '\n' {
|
||||||
|
n++
|
||||||
|
}
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
// newline ends the current line, flushing end-of-line comments.
|
||||||
|
func (p *printer) newline() {
|
||||||
|
if len(p.comment) > 0 {
|
||||||
|
p.printf(" ")
|
||||||
|
for i, com := range p.comment {
|
||||||
|
if i > 0 {
|
||||||
|
p.trim()
|
||||||
|
p.printf("\n")
|
||||||
|
for i := 0; i < p.margin; i++ {
|
||||||
|
p.printf("\t")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p.printf("%s", strings.TrimSpace(com.Token))
|
||||||
|
}
|
||||||
|
p.comment = p.comment[:0]
|
||||||
|
}
|
||||||
|
|
||||||
|
p.trim()
|
||||||
|
p.printf("\n")
|
||||||
|
for i := 0; i < p.margin; i++ {
|
||||||
|
p.printf("\t")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// trim removes trailing spaces and tabs from the current line.
|
||||||
|
func (p *printer) trim() {
|
||||||
|
// Remove trailing spaces and tabs from line we're about to end.
|
||||||
|
b := p.Bytes()
|
||||||
|
n := len(b)
|
||||||
|
for n > 0 && (b[n-1] == '\t' || b[n-1] == ' ') {
|
||||||
|
n--
|
||||||
|
}
|
||||||
|
p.Truncate(n)
|
||||||
|
}
|
||||||
|
|
||||||
|
// file formats the given file into the print buffer.
|
||||||
|
func (p *printer) file(f *FileSyntax) {
|
||||||
|
for _, com := range f.Before {
|
||||||
|
p.printf("%s", strings.TrimSpace(com.Token))
|
||||||
|
p.newline()
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, stmt := range f.Stmt {
|
||||||
|
switch x := stmt.(type) {
|
||||||
|
case *CommentBlock:
|
||||||
|
// comments already handled
|
||||||
|
p.expr(x)
|
||||||
|
|
||||||
|
default:
|
||||||
|
p.expr(x)
|
||||||
|
p.newline()
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, com := range stmt.Comment().After {
|
||||||
|
p.printf("%s", strings.TrimSpace(com.Token))
|
||||||
|
p.newline()
|
||||||
|
}
|
||||||
|
|
||||||
|
if i+1 < len(f.Stmt) {
|
||||||
|
p.newline()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *printer) expr(x Expr) {
|
||||||
|
// Emit line-comments preceding this expression.
|
||||||
|
if before := x.Comment().Before; len(before) > 0 {
|
||||||
|
// Want to print a line comment.
|
||||||
|
// Line comments must be at the current margin.
|
||||||
|
p.trim()
|
||||||
|
if p.indent() > 0 {
|
||||||
|
// There's other text on the line. Start a new line.
|
||||||
|
p.printf("\n")
|
||||||
|
}
|
||||||
|
// Re-indent to margin.
|
||||||
|
for i := 0; i < p.margin; i++ {
|
||||||
|
p.printf("\t")
|
||||||
|
}
|
||||||
|
for _, com := range before {
|
||||||
|
p.printf("%s", strings.TrimSpace(com.Token))
|
||||||
|
p.newline()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch x := x.(type) {
|
||||||
|
default:
|
||||||
|
panic(fmt.Errorf("printer: unexpected type %T", x))
|
||||||
|
|
||||||
|
case *CommentBlock:
|
||||||
|
// done
|
||||||
|
|
||||||
|
case *LParen:
|
||||||
|
p.printf("(")
|
||||||
|
case *RParen:
|
||||||
|
p.printf(")")
|
||||||
|
|
||||||
|
case *Line:
|
||||||
|
sep := ""
|
||||||
|
for _, tok := range x.Token {
|
||||||
|
p.printf("%s%s", sep, tok)
|
||||||
|
sep = " "
|
||||||
|
}
|
||||||
|
|
||||||
|
case *LineBlock:
|
||||||
|
for _, tok := range x.Token {
|
||||||
|
p.printf("%s ", tok)
|
||||||
|
}
|
||||||
|
p.expr(&x.LParen)
|
||||||
|
p.margin++
|
||||||
|
for _, l := range x.Line {
|
||||||
|
p.newline()
|
||||||
|
p.expr(l)
|
||||||
|
}
|
||||||
|
p.margin--
|
||||||
|
p.newline()
|
||||||
|
p.expr(&x.RParen)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Queue end-of-line comments for printing when we
|
||||||
|
// reach the end of the line.
|
||||||
|
p.comment = append(p.comment, x.Comment().Suffix...)
|
||||||
|
}
|
869
vendor/github.com/rogpeppe/go-internal/modfile/read.go
generated
vendored
Normal file
869
vendor/github.com/rogpeppe/go-internal/modfile/read.go
generated
vendored
Normal file
@ -0,0 +1,869 @@
|
|||||||
|
// Copyright 2018 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Module file parser.
|
||||||
|
// This is a simplified copy of Google's buildifier parser.
|
||||||
|
|
||||||
|
package modfile
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"unicode"
|
||||||
|
"unicode/utf8"
|
||||||
|
)
|
||||||
|
|
||||||
|
// A Position describes the position between two bytes of input.
|
||||||
|
type Position struct {
|
||||||
|
Line int // line in input (starting at 1)
|
||||||
|
LineRune int // rune in line (starting at 1)
|
||||||
|
Byte int // byte in input (starting at 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// add returns the position at the end of s, assuming it starts at p.
|
||||||
|
func (p Position) add(s string) Position {
|
||||||
|
p.Byte += len(s)
|
||||||
|
if n := strings.Count(s, "\n"); n > 0 {
|
||||||
|
p.Line += n
|
||||||
|
s = s[strings.LastIndex(s, "\n")+1:]
|
||||||
|
p.LineRune = 1
|
||||||
|
}
|
||||||
|
p.LineRune += utf8.RuneCountInString(s)
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
// An Expr represents an input element.
|
||||||
|
type Expr interface {
|
||||||
|
// Span returns the start and end position of the expression,
|
||||||
|
// excluding leading or trailing comments.
|
||||||
|
Span() (start, end Position)
|
||||||
|
|
||||||
|
// Comment returns the comments attached to the expression.
|
||||||
|
// This method would normally be named 'Comments' but that
|
||||||
|
// would interfere with embedding a type of the same name.
|
||||||
|
Comment() *Comments
|
||||||
|
}
|
||||||
|
|
||||||
|
// A Comment represents a single // comment.
|
||||||
|
type Comment struct {
|
||||||
|
Start Position
|
||||||
|
Token string // without trailing newline
|
||||||
|
Suffix bool // an end of line (not whole line) comment
|
||||||
|
}
|
||||||
|
|
||||||
|
// Comments collects the comments associated with an expression.
|
||||||
|
type Comments struct {
|
||||||
|
Before []Comment // whole-line comments before this expression
|
||||||
|
Suffix []Comment // end-of-line comments after this expression
|
||||||
|
|
||||||
|
// For top-level expressions only, After lists whole-line
|
||||||
|
// comments following the expression.
|
||||||
|
After []Comment
|
||||||
|
}
|
||||||
|
|
||||||
|
// Comment returns the receiver. This isn't useful by itself, but
|
||||||
|
// a Comments struct is embedded into all the expression
|
||||||
|
// implementation types, and this gives each of those a Comment
|
||||||
|
// method to satisfy the Expr interface.
|
||||||
|
func (c *Comments) Comment() *Comments {
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// A FileSyntax represents an entire go.mod file.
|
||||||
|
type FileSyntax struct {
|
||||||
|
Name string // file path
|
||||||
|
Comments
|
||||||
|
Stmt []Expr
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *FileSyntax) Span() (start, end Position) {
|
||||||
|
if len(x.Stmt) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
start, _ = x.Stmt[0].Span()
|
||||||
|
_, end = x.Stmt[len(x.Stmt)-1].Span()
|
||||||
|
return start, end
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *FileSyntax) addLine(hint Expr, tokens ...string) *Line {
|
||||||
|
if hint == nil {
|
||||||
|
// If no hint given, add to the last statement of the given type.
|
||||||
|
Loop:
|
||||||
|
for i := len(x.Stmt) - 1; i >= 0; i-- {
|
||||||
|
stmt := x.Stmt[i]
|
||||||
|
switch stmt := stmt.(type) {
|
||||||
|
case *Line:
|
||||||
|
if stmt.Token != nil && stmt.Token[0] == tokens[0] {
|
||||||
|
hint = stmt
|
||||||
|
break Loop
|
||||||
|
}
|
||||||
|
case *LineBlock:
|
||||||
|
if stmt.Token[0] == tokens[0] {
|
||||||
|
hint = stmt
|
||||||
|
break Loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if hint != nil {
|
||||||
|
for i, stmt := range x.Stmt {
|
||||||
|
switch stmt := stmt.(type) {
|
||||||
|
case *Line:
|
||||||
|
if stmt == hint {
|
||||||
|
// Convert line to line block.
|
||||||
|
stmt.InBlock = true
|
||||||
|
block := &LineBlock{Token: stmt.Token[:1], Line: []*Line{stmt}}
|
||||||
|
stmt.Token = stmt.Token[1:]
|
||||||
|
x.Stmt[i] = block
|
||||||
|
new := &Line{Token: tokens[1:], InBlock: true}
|
||||||
|
block.Line = append(block.Line, new)
|
||||||
|
return new
|
||||||
|
}
|
||||||
|
case *LineBlock:
|
||||||
|
if stmt == hint {
|
||||||
|
new := &Line{Token: tokens[1:], InBlock: true}
|
||||||
|
stmt.Line = append(stmt.Line, new)
|
||||||
|
return new
|
||||||
|
}
|
||||||
|
for j, line := range stmt.Line {
|
||||||
|
if line == hint {
|
||||||
|
// Add new line after hint.
|
||||||
|
stmt.Line = append(stmt.Line, nil)
|
||||||
|
copy(stmt.Line[j+2:], stmt.Line[j+1:])
|
||||||
|
new := &Line{Token: tokens[1:], InBlock: true}
|
||||||
|
stmt.Line[j+1] = new
|
||||||
|
return new
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
new := &Line{Token: tokens}
|
||||||
|
x.Stmt = append(x.Stmt, new)
|
||||||
|
return new
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *FileSyntax) updateLine(line *Line, tokens ...string) {
|
||||||
|
if line.InBlock {
|
||||||
|
tokens = tokens[1:]
|
||||||
|
}
|
||||||
|
line.Token = tokens
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *FileSyntax) removeLine(line *Line) {
|
||||||
|
line.Token = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cleanup cleans up the file syntax x after any edit operations.
|
||||||
|
// To avoid quadratic behavior, removeLine marks the line as dead
|
||||||
|
// by setting line.Token = nil but does not remove it from the slice
|
||||||
|
// in which it appears. After edits have all been indicated,
|
||||||
|
// calling Cleanup cleans out the dead lines.
|
||||||
|
func (x *FileSyntax) Cleanup() {
|
||||||
|
w := 0
|
||||||
|
for _, stmt := range x.Stmt {
|
||||||
|
switch stmt := stmt.(type) {
|
||||||
|
case *Line:
|
||||||
|
if stmt.Token == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
case *LineBlock:
|
||||||
|
ww := 0
|
||||||
|
for _, line := range stmt.Line {
|
||||||
|
if line.Token != nil {
|
||||||
|
stmt.Line[ww] = line
|
||||||
|
ww++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ww == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if ww == 1 {
|
||||||
|
// Collapse block into single line.
|
||||||
|
line := &Line{
|
||||||
|
Comments: Comments{
|
||||||
|
Before: commentsAdd(stmt.Before, stmt.Line[0].Before),
|
||||||
|
Suffix: commentsAdd(stmt.Line[0].Suffix, stmt.Suffix),
|
||||||
|
After: commentsAdd(stmt.Line[0].After, stmt.After),
|
||||||
|
},
|
||||||
|
Token: stringsAdd(stmt.Token, stmt.Line[0].Token),
|
||||||
|
}
|
||||||
|
x.Stmt[w] = line
|
||||||
|
w++
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
stmt.Line = stmt.Line[:ww]
|
||||||
|
}
|
||||||
|
x.Stmt[w] = stmt
|
||||||
|
w++
|
||||||
|
}
|
||||||
|
x.Stmt = x.Stmt[:w]
|
||||||
|
}
|
||||||
|
|
||||||
|
func commentsAdd(x, y []Comment) []Comment {
|
||||||
|
return append(x[:len(x):len(x)], y...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func stringsAdd(x, y []string) []string {
|
||||||
|
return append(x[:len(x):len(x)], y...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// A CommentBlock represents a top-level block of comments separate
|
||||||
|
// from any rule.
|
||||||
|
type CommentBlock struct {
|
||||||
|
Comments
|
||||||
|
Start Position
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *CommentBlock) Span() (start, end Position) {
|
||||||
|
return x.Start, x.Start
|
||||||
|
}
|
||||||
|
|
||||||
|
// A Line is a single line of tokens.
|
||||||
|
type Line struct {
|
||||||
|
Comments
|
||||||
|
Start Position
|
||||||
|
Token []string
|
||||||
|
InBlock bool
|
||||||
|
End Position
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *Line) Span() (start, end Position) {
|
||||||
|
return x.Start, x.End
|
||||||
|
}
|
||||||
|
|
||||||
|
// A LineBlock is a factored block of lines, like
|
||||||
|
//
|
||||||
|
// require (
|
||||||
|
// "x"
|
||||||
|
// "y"
|
||||||
|
// )
|
||||||
|
//
|
||||||
|
type LineBlock struct {
|
||||||
|
Comments
|
||||||
|
Start Position
|
||||||
|
LParen LParen
|
||||||
|
Token []string
|
||||||
|
Line []*Line
|
||||||
|
RParen RParen
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *LineBlock) Span() (start, end Position) {
|
||||||
|
return x.Start, x.RParen.Pos.add(")")
|
||||||
|
}
|
||||||
|
|
||||||
|
// An LParen represents the beginning of a parenthesized line block.
|
||||||
|
// It is a place to store suffix comments.
|
||||||
|
type LParen struct {
|
||||||
|
Comments
|
||||||
|
Pos Position
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *LParen) Span() (start, end Position) {
|
||||||
|
return x.Pos, x.Pos.add(")")
|
||||||
|
}
|
||||||
|
|
||||||
|
// An RParen represents the end of a parenthesized line block.
|
||||||
|
// It is a place to store whole-line (before) comments.
|
||||||
|
type RParen struct {
|
||||||
|
Comments
|
||||||
|
Pos Position
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *RParen) Span() (start, end Position) {
|
||||||
|
return x.Pos, x.Pos.add(")")
|
||||||
|
}
|
||||||
|
|
||||||
|
// An input represents a single input file being parsed.
|
||||||
|
type input struct {
|
||||||
|
// Lexing state.
|
||||||
|
filename string // name of input file, for errors
|
||||||
|
complete []byte // entire input
|
||||||
|
remaining []byte // remaining input
|
||||||
|
token []byte // token being scanned
|
||||||
|
lastToken string // most recently returned token, for error messages
|
||||||
|
pos Position // current input position
|
||||||
|
comments []Comment // accumulated comments
|
||||||
|
endRule int // position of end of current rule
|
||||||
|
|
||||||
|
// Parser state.
|
||||||
|
file *FileSyntax // returned top-level syntax tree
|
||||||
|
parseError error // error encountered during parsing
|
||||||
|
|
||||||
|
// Comment assignment state.
|
||||||
|
pre []Expr // all expressions, in preorder traversal
|
||||||
|
post []Expr // all expressions, in postorder traversal
|
||||||
|
}
|
||||||
|
|
||||||
|
func newInput(filename string, data []byte) *input {
|
||||||
|
return &input{
|
||||||
|
filename: filename,
|
||||||
|
complete: data,
|
||||||
|
remaining: data,
|
||||||
|
pos: Position{Line: 1, LineRune: 1, Byte: 0},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// parse parses the input file.
|
||||||
|
func parse(file string, data []byte) (f *FileSyntax, err error) {
|
||||||
|
in := newInput(file, data)
|
||||||
|
// The parser panics for both routine errors like syntax errors
|
||||||
|
// and for programmer bugs like array index errors.
|
||||||
|
// Turn both into error returns. Catching bug panics is
|
||||||
|
// especially important when processing many files.
|
||||||
|
defer func() {
|
||||||
|
if e := recover(); e != nil {
|
||||||
|
if e == in.parseError {
|
||||||
|
err = in.parseError
|
||||||
|
} else {
|
||||||
|
err = fmt.Errorf("%s:%d:%d: internal error: %v", in.filename, in.pos.Line, in.pos.LineRune, e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
// Invoke the parser.
|
||||||
|
in.parseFile()
|
||||||
|
if in.parseError != nil {
|
||||||
|
return nil, in.parseError
|
||||||
|
}
|
||||||
|
in.file.Name = in.filename
|
||||||
|
|
||||||
|
// Assign comments to nearby syntax.
|
||||||
|
in.assignComments()
|
||||||
|
|
||||||
|
return in.file, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error is called to report an error.
|
||||||
|
// The reason s is often "syntax error".
|
||||||
|
// Error does not return: it panics.
|
||||||
|
func (in *input) Error(s string) {
|
||||||
|
if s == "syntax error" && in.lastToken != "" {
|
||||||
|
s += " near " + in.lastToken
|
||||||
|
}
|
||||||
|
in.parseError = fmt.Errorf("%s:%d:%d: %v", in.filename, in.pos.Line, in.pos.LineRune, s)
|
||||||
|
panic(in.parseError)
|
||||||
|
}
|
||||||
|
|
||||||
|
// eof reports whether the input has reached end of file.
|
||||||
|
func (in *input) eof() bool {
|
||||||
|
return len(in.remaining) == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// peekRune returns the next rune in the input without consuming it.
|
||||||
|
func (in *input) peekRune() int {
|
||||||
|
if len(in.remaining) == 0 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
r, _ := utf8.DecodeRune(in.remaining)
|
||||||
|
return int(r)
|
||||||
|
}
|
||||||
|
|
||||||
|
// peekPrefix reports whether the remaining input begins with the given prefix.
|
||||||
|
func (in *input) peekPrefix(prefix string) bool {
|
||||||
|
// This is like bytes.HasPrefix(in.remaining, []byte(prefix))
|
||||||
|
// but without the allocation of the []byte copy of prefix.
|
||||||
|
for i := 0; i < len(prefix); i++ {
|
||||||
|
if i >= len(in.remaining) || in.remaining[i] != prefix[i] {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// readRune consumes and returns the next rune in the input.
|
||||||
|
func (in *input) readRune() int {
|
||||||
|
if len(in.remaining) == 0 {
|
||||||
|
in.Error("internal lexer error: readRune at EOF")
|
||||||
|
}
|
||||||
|
r, size := utf8.DecodeRune(in.remaining)
|
||||||
|
in.remaining = in.remaining[size:]
|
||||||
|
if r == '\n' {
|
||||||
|
in.pos.Line++
|
||||||
|
in.pos.LineRune = 1
|
||||||
|
} else {
|
||||||
|
in.pos.LineRune++
|
||||||
|
}
|
||||||
|
in.pos.Byte += size
|
||||||
|
return int(r)
|
||||||
|
}
|
||||||
|
|
||||||
|
type symType struct {
|
||||||
|
pos Position
|
||||||
|
endPos Position
|
||||||
|
text string
|
||||||
|
}
|
||||||
|
|
||||||
|
// startToken marks the beginning of the next input token.
|
||||||
|
// It must be followed by a call to endToken, once the token has
|
||||||
|
// been consumed using readRune.
|
||||||
|
func (in *input) startToken(sym *symType) {
|
||||||
|
in.token = in.remaining
|
||||||
|
sym.text = ""
|
||||||
|
sym.pos = in.pos
|
||||||
|
}
|
||||||
|
|
||||||
|
// endToken marks the end of an input token.
|
||||||
|
// It records the actual token string in sym.text if the caller
|
||||||
|
// has not done that already.
|
||||||
|
func (in *input) endToken(sym *symType) {
|
||||||
|
if sym.text == "" {
|
||||||
|
tok := string(in.token[:len(in.token)-len(in.remaining)])
|
||||||
|
sym.text = tok
|
||||||
|
in.lastToken = sym.text
|
||||||
|
}
|
||||||
|
sym.endPos = in.pos
|
||||||
|
}
|
||||||
|
|
||||||
|
// lex is called from the parser to obtain the next input token.
|
||||||
|
// It returns the token value (either a rune like '+' or a symbolic token _FOR)
|
||||||
|
// and sets val to the data associated with the token.
|
||||||
|
// For all our input tokens, the associated data is
|
||||||
|
// val.Pos (the position where the token begins)
|
||||||
|
// and val.Token (the input string corresponding to the token).
|
||||||
|
func (in *input) lex(sym *symType) int {
|
||||||
|
// Skip past spaces, stopping at non-space or EOF.
|
||||||
|
countNL := 0 // number of newlines we've skipped past
|
||||||
|
for !in.eof() {
|
||||||
|
// Skip over spaces. Count newlines so we can give the parser
|
||||||
|
// information about where top-level blank lines are,
|
||||||
|
// for top-level comment assignment.
|
||||||
|
c := in.peekRune()
|
||||||
|
if c == ' ' || c == '\t' || c == '\r' {
|
||||||
|
in.readRune()
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Comment runs to end of line.
|
||||||
|
if in.peekPrefix("//") {
|
||||||
|
in.startToken(sym)
|
||||||
|
|
||||||
|
// Is this comment the only thing on its line?
|
||||||
|
// Find the last \n before this // and see if it's all
|
||||||
|
// spaces from there to here.
|
||||||
|
i := bytes.LastIndex(in.complete[:in.pos.Byte], []byte("\n"))
|
||||||
|
suffix := len(bytes.TrimSpace(in.complete[i+1:in.pos.Byte])) > 0
|
||||||
|
in.readRune()
|
||||||
|
in.readRune()
|
||||||
|
|
||||||
|
// Consume comment.
|
||||||
|
for len(in.remaining) > 0 && in.readRune() != '\n' {
|
||||||
|
}
|
||||||
|
in.endToken(sym)
|
||||||
|
|
||||||
|
sym.text = strings.TrimRight(sym.text, "\n")
|
||||||
|
in.lastToken = "comment"
|
||||||
|
|
||||||
|
// If we are at top level (not in a statement), hand the comment to
|
||||||
|
// the parser as a _COMMENT token. The grammar is written
|
||||||
|
// to handle top-level comments itself.
|
||||||
|
if !suffix {
|
||||||
|
// Not in a statement. Tell parser about top-level comment.
|
||||||
|
return _COMMENT
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, save comment for later attachment to syntax tree.
|
||||||
|
if countNL > 1 {
|
||||||
|
in.comments = append(in.comments, Comment{sym.pos, "", false})
|
||||||
|
}
|
||||||
|
in.comments = append(in.comments, Comment{sym.pos, sym.text, suffix})
|
||||||
|
countNL = 1
|
||||||
|
return _EOL
|
||||||
|
}
|
||||||
|
|
||||||
|
if in.peekPrefix("/*") {
|
||||||
|
in.Error(fmt.Sprintf("mod files must use // comments (not /* */ comments)"))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Found non-space non-comment.
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
// Found the beginning of the next token.
|
||||||
|
in.startToken(sym)
|
||||||
|
defer in.endToken(sym)
|
||||||
|
|
||||||
|
// End of file.
|
||||||
|
if in.eof() {
|
||||||
|
in.lastToken = "EOF"
|
||||||
|
return _EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
// Punctuation tokens.
|
||||||
|
switch c := in.peekRune(); c {
|
||||||
|
case '\n':
|
||||||
|
in.readRune()
|
||||||
|
return c
|
||||||
|
|
||||||
|
case '(':
|
||||||
|
in.readRune()
|
||||||
|
return c
|
||||||
|
|
||||||
|
case ')':
|
||||||
|
in.readRune()
|
||||||
|
return c
|
||||||
|
|
||||||
|
case '"', '`': // quoted string
|
||||||
|
quote := c
|
||||||
|
in.readRune()
|
||||||
|
for {
|
||||||
|
if in.eof() {
|
||||||
|
in.pos = sym.pos
|
||||||
|
in.Error("unexpected EOF in string")
|
||||||
|
}
|
||||||
|
if in.peekRune() == '\n' {
|
||||||
|
in.Error("unexpected newline in string")
|
||||||
|
}
|
||||||
|
c := in.readRune()
|
||||||
|
if c == quote {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if c == '\\' && quote != '`' {
|
||||||
|
if in.eof() {
|
||||||
|
in.pos = sym.pos
|
||||||
|
in.Error("unexpected EOF in string")
|
||||||
|
}
|
||||||
|
in.readRune()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
in.endToken(sym)
|
||||||
|
return _STRING
|
||||||
|
}
|
||||||
|
|
||||||
|
// Checked all punctuation. Must be identifier token.
|
||||||
|
if c := in.peekRune(); !isIdent(c) {
|
||||||
|
in.Error(fmt.Sprintf("unexpected input character %#q", c))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scan over identifier.
|
||||||
|
for isIdent(in.peekRune()) {
|
||||||
|
if in.peekPrefix("//") {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if in.peekPrefix("/*") {
|
||||||
|
in.Error(fmt.Sprintf("mod files must use // comments (not /* */ comments)"))
|
||||||
|
}
|
||||||
|
in.readRune()
|
||||||
|
}
|
||||||
|
return _IDENT
|
||||||
|
}
|
||||||
|
|
||||||
|
// isIdent reports whether c is an identifier rune.
|
||||||
|
// We treat nearly all runes as identifier runes.
|
||||||
|
func isIdent(c int) bool {
|
||||||
|
return c != 0 && !unicode.IsSpace(rune(c))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Comment assignment.
|
||||||
|
// We build two lists of all subexpressions, preorder and postorder.
|
||||||
|
// The preorder list is ordered by start location, with outer expressions first.
|
||||||
|
// The postorder list is ordered by end location, with outer expressions last.
|
||||||
|
// We use the preorder list to assign each whole-line comment to the syntax
|
||||||
|
// immediately following it, and we use the postorder list to assign each
|
||||||
|
// end-of-line comment to the syntax immediately preceding it.
|
||||||
|
|
||||||
|
// order walks the expression adding it and its subexpressions to the
|
||||||
|
// preorder and postorder lists.
|
||||||
|
func (in *input) order(x Expr) {
|
||||||
|
if x != nil {
|
||||||
|
in.pre = append(in.pre, x)
|
||||||
|
}
|
||||||
|
switch x := x.(type) {
|
||||||
|
default:
|
||||||
|
panic(fmt.Errorf("order: unexpected type %T", x))
|
||||||
|
case nil:
|
||||||
|
// nothing
|
||||||
|
case *LParen, *RParen:
|
||||||
|
// nothing
|
||||||
|
case *CommentBlock:
|
||||||
|
// nothing
|
||||||
|
case *Line:
|
||||||
|
// nothing
|
||||||
|
case *FileSyntax:
|
||||||
|
for _, stmt := range x.Stmt {
|
||||||
|
in.order(stmt)
|
||||||
|
}
|
||||||
|
case *LineBlock:
|
||||||
|
in.order(&x.LParen)
|
||||||
|
for _, l := range x.Line {
|
||||||
|
in.order(l)
|
||||||
|
}
|
||||||
|
in.order(&x.RParen)
|
||||||
|
}
|
||||||
|
if x != nil {
|
||||||
|
in.post = append(in.post, x)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// assignComments attaches comments to nearby syntax.
|
||||||
|
func (in *input) assignComments() {
|
||||||
|
const debug = false
|
||||||
|
|
||||||
|
// Generate preorder and postorder lists.
|
||||||
|
in.order(in.file)
|
||||||
|
|
||||||
|
// Split into whole-line comments and suffix comments.
|
||||||
|
var line, suffix []Comment
|
||||||
|
for _, com := range in.comments {
|
||||||
|
if com.Suffix {
|
||||||
|
suffix = append(suffix, com)
|
||||||
|
} else {
|
||||||
|
line = append(line, com)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if debug {
|
||||||
|
for _, c := range line {
|
||||||
|
fmt.Fprintf(os.Stderr, "LINE %q :%d:%d #%d\n", c.Token, c.Start.Line, c.Start.LineRune, c.Start.Byte)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assign line comments to syntax immediately following.
|
||||||
|
for _, x := range in.pre {
|
||||||
|
start, _ := x.Span()
|
||||||
|
if debug {
|
||||||
|
fmt.Printf("pre %T :%d:%d #%d\n", x, start.Line, start.LineRune, start.Byte)
|
||||||
|
}
|
||||||
|
xcom := x.Comment()
|
||||||
|
for len(line) > 0 && start.Byte >= line[0].Start.Byte {
|
||||||
|
if debug {
|
||||||
|
fmt.Fprintf(os.Stderr, "ASSIGN LINE %q #%d\n", line[0].Token, line[0].Start.Byte)
|
||||||
|
}
|
||||||
|
xcom.Before = append(xcom.Before, line[0])
|
||||||
|
line = line[1:]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remaining line comments go at end of file.
|
||||||
|
in.file.After = append(in.file.After, line...)
|
||||||
|
|
||||||
|
if debug {
|
||||||
|
for _, c := range suffix {
|
||||||
|
fmt.Fprintf(os.Stderr, "SUFFIX %q :%d:%d #%d\n", c.Token, c.Start.Line, c.Start.LineRune, c.Start.Byte)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assign suffix comments to syntax immediately before.
|
||||||
|
for i := len(in.post) - 1; i >= 0; i-- {
|
||||||
|
x := in.post[i]
|
||||||
|
|
||||||
|
start, end := x.Span()
|
||||||
|
if debug {
|
||||||
|
fmt.Printf("post %T :%d:%d #%d :%d:%d #%d\n", x, start.Line, start.LineRune, start.Byte, end.Line, end.LineRune, end.Byte)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do not assign suffix comments to end of line block or whole file.
|
||||||
|
// Instead assign them to the last element inside.
|
||||||
|
switch x.(type) {
|
||||||
|
case *FileSyntax:
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do not assign suffix comments to something that starts
|
||||||
|
// on an earlier line, so that in
|
||||||
|
//
|
||||||
|
// x ( y
|
||||||
|
// z ) // comment
|
||||||
|
//
|
||||||
|
// we assign the comment to z and not to x ( ... ).
|
||||||
|
if start.Line != end.Line {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
xcom := x.Comment()
|
||||||
|
for len(suffix) > 0 && end.Byte <= suffix[len(suffix)-1].Start.Byte {
|
||||||
|
if debug {
|
||||||
|
fmt.Fprintf(os.Stderr, "ASSIGN SUFFIX %q #%d\n", suffix[len(suffix)-1].Token, suffix[len(suffix)-1].Start.Byte)
|
||||||
|
}
|
||||||
|
xcom.Suffix = append(xcom.Suffix, suffix[len(suffix)-1])
|
||||||
|
suffix = suffix[:len(suffix)-1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// We assigned suffix comments in reverse.
|
||||||
|
// If multiple suffix comments were appended to the same
|
||||||
|
// expression node, they are now in reverse. Fix that.
|
||||||
|
for _, x := range in.post {
|
||||||
|
reverseComments(x.Comment().Suffix)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remaining suffix comments go at beginning of file.
|
||||||
|
in.file.Before = append(in.file.Before, suffix...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// reverseComments reverses the []Comment list.
|
||||||
|
func reverseComments(list []Comment) {
|
||||||
|
for i, j := 0, len(list)-1; i < j; i, j = i+1, j-1 {
|
||||||
|
list[i], list[j] = list[j], list[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (in *input) parseFile() {
|
||||||
|
in.file = new(FileSyntax)
|
||||||
|
var sym symType
|
||||||
|
var cb *CommentBlock
|
||||||
|
for {
|
||||||
|
tok := in.lex(&sym)
|
||||||
|
switch tok {
|
||||||
|
case '\n':
|
||||||
|
if cb != nil {
|
||||||
|
in.file.Stmt = append(in.file.Stmt, cb)
|
||||||
|
cb = nil
|
||||||
|
}
|
||||||
|
case _COMMENT:
|
||||||
|
if cb == nil {
|
||||||
|
cb = &CommentBlock{Start: sym.pos}
|
||||||
|
}
|
||||||
|
com := cb.Comment()
|
||||||
|
com.Before = append(com.Before, Comment{Start: sym.pos, Token: sym.text})
|
||||||
|
case _EOF:
|
||||||
|
if cb != nil {
|
||||||
|
in.file.Stmt = append(in.file.Stmt, cb)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
default:
|
||||||
|
in.parseStmt(&sym)
|
||||||
|
if cb != nil {
|
||||||
|
in.file.Stmt[len(in.file.Stmt)-1].Comment().Before = cb.Before
|
||||||
|
cb = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (in *input) parseStmt(sym *symType) {
|
||||||
|
start := sym.pos
|
||||||
|
end := sym.endPos
|
||||||
|
token := []string{sym.text}
|
||||||
|
for {
|
||||||
|
tok := in.lex(sym)
|
||||||
|
switch tok {
|
||||||
|
case '\n', _EOF, _EOL:
|
||||||
|
in.file.Stmt = append(in.file.Stmt, &Line{
|
||||||
|
Start: start,
|
||||||
|
Token: token,
|
||||||
|
End: end,
|
||||||
|
})
|
||||||
|
return
|
||||||
|
case '(':
|
||||||
|
in.file.Stmt = append(in.file.Stmt, in.parseLineBlock(start, token, sym))
|
||||||
|
return
|
||||||
|
default:
|
||||||
|
token = append(token, sym.text)
|
||||||
|
end = sym.endPos
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (in *input) parseLineBlock(start Position, token []string, sym *symType) *LineBlock {
|
||||||
|
x := &LineBlock{
|
||||||
|
Start: start,
|
||||||
|
Token: token,
|
||||||
|
LParen: LParen{Pos: sym.pos},
|
||||||
|
}
|
||||||
|
var comments []Comment
|
||||||
|
for {
|
||||||
|
tok := in.lex(sym)
|
||||||
|
switch tok {
|
||||||
|
case _EOL:
|
||||||
|
// ignore
|
||||||
|
case '\n':
|
||||||
|
if len(comments) == 0 && len(x.Line) > 0 || len(comments) > 0 && comments[len(comments)-1].Token != "" {
|
||||||
|
comments = append(comments, Comment{})
|
||||||
|
}
|
||||||
|
case _COMMENT:
|
||||||
|
comments = append(comments, Comment{Start: sym.pos, Token: sym.text})
|
||||||
|
case _EOF:
|
||||||
|
in.Error(fmt.Sprintf("syntax error (unterminated block started at %s:%d:%d)", in.filename, x.Start.Line, x.Start.LineRune))
|
||||||
|
case ')':
|
||||||
|
x.RParen.Before = comments
|
||||||
|
x.RParen.Pos = sym.pos
|
||||||
|
tok = in.lex(sym)
|
||||||
|
if tok != '\n' && tok != _EOF && tok != _EOL {
|
||||||
|
in.Error("syntax error (expected newline after closing paren)")
|
||||||
|
}
|
||||||
|
return x
|
||||||
|
default:
|
||||||
|
l := in.parseLine(sym)
|
||||||
|
x.Line = append(x.Line, l)
|
||||||
|
l.Comment().Before = comments
|
||||||
|
comments = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (in *input) parseLine(sym *symType) *Line {
|
||||||
|
start := sym.pos
|
||||||
|
end := sym.endPos
|
||||||
|
token := []string{sym.text}
|
||||||
|
for {
|
||||||
|
tok := in.lex(sym)
|
||||||
|
switch tok {
|
||||||
|
case '\n', _EOF, _EOL:
|
||||||
|
return &Line{
|
||||||
|
Start: start,
|
||||||
|
Token: token,
|
||||||
|
End: end,
|
||||||
|
InBlock: true,
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
token = append(token, sym.text)
|
||||||
|
end = sym.endPos
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
_EOF = -(1 + iota)
|
||||||
|
_EOL
|
||||||
|
_IDENT
|
||||||
|
_STRING
|
||||||
|
_COMMENT
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
slashSlash = []byte("//")
|
||||||
|
moduleStr = []byte("module")
|
||||||
|
)
|
||||||
|
|
||||||
|
// ModulePath returns the module path from the gomod file text.
|
||||||
|
// If it cannot find a module path, it returns an empty string.
|
||||||
|
// It is tolerant of unrelated problems in the go.mod file.
|
||||||
|
func ModulePath(mod []byte) string {
|
||||||
|
for len(mod) > 0 {
|
||||||
|
line := mod
|
||||||
|
mod = nil
|
||||||
|
if i := bytes.IndexByte(line, '\n'); i >= 0 {
|
||||||
|
line, mod = line[:i], line[i+1:]
|
||||||
|
}
|
||||||
|
if i := bytes.Index(line, slashSlash); i >= 0 {
|
||||||
|
line = line[:i]
|
||||||
|
}
|
||||||
|
line = bytes.TrimSpace(line)
|
||||||
|
if !bytes.HasPrefix(line, moduleStr) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
line = line[len(moduleStr):]
|
||||||
|
n := len(line)
|
||||||
|
line = bytes.TrimSpace(line)
|
||||||
|
if len(line) == n || len(line) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if line[0] == '"' || line[0] == '`' {
|
||||||
|
p, err := strconv.Unquote(string(line))
|
||||||
|
if err != nil {
|
||||||
|
return "" // malformed quoted string or multiline module path
|
||||||
|
}
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
return string(line)
|
||||||
|
}
|
||||||
|
return "" // missing module path
|
||||||
|
}
|
724
vendor/github.com/rogpeppe/go-internal/modfile/rule.go
generated
vendored
Normal file
724
vendor/github.com/rogpeppe/go-internal/modfile/rule.go
generated
vendored
Normal file
@ -0,0 +1,724 @@
|
|||||||
|
// Copyright 2018 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package modfile
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"path/filepath"
|
||||||
|
"regexp"
|
||||||
|
"sort"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"unicode"
|
||||||
|
|
||||||
|
"github.com/rogpeppe/go-internal/module"
|
||||||
|
"github.com/rogpeppe/go-internal/semver"
|
||||||
|
)
|
||||||
|
|
||||||
|
// A File is the parsed, interpreted form of a go.mod file.
|
||||||
|
type File struct {
|
||||||
|
Module *Module
|
||||||
|
Go *Go
|
||||||
|
Require []*Require
|
||||||
|
Exclude []*Exclude
|
||||||
|
Replace []*Replace
|
||||||
|
|
||||||
|
Syntax *FileSyntax
|
||||||
|
}
|
||||||
|
|
||||||
|
// A Module is the module statement.
|
||||||
|
type Module struct {
|
||||||
|
Mod module.Version
|
||||||
|
Syntax *Line
|
||||||
|
}
|
||||||
|
|
||||||
|
// A Go is the go statement.
|
||||||
|
type Go struct {
|
||||||
|
Version string // "1.23"
|
||||||
|
Syntax *Line
|
||||||
|
}
|
||||||
|
|
||||||
|
// A Require is a single require statement.
|
||||||
|
type Require struct {
|
||||||
|
Mod module.Version
|
||||||
|
Indirect bool // has "// indirect" comment
|
||||||
|
Syntax *Line
|
||||||
|
}
|
||||||
|
|
||||||
|
// An Exclude is a single exclude statement.
|
||||||
|
type Exclude struct {
|
||||||
|
Mod module.Version
|
||||||
|
Syntax *Line
|
||||||
|
}
|
||||||
|
|
||||||
|
// A Replace is a single replace statement.
|
||||||
|
type Replace struct {
|
||||||
|
Old module.Version
|
||||||
|
New module.Version
|
||||||
|
Syntax *Line
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *File) AddModuleStmt(path string) error {
|
||||||
|
if f.Syntax == nil {
|
||||||
|
f.Syntax = new(FileSyntax)
|
||||||
|
}
|
||||||
|
if f.Module == nil {
|
||||||
|
f.Module = &Module{
|
||||||
|
Mod: module.Version{Path: path},
|
||||||
|
Syntax: f.Syntax.addLine(nil, "module", AutoQuote(path)),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
f.Module.Mod.Path = path
|
||||||
|
f.Syntax.updateLine(f.Module.Syntax, "module", AutoQuote(path))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *File) AddComment(text string) {
|
||||||
|
if f.Syntax == nil {
|
||||||
|
f.Syntax = new(FileSyntax)
|
||||||
|
}
|
||||||
|
f.Syntax.Stmt = append(f.Syntax.Stmt, &CommentBlock{
|
||||||
|
Comments: Comments{
|
||||||
|
Before: []Comment{
|
||||||
|
{
|
||||||
|
Token: text,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
type VersionFixer func(path, version string) (string, error)
|
||||||
|
|
||||||
|
// Parse parses the data, reported in errors as being from file,
|
||||||
|
// into a File struct. It applies fix, if non-nil, to canonicalize all module versions found.
|
||||||
|
func Parse(file string, data []byte, fix VersionFixer) (*File, error) {
|
||||||
|
return parseToFile(file, data, fix, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseLax is like Parse but ignores unknown statements.
|
||||||
|
// It is used when parsing go.mod files other than the main module,
|
||||||
|
// under the theory that most statement types we add in the future will
|
||||||
|
// only apply in the main module, like exclude and replace,
|
||||||
|
// and so we get better gradual deployments if old go commands
|
||||||
|
// simply ignore those statements when found in go.mod files
|
||||||
|
// in dependencies.
|
||||||
|
func ParseLax(file string, data []byte, fix VersionFixer) (*File, error) {
|
||||||
|
return parseToFile(file, data, fix, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseToFile(file string, data []byte, fix VersionFixer, strict bool) (*File, error) {
|
||||||
|
fs, err := parse(file, data)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
f := &File{
|
||||||
|
Syntax: fs,
|
||||||
|
}
|
||||||
|
|
||||||
|
var errs bytes.Buffer
|
||||||
|
for _, x := range fs.Stmt {
|
||||||
|
switch x := x.(type) {
|
||||||
|
case *Line:
|
||||||
|
f.add(&errs, x, x.Token[0], x.Token[1:], fix, strict)
|
||||||
|
|
||||||
|
case *LineBlock:
|
||||||
|
if len(x.Token) > 1 {
|
||||||
|
if strict {
|
||||||
|
fmt.Fprintf(&errs, "%s:%d: unknown block type: %s\n", file, x.Start.Line, strings.Join(x.Token, " "))
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
switch x.Token[0] {
|
||||||
|
default:
|
||||||
|
if strict {
|
||||||
|
fmt.Fprintf(&errs, "%s:%d: unknown block type: %s\n", file, x.Start.Line, strings.Join(x.Token, " "))
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
case "module", "require", "exclude", "replace":
|
||||||
|
for _, l := range x.Line {
|
||||||
|
f.add(&errs, l, x.Token[0], l.Token, fix, strict)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if errs.Len() > 0 {
|
||||||
|
return nil, errors.New(strings.TrimRight(errs.String(), "\n"))
|
||||||
|
}
|
||||||
|
return f, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var goVersionRE = regexp.MustCompile(`([1-9][0-9]*)\.(0|[1-9][0-9]*)`)
|
||||||
|
|
||||||
|
func (f *File) add(errs *bytes.Buffer, line *Line, verb string, args []string, fix VersionFixer, strict bool) {
|
||||||
|
// If strict is false, this module is a dependency.
|
||||||
|
// We ignore all unknown directives as well as main-module-only
|
||||||
|
// directives like replace and exclude. It will work better for
|
||||||
|
// forward compatibility if we can depend on modules that have unknown
|
||||||
|
// statements (presumed relevant only when acting as the main module)
|
||||||
|
// and simply ignore those statements.
|
||||||
|
if !strict {
|
||||||
|
switch verb {
|
||||||
|
case "module", "require", "go":
|
||||||
|
// want these even for dependency go.mods
|
||||||
|
default:
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch verb {
|
||||||
|
default:
|
||||||
|
fmt.Fprintf(errs, "%s:%d: unknown directive: %s\n", f.Syntax.Name, line.Start.Line, verb)
|
||||||
|
|
||||||
|
case "go":
|
||||||
|
if f.Go != nil {
|
||||||
|
fmt.Fprintf(errs, "%s:%d: repeated go statement\n", f.Syntax.Name, line.Start.Line)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if len(args) != 1 || !goVersionRE.MatchString(args[0]) {
|
||||||
|
fmt.Fprintf(errs, "%s:%d: usage: go 1.23\n", f.Syntax.Name, line.Start.Line)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
f.Go = &Go{Syntax: line}
|
||||||
|
f.Go.Version = args[0]
|
||||||
|
case "module":
|
||||||
|
if f.Module != nil {
|
||||||
|
fmt.Fprintf(errs, "%s:%d: repeated module statement\n", f.Syntax.Name, line.Start.Line)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
f.Module = &Module{Syntax: line}
|
||||||
|
if len(args) != 1 {
|
||||||
|
|
||||||
|
fmt.Fprintf(errs, "%s:%d: usage: module module/path [version]\n", f.Syntax.Name, line.Start.Line)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
s, err := parseString(&args[0])
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(errs, "%s:%d: invalid quoted string: %v\n", f.Syntax.Name, line.Start.Line, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
f.Module.Mod = module.Version{Path: s}
|
||||||
|
case "require", "exclude":
|
||||||
|
if len(args) != 2 {
|
||||||
|
fmt.Fprintf(errs, "%s:%d: usage: %s module/path v1.2.3\n", f.Syntax.Name, line.Start.Line, verb)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
s, err := parseString(&args[0])
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(errs, "%s:%d: invalid quoted string: %v\n", f.Syntax.Name, line.Start.Line, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
old := args[1]
|
||||||
|
v, err := parseVersion(s, &args[1], fix)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(errs, "%s:%d: invalid module version %q: %v\n", f.Syntax.Name, line.Start.Line, old, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
pathMajor, err := modulePathMajor(s)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(errs, "%s:%d: %v\n", f.Syntax.Name, line.Start.Line, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !module.MatchPathMajor(v, pathMajor) {
|
||||||
|
if pathMajor == "" {
|
||||||
|
pathMajor = "v0 or v1"
|
||||||
|
}
|
||||||
|
fmt.Fprintf(errs, "%s:%d: invalid module: %s should be %s, not %s (%s)\n", f.Syntax.Name, line.Start.Line, s, pathMajor, semver.Major(v), v)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if verb == "require" {
|
||||||
|
f.Require = append(f.Require, &Require{
|
||||||
|
Mod: module.Version{Path: s, Version: v},
|
||||||
|
Syntax: line,
|
||||||
|
Indirect: isIndirect(line),
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
f.Exclude = append(f.Exclude, &Exclude{
|
||||||
|
Mod: module.Version{Path: s, Version: v},
|
||||||
|
Syntax: line,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
case "replace":
|
||||||
|
arrow := 2
|
||||||
|
if len(args) >= 2 && args[1] == "=>" {
|
||||||
|
arrow = 1
|
||||||
|
}
|
||||||
|
if len(args) < arrow+2 || len(args) > arrow+3 || args[arrow] != "=>" {
|
||||||
|
fmt.Fprintf(errs, "%s:%d: usage: %s module/path [v1.2.3] => other/module v1.4\n\t or %s module/path [v1.2.3] => ../local/directory\n", f.Syntax.Name, line.Start.Line, verb, verb)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
s, err := parseString(&args[0])
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(errs, "%s:%d: invalid quoted string: %v\n", f.Syntax.Name, line.Start.Line, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
pathMajor, err := modulePathMajor(s)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(errs, "%s:%d: %v\n", f.Syntax.Name, line.Start.Line, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var v string
|
||||||
|
if arrow == 2 {
|
||||||
|
old := args[1]
|
||||||
|
v, err = parseVersion(s, &args[1], fix)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(errs, "%s:%d: invalid module version %v: %v\n", f.Syntax.Name, line.Start.Line, old, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !module.MatchPathMajor(v, pathMajor) {
|
||||||
|
if pathMajor == "" {
|
||||||
|
pathMajor = "v0 or v1"
|
||||||
|
}
|
||||||
|
fmt.Fprintf(errs, "%s:%d: invalid module: %s should be %s, not %s (%s)\n", f.Syntax.Name, line.Start.Line, s, pathMajor, semver.Major(v), v)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ns, err := parseString(&args[arrow+1])
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(errs, "%s:%d: invalid quoted string: %v\n", f.Syntax.Name, line.Start.Line, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
nv := ""
|
||||||
|
if len(args) == arrow+2 {
|
||||||
|
if !IsDirectoryPath(ns) {
|
||||||
|
fmt.Fprintf(errs, "%s:%d: replacement module without version must be directory path (rooted or starting with ./ or ../)\n", f.Syntax.Name, line.Start.Line)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if filepath.Separator == '/' && strings.Contains(ns, `\`) {
|
||||||
|
fmt.Fprintf(errs, "%s:%d: replacement directory appears to be Windows path (on a non-windows system)\n", f.Syntax.Name, line.Start.Line)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(args) == arrow+3 {
|
||||||
|
old := args[arrow+1]
|
||||||
|
nv, err = parseVersion(ns, &args[arrow+2], fix)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(errs, "%s:%d: invalid module version %v: %v\n", f.Syntax.Name, line.Start.Line, old, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if IsDirectoryPath(ns) {
|
||||||
|
fmt.Fprintf(errs, "%s:%d: replacement module directory path %q cannot have version\n", f.Syntax.Name, line.Start.Line, ns)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f.Replace = append(f.Replace, &Replace{
|
||||||
|
Old: module.Version{Path: s, Version: v},
|
||||||
|
New: module.Version{Path: ns, Version: nv},
|
||||||
|
Syntax: line,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// isIndirect reports whether line has a "// indirect" comment,
|
||||||
|
// meaning it is in go.mod only for its effect on indirect dependencies,
|
||||||
|
// so that it can be dropped entirely once the effective version of the
|
||||||
|
// indirect dependency reaches the given minimum version.
|
||||||
|
func isIndirect(line *Line) bool {
|
||||||
|
if len(line.Suffix) == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
f := strings.Fields(line.Suffix[0].Token)
|
||||||
|
return (len(f) == 2 && f[1] == "indirect" || len(f) > 2 && f[1] == "indirect;") && f[0] == "//"
|
||||||
|
}
|
||||||
|
|
||||||
|
// setIndirect sets line to have (or not have) a "// indirect" comment.
|
||||||
|
func setIndirect(line *Line, indirect bool) {
|
||||||
|
if isIndirect(line) == indirect {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if indirect {
|
||||||
|
// Adding comment.
|
||||||
|
if len(line.Suffix) == 0 {
|
||||||
|
// New comment.
|
||||||
|
line.Suffix = []Comment{{Token: "// indirect", Suffix: true}}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// Insert at beginning of existing comment.
|
||||||
|
com := &line.Suffix[0]
|
||||||
|
space := " "
|
||||||
|
if len(com.Token) > 2 && com.Token[2] == ' ' || com.Token[2] == '\t' {
|
||||||
|
space = ""
|
||||||
|
}
|
||||||
|
com.Token = "// indirect;" + space + com.Token[2:]
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Removing comment.
|
||||||
|
f := strings.Fields(line.Suffix[0].Token)
|
||||||
|
if len(f) == 2 {
|
||||||
|
// Remove whole comment.
|
||||||
|
line.Suffix = nil
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove comment prefix.
|
||||||
|
com := &line.Suffix[0]
|
||||||
|
i := strings.Index(com.Token, "indirect;")
|
||||||
|
com.Token = "//" + com.Token[i+len("indirect;"):]
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsDirectoryPath reports whether the given path should be interpreted
|
||||||
|
// as a directory path. Just like on the go command line, relative paths
|
||||||
|
// and rooted paths are directory paths; the rest are module paths.
|
||||||
|
func IsDirectoryPath(ns string) bool {
|
||||||
|
// Because go.mod files can move from one system to another,
|
||||||
|
// we check all known path syntaxes, both Unix and Windows.
|
||||||
|
return strings.HasPrefix(ns, "./") || strings.HasPrefix(ns, "../") || strings.HasPrefix(ns, "/") ||
|
||||||
|
strings.HasPrefix(ns, `.\`) || strings.HasPrefix(ns, `..\`) || strings.HasPrefix(ns, `\`) ||
|
||||||
|
len(ns) >= 2 && ('A' <= ns[0] && ns[0] <= 'Z' || 'a' <= ns[0] && ns[0] <= 'z') && ns[1] == ':'
|
||||||
|
}
|
||||||
|
|
||||||
|
// MustQuote reports whether s must be quoted in order to appear as
|
||||||
|
// a single token in a go.mod line.
|
||||||
|
func MustQuote(s string) bool {
|
||||||
|
for _, r := range s {
|
||||||
|
if !unicode.IsPrint(r) || r == ' ' || r == '"' || r == '\'' || r == '`' {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return s == "" || strings.Contains(s, "//") || strings.Contains(s, "/*")
|
||||||
|
}
|
||||||
|
|
||||||
|
// AutoQuote returns s or, if quoting is required for s to appear in a go.mod,
|
||||||
|
// the quotation of s.
|
||||||
|
func AutoQuote(s string) string {
|
||||||
|
if MustQuote(s) {
|
||||||
|
return strconv.Quote(s)
|
||||||
|
}
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseString(s *string) (string, error) {
|
||||||
|
t := *s
|
||||||
|
if strings.HasPrefix(t, `"`) {
|
||||||
|
var err error
|
||||||
|
if t, err = strconv.Unquote(t); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
} else if strings.ContainsAny(t, "\"'`") {
|
||||||
|
// Other quotes are reserved both for possible future expansion
|
||||||
|
// and to avoid confusion. For example if someone types 'x'
|
||||||
|
// we want that to be a syntax error and not a literal x in literal quotation marks.
|
||||||
|
return "", fmt.Errorf("unquoted string cannot contain quote")
|
||||||
|
}
|
||||||
|
*s = AutoQuote(t)
|
||||||
|
return t, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseVersion(path string, s *string, fix VersionFixer) (string, error) {
|
||||||
|
t, err := parseString(s)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if fix != nil {
|
||||||
|
var err error
|
||||||
|
t, err = fix(path, t)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if v := module.CanonicalVersion(t); v != "" {
|
||||||
|
*s = v
|
||||||
|
return *s, nil
|
||||||
|
}
|
||||||
|
return "", fmt.Errorf("version must be of the form v1.2.3")
|
||||||
|
}
|
||||||
|
|
||||||
|
func modulePathMajor(path string) (string, error) {
|
||||||
|
_, major, ok := module.SplitPathVersion(path)
|
||||||
|
if !ok {
|
||||||
|
return "", fmt.Errorf("invalid module path")
|
||||||
|
}
|
||||||
|
return major, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *File) Format() ([]byte, error) {
|
||||||
|
return Format(f.Syntax), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cleanup cleans up the file f after any edit operations.
|
||||||
|
// To avoid quadratic behavior, modifications like DropRequire
|
||||||
|
// clear the entry but do not remove it from the slice.
|
||||||
|
// Cleanup cleans out all the cleared entries.
|
||||||
|
func (f *File) Cleanup() {
|
||||||
|
w := 0
|
||||||
|
for _, r := range f.Require {
|
||||||
|
if r.Mod.Path != "" {
|
||||||
|
f.Require[w] = r
|
||||||
|
w++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f.Require = f.Require[:w]
|
||||||
|
|
||||||
|
w = 0
|
||||||
|
for _, x := range f.Exclude {
|
||||||
|
if x.Mod.Path != "" {
|
||||||
|
f.Exclude[w] = x
|
||||||
|
w++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f.Exclude = f.Exclude[:w]
|
||||||
|
|
||||||
|
w = 0
|
||||||
|
for _, r := range f.Replace {
|
||||||
|
if r.Old.Path != "" {
|
||||||
|
f.Replace[w] = r
|
||||||
|
w++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f.Replace = f.Replace[:w]
|
||||||
|
|
||||||
|
f.Syntax.Cleanup()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *File) AddRequire(path, vers string) error {
|
||||||
|
need := true
|
||||||
|
for _, r := range f.Require {
|
||||||
|
if r.Mod.Path == path {
|
||||||
|
if need {
|
||||||
|
r.Mod.Version = vers
|
||||||
|
f.Syntax.updateLine(r.Syntax, "require", AutoQuote(path), vers)
|
||||||
|
need = false
|
||||||
|
} else {
|
||||||
|
f.Syntax.removeLine(r.Syntax)
|
||||||
|
*r = Require{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if need {
|
||||||
|
f.AddNewRequire(path, vers, false)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *File) AddNewRequire(path, vers string, indirect bool) {
|
||||||
|
line := f.Syntax.addLine(nil, "require", AutoQuote(path), vers)
|
||||||
|
setIndirect(line, indirect)
|
||||||
|
f.Require = append(f.Require, &Require{module.Version{Path: path, Version: vers}, indirect, line})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *File) SetRequire(req []*Require) {
|
||||||
|
need := make(map[string]string)
|
||||||
|
indirect := make(map[string]bool)
|
||||||
|
for _, r := range req {
|
||||||
|
need[r.Mod.Path] = r.Mod.Version
|
||||||
|
indirect[r.Mod.Path] = r.Indirect
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, r := range f.Require {
|
||||||
|
if v, ok := need[r.Mod.Path]; ok {
|
||||||
|
r.Mod.Version = v
|
||||||
|
r.Indirect = indirect[r.Mod.Path]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var newStmts []Expr
|
||||||
|
for _, stmt := range f.Syntax.Stmt {
|
||||||
|
switch stmt := stmt.(type) {
|
||||||
|
case *LineBlock:
|
||||||
|
if len(stmt.Token) > 0 && stmt.Token[0] == "require" {
|
||||||
|
var newLines []*Line
|
||||||
|
for _, line := range stmt.Line {
|
||||||
|
if p, err := parseString(&line.Token[0]); err == nil && need[p] != "" {
|
||||||
|
line.Token[1] = need[p]
|
||||||
|
delete(need, p)
|
||||||
|
setIndirect(line, indirect[p])
|
||||||
|
newLines = append(newLines, line)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(newLines) == 0 {
|
||||||
|
continue // drop stmt
|
||||||
|
}
|
||||||
|
stmt.Line = newLines
|
||||||
|
}
|
||||||
|
|
||||||
|
case *Line:
|
||||||
|
if len(stmt.Token) > 0 && stmt.Token[0] == "require" {
|
||||||
|
if p, err := parseString(&stmt.Token[1]); err == nil && need[p] != "" {
|
||||||
|
stmt.Token[2] = need[p]
|
||||||
|
delete(need, p)
|
||||||
|
setIndirect(stmt, indirect[p])
|
||||||
|
} else {
|
||||||
|
continue // drop stmt
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
newStmts = append(newStmts, stmt)
|
||||||
|
}
|
||||||
|
f.Syntax.Stmt = newStmts
|
||||||
|
|
||||||
|
for path, vers := range need {
|
||||||
|
f.AddNewRequire(path, vers, indirect[path])
|
||||||
|
}
|
||||||
|
f.SortBlocks()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *File) DropRequire(path string) error {
|
||||||
|
for _, r := range f.Require {
|
||||||
|
if r.Mod.Path == path {
|
||||||
|
f.Syntax.removeLine(r.Syntax)
|
||||||
|
*r = Require{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *File) AddExclude(path, vers string) error {
|
||||||
|
var hint *Line
|
||||||
|
for _, x := range f.Exclude {
|
||||||
|
if x.Mod.Path == path && x.Mod.Version == vers {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if x.Mod.Path == path {
|
||||||
|
hint = x.Syntax
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
f.Exclude = append(f.Exclude, &Exclude{Mod: module.Version{Path: path, Version: vers}, Syntax: f.Syntax.addLine(hint, "exclude", AutoQuote(path), vers)})
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *File) DropExclude(path, vers string) error {
|
||||||
|
for _, x := range f.Exclude {
|
||||||
|
if x.Mod.Path == path && x.Mod.Version == vers {
|
||||||
|
f.Syntax.removeLine(x.Syntax)
|
||||||
|
*x = Exclude{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *File) AddReplace(oldPath, oldVers, newPath, newVers string) error {
|
||||||
|
need := true
|
||||||
|
old := module.Version{Path: oldPath, Version: oldVers}
|
||||||
|
new := module.Version{Path: newPath, Version: newVers}
|
||||||
|
tokens := []string{"replace", AutoQuote(oldPath)}
|
||||||
|
if oldVers != "" {
|
||||||
|
tokens = append(tokens, oldVers)
|
||||||
|
}
|
||||||
|
tokens = append(tokens, "=>", AutoQuote(newPath))
|
||||||
|
if newVers != "" {
|
||||||
|
tokens = append(tokens, newVers)
|
||||||
|
}
|
||||||
|
|
||||||
|
var hint *Line
|
||||||
|
for _, r := range f.Replace {
|
||||||
|
if r.Old.Path == oldPath && (oldVers == "" || r.Old.Version == oldVers) {
|
||||||
|
if need {
|
||||||
|
// Found replacement for old; update to use new.
|
||||||
|
r.New = new
|
||||||
|
f.Syntax.updateLine(r.Syntax, tokens...)
|
||||||
|
need = false
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// Already added; delete other replacements for same.
|
||||||
|
f.Syntax.removeLine(r.Syntax)
|
||||||
|
*r = Replace{}
|
||||||
|
}
|
||||||
|
if r.Old.Path == oldPath {
|
||||||
|
hint = r.Syntax
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if need {
|
||||||
|
f.Replace = append(f.Replace, &Replace{Old: old, New: new, Syntax: f.Syntax.addLine(hint, tokens...)})
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *File) DropReplace(oldPath, oldVers string) error {
|
||||||
|
for _, r := range f.Replace {
|
||||||
|
if r.Old.Path == oldPath && r.Old.Version == oldVers {
|
||||||
|
f.Syntax.removeLine(r.Syntax)
|
||||||
|
*r = Replace{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *File) SortBlocks() {
|
||||||
|
f.removeDups() // otherwise sorting is unsafe
|
||||||
|
|
||||||
|
for _, stmt := range f.Syntax.Stmt {
|
||||||
|
block, ok := stmt.(*LineBlock)
|
||||||
|
if !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
sort.Slice(block.Line, func(i, j int) bool {
|
||||||
|
li := block.Line[i]
|
||||||
|
lj := block.Line[j]
|
||||||
|
for k := 0; k < len(li.Token) && k < len(lj.Token); k++ {
|
||||||
|
if li.Token[k] != lj.Token[k] {
|
||||||
|
return li.Token[k] < lj.Token[k]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return len(li.Token) < len(lj.Token)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *File) removeDups() {
|
||||||
|
have := make(map[module.Version]bool)
|
||||||
|
kill := make(map[*Line]bool)
|
||||||
|
for _, x := range f.Exclude {
|
||||||
|
if have[x.Mod] {
|
||||||
|
kill[x.Syntax] = true
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
have[x.Mod] = true
|
||||||
|
}
|
||||||
|
var excl []*Exclude
|
||||||
|
for _, x := range f.Exclude {
|
||||||
|
if !kill[x.Syntax] {
|
||||||
|
excl = append(excl, x)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f.Exclude = excl
|
||||||
|
|
||||||
|
have = make(map[module.Version]bool)
|
||||||
|
// Later replacements take priority over earlier ones.
|
||||||
|
for i := len(f.Replace) - 1; i >= 0; i-- {
|
||||||
|
x := f.Replace[i]
|
||||||
|
if have[x.Old] {
|
||||||
|
kill[x.Syntax] = true
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
have[x.Old] = true
|
||||||
|
}
|
||||||
|
var repl []*Replace
|
||||||
|
for _, x := range f.Replace {
|
||||||
|
if !kill[x.Syntax] {
|
||||||
|
repl = append(repl, x)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f.Replace = repl
|
||||||
|
|
||||||
|
var stmts []Expr
|
||||||
|
for _, stmt := range f.Syntax.Stmt {
|
||||||
|
switch stmt := stmt.(type) {
|
||||||
|
case *Line:
|
||||||
|
if kill[stmt] {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
case *LineBlock:
|
||||||
|
var lines []*Line
|
||||||
|
for _, line := range stmt.Line {
|
||||||
|
if !kill[line] {
|
||||||
|
lines = append(lines, line)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stmt.Line = lines
|
||||||
|
if len(lines) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stmts = append(stmts, stmt)
|
||||||
|
}
|
||||||
|
f.Syntax.Stmt = stmts
|
||||||
|
}
|
540
vendor/github.com/rogpeppe/go-internal/module/module.go
generated
vendored
Normal file
540
vendor/github.com/rogpeppe/go-internal/module/module.go
generated
vendored
Normal file
@ -0,0 +1,540 @@
|
|||||||
|
// Copyright 2018 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Package module defines the module.Version type
|
||||||
|
// along with support code.
|
||||||
|
package module
|
||||||
|
|
||||||
|
// IMPORTANT NOTE
|
||||||
|
//
|
||||||
|
// This file essentially defines the set of valid import paths for the go command.
|
||||||
|
// There are many subtle considerations, including Unicode ambiguity,
|
||||||
|
// security, network, and file system representations.
|
||||||
|
//
|
||||||
|
// This file also defines the set of valid module path and version combinations,
|
||||||
|
// another topic with many subtle considerations.
|
||||||
|
//
|
||||||
|
// Changes to the semantics in this file require approval from rsc.
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"sort"
|
||||||
|
"strings"
|
||||||
|
"unicode"
|
||||||
|
"unicode/utf8"
|
||||||
|
|
||||||
|
"github.com/rogpeppe/go-internal/semver"
|
||||||
|
)
|
||||||
|
|
||||||
|
// A Version is defined by a module path and version pair.
|
||||||
|
type Version struct {
|
||||||
|
Path string
|
||||||
|
|
||||||
|
// Version is usually a semantic version in canonical form.
|
||||||
|
// There are two exceptions to this general rule.
|
||||||
|
// First, the top-level target of a build has no specific version
|
||||||
|
// and uses Version = "".
|
||||||
|
// Second, during MVS calculations the version "none" is used
|
||||||
|
// to represent the decision to take no version of a given module.
|
||||||
|
Version string `json:",omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check checks that a given module path, version pair is valid.
|
||||||
|
// In addition to the path being a valid module path
|
||||||
|
// and the version being a valid semantic version,
|
||||||
|
// the two must correspond.
|
||||||
|
// For example, the path "yaml/v2" only corresponds to
|
||||||
|
// semantic versions beginning with "v2.".
|
||||||
|
func Check(path, version string) error {
|
||||||
|
if err := CheckPath(path); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !semver.IsValid(version) {
|
||||||
|
return fmt.Errorf("malformed semantic version %v", version)
|
||||||
|
}
|
||||||
|
_, pathMajor, _ := SplitPathVersion(path)
|
||||||
|
if !MatchPathMajor(version, pathMajor) {
|
||||||
|
if pathMajor == "" {
|
||||||
|
pathMajor = "v0 or v1"
|
||||||
|
}
|
||||||
|
if pathMajor[0] == '.' { // .v1
|
||||||
|
pathMajor = pathMajor[1:]
|
||||||
|
}
|
||||||
|
return fmt.Errorf("mismatched module path %v and version %v (want %v)", path, version, pathMajor)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// firstPathOK reports whether r can appear in the first element of a module path.
|
||||||
|
// The first element of the path must be an LDH domain name, at least for now.
|
||||||
|
// To avoid case ambiguity, the domain name must be entirely lower case.
|
||||||
|
func firstPathOK(r rune) bool {
|
||||||
|
return r == '-' || r == '.' ||
|
||||||
|
'0' <= r && r <= '9' ||
|
||||||
|
'a' <= r && r <= 'z'
|
||||||
|
}
|
||||||
|
|
||||||
|
// pathOK reports whether r can appear in an import path element.
|
||||||
|
// Paths can be ASCII letters, ASCII digits, and limited ASCII punctuation: + - . _ and ~.
|
||||||
|
// This matches what "go get" has historically recognized in import paths.
|
||||||
|
// TODO(rsc): We would like to allow Unicode letters, but that requires additional
|
||||||
|
// care in the safe encoding (see note below).
|
||||||
|
func pathOK(r rune) bool {
|
||||||
|
if r < utf8.RuneSelf {
|
||||||
|
return r == '+' || r == '-' || r == '.' || r == '_' || r == '~' ||
|
||||||
|
'0' <= r && r <= '9' ||
|
||||||
|
'A' <= r && r <= 'Z' ||
|
||||||
|
'a' <= r && r <= 'z'
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// fileNameOK reports whether r can appear in a file name.
|
||||||
|
// For now we allow all Unicode letters but otherwise limit to pathOK plus a few more punctuation characters.
|
||||||
|
// If we expand the set of allowed characters here, we have to
|
||||||
|
// work harder at detecting potential case-folding and normalization collisions.
|
||||||
|
// See note about "safe encoding" below.
|
||||||
|
func fileNameOK(r rune) bool {
|
||||||
|
if r < utf8.RuneSelf {
|
||||||
|
// Entire set of ASCII punctuation, from which we remove characters:
|
||||||
|
// ! " # $ % & ' ( ) * + , - . / : ; < = > ? @ [ \ ] ^ _ ` { | } ~
|
||||||
|
// We disallow some shell special characters: " ' * < > ? ` |
|
||||||
|
// (Note that some of those are disallowed by the Windows file system as well.)
|
||||||
|
// We also disallow path separators / : and \ (fileNameOK is only called on path element characters).
|
||||||
|
// We allow spaces (U+0020) in file names.
|
||||||
|
const allowed = "!#$%&()+,-.=@[]^_{}~ "
|
||||||
|
if '0' <= r && r <= '9' || 'A' <= r && r <= 'Z' || 'a' <= r && r <= 'z' {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
for i := 0; i < len(allowed); i++ {
|
||||||
|
if rune(allowed[i]) == r {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
// It may be OK to add more ASCII punctuation here, but only carefully.
|
||||||
|
// For example Windows disallows < > \, and macOS disallows :, so we must not allow those.
|
||||||
|
return unicode.IsLetter(r)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CheckPath checks that a module path is valid.
|
||||||
|
func CheckPath(path string) error {
|
||||||
|
if err := checkPath(path, false); err != nil {
|
||||||
|
return fmt.Errorf("malformed module path %q: %v", path, err)
|
||||||
|
}
|
||||||
|
i := strings.Index(path, "/")
|
||||||
|
if i < 0 {
|
||||||
|
i = len(path)
|
||||||
|
}
|
||||||
|
if i == 0 {
|
||||||
|
return fmt.Errorf("malformed module path %q: leading slash", path)
|
||||||
|
}
|
||||||
|
if !strings.Contains(path[:i], ".") {
|
||||||
|
return fmt.Errorf("malformed module path %q: missing dot in first path element", path)
|
||||||
|
}
|
||||||
|
if path[0] == '-' {
|
||||||
|
return fmt.Errorf("malformed module path %q: leading dash in first path element", path)
|
||||||
|
}
|
||||||
|
for _, r := range path[:i] {
|
||||||
|
if !firstPathOK(r) {
|
||||||
|
return fmt.Errorf("malformed module path %q: invalid char %q in first path element", path, r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if _, _, ok := SplitPathVersion(path); !ok {
|
||||||
|
return fmt.Errorf("malformed module path %q: invalid version", path)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CheckImportPath checks that an import path is valid.
|
||||||
|
func CheckImportPath(path string) error {
|
||||||
|
if err := checkPath(path, false); err != nil {
|
||||||
|
return fmt.Errorf("malformed import path %q: %v", path, err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// checkPath checks that a general path is valid.
|
||||||
|
// It returns an error describing why but not mentioning path.
|
||||||
|
// Because these checks apply to both module paths and import paths,
|
||||||
|
// the caller is expected to add the "malformed ___ path %q: " prefix.
|
||||||
|
// fileName indicates whether the final element of the path is a file name
|
||||||
|
// (as opposed to a directory name).
|
||||||
|
func checkPath(path string, fileName bool) error {
|
||||||
|
if !utf8.ValidString(path) {
|
||||||
|
return fmt.Errorf("invalid UTF-8")
|
||||||
|
}
|
||||||
|
if path == "" {
|
||||||
|
return fmt.Errorf("empty string")
|
||||||
|
}
|
||||||
|
if strings.Contains(path, "..") {
|
||||||
|
return fmt.Errorf("double dot")
|
||||||
|
}
|
||||||
|
if strings.Contains(path, "//") {
|
||||||
|
return fmt.Errorf("double slash")
|
||||||
|
}
|
||||||
|
if path[len(path)-1] == '/' {
|
||||||
|
return fmt.Errorf("trailing slash")
|
||||||
|
}
|
||||||
|
elemStart := 0
|
||||||
|
for i, r := range path {
|
||||||
|
if r == '/' {
|
||||||
|
if err := checkElem(path[elemStart:i], fileName); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
elemStart = i + 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err := checkElem(path[elemStart:], fileName); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// checkElem checks whether an individual path element is valid.
|
||||||
|
// fileName indicates whether the element is a file name (not a directory name).
|
||||||
|
func checkElem(elem string, fileName bool) error {
|
||||||
|
if elem == "" {
|
||||||
|
return fmt.Errorf("empty path element")
|
||||||
|
}
|
||||||
|
if strings.Count(elem, ".") == len(elem) {
|
||||||
|
return fmt.Errorf("invalid path element %q", elem)
|
||||||
|
}
|
||||||
|
if elem[0] == '.' && !fileName {
|
||||||
|
return fmt.Errorf("leading dot in path element")
|
||||||
|
}
|
||||||
|
if elem[len(elem)-1] == '.' {
|
||||||
|
return fmt.Errorf("trailing dot in path element")
|
||||||
|
}
|
||||||
|
charOK := pathOK
|
||||||
|
if fileName {
|
||||||
|
charOK = fileNameOK
|
||||||
|
}
|
||||||
|
for _, r := range elem {
|
||||||
|
if !charOK(r) {
|
||||||
|
return fmt.Errorf("invalid char %q", r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Windows disallows a bunch of path elements, sadly.
|
||||||
|
// See https://docs.microsoft.com/en-us/windows/desktop/fileio/naming-a-file
|
||||||
|
short := elem
|
||||||
|
if i := strings.Index(short, "."); i >= 0 {
|
||||||
|
short = short[:i]
|
||||||
|
}
|
||||||
|
for _, bad := range badWindowsNames {
|
||||||
|
if strings.EqualFold(bad, short) {
|
||||||
|
return fmt.Errorf("disallowed path element %q", elem)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CheckFilePath checks whether a slash-separated file path is valid.
|
||||||
|
func CheckFilePath(path string) error {
|
||||||
|
if err := checkPath(path, true); err != nil {
|
||||||
|
return fmt.Errorf("malformed file path %q: %v", path, err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// badWindowsNames are the reserved file path elements on Windows.
|
||||||
|
// See https://docs.microsoft.com/en-us/windows/desktop/fileio/naming-a-file
|
||||||
|
var badWindowsNames = []string{
|
||||||
|
"CON",
|
||||||
|
"PRN",
|
||||||
|
"AUX",
|
||||||
|
"NUL",
|
||||||
|
"COM1",
|
||||||
|
"COM2",
|
||||||
|
"COM3",
|
||||||
|
"COM4",
|
||||||
|
"COM5",
|
||||||
|
"COM6",
|
||||||
|
"COM7",
|
||||||
|
"COM8",
|
||||||
|
"COM9",
|
||||||
|
"LPT1",
|
||||||
|
"LPT2",
|
||||||
|
"LPT3",
|
||||||
|
"LPT4",
|
||||||
|
"LPT5",
|
||||||
|
"LPT6",
|
||||||
|
"LPT7",
|
||||||
|
"LPT8",
|
||||||
|
"LPT9",
|
||||||
|
}
|
||||||
|
|
||||||
|
// SplitPathVersion returns prefix and major version such that prefix+pathMajor == path
|
||||||
|
// and version is either empty or "/vN" for N >= 2.
|
||||||
|
// As a special case, gopkg.in paths are recognized directly;
|
||||||
|
// they require ".vN" instead of "/vN", and for all N, not just N >= 2.
|
||||||
|
func SplitPathVersion(path string) (prefix, pathMajor string, ok bool) {
|
||||||
|
if strings.HasPrefix(path, "gopkg.in/") {
|
||||||
|
return splitGopkgIn(path)
|
||||||
|
}
|
||||||
|
|
||||||
|
i := len(path)
|
||||||
|
dot := false
|
||||||
|
for i > 0 && ('0' <= path[i-1] && path[i-1] <= '9' || path[i-1] == '.') {
|
||||||
|
if path[i-1] == '.' {
|
||||||
|
dot = true
|
||||||
|
}
|
||||||
|
i--
|
||||||
|
}
|
||||||
|
if i <= 1 || path[i-1] != 'v' || path[i-2] != '/' {
|
||||||
|
return path, "", true
|
||||||
|
}
|
||||||
|
prefix, pathMajor = path[:i-2], path[i-2:]
|
||||||
|
if dot || len(pathMajor) <= 2 || pathMajor[2] == '0' || pathMajor == "/v1" {
|
||||||
|
return path, "", false
|
||||||
|
}
|
||||||
|
return prefix, pathMajor, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// splitGopkgIn is like SplitPathVersion but only for gopkg.in paths.
|
||||||
|
func splitGopkgIn(path string) (prefix, pathMajor string, ok bool) {
|
||||||
|
if !strings.HasPrefix(path, "gopkg.in/") {
|
||||||
|
return path, "", false
|
||||||
|
}
|
||||||
|
i := len(path)
|
||||||
|
if strings.HasSuffix(path, "-unstable") {
|
||||||
|
i -= len("-unstable")
|
||||||
|
}
|
||||||
|
for i > 0 && ('0' <= path[i-1] && path[i-1] <= '9') {
|
||||||
|
i--
|
||||||
|
}
|
||||||
|
if i <= 1 || path[i-1] != 'v' || path[i-2] != '.' {
|
||||||
|
// All gopkg.in paths must end in vN for some N.
|
||||||
|
return path, "", false
|
||||||
|
}
|
||||||
|
prefix, pathMajor = path[:i-2], path[i-2:]
|
||||||
|
if len(pathMajor) <= 2 || pathMajor[2] == '0' && pathMajor != ".v0" {
|
||||||
|
return path, "", false
|
||||||
|
}
|
||||||
|
return prefix, pathMajor, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// MatchPathMajor reports whether the semantic version v
|
||||||
|
// matches the path major version pathMajor.
|
||||||
|
func MatchPathMajor(v, pathMajor string) bool {
|
||||||
|
if strings.HasPrefix(pathMajor, ".v") && strings.HasSuffix(pathMajor, "-unstable") {
|
||||||
|
pathMajor = strings.TrimSuffix(pathMajor, "-unstable")
|
||||||
|
}
|
||||||
|
if strings.HasPrefix(v, "v0.0.0-") && pathMajor == ".v1" {
|
||||||
|
// Allow old bug in pseudo-versions that generated v0.0.0- pseudoversion for gopkg .v1.
|
||||||
|
// For example, gopkg.in/yaml.v2@v2.2.1's go.mod requires gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405.
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
m := semver.Major(v)
|
||||||
|
if pathMajor == "" {
|
||||||
|
return m == "v0" || m == "v1" || semver.Build(v) == "+incompatible"
|
||||||
|
}
|
||||||
|
return (pathMajor[0] == '/' || pathMajor[0] == '.') && m == pathMajor[1:]
|
||||||
|
}
|
||||||
|
|
||||||
|
// CanonicalVersion returns the canonical form of the version string v.
|
||||||
|
// It is the same as semver.Canonical(v) except that it preserves the special build suffix "+incompatible".
|
||||||
|
func CanonicalVersion(v string) string {
|
||||||
|
cv := semver.Canonical(v)
|
||||||
|
if semver.Build(v) == "+incompatible" {
|
||||||
|
cv += "+incompatible"
|
||||||
|
}
|
||||||
|
return cv
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort sorts the list by Path, breaking ties by comparing Versions.
|
||||||
|
func Sort(list []Version) {
|
||||||
|
sort.Slice(list, func(i, j int) bool {
|
||||||
|
mi := list[i]
|
||||||
|
mj := list[j]
|
||||||
|
if mi.Path != mj.Path {
|
||||||
|
return mi.Path < mj.Path
|
||||||
|
}
|
||||||
|
// To help go.sum formatting, allow version/file.
|
||||||
|
// Compare semver prefix by semver rules,
|
||||||
|
// file by string order.
|
||||||
|
vi := mi.Version
|
||||||
|
vj := mj.Version
|
||||||
|
var fi, fj string
|
||||||
|
if k := strings.Index(vi, "/"); k >= 0 {
|
||||||
|
vi, fi = vi[:k], vi[k:]
|
||||||
|
}
|
||||||
|
if k := strings.Index(vj, "/"); k >= 0 {
|
||||||
|
vj, fj = vj[:k], vj[k:]
|
||||||
|
}
|
||||||
|
if vi != vj {
|
||||||
|
return semver.Compare(vi, vj) < 0
|
||||||
|
}
|
||||||
|
return fi < fj
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Safe encodings
|
||||||
|
//
|
||||||
|
// Module paths appear as substrings of file system paths
|
||||||
|
// (in the download cache) and of web server URLs in the proxy protocol.
|
||||||
|
// In general we cannot rely on file systems to be case-sensitive,
|
||||||
|
// nor can we rely on web servers, since they read from file systems.
|
||||||
|
// That is, we cannot rely on the file system to keep rsc.io/QUOTE
|
||||||
|
// and rsc.io/quote separate. Windows and macOS don't.
|
||||||
|
// Instead, we must never require two different casings of a file path.
|
||||||
|
// Because we want the download cache to match the proxy protocol,
|
||||||
|
// and because we want the proxy protocol to be possible to serve
|
||||||
|
// from a tree of static files (which might be stored on a case-insensitive
|
||||||
|
// file system), the proxy protocol must never require two different casings
|
||||||
|
// of a URL path either.
|
||||||
|
//
|
||||||
|
// One possibility would be to make the safe encoding be the lowercase
|
||||||
|
// hexadecimal encoding of the actual path bytes. This would avoid ever
|
||||||
|
// needing different casings of a file path, but it would be fairly illegible
|
||||||
|
// to most programmers when those paths appeared in the file system
|
||||||
|
// (including in file paths in compiler errors and stack traces)
|
||||||
|
// in web server logs, and so on. Instead, we want a safe encoding that
|
||||||
|
// leaves most paths unaltered.
|
||||||
|
//
|
||||||
|
// The safe encoding is this:
|
||||||
|
// replace every uppercase letter with an exclamation mark
|
||||||
|
// followed by the letter's lowercase equivalent.
|
||||||
|
//
|
||||||
|
// For example,
|
||||||
|
// github.com/Azure/azure-sdk-for-go -> github.com/!azure/azure-sdk-for-go.
|
||||||
|
// github.com/GoogleCloudPlatform/cloudsql-proxy -> github.com/!google!cloud!platform/cloudsql-proxy
|
||||||
|
// github.com/Sirupsen/logrus -> github.com/!sirupsen/logrus.
|
||||||
|
//
|
||||||
|
// Import paths that avoid upper-case letters are left unchanged.
|
||||||
|
// Note that because import paths are ASCII-only and avoid various
|
||||||
|
// problematic punctuation (like : < and >), the safe encoding is also ASCII-only
|
||||||
|
// and avoids the same problematic punctuation.
|
||||||
|
//
|
||||||
|
// Import paths have never allowed exclamation marks, so there is no
|
||||||
|
// need to define how to encode a literal !.
|
||||||
|
//
|
||||||
|
// Although paths are disallowed from using Unicode (see pathOK above),
|
||||||
|
// the eventual plan is to allow Unicode letters as well, to assume that
|
||||||
|
// file systems and URLs are Unicode-safe (storing UTF-8), and apply
|
||||||
|
// the !-for-uppercase convention. Note however that not all runes that
|
||||||
|
// are different but case-fold equivalent are an upper/lower pair.
|
||||||
|
// For example, U+004B ('K'), U+006B ('k'), and U+212A ('K' for Kelvin)
|
||||||
|
// are considered to case-fold to each other. When we do add Unicode
|
||||||
|
// letters, we must not assume that upper/lower are the only case-equivalent pairs.
|
||||||
|
// Perhaps the Kelvin symbol would be disallowed entirely, for example.
|
||||||
|
// Or perhaps it would encode as "!!k", or perhaps as "(212A)".
|
||||||
|
//
|
||||||
|
// Also, it would be nice to allow Unicode marks as well as letters,
|
||||||
|
// but marks include combining marks, and then we must deal not
|
||||||
|
// only with case folding but also normalization: both U+00E9 ('é')
|
||||||
|
// and U+0065 U+0301 ('e' followed by combining acute accent)
|
||||||
|
// look the same on the page and are treated by some file systems
|
||||||
|
// as the same path. If we do allow Unicode marks in paths, there
|
||||||
|
// must be some kind of normalization to allow only one canonical
|
||||||
|
// encoding of any character used in an import path.
|
||||||
|
|
||||||
|
// EncodePath returns the safe encoding of the given module path.
|
||||||
|
// It fails if the module path is invalid.
|
||||||
|
func EncodePath(path string) (encoding string, err error) {
|
||||||
|
if err := CheckPath(path); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return encodeString(path)
|
||||||
|
}
|
||||||
|
|
||||||
|
// EncodeVersion returns the safe encoding of the given module version.
|
||||||
|
// Versions are allowed to be in non-semver form but must be valid file names
|
||||||
|
// and not contain exclamation marks.
|
||||||
|
func EncodeVersion(v string) (encoding string, err error) {
|
||||||
|
if err := checkElem(v, true); err != nil || strings.Contains(v, "!") {
|
||||||
|
return "", fmt.Errorf("disallowed version string %q", v)
|
||||||
|
}
|
||||||
|
return encodeString(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
func encodeString(s string) (encoding string, err error) {
|
||||||
|
haveUpper := false
|
||||||
|
for _, r := range s {
|
||||||
|
if r == '!' || r >= utf8.RuneSelf {
|
||||||
|
// This should be disallowed by CheckPath, but diagnose anyway.
|
||||||
|
// The correctness of the encoding loop below depends on it.
|
||||||
|
return "", fmt.Errorf("internal error: inconsistency in EncodePath")
|
||||||
|
}
|
||||||
|
if 'A' <= r && r <= 'Z' {
|
||||||
|
haveUpper = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !haveUpper {
|
||||||
|
return s, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var buf []byte
|
||||||
|
for _, r := range s {
|
||||||
|
if 'A' <= r && r <= 'Z' {
|
||||||
|
buf = append(buf, '!', byte(r+'a'-'A'))
|
||||||
|
} else {
|
||||||
|
buf = append(buf, byte(r))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return string(buf), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecodePath returns the module path of the given safe encoding.
|
||||||
|
// It fails if the encoding is invalid or encodes an invalid path.
|
||||||
|
func DecodePath(encoding string) (path string, err error) {
|
||||||
|
path, ok := decodeString(encoding)
|
||||||
|
if !ok {
|
||||||
|
return "", fmt.Errorf("invalid module path encoding %q", encoding)
|
||||||
|
}
|
||||||
|
if err := CheckPath(path); err != nil {
|
||||||
|
return "", fmt.Errorf("invalid module path encoding %q: %v", encoding, err)
|
||||||
|
}
|
||||||
|
return path, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecodeVersion returns the version string for the given safe encoding.
|
||||||
|
// It fails if the encoding is invalid or encodes an invalid version.
|
||||||
|
// Versions are allowed to be in non-semver form but must be valid file names
|
||||||
|
// and not contain exclamation marks.
|
||||||
|
func DecodeVersion(encoding string) (v string, err error) {
|
||||||
|
v, ok := decodeString(encoding)
|
||||||
|
if !ok {
|
||||||
|
return "", fmt.Errorf("invalid version encoding %q", encoding)
|
||||||
|
}
|
||||||
|
if err := checkElem(v, true); err != nil {
|
||||||
|
return "", fmt.Errorf("disallowed version string %q", v)
|
||||||
|
}
|
||||||
|
return v, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeString(encoding string) (string, bool) {
|
||||||
|
var buf []byte
|
||||||
|
|
||||||
|
bang := false
|
||||||
|
for _, r := range encoding {
|
||||||
|
if r >= utf8.RuneSelf {
|
||||||
|
return "", false
|
||||||
|
}
|
||||||
|
if bang {
|
||||||
|
bang = false
|
||||||
|
if r < 'a' || 'z' < r {
|
||||||
|
return "", false
|
||||||
|
}
|
||||||
|
buf = append(buf, byte(r+'A'-'a'))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if r == '!' {
|
||||||
|
bang = true
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if 'A' <= r && r <= 'Z' {
|
||||||
|
return "", false
|
||||||
|
}
|
||||||
|
buf = append(buf, byte(r))
|
||||||
|
}
|
||||||
|
if bang {
|
||||||
|
return "", false
|
||||||
|
}
|
||||||
|
return string(buf), true
|
||||||
|
}
|
388
vendor/github.com/rogpeppe/go-internal/semver/semver.go
generated
vendored
Normal file
388
vendor/github.com/rogpeppe/go-internal/semver/semver.go
generated
vendored
Normal file
@ -0,0 +1,388 @@
|
|||||||
|
// Copyright 2018 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Package semver implements comparison of semantic version strings.
|
||||||
|
// In this package, semantic version strings must begin with a leading "v",
|
||||||
|
// as in "v1.0.0".
|
||||||
|
//
|
||||||
|
// The general form of a semantic version string accepted by this package is
|
||||||
|
//
|
||||||
|
// vMAJOR[.MINOR[.PATCH[-PRERELEASE][+BUILD]]]
|
||||||
|
//
|
||||||
|
// where square brackets indicate optional parts of the syntax;
|
||||||
|
// MAJOR, MINOR, and PATCH are decimal integers without extra leading zeros;
|
||||||
|
// PRERELEASE and BUILD are each a series of non-empty dot-separated identifiers
|
||||||
|
// using only alphanumeric characters and hyphens; and
|
||||||
|
// all-numeric PRERELEASE identifiers must not have leading zeros.
|
||||||
|
//
|
||||||
|
// This package follows Semantic Versioning 2.0.0 (see semver.org)
|
||||||
|
// with two exceptions. First, it requires the "v" prefix. Second, it recognizes
|
||||||
|
// vMAJOR and vMAJOR.MINOR (with no prerelease or build suffixes)
|
||||||
|
// as shorthands for vMAJOR.0.0 and vMAJOR.MINOR.0.
|
||||||
|
package semver
|
||||||
|
|
||||||
|
// parsed returns the parsed form of a semantic version string.
|
||||||
|
type parsed struct {
|
||||||
|
major string
|
||||||
|
minor string
|
||||||
|
patch string
|
||||||
|
short string
|
||||||
|
prerelease string
|
||||||
|
build string
|
||||||
|
err string
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsValid reports whether v is a valid semantic version string.
|
||||||
|
func IsValid(v string) bool {
|
||||||
|
_, ok := parse(v)
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
|
||||||
|
// Canonical returns the canonical formatting of the semantic version v.
|
||||||
|
// It fills in any missing .MINOR or .PATCH and discards build metadata.
|
||||||
|
// Two semantic versions compare equal only if their canonical formattings
|
||||||
|
// are identical strings.
|
||||||
|
// The canonical invalid semantic version is the empty string.
|
||||||
|
func Canonical(v string) string {
|
||||||
|
p, ok := parse(v)
|
||||||
|
if !ok {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
if p.build != "" {
|
||||||
|
return v[:len(v)-len(p.build)]
|
||||||
|
}
|
||||||
|
if p.short != "" {
|
||||||
|
return v + p.short
|
||||||
|
}
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
// Major returns the major version prefix of the semantic version v.
|
||||||
|
// For example, Major("v2.1.0") == "v2".
|
||||||
|
// If v is an invalid semantic version string, Major returns the empty string.
|
||||||
|
func Major(v string) string {
|
||||||
|
pv, ok := parse(v)
|
||||||
|
if !ok {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return v[:1+len(pv.major)]
|
||||||
|
}
|
||||||
|
|
||||||
|
// MajorMinor returns the major.minor version prefix of the semantic version v.
|
||||||
|
// For example, MajorMinor("v2.1.0") == "v2.1".
|
||||||
|
// If v is an invalid semantic version string, MajorMinor returns the empty string.
|
||||||
|
func MajorMinor(v string) string {
|
||||||
|
pv, ok := parse(v)
|
||||||
|
if !ok {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
i := 1 + len(pv.major)
|
||||||
|
if j := i + 1 + len(pv.minor); j <= len(v) && v[i] == '.' && v[i+1:j] == pv.minor {
|
||||||
|
return v[:j]
|
||||||
|
}
|
||||||
|
return v[:i] + "." + pv.minor
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prerelease returns the prerelease suffix of the semantic version v.
|
||||||
|
// For example, Prerelease("v2.1.0-pre+meta") == "-pre".
|
||||||
|
// If v is an invalid semantic version string, Prerelease returns the empty string.
|
||||||
|
func Prerelease(v string) string {
|
||||||
|
pv, ok := parse(v)
|
||||||
|
if !ok {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return pv.prerelease
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build returns the build suffix of the semantic version v.
|
||||||
|
// For example, Build("v2.1.0+meta") == "+meta".
|
||||||
|
// If v is an invalid semantic version string, Build returns the empty string.
|
||||||
|
func Build(v string) string {
|
||||||
|
pv, ok := parse(v)
|
||||||
|
if !ok {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return pv.build
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compare returns an integer comparing two versions according to
|
||||||
|
// according to semantic version precedence.
|
||||||
|
// The result will be 0 if v == w, -1 if v < w, or +1 if v > w.
|
||||||
|
//
|
||||||
|
// An invalid semantic version string is considered less than a valid one.
|
||||||
|
// All invalid semantic version strings compare equal to each other.
|
||||||
|
func Compare(v, w string) int {
|
||||||
|
pv, ok1 := parse(v)
|
||||||
|
pw, ok2 := parse(w)
|
||||||
|
if !ok1 && !ok2 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
if !ok1 {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
if !ok2 {
|
||||||
|
return +1
|
||||||
|
}
|
||||||
|
if c := compareInt(pv.major, pw.major); c != 0 {
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
if c := compareInt(pv.minor, pw.minor); c != 0 {
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
if c := compareInt(pv.patch, pw.patch); c != 0 {
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
return comparePrerelease(pv.prerelease, pw.prerelease)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Max canonicalizes its arguments and then returns the version string
|
||||||
|
// that compares greater.
|
||||||
|
func Max(v, w string) string {
|
||||||
|
v = Canonical(v)
|
||||||
|
w = Canonical(w)
|
||||||
|
if Compare(v, w) > 0 {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
return w
|
||||||
|
}
|
||||||
|
|
||||||
|
func parse(v string) (p parsed, ok bool) {
|
||||||
|
if v == "" || v[0] != 'v' {
|
||||||
|
p.err = "missing v prefix"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
p.major, v, ok = parseInt(v[1:])
|
||||||
|
if !ok {
|
||||||
|
p.err = "bad major version"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if v == "" {
|
||||||
|
p.minor = "0"
|
||||||
|
p.patch = "0"
|
||||||
|
p.short = ".0.0"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if v[0] != '.' {
|
||||||
|
p.err = "bad minor prefix"
|
||||||
|
ok = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
p.minor, v, ok = parseInt(v[1:])
|
||||||
|
if !ok {
|
||||||
|
p.err = "bad minor version"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if v == "" {
|
||||||
|
p.patch = "0"
|
||||||
|
p.short = ".0"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if v[0] != '.' {
|
||||||
|
p.err = "bad patch prefix"
|
||||||
|
ok = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
p.patch, v, ok = parseInt(v[1:])
|
||||||
|
if !ok {
|
||||||
|
p.err = "bad patch version"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if len(v) > 0 && v[0] == '-' {
|
||||||
|
p.prerelease, v, ok = parsePrerelease(v)
|
||||||
|
if !ok {
|
||||||
|
p.err = "bad prerelease"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(v) > 0 && v[0] == '+' {
|
||||||
|
p.build, v, ok = parseBuild(v)
|
||||||
|
if !ok {
|
||||||
|
p.err = "bad build"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if v != "" {
|
||||||
|
p.err = "junk on end"
|
||||||
|
ok = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ok = true
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseInt(v string) (t, rest string, ok bool) {
|
||||||
|
if v == "" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if v[0] < '0' || '9' < v[0] {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
i := 1
|
||||||
|
for i < len(v) && '0' <= v[i] && v[i] <= '9' {
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
if v[0] == '0' && i != 1 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return v[:i], v[i:], true
|
||||||
|
}
|
||||||
|
|
||||||
|
func parsePrerelease(v string) (t, rest string, ok bool) {
|
||||||
|
// "A pre-release version MAY be denoted by appending a hyphen and
|
||||||
|
// a series of dot separated identifiers immediately following the patch version.
|
||||||
|
// Identifiers MUST comprise only ASCII alphanumerics and hyphen [0-9A-Za-z-].
|
||||||
|
// Identifiers MUST NOT be empty. Numeric identifiers MUST NOT include leading zeroes."
|
||||||
|
if v == "" || v[0] != '-' {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
i := 1
|
||||||
|
start := 1
|
||||||
|
for i < len(v) && v[i] != '+' {
|
||||||
|
if !isIdentChar(v[i]) && v[i] != '.' {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if v[i] == '.' {
|
||||||
|
if start == i || isBadNum(v[start:i]) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
start = i + 1
|
||||||
|
}
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
if start == i || isBadNum(v[start:i]) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return v[:i], v[i:], true
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseBuild(v string) (t, rest string, ok bool) {
|
||||||
|
if v == "" || v[0] != '+' {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
i := 1
|
||||||
|
start := 1
|
||||||
|
for i < len(v) {
|
||||||
|
if !isIdentChar(v[i]) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if v[i] == '.' {
|
||||||
|
if start == i {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
start = i + 1
|
||||||
|
}
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
if start == i {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return v[:i], v[i:], true
|
||||||
|
}
|
||||||
|
|
||||||
|
func isIdentChar(c byte) bool {
|
||||||
|
return 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || '0' <= c && c <= '9' || c == '-'
|
||||||
|
}
|
||||||
|
|
||||||
|
func isBadNum(v string) bool {
|
||||||
|
i := 0
|
||||||
|
for i < len(v) && '0' <= v[i] && v[i] <= '9' {
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
return i == len(v) && i > 1 && v[0] == '0'
|
||||||
|
}
|
||||||
|
|
||||||
|
func isNum(v string) bool {
|
||||||
|
i := 0
|
||||||
|
for i < len(v) && '0' <= v[i] && v[i] <= '9' {
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
return i == len(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
func compareInt(x, y string) int {
|
||||||
|
if x == y {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
if len(x) < len(y) {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
if len(x) > len(y) {
|
||||||
|
return +1
|
||||||
|
}
|
||||||
|
if x < y {
|
||||||
|
return -1
|
||||||
|
} else {
|
||||||
|
return +1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func comparePrerelease(x, y string) int {
|
||||||
|
// "When major, minor, and patch are equal, a pre-release version has
|
||||||
|
// lower precedence than a normal version.
|
||||||
|
// Example: 1.0.0-alpha < 1.0.0.
|
||||||
|
// Precedence for two pre-release versions with the same major, minor,
|
||||||
|
// and patch version MUST be determined by comparing each dot separated
|
||||||
|
// identifier from left to right until a difference is found as follows:
|
||||||
|
// identifiers consisting of only digits are compared numerically and
|
||||||
|
// identifiers with letters or hyphens are compared lexically in ASCII
|
||||||
|
// sort order. Numeric identifiers always have lower precedence than
|
||||||
|
// non-numeric identifiers. A larger set of pre-release fields has a
|
||||||
|
// higher precedence than a smaller set, if all of the preceding
|
||||||
|
// identifiers are equal.
|
||||||
|
// Example: 1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-alpha.beta <
|
||||||
|
// 1.0.0-beta < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0-rc.1 < 1.0.0."
|
||||||
|
if x == y {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
if x == "" {
|
||||||
|
return +1
|
||||||
|
}
|
||||||
|
if y == "" {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
for x != "" && y != "" {
|
||||||
|
x = x[1:] // skip - or .
|
||||||
|
y = y[1:] // skip - or .
|
||||||
|
var dx, dy string
|
||||||
|
dx, x = nextIdent(x)
|
||||||
|
dy, y = nextIdent(y)
|
||||||
|
if dx != dy {
|
||||||
|
ix := isNum(dx)
|
||||||
|
iy := isNum(dy)
|
||||||
|
if ix != iy {
|
||||||
|
if ix {
|
||||||
|
return -1
|
||||||
|
} else {
|
||||||
|
return +1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ix {
|
||||||
|
if len(dx) < len(dy) {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
if len(dx) > len(dy) {
|
||||||
|
return +1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if dx < dy {
|
||||||
|
return -1
|
||||||
|
} else {
|
||||||
|
return +1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if x == "" {
|
||||||
|
return -1
|
||||||
|
} else {
|
||||||
|
return +1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func nextIdent(x string) (dx, rest string) {
|
||||||
|
i := 0
|
||||||
|
for i < len(x) && x[i] != '.' {
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
return x[:i], x[i:]
|
||||||
|
}
|
13
vendor/modules.txt
vendored
13
vendor/modules.txt
vendored
@ -1,3 +1,12 @@
|
|||||||
|
# github.com/gobuffalo/envy v1.7.0
|
||||||
|
github.com/gobuffalo/envy
|
||||||
|
# github.com/gobuffalo/packd v0.3.0
|
||||||
|
github.com/gobuffalo/packd
|
||||||
|
github.com/gobuffalo/packd/internal/takeon/github.com/markbates/errx
|
||||||
|
# github.com/gobuffalo/packr v1.30.1
|
||||||
|
github.com/gobuffalo/packr
|
||||||
|
# github.com/joho/godotenv v1.3.0
|
||||||
|
github.com/joho/godotenv
|
||||||
# github.com/labstack/echo/v4 v4.1.11
|
# github.com/labstack/echo/v4 v4.1.11
|
||||||
github.com/labstack/echo/v4
|
github.com/labstack/echo/v4
|
||||||
# github.com/labstack/gommon v0.3.0
|
# github.com/labstack/gommon v0.3.0
|
||||||
@ -14,6 +23,10 @@ github.com/likexian/whois-parser-go
|
|||||||
github.com/mattn/go-colorable
|
github.com/mattn/go-colorable
|
||||||
# github.com/mattn/go-isatty v0.0.9
|
# github.com/mattn/go-isatty v0.0.9
|
||||||
github.com/mattn/go-isatty
|
github.com/mattn/go-isatty
|
||||||
|
# github.com/rogpeppe/go-internal v1.3.0
|
||||||
|
github.com/rogpeppe/go-internal/modfile
|
||||||
|
github.com/rogpeppe/go-internal/module
|
||||||
|
github.com/rogpeppe/go-internal/semver
|
||||||
# github.com/valyala/bytebufferpool v1.0.0
|
# github.com/valyala/bytebufferpool v1.0.0
|
||||||
github.com/valyala/bytebufferpool
|
github.com/valyala/bytebufferpool
|
||||||
# github.com/valyala/fasttemplate v1.0.1
|
# github.com/valyala/fasttemplate v1.0.1
|
||||||
|
Loading…
Reference in New Issue
Block a user