Task Attachments (#104)
This commit is contained in:
parent
e2f481a6e5
commit
2169464983
349 changed files with 22540 additions and 5267 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -17,4 +17,6 @@ debian/
|
|||
logs/
|
||||
docs/public/
|
||||
docs/resources/
|
||||
pkg/static/templates_vfsdata.go
|
||||
pkg/static/templates_vfsdata.go
|
||||
files/
|
||||
!pkg/files/
|
||||
|
|
|
@ -212,7 +212,13 @@ Sorry for some of them being in German, I'll tranlate them at some point.
|
|||
* [x] "One endpoint to rule them all" -> Array-addable
|
||||
* [x] Description should be longtext
|
||||
* [x] Percent done - For now just a float, may later depend on how many sub tasks are done or so
|
||||
* [ ] Attachments
|
||||
* [x] Attachments
|
||||
* Extra file handling package
|
||||
* Files are saved "somewhere" (configurable) using their ID -> now only fs, later other things, based on afero
|
||||
* A files table which holds metadata like filename, created by etc
|
||||
* The files sub package should have methods to return files as byte slice or so
|
||||
* -> The concrete implementation (in this case task attachments) handles the rights for a file
|
||||
* task attachments are just a n:m between a task and a file id
|
||||
* [x] Related tasks -> settable with a "kind" of relation like blocked, subtask, or just related or so
|
||||
* [x] Should be possible to relate tasks which are not in the same list
|
||||
* [x] Replace the old subtask implementation
|
||||
|
@ -270,6 +276,7 @@ Sorry for some of them being in German, I'll tranlate them at some point.
|
|||
* [ ] IMAP-Integration -> Man schickt eine email an Vikunja und es macht daraus dann nen task -> Achtung missbrauchsmöglichkeiten
|
||||
* [ ] In und Out webhooks, mit Templates vom Payload
|
||||
* [ ] Some kind of milestones for tasks
|
||||
* [ ] Global/Per Namespace labels
|
||||
* [ ] Get Weekly/Daily summary of the tasks to come per mail
|
||||
* [ ] Boards (Boards)
|
||||
* [ ] Sprints
|
||||
|
|
2
Makefile
2
Makefile
|
@ -214,7 +214,7 @@ gocyclo-check:
|
|||
go get -u github.com/fzipp/gocyclo; \
|
||||
go install $(GOFLAGS) github.com/fzipp/gocyclo; \
|
||||
fi
|
||||
for S in $(GOFILES); do gocyclo -over 19 $$S || exit 1; done;
|
||||
for S in $(GOFILES); do gocyclo -over 23 $$S || exit 1; done;
|
||||
|
||||
.PHONY: static-check
|
||||
static-check:
|
||||
|
|
|
@ -106,3 +106,9 @@ ratelimit:
|
|||
limit: 100
|
||||
# The store where the limit counter for each user is stored. Possible values are "memory" or "redis"
|
||||
store: memory
|
||||
|
||||
files:
|
||||
# The path where files are stored
|
||||
basepath: ./files # relative to the binary
|
||||
# The maximum size of a file, in bytes.
|
||||
maxsize: 21474836480 # 20 MB
|
||||
|
|
|
@ -149,4 +149,10 @@ ratelimit:
|
|||
limit: 100
|
||||
# The store where the limit counter for each user is stored. Possible values are "memory" or "redis"
|
||||
store: memory
|
||||
|
||||
files:
|
||||
# The path where files are stored
|
||||
basepath: ./files # relative to the binary
|
||||
# The maximum size of a file, in bytes.
|
||||
maxsize: 21474836480 # 20 MB
|
||||
{{< /highlight >}}
|
||||
|
|
|
@ -43,6 +43,8 @@ This document describes the different errors Vikunja can return.
|
|||
| 4008 | 409 | The user tried to create a task relation which already exists. |
|
||||
| 4009 | 404 | The task relation does not exist. |
|
||||
| 4010 | 400 | Cannot relate a task with itself. |
|
||||
| 4011 | 404 | The task attachment does not exist. |
|
||||
| 4012 | 400 | The task attachment is too large. |
|
||||
| 5001 | 404 | The namspace does not exist. |
|
||||
| 5003 | 403 | The user does not have access to the specified namespace. |
|
||||
| 5006 | 400 | The namespace name cannot be empty. |
|
||||
|
|
34
go.mod
34
go.mod
|
@ -19,18 +19,18 @@ module code.vikunja.io/api
|
|||
require (
|
||||
cloud.google.com/go v0.34.0 // indirect
|
||||
code.vikunja.io/web v0.0.0-20190628075253-b457b5a1a332
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751
|
||||
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a
|
||||
github.com/beevik/etree v1.1.0 // indirect
|
||||
github.com/client9/misspell v0.3.4
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect
|
||||
github.com/creack/pty v1.1.9 // indirect
|
||||
github.com/d4l3k/messagediff v1.2.1 // indirect
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible
|
||||
github.com/fzipp/gocyclo v0.0.0-20150627053110-6acd4345c835
|
||||
github.com/garyburd/redigo v1.6.0 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.19.0 // indirect
|
||||
github.com/go-openapi/jsonreference v0.19.0 // indirect
|
||||
github.com/go-openapi/spec v0.19.0 // indirect
|
||||
github.com/go-openapi/swag v0.19.0 // indirect
|
||||
github.com/go-openapi/jsonreference v0.19.3 // indirect
|
||||
github.com/go-openapi/spec v0.19.3 // indirect
|
||||
github.com/go-redis/redis v6.15.2+incompatible
|
||||
github.com/go-sql-driver/mysql v1.4.1
|
||||
github.com/go-xorm/builder v0.3.4
|
||||
|
@ -38,14 +38,18 @@ require (
|
|||
github.com/go-xorm/tests v0.5.6 // indirect
|
||||
github.com/go-xorm/xorm v0.7.1
|
||||
github.com/go-xorm/xorm-redis-cache v0.0.0-20180727005610-859b313566b2
|
||||
github.com/golang/protobuf v1.3.2 // indirect
|
||||
github.com/gordonklaus/ineffassign v0.0.0-20180909121442-1003c8bd00dc
|
||||
github.com/imdario/mergo v0.3.7
|
||||
github.com/inconshreveable/mousetrap v1.0.0 // indirect
|
||||
github.com/jgautheron/goconst v0.0.0-20170703170152-9740945f5dcb
|
||||
github.com/json-iterator/go v1.1.7 // indirect
|
||||
github.com/kr/pty v1.1.8 // indirect
|
||||
github.com/labstack/echo/v4 v4.1.7-0.20190627175217-8fb7b5be270f
|
||||
github.com/labstack/gommon v0.2.9
|
||||
github.com/laurent22/ical-go v0.1.1-0.20181107184520-7e5d6ade8eef
|
||||
github.com/mailru/easyjson v0.0.0-20190403194419-1ea4449da983 // indirect
|
||||
github.com/mailru/easyjson v0.7.0 // indirect
|
||||
github.com/mattn/go-isatty v0.0.10 // indirect
|
||||
github.com/mattn/go-oci8 v0.0.0-20181130072307-052f5d97b9b6 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.4 // indirect
|
||||
github.com/mattn/go-sqlite3 v1.10.0
|
||||
|
@ -54,24 +58,34 @@ require (
|
|||
github.com/onsi/gomega v1.4.3 // indirect
|
||||
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7
|
||||
github.com/pelletier/go-toml v1.4.0 // indirect
|
||||
github.com/pkg/errors v0.8.1 // indirect
|
||||
github.com/prometheus/client_golang v0.9.2
|
||||
github.com/samedi/caldav-go v3.0.0+incompatible
|
||||
github.com/shurcooL/httpfs v0.0.0-20190527155220-6a4d4a70508b
|
||||
github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd
|
||||
github.com/spf13/afero v1.2.2 // indirect
|
||||
github.com/spf13/afero v1.2.2
|
||||
github.com/spf13/cobra v0.0.3
|
||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||
github.com/spf13/viper v1.3.2
|
||||
github.com/stretchr/testify v1.3.0
|
||||
github.com/swaggo/swag v1.5.0
|
||||
github.com/stretchr/testify v1.4.0
|
||||
github.com/swaggo/swag v1.6.3
|
||||
github.com/ugorji/go v1.1.7 // indirect
|
||||
github.com/ulule/limiter/v3 v3.3.0
|
||||
golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4
|
||||
github.com/urfave/cli v1.22.1 // indirect
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550
|
||||
golang.org/x/lint v0.0.0-20190409202823-959b441ac422
|
||||
golang.org/x/net v0.0.0-20191011234655-491137f69257 // indirect
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e // indirect
|
||||
golang.org/x/sys v0.0.0-20191010194322-b09406accb47 // indirect
|
||||
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a // indirect
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898 // indirect
|
||||
google.golang.org/appengine v1.5.0 // indirect
|
||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
|
||||
gopkg.in/d4l3k/messagediff.v1 v1.2.1
|
||||
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
|
||||
gopkg.in/testfixtures.v2 v2.5.3
|
||||
gopkg.in/yaml.v2 v2.2.4 // indirect
|
||||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a
|
||||
src.techknowlogick.com/xgo v0.0.0-20190507142556-a5b29ecb0ff4
|
||||
src.techknowlogick.com/xormigrate v0.0.0-20190321151057-24497c23c09c
|
||||
|
|
83
go.sum
83
go.sum
|
@ -9,6 +9,8 @@ code.vikunja.io/web v0.0.0-20190628075253-b457b5a1a332 h1:gXxyLkjhgN+vqrLvPyqySc
|
|||
code.vikunja.io/web v0.0.0-20190628075253-b457b5a1a332/go.mod h1:cuP1/ieGWAZzgQGw+QPt6Y5F0fVb/8Ol5NV4QSezGdo=
|
||||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
|
||||
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
|
||||
github.com/PuerkitoBio/purell v1.1.0 h1:rmGxhojJlM0tuKtfdvliR84CFHljx9ag64t2xmVkjK4=
|
||||
github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||
github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI=
|
||||
|
@ -17,6 +19,8 @@ github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV
|
|||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc h1:cAKDfWh5VpdgMhJosfJnn5/FoN2SRZ4p7fJNX58YPaU=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a h1:idn718Q4B6AGu/h5Sxe66HYVdqdGu2l9Iebqhi/AEoA=
|
||||
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
|
||||
|
@ -32,6 +36,11 @@ github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMe
|
|||
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/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/cweill/gotests v1.5.3 h1:k3t4wW/x/YNixWZJhUIn+mivmK5iV1tJVOwVYkx0UcU=
|
||||
github.com/d4l3k/messagediff v1.2.1 h1:ZcAIMYsUg0EAp9X+tt8/enBE/Q8Yd5kzPynLyKptt9U=
|
||||
github.com/d4l3k/messagediff v1.2.1/go.mod h1:Oozbb1TVXFac9FtSIxHBMnBCq2qeH/2KkEQxENCrlLo=
|
||||
|
@ -50,27 +59,41 @@ github.com/garyburd/redigo v1.6.0 h1:0VruCpn7yAIIu7pWVClQC8wxCJEcG3nyzpMSHKi1PQc
|
|||
github.com/garyburd/redigo v1.6.0/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY=
|
||||
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/gin-contrib/gzip v0.0.1/go.mod h1:fGBJBCdt6qCZuCAOwWuFhBB4OOq9EFqlo5dEaFhhu5w=
|
||||
github.com/gin-contrib/sse v0.0.0-20170109093832-22d885f9ecc7/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s=
|
||||
github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s=
|
||||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||
github.com/gin-gonic/gin v1.3.0/go.mod h1:7cKuhb5qV2ggCFctp2fJQ+ErvciLZrIeoOSOm6mUr7Y=
|
||||
github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM=
|
||||
github.com/go-chi/chi v3.3.3+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ=
|
||||
github.com/go-openapi/jsonpointer v0.17.0 h1:nH6xp8XdXHx8dqveo0ZuJBluCO2qGrPbDNZ0dwoRHP0=
|
||||
github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
|
||||
github.com/go-openapi/jsonpointer v0.18.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
|
||||
github.com/go-openapi/jsonpointer v0.19.0 h1:FTUMcX77w5rQkClIzDtTxvn6Bsa894CcrzNj2MMfeg8=
|
||||
github.com/go-openapi/jsonpointer v0.19.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
|
||||
github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
|
||||
github.com/go-openapi/jsonpointer v0.19.3 h1:gihV7YNZK1iK6Tgwwsxo2rJbD1GTbdm72325Bq8FI3w=
|
||||
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||
github.com/go-openapi/jsonreference v0.17.0 h1:yJW3HCkTHg7NOA+gZ83IPHzUSnUzGXhGmsdiCcMexbA=
|
||||
github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
|
||||
github.com/go-openapi/jsonreference v0.18.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
|
||||
github.com/go-openapi/jsonreference v0.19.0 h1:BqWKpV1dFd+AuiKlgtddwVIFQsuMpxfBDBHGfM2yNpk=
|
||||
github.com/go-openapi/jsonreference v0.19.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
|
||||
github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc=
|
||||
github.com/go-openapi/jsonreference v0.19.3 h1:5cxNfTy0UVC3X8JL5ymxzyoUZmo8iZb+jeTWn7tUa8o=
|
||||
github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8=
|
||||
github.com/go-openapi/spec v0.18.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
|
||||
github.com/go-openapi/spec v0.19.0 h1:A4SZ6IWh3lnjH0rG0Z5lkxazMGBECtrZcbyYQi+64k4=
|
||||
github.com/go-openapi/spec v0.19.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
|
||||
github.com/go-openapi/spec v0.19.3 h1:0XRyw8kguri6Yw4SxhsQA/atC88yqrk0+G4YhI2wabc=
|
||||
github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo=
|
||||
github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
|
||||
github.com/go-openapi/swag v0.18.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
|
||||
github.com/go-openapi/swag v0.19.0 h1:Kg7Wl7LkTPlmc393QZQ/5rQadPhi7pBVEMZxyTi0Ii8=
|
||||
github.com/go-openapi/swag v0.19.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
|
||||
github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||
github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY=
|
||||
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||
github.com/go-redis/redis v6.14.0+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
|
||||
github.com/go-redis/redis v6.15.2+incompatible h1:9SpNVG76gr6InJGxoZ6IuuxaCOQwDAhzyXg+Bs+0Sb4=
|
||||
github.com/go-redis/redis v6.15.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
|
||||
|
@ -97,8 +120,11 @@ github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM
|
|||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/gordonklaus/ineffassign v0.0.0-20180909121442-1003c8bd00dc h1:cJlkeAx1QYgO5N80aF5xRGstVsRQwgLR7uA2FnP1ZjY=
|
||||
github.com/gordonklaus/ineffassign v0.0.0-20180909121442-1003c8bd00dc/go.mod h1:cuNKsD1zp2v6XfE/orVX2QE1LC+i254ceGcVeDT3pTU=
|
||||
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
||||
|
@ -118,7 +144,9 @@ github.com/jgautheron/goconst v0.0.0-20170703170152-9740945f5dcb/go.mod h1:82Txj
|
|||
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/json-iterator/go v0.0.0-20180806060727-1624edc4454b/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/kolaente/caldav-go v3.0.1-0.20190524174923-9e5cd1688227+incompatible h1:PkEEpmbrFXlMul8cOplR8nkcIM/NDbx+H6fq2+vaKAA=
|
||||
github.com/kolaente/caldav-go v3.0.1-0.20190524174923-9e5cd1688227+incompatible/go.mod h1:y1UhTNI4g0hVymJrI6yJ5/ohy09hNBeU8iJEZjgdDOw=
|
||||
github.com/kolaente/echo/v4 v4.0.0-20190507190305-3725a216d803/go.mod h1:3LbYC6VkwmUnmLPZ8WFdHdQHG77e9GQbjyhWdb1QvC4=
|
||||
|
@ -129,6 +157,8 @@ github.com/kolaente/echo/v4 v4.0.0-20190622213746-34000ea0f7d3/go.mod h1:kU/7Pwz
|
|||
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/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
|
||||
github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
|
||||
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 v3.3.10+incompatible h1:pGRcYk231ExFAyoAjAfD85kQzRJCRI8bbnE7CX5OEgg=
|
||||
|
@ -153,6 +183,10 @@ github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN
|
|||
github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.0.0-20190403194419-1ea4449da983 h1:wL11wNW7dhKIcRCHSm4sHKPWz0tt4mwBsVodG7+Xyqg=
|
||||
github.com/mailru/easyjson v0.0.0-20190403194419-1ea4449da983/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.7.0 h1:aizVhC/NAAcKWb+5QsU1iNOZb4Yws5UO2I+aIprQITM=
|
||||
github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
|
||||
github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg=
|
||||
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
|
||||
github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU=
|
||||
|
@ -164,6 +198,8 @@ github.com/mattn/go-isatty v0.0.7 h1:UvyT9uN+3r7yLEYSlJsbQGdsaB/a0DlgWP3pql6iwOc
|
|||
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE=
|
||||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.10 h1:qxFzApOv4WsAL965uUPIsXzAKCZxN2p9UqdhFS4ZW10=
|
||||
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
|
||||
github.com/mattn/go-oci8 v0.0.0-20181115070430-6eefff3c767c/go.mod h1:/M9VLO+lUPmxvoOK2PfWRZ8mTtB4q1Hy9lEGijv9Nr8=
|
||||
github.com/mattn/go-oci8 v0.0.0-20181130072307-052f5d97b9b6 h1:gheNi9lnffYyVyqQzJqY7lo+M3bCDVw5fLU/jSuCMhc=
|
||||
github.com/mattn/go-oci8 v0.0.0-20181130072307-052f5d97b9b6/go.mod h1:/M9VLO+lUPmxvoOK2PfWRZ8mTtB4q1Hy9lEGijv9Nr8=
|
||||
|
@ -176,6 +212,7 @@ github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0j
|
|||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
|
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
|
@ -207,12 +244,16 @@ github.com/prometheus/common v0.0.0-20181126121408-4724e9255275 h1:PnBWHBf+6L0jO
|
|||
github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||
github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a h1:9a8MnZMP0X2nLJdBg+pBmGgkJlSaKC2KaQmTCk1XDtE=
|
||||
github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
|
||||
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24 h1:pntxY8Ary0t43dCZ5dqY4YTJCObLY1kIXl0uzMv+7DE=
|
||||
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
|
||||
github.com/shurcooL/httpfs v0.0.0-20190527155220-6a4d4a70508b h1:4kg1wyftSKxLtnPAvcRWakIPpokB9w780/KwrNLnfPA=
|
||||
github.com/shurcooL/httpfs v0.0.0-20190527155220-6a4d4a70508b/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd h1:ug7PpSOB5RBPK1Kg6qskGBoP3Vnj/aNYFTznWvlkGo0=
|
||||
github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw=
|
||||
github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI=
|
||||
|
@ -237,19 +278,34 @@ github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1
|
|||
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/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/swaggo/files v0.0.0-20190704085106-630677cd5c14/go.mod h1:gxQT6pBGRuIGunNf/+tSOB5OHvguWi8Tbt82WOkf35E=
|
||||
github.com/swaggo/gin-swagger v1.1.0/go.mod h1:FQlm07YuT1glfN3hQiO11UQ2m39vOCZ/aa3WWr5E+XU=
|
||||
github.com/swaggo/gin-swagger v1.2.0/go.mod h1:qlH2+W7zXGZkczuL+r2nEBR2JTT+/lX05Nn6vPhc7OI=
|
||||
github.com/swaggo/swag v1.4.0/go.mod h1:hog2WgeMOrQ/LvQ+o1YGTeT+vWVrbi0SiIslBtxKTyM=
|
||||
github.com/swaggo/swag v1.5.0 h1:haK8VG3hj+v/c8hQ4f3U+oYpkdI/26m9LAUTXHOv+2U=
|
||||
github.com/swaggo/swag v1.5.0/go.mod h1:+xZrnu5Ut3GcUkKAJm9spnOooIS1WB1cUOkLNPrvrE0=
|
||||
github.com/swaggo/swag v1.5.1/go.mod h1:1Bl9F/ZBpVWh22nY0zmYyASPO1lI/zIwRDrpZU+tv8Y=
|
||||
github.com/swaggo/swag v1.6.3 h1:N+uVPGP4H2hXoss2pt5dctoSUPKKRInr6qcTMOm0usI=
|
||||
github.com/swaggo/swag v1.6.3/go.mod h1:wcc83tB4Mb2aNiL/HP4MFeQdpHUrca+Rp/DRNgWAUio=
|
||||
github.com/ugorji/go v1.1.1/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ=
|
||||
github.com/ugorji/go v1.1.2/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ=
|
||||
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
|
||||
github.com/ugorji/go v1.1.5-pre/go.mod h1:FwP/aQVg39TXzItUBMwnWp9T9gPQnXw4Poh4/oBQZ/0=
|
||||
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
|
||||
github.com/ugorji/go/codec v0.0.0-20181022190402-e5e69e061d4f/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
||||
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
||||
github.com/ugorji/go/codec v0.0.0-20181209151446-772ced7fd4c2/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
||||
github.com/ugorji/go/codec v0.0.0-20190320090025-2dc34c0b8780/go.mod h1:iT03XoTwV7xq/+UGwKO3UbC1nNNlopQiY61beSdrtOA=
|
||||
github.com/ugorji/go/codec v1.1.5-pre/go.mod h1:tULtS6Gy1AE1yCENaw4Vb//HLH5njI2tfCQDUqRd8fI=
|
||||
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
|
||||
github.com/ulule/limiter/v3 v3.3.0 h1:DuMRthpkl1wW9Em6xOVw5HMHnbDumSIDydiMqP0PTXs=
|
||||
github.com/ulule/limiter/v3 v3.3.0/go.mod h1:E6sfg3hfRgW+yFvkE/rZf6YLqXYFMWTmZaZKvdEiQsA=
|
||||
github.com/urfave/cli v1.20.0 h1:fDqGv3UG/4jbVl/QkFwEdddtEDjh/5Ov6X+0B/3bPaw=
|
||||
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
||||
github.com/urfave/cli v1.22.1 h1:+mkCCcOFKPnCmVYVcURKps1Xe+3zP90gSYGNfRkjoIY=
|
||||
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
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/fasttemplate v1.0.1 h1:tY9CJiPnMXf1ERmG2EyK7gNUd+c6RKGD0IfU8WdUSz8=
|
||||
|
@ -265,8 +321,11 @@ golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8U
|
|||
golang.org/x/crypto v0.0.0-20190506204251-e1dfcc566284 h1:rlLehGeYg6jfoyz/eDqDU1iRXLKfR42nnNh57ytKEWo=
|
||||
golang.org/x/crypto v0.0.0-20190506204251-e1dfcc566284/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
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/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/lint v0.0.0-20190409202823-959b441ac422 h1:QzoH/1pFpZguR8NrRHLcO6jKqfv2zpuSqZLgdm7ZmjI=
|
||||
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
|
@ -276,6 +335,7 @@ golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73r
|
|||
golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc h1:a3CU5tJYVj92DY2LaA1kUkrsqD5/3mLDhx2NcNqyW+0=
|
||||
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190322120337-addf6b3196f6/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
|
@ -283,14 +343,22 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
|
|||
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c h1:uOCk1iQW6Vc18bnC13MfzScl+wdKBmM9Y9kU7Z83/lw=
|
||||
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190607181551-461777fb6f67/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190611141213-3f473d35a33a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191011234655-491137f69257 h1:ry8e2D+cwaV6hk7lb3aRTjjZo24shrbK0e11QEOkTIg=
|
||||
golang.org/x/net v0.0.0-20191011234655-491137f69257/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f h1:Bl/8QSvNqXvPGPGXa2z5xUTmV7VDcZyvRZ+QQXkXTZQ=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181228144115-9a3f9b0469bb/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-20190322080309-f49334f85ddc/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
@ -299,10 +367,15 @@ golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b h1:ag/x1USPSsqHud38I9BAC88qd
|
|||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190609082536-301114b31cce/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190610200419-93c9922d18ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190621203818-d432491b9138 h1:t8BZD9RDjkm9/h7yYN6kE8oaeov5r9aztkB7zKA5Tkg=
|
||||
golang.org/x/sys v0.0.0-20190621203818-d432491b9138/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb h1:fgwFCsaw9buMuxNd6+DQfAuSFqbNiQZpcgJQAgJsK6k=
|
||||
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191010194322-b09406accb47 h1:/XfQ9z7ib8eEJX2hdgFTZJ/ntt0swNk5oYBziWeTCvY=
|
||||
golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
||||
|
@ -311,11 +384,18 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm
|
|||
golang.org/x/tools v0.0.0-20190110015856-aa033095749b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190322203728-c1a832b0ad89/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190606050223-4d9ae51c2468/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190608022120-eacb66d2a7c3/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190611222205-d73e1c7e250b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac h1:MQEvx39qSf8vyrx3XRaOe+j1UDIzKwkYOVObRgGPVqI=
|
||||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190628034336-212fb13d595e h1:ZlQjfVdpDxeqxRfmO30CdqWWzTvgRCj0MxaUVfxEG1k=
|
||||
golang.org/x/tools v0.0.0-20190628034336-212fb13d595e/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a h1:TwMENskLwU2NnWBzrJGEWHqSiGUkO/B4rfyhwqDxDYQ=
|
||||
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/appengine v1.3.0 h1:FBSsiFRMz3LBeXIomRnVzrQwSDj4ibvcRexLG0LZGQk=
|
||||
google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
|
@ -327,6 +407,7 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+
|
|||
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/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/d4l3k/messagediff.v1 v1.2.1 h1:70AthpjunwzUiarMHyED52mj9UwtAnE89l1Gmrt3EU0=
|
||||
gopkg.in/d4l3k/messagediff.v1 v1.2.1/go.mod h1:EUzikiKadqXWcD1AzJLagx0j/BeeWGtn++04Xniyg44=
|
||||
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
|
||||
|
@ -345,6 +426,8 @@ gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE=
|
|||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
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.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a h1:LJwr7TCTghdatWv40WobzlKXc9c4s8oGa7QKJUtHhWA=
|
||||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
src.techknowlogick.com/xgo v0.0.0-20190507142556-a5b29ecb0ff4 h1:DZKMg4qnT7UIyB5ZaC6ZqltF2K5KhA1oQ2PdxOLZ3jg=
|
||||
|
|
|
@ -18,6 +18,7 @@ package cmd
|
|||
|
||||
import (
|
||||
"code.vikunja.io/api/pkg/config"
|
||||
"code.vikunja.io/api/pkg/files"
|
||||
"code.vikunja.io/api/pkg/log"
|
||||
"code.vikunja.io/api/pkg/mail"
|
||||
"code.vikunja.io/api/pkg/migration"
|
||||
|
@ -74,6 +75,13 @@ func initialize() {
|
|||
if err != nil {
|
||||
log.Fatal(err.Error())
|
||||
}
|
||||
err = files.SetEngine()
|
||||
if err != nil {
|
||||
log.Fatal(err.Error())
|
||||
}
|
||||
|
||||
// Initialize the files handler
|
||||
files.InitFileHandler()
|
||||
|
||||
// Start the mail daemon
|
||||
mail.StartMailDaemon()
|
||||
|
|
|
@ -85,6 +85,9 @@ const (
|
|||
RateLimitPeriod Key = `ratelimit.period`
|
||||
RateLimitLimit Key = `ratelimit.limit`
|
||||
RateLimitStore Key = `ratelimit.store`
|
||||
|
||||
FilesBasePath Key = `files.basepath`
|
||||
FilesMaxSize Key = `files.maxsize`
|
||||
)
|
||||
|
||||
// GetString returns a string config value
|
||||
|
@ -122,10 +125,9 @@ func (k Key) setDefault(i interface{}) {
|
|||
viper.SetDefault(string(k), i)
|
||||
}
|
||||
|
||||
// InitConfig initializes the config, sets defaults etc.
|
||||
func InitConfig() {
|
||||
|
||||
// Set defaults
|
||||
// InitDefaultConfig sets default config values
|
||||
// This is an extra function so we can call it when initializing tests without initializing the full config
|
||||
func InitDefaultConfig() {
|
||||
// Service config
|
||||
random, err := random(32)
|
||||
if err != nil {
|
||||
|
@ -193,6 +195,16 @@ func InitConfig() {
|
|||
RateLimitLimit.setDefault(100)
|
||||
RateLimitPeriod.setDefault(60)
|
||||
RateLimitStore.setDefault("memory")
|
||||
// Files
|
||||
FilesBasePath.setDefault("files")
|
||||
FilesMaxSize.setDefault(21474836480) // 20 MB
|
||||
}
|
||||
|
||||
// InitConfig initializes the config, sets defaults etc.
|
||||
func InitConfig() {
|
||||
|
||||
// Set defaults
|
||||
InitDefaultConfig()
|
||||
|
||||
// Init checking for environment variables
|
||||
viper.SetEnvPrefix("vikunja")
|
||||
|
@ -205,7 +217,7 @@ func InitConfig() {
|
|||
viper.AddConfigPath("~/.config/vikunja")
|
||||
viper.AddConfigPath(".")
|
||||
viper.SetConfigName("config")
|
||||
err = viper.ReadInConfig()
|
||||
err := viper.ReadInConfig()
|
||||
if err != nil {
|
||||
log.Println(err.Error())
|
||||
log.Println("Using defaults.")
|
||||
|
|
60
pkg/db/db.go
60
pkg/db/db.go
|
@ -19,18 +19,30 @@ package db
|
|||
import (
|
||||
"code.vikunja.io/api/pkg/config"
|
||||
"code.vikunja.io/api/pkg/log"
|
||||
"encoding/gob"
|
||||
"fmt"
|
||||
"github.com/go-xorm/core"
|
||||
"github.com/go-xorm/xorm"
|
||||
"os"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
xrc "github.com/go-xorm/xorm-redis-cache"
|
||||
|
||||
_ "github.com/go-sql-driver/mysql" // Because.
|
||||
_ "github.com/mattn/go-sqlite3" // Because.
|
||||
)
|
||||
|
||||
// We only want one instance of the engine, so we can reate it once and reuse it
|
||||
var x *xorm.Engine
|
||||
|
||||
// CreateDBEngine initializes a db engine from the config
|
||||
func CreateDBEngine() (engine *xorm.Engine, err error) {
|
||||
|
||||
if x != nil {
|
||||
return x, nil
|
||||
}
|
||||
|
||||
// If the database type is not set, this likely means we need to initialize the config first
|
||||
if config.DatabaseType.GetString() == "" {
|
||||
config.InitConfig()
|
||||
|
@ -54,9 +66,57 @@ func CreateDBEngine() (engine *xorm.Engine, err error) {
|
|||
engine.ShowSQL(config.LogDatabase.GetString() != "off")
|
||||
engine.SetLogger(xorm.NewSimpleLogger(log.GetLogWriter("database")))
|
||||
|
||||
// Cache
|
||||
// We have to initialize the cache here to avoid import cycles
|
||||
if config.CacheEnabled.GetBool() {
|
||||
switch config.CacheType.GetString() {
|
||||
case "memory":
|
||||
cacher := xorm.NewLRUCacher(xorm.NewMemoryStore(), config.CacheMaxElementSize.GetInt())
|
||||
engine.SetDefaultCacher(cacher)
|
||||
case "redis":
|
||||
cacher := xrc.NewRedisCacher(config.RedisEnabled.GetString(), config.RedisPassword.GetString(), xrc.DEFAULT_EXPIRATION, engine.Logger())
|
||||
engine.SetDefaultCacher(cacher)
|
||||
default:
|
||||
log.Info("Did not find a valid cache type. Caching disabled. Please refer to the docs for poosible cache types.")
|
||||
}
|
||||
}
|
||||
|
||||
x = engine
|
||||
return
|
||||
}
|
||||
|
||||
// CreateTestEngine creates an instance of the db engine which lives in memory
|
||||
func CreateTestEngine() (engine *xorm.Engine, err error) {
|
||||
|
||||
if x != nil {
|
||||
return x, nil
|
||||
}
|
||||
|
||||
if os.Getenv("VIKUNJA_TESTS_USE_CONFIG") == "1" {
|
||||
config.InitConfig()
|
||||
engine, err = CreateDBEngine()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
engine, err = xorm.NewEngine("sqlite3", "file::memory:?cache=shared")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
engine.SetMapper(core.GonicMapper{})
|
||||
engine.ShowSQL(os.Getenv("UNIT_TESTS_VERBOSE") == "1")
|
||||
engine.SetLogger(xorm.NewSimpleLogger(log.GetLogWriter("database")))
|
||||
x = engine
|
||||
return
|
||||
}
|
||||
|
||||
// RegisterTableStructsForCache registers tables in gob encoding for redis cache
|
||||
func RegisterTableStructsForCache(val interface{}) {
|
||||
gob.Register(val)
|
||||
}
|
||||
|
||||
func initMysqlEngine() (engine *xorm.Engine, err error) {
|
||||
connStr := fmt.Sprintf(
|
||||
"%s:%s@tcp(%s)/%s?charset=utf8&parseTime=true",
|
||||
|
|
36
pkg/db/test_fixtures.go
Normal file
36
pkg/db/test_fixtures.go
Normal file
|
@ -0,0 +1,36 @@
|
|||
// Copyright 2019 Vikunja and contriubtors. All rights reserved.
|
||||
//
|
||||
// This file is part of Vikunja.
|
||||
//
|
||||
// Vikunja is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Vikunja is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Vikunja. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
package db
|
||||
|
||||
import (
|
||||
"gopkg.in/testfixtures.v2"
|
||||
)
|
||||
|
||||
var fixtures *testfixtures.Context
|
||||
|
||||
// InitFixtures initialize test fixtures for a test database
|
||||
func InitFixtures(helper testfixtures.Helper, dir string) (err error) {
|
||||
testfixtures.SkipDatabaseNameCheck(true)
|
||||
fixtures, err = testfixtures.NewFolder(x.DB().DB, helper, dir)
|
||||
return err
|
||||
}
|
||||
|
||||
// LoadFixtures load fixtures for a test database
|
||||
func LoadFixtures() error {
|
||||
return fixtures.Load()
|
||||
}
|
49
pkg/files/db.go
Normal file
49
pkg/files/db.go
Normal file
|
@ -0,0 +1,49 @@
|
|||
// Vikunja is a todo-list application to facilitate your life.
|
||||
// Copyright 2019 Vikunja and contributors. All rights reserved.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
package files
|
||||
|
||||
import (
|
||||
"code.vikunja.io/api/pkg/config"
|
||||
"code.vikunja.io/api/pkg/db"
|
||||
"code.vikunja.io/api/pkg/log"
|
||||
"github.com/go-xorm/xorm"
|
||||
)
|
||||
|
||||
var x *xorm.Engine
|
||||
|
||||
// SetEngine sets the xorm.Engine
|
||||
func SetEngine() (err error) {
|
||||
x, err = db.CreateDBEngine()
|
||||
if err != nil {
|
||||
log.Criticalf("Could not connect to db: %v", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// Cache
|
||||
if config.CacheEnabled.GetBool() && config.CacheType.GetString() == "redis" {
|
||||
db.RegisterTableStructsForCache(GetTables())
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetTables returns all structs which are also a table.
|
||||
func GetTables() []interface{} {
|
||||
return []interface{}{
|
||||
&File{},
|
||||
}
|
||||
}
|
52
pkg/files/error.go
Normal file
52
pkg/files/error.go
Normal file
|
@ -0,0 +1,52 @@
|
|||
// Copyright 2019 Vikunja and contriubtors. All rights reserved.
|
||||
//
|
||||
// This file is part of Vikunja.
|
||||
//
|
||||
// Vikunja is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Vikunja is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Vikunja. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
package files
|
||||
|
||||
import "fmt"
|
||||
|
||||
// ErrFileDoesNotExist defines an error where a file does not exist in the db
|
||||
type ErrFileDoesNotExist struct {
|
||||
FileID int64
|
||||
}
|
||||
|
||||
// Error is the error implementation of ErrFileDoesNotExist
|
||||
func (err ErrFileDoesNotExist) Error() string {
|
||||
return fmt.Sprintf("file %d does not exist", err.FileID)
|
||||
}
|
||||
|
||||
//IsErrFileDoesNotExist checks if an error is ErrFileDoesNotExist
|
||||
func IsErrFileDoesNotExist(err error) bool {
|
||||
_, ok := err.(ErrFileDoesNotExist)
|
||||
return ok
|
||||
}
|
||||
|
||||
// ErrFileIsTooLarge defines an error where a file is larger than the configured limit
|
||||
type ErrFileIsTooLarge struct {
|
||||
Size int64
|
||||
}
|
||||
|
||||
// Error is the error implementation of ErrFileIsTooLarge
|
||||
func (err ErrFileIsTooLarge) Error() string {
|
||||
return fmt.Sprintf("file is too large [Size: %d]", err.Size)
|
||||
}
|
||||
|
||||
//IsErrFileIsTooLarge checks if an error is ErrFileIsTooLarge
|
||||
func IsErrFileIsTooLarge(err error) bool {
|
||||
_, ok := err.(ErrFileIsTooLarge)
|
||||
return ok
|
||||
}
|
97
pkg/files/filehandling.go
Normal file
97
pkg/files/filehandling.go
Normal file
|
@ -0,0 +1,97 @@
|
|||
// Vikunja is a todo-list application to facilitate your life.
|
||||
// Copyright 2019 Vikunja and contributors. All rights reserved.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
package files
|
||||
|
||||
import (
|
||||
"code.vikunja.io/api/pkg/config"
|
||||
"code.vikunja.io/api/pkg/db"
|
||||
"code.vikunja.io/api/pkg/log"
|
||||
"github.com/spf13/afero"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"gopkg.in/testfixtures.v2"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// This file handles storing and retrieving a file for different backends
|
||||
var fs afero.Fs
|
||||
var afs *afero.Afero
|
||||
|
||||
// InitFileHandler creates a new file handler for the file backend we want to use
|
||||
func InitFileHandler() {
|
||||
fs = afero.NewOsFs()
|
||||
afs = &afero.Afero{Fs: fs}
|
||||
}
|
||||
|
||||
// InitTestFileHandler initializes a new memory file system for testing
|
||||
func InitTestFileHandler() {
|
||||
fs = afero.NewMemMapFs()
|
||||
afs = &afero.Afero{Fs: fs}
|
||||
}
|
||||
|
||||
func initFixtures(t *testing.T) {
|
||||
// Init db fixtures
|
||||
err := db.LoadFixtures()
|
||||
assert.NoError(t, err)
|
||||
|
||||
InitTestFileFixtures(t)
|
||||
}
|
||||
|
||||
//InitTestFileFixtures initializes file fixtures
|
||||
func InitTestFileFixtures(t *testing.T) {
|
||||
// Init fixture files
|
||||
filename := config.FilesBasePath.GetString() + "/1"
|
||||
err := afero.WriteFile(afs, filename, []byte("testfile1"), 0644)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
// InitTests handles the actual bootstrapping of the test env
|
||||
func InitTests() {
|
||||
var err error
|
||||
x, err = db.CreateTestEngine()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
err = x.Sync2(GetTables()...)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
config.InitDefaultConfig()
|
||||
// We need to set the root path even if we're not using the config, otherwise fixtures are not loaded correctly
|
||||
config.ServiceRootpath.Set(os.Getenv("VIKUNJA_SERVICE_ROOTPATH"))
|
||||
|
||||
// Sync fixtures
|
||||
var fixturesHelper testfixtures.Helper = &testfixtures.SQLite{}
|
||||
if config.DatabaseType.GetString() == "mysql" {
|
||||
fixturesHelper = &testfixtures.MySQL{}
|
||||
}
|
||||
fixturesDir := filepath.Join(config.ServiceRootpath.GetString(), "pkg", "files", "fixtures")
|
||||
err = db.InitFixtures(fixturesHelper, fixturesDir)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
InitTestFileHandler()
|
||||
}
|
||||
|
||||
// FileStat stats a file. This is an exported function to be able to test this from outide of the package
|
||||
func FileStat(filename string) (os.FileInfo, error) {
|
||||
return afs.Stat(filename)
|
||||
}
|
104
pkg/files/files.go
Normal file
104
pkg/files/files.go
Normal file
|
@ -0,0 +1,104 @@
|
|||
// Vikunja is a todo-list application to facilitate your life.
|
||||
// Copyright 2019 Vikunja and contributors. All rights reserved.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
package files
|
||||
|
||||
import (
|
||||
"code.vikunja.io/api/pkg/config"
|
||||
"code.vikunja.io/web"
|
||||
"github.com/spf13/afero"
|
||||
"io"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
// File holds all information about a file
|
||||
type File struct {
|
||||
ID int64 `xorm:"int(11) autoincr not null unique pk" json:"id"`
|
||||
Name string `xorm:"text not null" json:"name"`
|
||||
Mime string `xorm:"text null" json:"mime"`
|
||||
Size int64 `xorm:"int(11) not null" json:"size"`
|
||||
|
||||
Created time.Time `xorm:"-" json:"created"`
|
||||
|
||||
CreatedUnix int64 `xorm:"created" json:"-"`
|
||||
CreatedByID int64 `xorm:"int(11) not null" json:"-"`
|
||||
|
||||
File afero.File `xorm:"-" json:"-"`
|
||||
}
|
||||
|
||||
// TableName is the table name for the files table
|
||||
func (File) TableName() string {
|
||||
return "files"
|
||||
}
|
||||
|
||||
func (f *File) getFileName() string {
|
||||
return config.FilesBasePath.GetString() + "/" + strconv.FormatInt(f.ID, 10)
|
||||
}
|
||||
|
||||
// LoadFileByID returns a file by its ID
|
||||
func (f *File) LoadFileByID() (err error) {
|
||||
f.File, err = afs.Open(f.getFileName())
|
||||
return
|
||||
}
|
||||
|
||||
// LoadFileMetaByID loads everything about a file without loading the actual file
|
||||
func (f *File) LoadFileMetaByID() (err error) {
|
||||
exists, err := x.Where("id = ?", f.ID).Get(f)
|
||||
if !exists {
|
||||
return ErrFileDoesNotExist{FileID: f.ID}
|
||||
}
|
||||
f.Created = time.Unix(f.CreatedUnix, 0)
|
||||
return
|
||||
}
|
||||
|
||||
// Create creates a new file from an FileHeader
|
||||
func Create(f io.ReadCloser, realname string, realsize int64, a web.Auth) (file *File, err error) {
|
||||
|
||||
if realsize > config.FilesMaxSize.GetInt64() {
|
||||
return nil, ErrFileIsTooLarge{Size: realsize}
|
||||
}
|
||||
|
||||
// We first insert the file into the db to get it's ID
|
||||
file = &File{
|
||||
Name: realname,
|
||||
Size: realsize,
|
||||
CreatedByID: a.GetID(),
|
||||
}
|
||||
|
||||
_, err = x.Insert(file)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Save the file to storage with its new ID as path
|
||||
err = afs.WriteReader(file.getFileName(), f)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete removes a file from the DB and the file system
|
||||
func (f *File) Delete() (err error) {
|
||||
deleted, err := x.Where("id = ?", f.ID).Delete(f)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if deleted == 0 {
|
||||
return ErrFileDoesNotExist{FileID: f.ID}
|
||||
}
|
||||
|
||||
err = afs.Remove(f.getFileName())
|
||||
return
|
||||
}
|
131
pkg/files/files_test.go
Normal file
131
pkg/files/files_test.go
Normal file
|
@ -0,0 +1,131 @@
|
|||
// Copyright 2019 Vikunja and contriubtors. All rights reserved.
|
||||
//
|
||||
// This file is part of Vikunja.
|
||||
//
|
||||
// Vikunja is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Vikunja is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Vikunja. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
package files
|
||||
|
||||
import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"io"
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type testfile struct {
|
||||
content []byte
|
||||
done bool
|
||||
}
|
||||
|
||||
func (t *testfile) Read(p []byte) (n int, err error) {
|
||||
if t.done {
|
||||
return 0, io.EOF
|
||||
}
|
||||
copy(p, t.content)
|
||||
t.done = true
|
||||
return len(p), nil
|
||||
}
|
||||
|
||||
func (t *testfile) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type testauth struct {
|
||||
id int64
|
||||
}
|
||||
|
||||
func (a *testauth) GetID() int64 {
|
||||
return a.id
|
||||
}
|
||||
|
||||
func TestCreate(t *testing.T) {
|
||||
t.Run("Normal", func(t *testing.T) {
|
||||
initFixtures(t)
|
||||
tf := &testfile{
|
||||
content: []byte("testfile"),
|
||||
}
|
||||
ta := &testauth{id: 1}
|
||||
_, err := Create(tf, "testfile", 100, ta)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Check the file was created correctly
|
||||
file := &File{ID: 2}
|
||||
err = file.LoadFileMetaByID()
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, int64(1), file.CreatedByID)
|
||||
assert.Equal(t, "testfile", file.Name)
|
||||
assert.Equal(t, int64(100), file.Size)
|
||||
|
||||
})
|
||||
t.Run("Too Large", func(t *testing.T) {
|
||||
initFixtures(t)
|
||||
tf := &testfile{
|
||||
content: []byte("testfile"),
|
||||
}
|
||||
ta := &testauth{id: 1}
|
||||
_, err := Create(tf, "testfile", 99999999999, ta)
|
||||
assert.Error(t, err)
|
||||
assert.True(t, IsErrFileIsTooLarge(err))
|
||||
})
|
||||
}
|
||||
|
||||
func TestFile_Delete(t *testing.T) {
|
||||
t.Run("Normal", func(t *testing.T) {
|
||||
initFixtures(t)
|
||||
f := &File{ID: 1}
|
||||
err := f.Delete()
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
t.Run("Nonexisting", func(t *testing.T) {
|
||||
initFixtures(t)
|
||||
f := &File{ID: 9999}
|
||||
err := f.Delete()
|
||||
assert.Error(t, err)
|
||||
assert.True(t, IsErrFileDoesNotExist(err))
|
||||
})
|
||||
}
|
||||
|
||||
func TestFile_LoadFileByID(t *testing.T) {
|
||||
t.Run("Normal", func(t *testing.T) {
|
||||
initFixtures(t)
|
||||
f := &File{ID: 1}
|
||||
err := f.LoadFileByID()
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
t.Run("Nonexisting", func(t *testing.T) {
|
||||
initFixtures(t)
|
||||
f := &File{ID: 9999}
|
||||
err := f.LoadFileByID()
|
||||
assert.Error(t, err)
|
||||
assert.True(t, os.IsNotExist(err))
|
||||
})
|
||||
}
|
||||
|
||||
func TestFile_LoadFileMetaByID(t *testing.T) {
|
||||
t.Run("Normal", func(t *testing.T) {
|
||||
initFixtures(t)
|
||||
f := &File{ID: 1}
|
||||
err := f.LoadFileMetaByID()
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "test", f.Name)
|
||||
})
|
||||
t.Run("Nonexisting", func(t *testing.T) {
|
||||
initFixtures(t)
|
||||
f := &File{ID: 9999}
|
||||
err := f.LoadFileMetaByID()
|
||||
assert.Error(t, err)
|
||||
assert.True(t, IsErrFileDoesNotExist(err))
|
||||
})
|
||||
}
|
5
pkg/files/fixtures/files.yml
Normal file
5
pkg/files/fixtures/files.yml
Normal file
|
@ -0,0 +1,5 @@
|
|||
- id: 1
|
||||
name: test
|
||||
size: 100
|
||||
created_unix: 1570998791
|
||||
created_by_id: 1
|
29
pkg/files/main_test.go
Normal file
29
pkg/files/main_test.go
Normal file
|
@ -0,0 +1,29 @@
|
|||
// Copyright 2019 Vikunja and contriubtors. All rights reserved.
|
||||
//
|
||||
// This file is part of Vikunja.
|
||||
//
|
||||
// Vikunja is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Vikunja is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Vikunja. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
package files
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// TestMain is the main test function used to bootstrap the test env
|
||||
func TestMain(m *testing.M) {
|
||||
InitTests()
|
||||
os.Exit(m.Run())
|
||||
}
|
|
@ -18,6 +18,8 @@ package integrations
|
|||
|
||||
import (
|
||||
"code.vikunja.io/api/pkg/config"
|
||||
"code.vikunja.io/api/pkg/db"
|
||||
"code.vikunja.io/api/pkg/files"
|
||||
"code.vikunja.io/api/pkg/models"
|
||||
"code.vikunja.io/api/pkg/routes"
|
||||
v1 "code.vikunja.io/api/pkg/routes/api/v1"
|
||||
|
@ -29,6 +31,7 @@ import (
|
|||
"net/http"
|
||||
"net/http/httptest"
|
||||
"net/url"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
@ -73,10 +76,14 @@ var (
|
|||
)
|
||||
|
||||
func setupTestEnv() (e *echo.Echo, err error) {
|
||||
config.InitConfig()
|
||||
config.InitDefaultConfig()
|
||||
// We need to set the root path even if we're not using the config, otherwise fixtures are not loaded correctly
|
||||
config.ServiceRootpath.Set(os.Getenv("VIKUNJA_SERVICE_ROOTPATH"))
|
||||
// Some tests use the file engine, so we'll need to initialize that
|
||||
files.InitTests()
|
||||
models.SetupTests(config.ServiceRootpath.GetString())
|
||||
|
||||
err = models.LoadFixtures()
|
||||
err = db.LoadFixtures()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
|
|
@ -80,33 +80,33 @@ func TestTask(t *testing.T) {
|
|||
t.Run("by priority", func(t *testing.T) {
|
||||
rec, err := testHandler.testReadAllWithUser(url.Values{"sort": []string{"priority"}}, nil)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `[{"id":3,"text":"task #3 high prio","description":"","done":false,"doneAt":0,"dueDate":0,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":100,"startDate":0,"endDate":0,"assignees":null,"labels":null,"hexColor":"","percentDone":0,"related_tasks":{},"created":1543626724,"updated":1543626724,"createdBy":{"id":1,"username":"user1","avatarUrl":"111d68d06e2d317b5a59c2c6c5bad808","created":0,"updated":0}},{"id":4,"text":"task #4 low prio","description":"","done":false,"doneAt":0,"dueDate":0,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":1`)
|
||||
assert.Contains(t, rec.Body.String(), `[{"id":3,"text":"task #3 high prio","description":"","done":false,"doneAt":0,"dueDate":0,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":100,"startDate":0,"endDate":0,"assignees":null,"labels":null,"hexColor":"","percentDone":0,"related_tasks":{},"attachments":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":1,"username":"user1","avatarUrl":"111d68d06e2d317b5a59c2c6c5bad808","created":0,"updated":0}},{"id":4,"text":"task #4 low prio","description":"","done":false,"doneAt":0,"dueDate":0,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":1,`)
|
||||
})
|
||||
t.Run("by priority desc", func(t *testing.T) {
|
||||
rec, err := testHandler.testReadAllWithUser(url.Values{"sort": []string{"prioritydesc"}}, nil)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `[{"id":3,"text":"task #3 high prio","description":"","done":false,"doneAt":0,"dueDate":0,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":100,"startDate":0,"endDate":0,"assignees":null,"labels":null,"hexColor":"","percentDone":0,"related_tasks":{},"created":1543626724,"updated":1543626724,"createdBy":{"id":1,"username":"user1","avatarUrl":"111d68d06e2d317b5a59c2c6c5bad808","created":0,"updated":0}},{"id":4,"text":"task #4 low prio","description":"","done":false,"doneAt":0,"dueDate":0,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":1`)
|
||||
assert.Contains(t, rec.Body.String(), `[{"id":3,"text":"task #3 high prio","description":"","done":false,"doneAt":0,"dueDate":0,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":100,"startDate":0,"endDate":0,"assignees":null,"labels":null,"hexColor":"","percentDone":0,"related_tasks":{},"attachments":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":1,"username":"user1","avatarUrl":"111d68d06e2d317b5a59c2c6c5bad808","created":0,"updated":0}},{"id":4,"text":"task #4 low prio","description":"","done":false,"doneAt":0,"dueDate":0,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":1,`)
|
||||
})
|
||||
t.Run("by priority asc", func(t *testing.T) {
|
||||
rec, err := testHandler.testReadAllWithUser(url.Values{"sort": []string{"priorityasc"}}, nil)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `{"id":33,"text":"task #33 with percent done","description":"","done":false,"doneAt":0,"dueDate":0,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":0,"startDate":0,"endDate":0,"assignees":null,"labels":null,"hexColor":"","percentDone":0.5,"related_tasks":{},"created":1543626724,"updated":1543626724,"createdBy":{"id":1,"username":"user1","avatarUrl":"111d68d06e2d317b5a59c2c6c5bad808","created":0,"updated":0}},{"id":4,"text":"task #4 low prio","description":"","done":false,"doneAt":0,"dueDate":0,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":1,"startDate":0,"endDate":0,"assignees":null,"labels":null,"hexColor":"","percentDone":0,"related_tasks":{},"created":1543626724,"updated":1543626724,"createdBy":{"id":1,"username":"user1","avatarUrl":"111d68d06e2d317b5a59c2c6c5bad808","created":0,"updated":0}},{"id":3,"text":"task #3 high prio","description":"","done":false,"doneAt":0,"dueDate":0,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":100,"startDate":0,"endDate":0,"assignees":null,"labels":null,"hexColor":"","percentDone":0,"related_tasks":{},"created":1543626724,"updated":1543626724,"createdBy":{"id":1,"username":"user1","avatarUrl":"111d68d06e2d317b5a59c2c6c5bad808","created":0,"updated":0}}]`)
|
||||
assert.Contains(t, rec.Body.String(), `{"id":33,"text":"task #33 with percent done","description":"","done":false,"doneAt":0,"dueDate":0,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":0,"startDate":0,"endDate":0,"assignees":null,"labels":null,"hexColor":"","percentDone":0.5,"related_tasks":{},"attachments":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":1,"username":"user1","avatarUrl":"111d68d06e2d317b5a59c2c6c5bad808","created":0,"updated":0}},{"id":4,"text":"task #4 low prio","description":"","done":false,"doneAt":0,"dueDate":0,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":1,"startDate":0,"endDate":0,"assignees":null,"labels":null,"hexColor":"","percentDone":0,"related_tasks":{},"attachments":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":1,"username":"user1","avatarUrl":"111d68d06e2d317b5a59c2c6c5bad808","created":0,"updated":0}},{"id":3,"text":"task #3 high prio","description":"","done":false,"doneAt":0,"dueDate":0,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":100,"startDate":0,"endDate":0,"assignees":null,"labels":null,"hexColor":"","percentDone":0,"related_tasks":{},"attachments":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":1,"username":"user1","avatarUrl":"111d68d06e2d317b5a59c2c6c5bad808","created":0,"updated":0}}]`)
|
||||
})
|
||||
// should equal duedate desc
|
||||
t.Run("by duedate", func(t *testing.T) {
|
||||
rec, err := testHandler.testReadAllWithUser(url.Values{"sort": []string{"duedate"}}, nil)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `[{"id":5,"text":"task #5 higher due date","description":"","done":false,"doneAt":0,"dueDate":1543636724,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":0,"startDate":0,"endDate":0,"assignees":null,"labels":null,"hexColor":"","percentDone":0,"related_tasks":{},"created":1543626724,"updated":1543626724,"createdBy":{"id":1,"username":"user1","avatarUrl":"111d68d06e2d317b5a59c2c6c5bad808","created":0,"updated":0}},{"id":6,"text":"task #6 lower due date"`)
|
||||
assert.Contains(t, rec.Body.String(), `[{"id":5,"text":"task #5 higher due date","description":"","done":false,"doneAt":0,"dueDate":1543636724,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":0,"startDate":0,"endDate":0,"assignees":null,"labels":null,"hexColor":"","percentDone":0,"related_tasks":{},"attachments":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":1,"username":"user1","avatarUrl":"111d68d06e2d317b5a59c2c6c5bad808","created":0,"updated":0}},{"id":6,"text":"task #6 lower due date"`)
|
||||
})
|
||||
t.Run("by duedate desc", func(t *testing.T) {
|
||||
rec, err := testHandler.testReadAllWithUser(url.Values{"sort": []string{"duedatedesc"}}, nil)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `[{"id":5,"text":"task #5 higher due date","description":"","done":false,"doneAt":0,"dueDate":1543636724,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":0,"startDate":0,"endDate":0,"assignees":null,"labels":null,"hexColor":"","percentDone":0,"related_tasks":{},"created":1543626724,"updated":1543626724,"createdBy":{"id":1,"username":"user1","avatarUrl":"111d68d06e2d317b5a59c2c6c5bad808","created":0,"updated":0}},{"id":6,"text":"task #6 lower due date"`)
|
||||
assert.Contains(t, rec.Body.String(), `[{"id":5,"text":"task #5 higher due date","description":"","done":false,"doneAt":0,"dueDate":1543636724,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":0,"startDate":0,"endDate":0,"assignees":null,"labels":null,"hexColor":"","percentDone":0,"related_tasks":{},"attachments":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":1,"username":"user1","avatarUrl":"111d68d06e2d317b5a59c2c6c5bad808","created":0,"updated":0}},{"id":6,"text":"task #6 lower due date"`)
|
||||
})
|
||||
t.Run("by duedate asc", func(t *testing.T) {
|
||||
rec, err := testHandler.testReadAllWithUser(url.Values{"sort": []string{"duedateasc"}}, nil)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `{"id":6,"text":"task #6 lower due date","description":"","done":false,"doneAt":0,"dueDate":1543616724,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":0,"startDate":0,"endDate":0,"assignees":null,"labels":null,"hexColor":"","percentDone":0,"related_tasks":{},"created":1543626724,"updated":1543626724,"createdBy":{"id":1,"username":"user1","avatarUrl":"111d68d06e2d317b5a59c2c6c5bad808","created":0,"updated":0}},{"id":5,"text":"task #5 higher due date","description":"","done":false,"doneAt":0,"dueDate":1543636724,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":0,"startDate":0,"endDate":0,"assignees":null,"labels":null,"hexColor":"","percentDone":0,"related_tasks":{},"created":1543626724,"updated":1543626724,"createdBy":{"id":1,"username":"user1","avatarUrl":"111d68d06e2d317b5a59c2c6c5bad808","created":0,"updated":0}}]`)
|
||||
assert.Contains(t, rec.Body.String(), `{"id":6,"text":"task #6 lower due date","description":"","done":false,"doneAt":0,"dueDate":1543616724,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":0,"startDate":0,"endDate":0,"assignees":null,"labels":null,"hexColor":"","percentDone":0,"related_tasks":{},"attachments":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":1,"username":"user1","avatarUrl":"111d68d06e2d317b5a59c2c6c5bad808","created":0,"updated":0}},{"id":5,"text":"task #5 higher due date","description":"","done":false,"doneAt":0,"dueDate":1543636724,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":0,"startDate":0,"endDate":0,"assignees":null,"labels":null,"hexColor":"","percentDone":0,"related_tasks":{},"attachments":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":1,"username":"user1","avatarUrl":"111d68d06e2d317b5a59c2c6c5bad808","created":0,"updated":0}}]`)
|
||||
})
|
||||
t.Run("invalid parameter", func(t *testing.T) {
|
||||
// Invalid parameter should not sort at all
|
||||
|
|
48
pkg/migration/20191008194238.go
Normal file
48
pkg/migration/20191008194238.go
Normal file
|
@ -0,0 +1,48 @@
|
|||
// Vikunja is a todo-list application to facilitate your life.
|
||||
// Copyright 2019 Vikunja and contributors. All rights reserved.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
package migration
|
||||
|
||||
import (
|
||||
"github.com/go-xorm/xorm"
|
||||
"src.techknowlogick.com/xormigrate"
|
||||
)
|
||||
|
||||
type file20191008194238 struct {
|
||||
ID int64 `xorm:"int(11) autoincr not null unique pk" json:"id"`
|
||||
Name string `xorm:"text not null" json:"name"`
|
||||
Mime string `xorm:"text null" json:"mime"`
|
||||
Size int64 `xorm:"int(11) not null default 0" json:"size"`
|
||||
CreatedUnix int64 `xorm:"created" json:"inserted_unix"`
|
||||
CreatedByID int64 `xorm:"int(11) not null" json:"-"`
|
||||
}
|
||||
|
||||
func (file20191008194238) TableName() string {
|
||||
return "files"
|
||||
}
|
||||
|
||||
func init() {
|
||||
migrations = append(migrations, &xormigrate.Migration{
|
||||
ID: "20191008194238",
|
||||
Description: "Added files table",
|
||||
Migrate: func(tx *xorm.Engine) error {
|
||||
return tx.Sync2(file20191008194238{})
|
||||
},
|
||||
Rollback: func(tx *xorm.Engine) error {
|
||||
return tx.DropTables(file20191008194238{})
|
||||
},
|
||||
})
|
||||
}
|
50
pkg/migration/20191010131430.go
Normal file
50
pkg/migration/20191010131430.go
Normal file
|
@ -0,0 +1,50 @@
|
|||
// Copyright 2019 Vikunja and contriubtors. All rights reserved.
|
||||
//
|
||||
// This file is part of Vikunja.
|
||||
//
|
||||
// Vikunja is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Vikunja is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Vikunja. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
package migration
|
||||
|
||||
import (
|
||||
"github.com/go-xorm/xorm"
|
||||
"src.techknowlogick.com/xormigrate"
|
||||
)
|
||||
|
||||
type taskAttachment20191010131430 struct {
|
||||
ID int64 `xorm:"int(11) autoincr not null unique pk" json:"id" param:"attachment"`
|
||||
TaskID int64 `xorm:"int(11) not null" json:"task_id" param:"task"`
|
||||
FileID int64 `xorm:"int(11) not null" json:"-"`
|
||||
|
||||
CreatedByID int64 `xorm:"int(11) not null" json:"-"`
|
||||
|
||||
Created int64 `xorm:"created"`
|
||||
}
|
||||
|
||||
func (taskAttachment20191010131430) TableName() string {
|
||||
return "task_attachments"
|
||||
}
|
||||
|
||||
func init() {
|
||||
migrations = append(migrations, &xormigrate.Migration{
|
||||
ID: "20191010131430",
|
||||
Description: "Added task attachments table",
|
||||
Migrate: func(tx *xorm.Engine) error {
|
||||
return tx.Sync2(taskAttachment20191010131430{})
|
||||
},
|
||||
Rollback: func(tx *xorm.Engine) error {
|
||||
return tx.DropTables(taskAttachment20191010131430{})
|
||||
},
|
||||
})
|
||||
}
|
|
@ -19,6 +19,7 @@ package migration
|
|||
import (
|
||||
"code.vikunja.io/api/pkg/config"
|
||||
"code.vikunja.io/api/pkg/db"
|
||||
"code.vikunja.io/api/pkg/files"
|
||||
"code.vikunja.io/api/pkg/log"
|
||||
"code.vikunja.io/api/pkg/models"
|
||||
"github.com/go-xorm/xorm"
|
||||
|
@ -134,7 +135,8 @@ func modifyColumn(x *xorm.Engine, tableName, col, newDefinition string) error {
|
|||
}
|
||||
|
||||
func initSchema(tx *xorm.Engine) error {
|
||||
return tx.Sync2(
|
||||
models.GetTables()...,
|
||||
)
|
||||
schemeBeans := []interface{}{}
|
||||
schemeBeans = append(schemeBeans, models.GetTables()...)
|
||||
schemeBeans = append(schemeBeans, files.GetTables()...)
|
||||
return tx.Sync2(schemeBeans...)
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
package models
|
||||
|
||||
import (
|
||||
"code.vikunja.io/api/pkg/config"
|
||||
"code.vikunja.io/web"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
@ -731,6 +732,62 @@ func (err ErrRelationTasksCannotBeTheSame) HTTPError() web.HTTPError {
|
|||
}
|
||||
}
|
||||
|
||||
// ErrTaskAttachmentDoesNotExist represents an error where the user tries to relate a task with itself
|
||||
type ErrTaskAttachmentDoesNotExist struct {
|
||||
TaskID int64
|
||||
AttachmentID int64
|
||||
FileID int64
|
||||
}
|
||||
|
||||
// IsErrTaskAttachmentDoesNotExist checks if an error is ErrTaskAttachmentDoesNotExist.
|
||||
func IsErrTaskAttachmentDoesNotExist(err error) bool {
|
||||
_, ok := err.(ErrTaskAttachmentDoesNotExist)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrTaskAttachmentDoesNotExist) Error() string {
|
||||
return fmt.Sprintf("Task attachment does not exist [TaskID: %d, AttachmentID: %d, FileID: %d]", err.TaskID, err.AttachmentID, err.FileID)
|
||||
}
|
||||
|
||||
// ErrCodeTaskAttachmentDoesNotExist holds the unique world-error code of this error
|
||||
const ErrCodeTaskAttachmentDoesNotExist = 4011
|
||||
|
||||
// HTTPError holds the http error description
|
||||
func (err ErrTaskAttachmentDoesNotExist) HTTPError() web.HTTPError {
|
||||
return web.HTTPError{
|
||||
HTTPCode: http.StatusNotFound,
|
||||
Code: ErrCodeTaskAttachmentDoesNotExist,
|
||||
Message: "This task attachment does not exist.",
|
||||
}
|
||||
}
|
||||
|
||||
// ErrTaskAttachmentIsTooLarge represents an error where the user tries to relate a task with itself
|
||||
type ErrTaskAttachmentIsTooLarge struct {
|
||||
Size int64
|
||||
}
|
||||
|
||||
// IsErrTaskAttachmentIsTooLarge checks if an error is ErrTaskAttachmentIsTooLarge.
|
||||
func IsErrTaskAttachmentIsTooLarge(err error) bool {
|
||||
_, ok := err.(ErrTaskAttachmentIsTooLarge)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrTaskAttachmentIsTooLarge) Error() string {
|
||||
return fmt.Sprintf("Task attachment is too large [Size: %d]", err.Size)
|
||||
}
|
||||
|
||||
// ErrCodeTaskAttachmentIsTooLarge holds the unique world-error code of this error
|
||||
const ErrCodeTaskAttachmentIsTooLarge = 4012
|
||||
|
||||
// HTTPError holds the http error description
|
||||
func (err ErrTaskAttachmentIsTooLarge) HTTPError() web.HTTPError {
|
||||
return web.HTTPError{
|
||||
HTTPCode: http.StatusBadRequest,
|
||||
Code: ErrCodeTaskAttachmentIsTooLarge,
|
||||
Message: fmt.Sprintf("The task attachment exceeds the configured file size of %d bytes, filesize was %d", config.FilesMaxSize.GetInt64(), err.Size),
|
||||
}
|
||||
}
|
||||
|
||||
// =================
|
||||
// Namespace errors
|
||||
// =================
|
||||
|
|
1
pkg/models/fixtures/files.yml
Symbolic link
1
pkg/models/fixtures/files.yml
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../files/fixtures/files.yml
|
11
pkg/models/fixtures/task_attachments.yml
Normal file
11
pkg/models/fixtures/task_attachments.yml
Normal file
|
@ -0,0 +1,11 @@
|
|||
- id: 1
|
||||
task_id: 1
|
||||
file_id: 1
|
||||
created_by_id: 1
|
||||
created: 0
|
||||
# The file for this attachment does not exist
|
||||
- id: 2
|
||||
task_id: 1
|
||||
file_id: 9999
|
||||
created_by_id: 1
|
||||
created: 0
|
|
@ -18,10 +18,22 @@ package models
|
|||
|
||||
import (
|
||||
"code.vikunja.io/api/pkg/config"
|
||||
"code.vikunja.io/api/pkg/files"
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
config.InitConfig()
|
||||
MainTest(m, config.ServiceRootpath.GetString())
|
||||
|
||||
// Set default config
|
||||
config.InitDefaultConfig()
|
||||
// We need to set the root path even if we're not using the config, otherwise fixtures are not loaded correctly
|
||||
config.ServiceRootpath.Set(os.Getenv("VIKUNJA_SERVICE_ROOTPATH"))
|
||||
|
||||
// Some tests use the file engine, so we'll need to initialize that
|
||||
files.InitTests()
|
||||
|
||||
SetupTests(config.ServiceRootpath.GetString())
|
||||
|
||||
os.Exit(m.Run())
|
||||
}
|
||||
|
|
|
@ -20,10 +20,9 @@ import (
|
|||
"code.vikunja.io/api/pkg/config"
|
||||
"code.vikunja.io/api/pkg/db"
|
||||
"code.vikunja.io/api/pkg/log"
|
||||
"encoding/gob"
|
||||
_ "github.com/go-sql-driver/mysql" // Because.
|
||||
"github.com/go-xorm/xorm"
|
||||
xrc "github.com/go-xorm/xorm-redis-cache"
|
||||
|
||||
_ "github.com/mattn/go-sqlite3" // Because.
|
||||
)
|
||||
|
||||
|
@ -50,6 +49,7 @@ func GetTables() []interface{} {
|
|||
&TaskReminder{},
|
||||
&LinkSharing{},
|
||||
&TaskRelation{},
|
||||
&TaskAttachment{},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -62,19 +62,8 @@ func SetEngine() (err error) {
|
|||
}
|
||||
|
||||
// Cache
|
||||
// We have to initialize the cache here to avoid import cycles
|
||||
if config.CacheEnabled.GetBool() {
|
||||
switch config.CacheType.GetString() {
|
||||
case "memory":
|
||||
cacher := xorm.NewLRUCacher(xorm.NewMemoryStore(), config.CacheMaxElementSize.GetInt())
|
||||
x.SetDefaultCacher(cacher)
|
||||
case "redis":
|
||||
cacher := xrc.NewRedisCacher(config.RedisEnabled.GetString(), config.RedisPassword.GetString(), xrc.DEFAULT_EXPIRATION, x.Logger())
|
||||
x.SetDefaultCacher(cacher)
|
||||
gob.Register(GetTables())
|
||||
default:
|
||||
log.Info("Did not find a valid cache type. Caching disabled. Please refer to the docs for poosible cache types.")
|
||||
}
|
||||
if config.CacheEnabled.GetBool() && config.CacheType.GetString() == "redis" {
|
||||
db.RegisterTableStructsForCache(GetTables())
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
186
pkg/models/task_attachment.go
Normal file
186
pkg/models/task_attachment.go
Normal file
|
@ -0,0 +1,186 @@
|
|||
// Vikunja is a todo-list application to facilitate your life.
|
||||
// Copyright 2019 Vikunja and contributors. All rights reserved.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
package models
|
||||
|
||||
import (
|
||||
"code.vikunja.io/api/pkg/files"
|
||||
"code.vikunja.io/web"
|
||||
"io"
|
||||
"time"
|
||||
)
|
||||
|
||||
// TaskAttachment is the definition of a task attachment
|
||||
type TaskAttachment struct {
|
||||
ID int64 `xorm:"int(11) autoincr not null unique pk" json:"id" param:"attachment"`
|
||||
TaskID int64 `xorm:"int(11) not null" json:"task_id" param:"task"`
|
||||
FileID int64 `xorm:"int(11) not null" json:"-"`
|
||||
|
||||
CreatedByID int64 `xorm:"int(11) not null" json:"-"`
|
||||
CreatedBy *User `xorm:"-" json:"created_by"`
|
||||
|
||||
File *files.File `xorm:"-" json:"file"`
|
||||
|
||||
Created int64 `xorm:"created" json:"created"`
|
||||
|
||||
web.CRUDable `xorm:"-" json:"-"`
|
||||
web.Rights `xorm:"-" json:"-"`
|
||||
}
|
||||
|
||||
// TableName returns the table name for task attachments
|
||||
func (TaskAttachment) TableName() string {
|
||||
return "task_attachments"
|
||||
}
|
||||
|
||||
// NewAttachment creates a new task attachment
|
||||
// Note: I'm not sure if only accepting an io.ReadCloser and not an afero.File or os.File instead is a good way of doing things.
|
||||
func (ta *TaskAttachment) NewAttachment(f io.ReadCloser, realname string, realsize int64, a web.Auth) error {
|
||||
|
||||
// Store the file
|
||||
file, err := files.Create(f, realname, realsize, a)
|
||||
if err != nil {
|
||||
if files.IsErrFileIsTooLarge(err) {
|
||||
return ErrTaskAttachmentIsTooLarge{Size: realsize}
|
||||
}
|
||||
return err
|
||||
}
|
||||
ta.File = file
|
||||
|
||||
// Add an entry to the db
|
||||
ta.FileID = file.ID
|
||||
ta.CreatedByID = a.GetID()
|
||||
_, err = x.Insert(ta)
|
||||
if err != nil {
|
||||
// remove the uploaded file if adding it to the db fails
|
||||
if err2 := file.Delete(); err2 != nil {
|
||||
return err2
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ReadOne returns a task attachment
|
||||
func (ta *TaskAttachment) ReadOne() (err error) {
|
||||
exists, err := x.Where("id = ?", ta.ID).Get(ta)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if !exists {
|
||||
return ErrTaskAttachmentDoesNotExist{
|
||||
TaskID: ta.TaskID,
|
||||
AttachmentID: ta.ID,
|
||||
}
|
||||
}
|
||||
|
||||
// Get the file
|
||||
ta.File = &files.File{ID: ta.FileID}
|
||||
err = ta.File.LoadFileMetaByID()
|
||||
return
|
||||
}
|
||||
|
||||
// ReadAll returns a list with all attachments
|
||||
// @Summary Get all attachments for one task.
|
||||
// @Description Get all task attachments for one task.
|
||||
// @tags task
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param id path int true "Task ID"
|
||||
// @Security JWTKeyAuth
|
||||
// @Success 200 {array} models.TaskAttachment "All attachments for this task"
|
||||
// @Failure 403 {object} models.Message "No access to this task."
|
||||
// @Failure 404 {object} models.Message "The task does not exist."
|
||||
// @Failure 500 {object} models.Message "Internal error"
|
||||
// @Router /tasks/{id}/attachments [get]
|
||||
func (ta *TaskAttachment) ReadAll(s string, a web.Auth, page int) (interface{}, error) {
|
||||
attachments := []*TaskAttachment{}
|
||||
|
||||
err := x.
|
||||
Limit(getLimitFromPageIndex(page)).
|
||||
Where("task_id = ?", ta.TaskID).
|
||||
Find(&attachments)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
fileIDs := make([]int64, 0, len(attachments))
|
||||
userIDs := make([]int64, 0, len(attachments))
|
||||
for _, r := range attachments {
|
||||
fileIDs = append(fileIDs, r.FileID)
|
||||
userIDs = append(userIDs, r.CreatedByID)
|
||||
}
|
||||
|
||||
fs := make(map[int64]*files.File)
|
||||
err = x.In("id", fileIDs).Find(&fs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
us := make(map[int64]*User)
|
||||
err = x.In("id", userIDs).Find(&us)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, r := range attachments {
|
||||
// If the actual file does not exist, don't try to load it as that would fail with nil panic
|
||||
if _, exists := fs[r.FileID]; !exists {
|
||||
continue
|
||||
}
|
||||
r.File = fs[r.FileID]
|
||||
r.File.Created = time.Unix(r.File.CreatedUnix, 0)
|
||||
r.CreatedBy = us[r.CreatedByID]
|
||||
}
|
||||
|
||||
return attachments, err
|
||||
}
|
||||
|
||||
// Delete removes an attachment
|
||||
// @Summary Delete an attachment
|
||||
// @Description Delete an attachment.
|
||||
// @tags task
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param id path int true "Task ID"
|
||||
// @Param attachmentID path int true "Attachment ID"
|
||||
// @Security JWTKeyAuth
|
||||
// @Success 200 {object} models.Message "The attachment was deleted successfully."
|
||||
// @Failure 403 {object} models.Message "No access to this task."
|
||||
// @Failure 404 {object} models.Message "The task does not exist."
|
||||
// @Failure 500 {object} models.Message "Internal error"
|
||||
// @Router /tasks/{id}/attachments/{attachmentID} [delete]
|
||||
func (ta *TaskAttachment) Delete() error {
|
||||
// Load the attachment
|
||||
err := ta.ReadOne()
|
||||
if err != nil && !files.IsErrFileDoesNotExist(err) {
|
||||
return err
|
||||
}
|
||||
|
||||
// Delete it
|
||||
_, err = x.Where("task_id = ? AND id = ?", ta.TaskID, ta.ID).Delete(ta)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Delete the underlying file
|
||||
err = ta.File.Delete()
|
||||
// If the file does not exist, we don't want to error out
|
||||
if err != nil && files.IsErrFileDoesNotExist(err) {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
46
pkg/models/task_attachment_rights.go
Normal file
46
pkg/models/task_attachment_rights.go
Normal file
|
@ -0,0 +1,46 @@
|
|||
// Vikunja is a todo-list application to facilitate your life.
|
||||
// Copyright 2019 Vikunja and contributors. All rights reserved.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
package models
|
||||
|
||||
import "code.vikunja.io/web"
|
||||
|
||||
// CanRead checks if the user can see an attachment
|
||||
func (ta *TaskAttachment) CanRead(a web.Auth) (bool, error) {
|
||||
t, err := GetTaskByIDSimple(ta.TaskID)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return t.CanRead(a)
|
||||
}
|
||||
|
||||
// CanDelete checks if the user can delete an attachment
|
||||
func (ta *TaskAttachment) CanDelete(a web.Auth) (bool, error) {
|
||||
t, err := GetTaskByIDSimple(ta.TaskID)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return t.CanWrite(a)
|
||||
}
|
||||
|
||||
// CanCreate checks if the user can create an attachment
|
||||
func (ta *TaskAttachment) CanCreate(a web.Auth) (bool, error) {
|
||||
t, err := GetTaskByIDSimple(ta.TaskID)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return t.CanCreate(a)
|
||||
}
|
152
pkg/models/task_attachment_test.go
Normal file
152
pkg/models/task_attachment_test.go
Normal file
|
@ -0,0 +1,152 @@
|
|||
// Copyright 2019 Vikunja and contriubtors. All rights reserved.
|
||||
//
|
||||
// This file is part of Vikunja.
|
||||
//
|
||||
// Vikunja is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Vikunja is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Vikunja. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
package models
|
||||
|
||||
import (
|
||||
"code.vikunja.io/api/pkg/config"
|
||||
"code.vikunja.io/api/pkg/files"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"io"
|
||||
"os"
|
||||
"strconv"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestTaskAttachment_ReadOne(t *testing.T) {
|
||||
t.Run("Normal File", func(t *testing.T) {
|
||||
files.InitTestFileFixtures(t)
|
||||
ta := &TaskAttachment{
|
||||
ID: 1,
|
||||
}
|
||||
err := ta.ReadOne()
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, ta.File)
|
||||
assert.True(t, ta.File.ID == ta.FileID && ta.FileID != 0)
|
||||
|
||||
// Load the actual attachment file and check its content
|
||||
err = ta.File.LoadFileByID()
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, config.FilesBasePath.GetString()+"/1", ta.File.File.Name())
|
||||
content := make([]byte, 9)
|
||||
read, err := ta.File.File.Read(content)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 9, read)
|
||||
assert.Equal(t, []byte("testfile1"), content)
|
||||
})
|
||||
t.Run("Nonexisting Attachment", func(t *testing.T) {
|
||||
files.InitTestFileFixtures(t)
|
||||
ta := &TaskAttachment{
|
||||
ID: 9999,
|
||||
}
|
||||
err := ta.ReadOne()
|
||||
assert.Error(t, err)
|
||||
assert.True(t, IsErrTaskAttachmentDoesNotExist(err))
|
||||
})
|
||||
t.Run("Existing Attachment, Nonexisting File", func(t *testing.T) {
|
||||
files.InitTestFileFixtures(t)
|
||||
ta := &TaskAttachment{
|
||||
ID: 2,
|
||||
}
|
||||
err := ta.ReadOne()
|
||||
assert.Error(t, err)
|
||||
assert.EqualError(t, err, "file 9999 does not exist")
|
||||
})
|
||||
}
|
||||
|
||||
type testfile struct {
|
||||
content []byte
|
||||
done bool
|
||||
}
|
||||
|
||||
func (t *testfile) Read(p []byte) (n int, err error) {
|
||||
if t.done {
|
||||
return 0, io.EOF
|
||||
}
|
||||
copy(p, t.content)
|
||||
t.done = true
|
||||
return len(p), nil
|
||||
}
|
||||
|
||||
func (t *testfile) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestTaskAttachment_NewAttachment(t *testing.T) {
|
||||
files.InitTestFileFixtures(t)
|
||||
// Assert the file is being stored correctly
|
||||
ta := TaskAttachment{
|
||||
TaskID: 1,
|
||||
}
|
||||
tf := &testfile{
|
||||
content: []byte("testingstuff"),
|
||||
}
|
||||
testuser := &User{ID: 1}
|
||||
|
||||
err := ta.NewAttachment(tf, "testfile", 100, testuser)
|
||||
assert.NoError(t, err)
|
||||
assert.NotEqual(t, 0, ta.FileID)
|
||||
_, err = files.FileStat("files/" + strconv.FormatInt(ta.FileID, 10))
|
||||
assert.NoError(t, err)
|
||||
assert.False(t, os.IsNotExist(err))
|
||||
assert.Equal(t, testuser.ID, ta.CreatedByID)
|
||||
|
||||
// Check the file was inserted correctly
|
||||
ta.File = &files.File{ID: ta.FileID}
|
||||
err = ta.File.LoadFileMetaByID()
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, testuser.ID, ta.File.CreatedByID)
|
||||
assert.Equal(t, "testfile", ta.File.Name)
|
||||
assert.Equal(t, int64(100), ta.File.Size)
|
||||
|
||||
// Extra test for max size test
|
||||
}
|
||||
|
||||
func TestTaskAttachment_ReadAll(t *testing.T) {
|
||||
files.InitTestFileFixtures(t)
|
||||
ta := &TaskAttachment{TaskID: 1}
|
||||
as, err := ta.ReadAll("", &User{ID: 1}, 0)
|
||||
attachments, _ := as.([]*TaskAttachment)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, attachments, 3)
|
||||
assert.Equal(t, "test", attachments[0].File.Name)
|
||||
}
|
||||
|
||||
func TestTaskAttachment_Delete(t *testing.T) {
|
||||
files.InitTestFileFixtures(t)
|
||||
t.Run("Normal", func(t *testing.T) {
|
||||
ta := &TaskAttachment{ID: 1}
|
||||
err := ta.Delete()
|
||||
assert.NoError(t, err)
|
||||
// Check if the file itself was deleted
|
||||
_, err = files.FileStat("/1") // The new file has the id 2 since it's the second attachment
|
||||
assert.True(t, os.IsNotExist(err))
|
||||
})
|
||||
t.Run("Nonexisting", func(t *testing.T) {
|
||||
files.InitTestFileFixtures(t)
|
||||
ta := &TaskAttachment{ID: 9999}
|
||||
err := ta.Delete()
|
||||
assert.Error(t, err)
|
||||
assert.True(t, IsErrTaskAttachmentDoesNotExist(err))
|
||||
})
|
||||
t.Run("Existing attachment, nonexisting file", func(t *testing.T) {
|
||||
files.InitTestFileFixtures(t)
|
||||
ta := &TaskAttachment{ID: 2}
|
||||
err := ta.Delete()
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
}
|
|
@ -7,6 +7,8 @@
|
|||
package models
|
||||
|
||||
import (
|
||||
"code.vikunja.io/api/pkg/db"
|
||||
"code.vikunja.io/api/pkg/files"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"gopkg.in/d4l3k/messagediff.v1"
|
||||
"sort"
|
||||
|
@ -67,6 +69,29 @@ func sortTasksForTesting(by SortBy) (tasks []*Task) {
|
|||
},
|
||||
},
|
||||
},
|
||||
Attachments: []*TaskAttachment{
|
||||
{
|
||||
ID: 1,
|
||||
TaskID: 1,
|
||||
FileID: 1,
|
||||
CreatedByID: 1,
|
||||
CreatedBy: user1,
|
||||
File: &files.File{
|
||||
ID: 1,
|
||||
Name: "test",
|
||||
Size: 100,
|
||||
CreatedUnix: 1570998791,
|
||||
CreatedByID: 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
ID: 2,
|
||||
TaskID: 1,
|
||||
FileID: 9999,
|
||||
CreatedByID: 1,
|
||||
CreatedBy: user1,
|
||||
},
|
||||
},
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
},
|
||||
|
@ -434,7 +459,7 @@ func sortTasksForTesting(by SortBy) (tasks []*Task) {
|
|||
}
|
||||
|
||||
func TestTask_ReadAll(t *testing.T) {
|
||||
assert.NoError(t, LoadFixtures())
|
||||
assert.NoError(t, db.LoadFixtures())
|
||||
|
||||
// Dummy users
|
||||
user1 := &User{
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
package models
|
||||
|
||||
import (
|
||||
"code.vikunja.io/api/pkg/files"
|
||||
"code.vikunja.io/api/pkg/metrics"
|
||||
"code.vikunja.io/api/pkg/utils"
|
||||
"code.vikunja.io/web"
|
||||
|
@ -71,6 +72,9 @@ type Task struct {
|
|||
// All related tasks, grouped by their relation kind
|
||||
RelatedTasks RelatedTaskMap `xorm:"-" json:"related_tasks"`
|
||||
|
||||
// All attachments this task has
|
||||
Attachments []*TaskAttachment `xorm:"-" json:"attachments"`
|
||||
|
||||
// A unix timestamp when this task was created. You cannot change this value.
|
||||
Created int64 `xorm:"created not null" json:"created"`
|
||||
// A unix timestamp when this task was last updated. You cannot change this value.
|
||||
|
@ -409,6 +413,28 @@ func addMoreInfoToTasks(taskMap map[int64]*Task) (tasks []*Task, err error) {
|
|||
}
|
||||
}
|
||||
|
||||
// Get task attachments
|
||||
attachments := []*TaskAttachment{}
|
||||
err = x.
|
||||
In("task_id", taskIDs).
|
||||
Find(&attachments)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
fileIDs := []int64{}
|
||||
for _, a := range attachments {
|
||||
userIDs = append(userIDs, a.CreatedByID)
|
||||
fileIDs = append(fileIDs, a.FileID)
|
||||
}
|
||||
|
||||
// Get all files
|
||||
fs := make(map[int64]*files.File)
|
||||
err = x.In("id", fileIDs).Find(&fs)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Get all users of a task
|
||||
// aka the ones who created a task
|
||||
users := make(map[int64]*User)
|
||||
|
@ -422,6 +448,13 @@ func addMoreInfoToTasks(taskMap map[int64]*Task) (tasks []*Task, err error) {
|
|||
u.Email = ""
|
||||
}
|
||||
|
||||
// Put the users and files in task attachments
|
||||
for _, a := range attachments {
|
||||
a.CreatedBy = users[a.CreatedByID]
|
||||
a.File = fs[a.FileID]
|
||||
taskMap[a.TaskID].Attachments = append(taskMap[a.TaskID].Attachments, a)
|
||||
}
|
||||
|
||||
// Get all reminders and put them in a map to have it easier later
|
||||
reminders := []*TaskReminder{}
|
||||
err = x.Table("task_reminders").In("task_id", taskIDs).Find(&reminders)
|
||||
|
|
|
@ -1,35 +0,0 @@
|
|||
// Vikunja is a todo-list application to facilitate your life.
|
||||
// Copyright 2018 Vikunja and contributors. All rights reserved.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
package models
|
||||
|
||||
import (
|
||||
"gopkg.in/testfixtures.v2"
|
||||
)
|
||||
|
||||
var fixtures *testfixtures.Context
|
||||
|
||||
// InitFixtures initialize test fixtures for a test database
|
||||
func InitFixtures(helper testfixtures.Helper, dir string) (err error) {
|
||||
testfixtures.SkipDatabaseNameCheck(true)
|
||||
fixtures, err = testfixtures.NewFolder(x.DB().DB, helper, dir)
|
||||
return err
|
||||
}
|
||||
|
||||
// LoadFixtures load fixtures for a test database
|
||||
func LoadFixtures() error {
|
||||
return fixtures.Load()
|
||||
}
|
|
@ -19,23 +19,16 @@ package models
|
|||
import (
|
||||
"code.vikunja.io/api/pkg/config"
|
||||
_ "code.vikunja.io/api/pkg/config" // To trigger its init() which initializes the config
|
||||
"code.vikunja.io/api/pkg/db"
|
||||
"code.vikunja.io/api/pkg/log"
|
||||
"code.vikunja.io/api/pkg/mail"
|
||||
"fmt"
|
||||
"github.com/go-xorm/core"
|
||||
"github.com/go-xorm/xorm"
|
||||
"gopkg.in/testfixtures.v2"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// MainTest creates the test engine
|
||||
func MainTest(m *testing.M, pathToRoot string) {
|
||||
SetupTests(pathToRoot)
|
||||
os.Exit(m.Run())
|
||||
}
|
||||
|
||||
// SetupTests takes care of seting up the db, fixtures etc.
|
||||
// This is an extra function to be able to call the fixtures setup from the integration tests.
|
||||
func SetupTests(pathToRoot string) {
|
||||
|
@ -49,7 +42,7 @@ func SetupTests(pathToRoot string) {
|
|||
mail.StartMailDaemon()
|
||||
|
||||
// Create test database
|
||||
if err = LoadFixtures(); err != nil {
|
||||
if err = db.LoadFixtures(); err != nil {
|
||||
log.Fatalf("Error preparing test database: %v", err.Error())
|
||||
}
|
||||
}
|
||||
|
@ -59,13 +52,12 @@ func createTestEngine(fixturesDir string) error {
|
|||
var fixturesHelper testfixtures.Helper = &testfixtures.SQLite{}
|
||||
// If set, use the config we provided instead of normal
|
||||
if os.Getenv("VIKUNJA_TESTS_USE_CONFIG") == "1" {
|
||||
config.InitConfig()
|
||||
err = SetEngine()
|
||||
x, err = db.CreateTestEngine()
|
||||
if err != nil {
|
||||
return err
|
||||
return fmt.Errorf("error getting test engine: %v", err)
|
||||
}
|
||||
|
||||
err = x.Sync2(GetTables()...)
|
||||
err = initSchema(x)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -74,23 +66,21 @@ func createTestEngine(fixturesDir string) error {
|
|||
fixturesHelper = &testfixtures.MySQL{}
|
||||
}
|
||||
} else {
|
||||
x, err = xorm.NewEngine("sqlite3", "file::memory:?cache=shared")
|
||||
x, err = db.CreateTestEngine()
|
||||
if err != nil {
|
||||
return err
|
||||
return fmt.Errorf("error getting test engine: %v", err)
|
||||
}
|
||||
|
||||
x.SetMapper(core.GonicMapper{})
|
||||
|
||||
// Sync dat shit
|
||||
if err := x.Sync2(GetTables()...); err != nil {
|
||||
err = initSchema(x)
|
||||
if err != nil {
|
||||
return fmt.Errorf("sync database struct error: %v", err)
|
||||
}
|
||||
|
||||
// Show SQL-Queries if necessary
|
||||
if os.Getenv("UNIT_TESTS_VERBOSE") == "1" {
|
||||
x.ShowSQL(true)
|
||||
}
|
||||
}
|
||||
|
||||
return InitFixtures(fixturesHelper, fixturesDir)
|
||||
return db.InitFixtures(fixturesHelper, fixturesDir)
|
||||
}
|
||||
|
||||
func initSchema(tx *xorm.Engine) error {
|
||||
return tx.Sync2(GetTables()...)
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package models
|
||||
|
||||
import (
|
||||
"code.vikunja.io/api/pkg/db"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"gopkg.in/d4l3k/messagediff.v1"
|
||||
"testing"
|
||||
|
@ -8,7 +9,7 @@ import (
|
|||
|
||||
func TestListUsersFromList(t *testing.T) {
|
||||
|
||||
err := LoadFixtures()
|
||||
err := db.LoadFixtures()
|
||||
assert.NoError(t, err)
|
||||
|
||||
testuser1 := &User{
|
||||
|
|
|
@ -28,6 +28,7 @@ type vikunjaInfos struct {
|
|||
FrontendURL string `json:"frontend_url"`
|
||||
Motd string `json:"motd"`
|
||||
LinkSharingEnabled bool `json:"link_sharing_enabled"`
|
||||
MaxFileSize int64 `json:"max_file_size"`
|
||||
}
|
||||
|
||||
// Info is the handler to get infos about this vikunja instance
|
||||
|
@ -43,5 +44,6 @@ func Info(c echo.Context) error {
|
|||
FrontendURL: config.ServiceFrontendurl.GetString(),
|
||||
Motd: config.ServiceMotd.GetString(),
|
||||
LinkSharingEnabled: config.ServiceEnableLinkSharing.GetBool(),
|
||||
MaxFileSize: config.FilesMaxSize.GetInt64(),
|
||||
})
|
||||
}
|
||||
|
|
|
@ -77,7 +77,7 @@ func getNamespace(c echo.Context) (namespace *models.Namespace, err error) {
|
|||
if err != nil {
|
||||
return
|
||||
}
|
||||
namespace.ID = namespaceID
|
||||
namespace = &models.Namespace{ID: namespaceID}
|
||||
canRead, err := namespace.CanRead(user)
|
||||
if err != nil {
|
||||
return namespace, err
|
||||
|
|
143
pkg/routes/api/v1/task_attachment.go
Normal file
143
pkg/routes/api/v1/task_attachment.go
Normal file
|
@ -0,0 +1,143 @@
|
|||
// Vikunja is a todo-list application to facilitate your life.
|
||||
// Copyright 2019 Vikunja and contributors. All rights reserved.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
package v1
|
||||
|
||||
import (
|
||||
"code.vikunja.io/api/pkg/models"
|
||||
"code.vikunja.io/web/handler"
|
||||
"github.com/labstack/echo/v4"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// UploadTaskAttachment handles everything needed for the upload of a task attachment
|
||||
// @Summary Upload a task attachment
|
||||
// @Description Upload a task attachment. You can pass multiple files with the files form param.
|
||||
// @tags task
|
||||
// @Accept mpfd
|
||||
// @Produce json
|
||||
// @Param id path int true "Task ID"
|
||||
// @Param files formData string true "The file, as multipart form file. You can pass multiple."
|
||||
// @Security JWTKeyAuth
|
||||
// @Success 200 {object} models.Message "Attachments were uploaded successfully."
|
||||
// @Failure 403 {object} models.Message "No access to the task."
|
||||
// @Failure 404 {object} models.Message "The task does not exist."
|
||||
// @Failure 500 {object} models.Message "Internal error"
|
||||
// @Router /tasks/{id}/attachments [put]
|
||||
func UploadTaskAttachment(c echo.Context) error {
|
||||
|
||||
var taskAttachment models.TaskAttachment
|
||||
if err := c.Bind(&taskAttachment); err != nil {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, "No task ID provided")
|
||||
}
|
||||
|
||||
// Rights check
|
||||
user, err := models.GetCurrentUser(c)
|
||||
if err != nil {
|
||||
return handler.HandleHTTPError(err, c)
|
||||
}
|
||||
can, err := taskAttachment.CanCreate(user)
|
||||
if err != nil {
|
||||
return handler.HandleHTTPError(err, c)
|
||||
}
|
||||
if !can {
|
||||
return echo.ErrForbidden
|
||||
}
|
||||
|
||||
// Multipart form
|
||||
form, err := c.MultipartForm()
|
||||
if err != nil {
|
||||
return handler.HandleHTTPError(err, c)
|
||||
}
|
||||
|
||||
type result struct {
|
||||
Errors []*echo.HTTPError `json:"errors"`
|
||||
Success []*models.TaskAttachment `json:"success"`
|
||||
}
|
||||
r := &result{}
|
||||
fileHeaders := form.File["files"]
|
||||
for _, file := range fileHeaders {
|
||||
// We create a new attachment object here to have a clean start
|
||||
ta := &models.TaskAttachment{
|
||||
TaskID: taskAttachment.TaskID,
|
||||
}
|
||||
|
||||
f, err := file.Open()
|
||||
if err != nil {
|
||||
r.Errors = append(r.Errors, handler.HandleHTTPError(err, c))
|
||||
continue
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
err = ta.NewAttachment(f, file.Filename, file.Size, user)
|
||||
if err != nil {
|
||||
r.Errors = append(r.Errors, handler.HandleHTTPError(err, c))
|
||||
continue
|
||||
}
|
||||
r.Success = append(r.Success, ta)
|
||||
}
|
||||
|
||||
return c.JSON(http.StatusOK, r)
|
||||
}
|
||||
|
||||
// GetTaskAttachment returns a task attachment to download for the user
|
||||
// @Summary Get one attachment.
|
||||
// @Description Get one attachment for download. **Returns json on error.**
|
||||
// @tags task
|
||||
// @Produce octet-stream
|
||||
// @Param id path int true "Task ID"
|
||||
// @Param attachmentID path int true "Attachment ID"
|
||||
// @Security JWTKeyAuth
|
||||
// @Success 200 {} string "The attachment file."
|
||||
// @Failure 403 {object} models.Message "No access to this task."
|
||||
// @Failure 404 {object} models.Message "The task does not exist."
|
||||
// @Failure 500 {object} models.Message "Internal error"
|
||||
// @Router /tasks/{id}/attachments/{attachmentID} [get]
|
||||
func GetTaskAttachment(c echo.Context) error {
|
||||
|
||||
var taskAttachment models.TaskAttachment
|
||||
if err := c.Bind(&taskAttachment); err != nil {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, "No task ID provided")
|
||||
}
|
||||
|
||||
// Rights check
|
||||
user, err := models.GetCurrentUser(c)
|
||||
if err != nil {
|
||||
return handler.HandleHTTPError(err, c)
|
||||
}
|
||||
can, err := taskAttachment.CanRead(user)
|
||||
if err != nil {
|
||||
return handler.HandleHTTPError(err, c)
|
||||
}
|
||||
if !can {
|
||||
return echo.ErrForbidden
|
||||
}
|
||||
|
||||
// Get the attachment incl file
|
||||
err = taskAttachment.ReadOne()
|
||||
if err != nil {
|
||||
return handler.HandleHTTPError(err, c)
|
||||
}
|
||||
|
||||
// Open an send the file to the client
|
||||
err = taskAttachment.File.LoadFileByID()
|
||||
if err != nil {
|
||||
return handler.HandleHTTPError(err, c)
|
||||
}
|
||||
|
||||
http.ServeContent(c.Response(), c.Request(), taskAttachment.File.Name, taskAttachment.File.Created, taskAttachment.File.File)
|
||||
return nil
|
||||
}
|
|
@ -17,7 +17,7 @@
|
|||
// @title Vikunja API
|
||||
// @description This is the documentation for the [Vikunja](http://vikunja.io) API. Vikunja is a cross-plattform Todo-application with a lot of features, such as sharing lists with users or teams. <!-- ReDoc-Inject: <security-definitions> -->
|
||||
// @description # Authorization
|
||||
// @description **JWT-Auth:** Main authorization method, used for most of the requests. Needs ` + "`" + `Authorization: Bearer <jwt-token>` + "`" + `-header to authenticate successfully.
|
||||
// @description **JWT-Auth:** Main authorization method, used for most of the requests. Needs `Authorization: Bearer <jwt-token>`-header to authenticate successfully.
|
||||
// @description
|
||||
// @description **BasicAuth:** Only used when requesting tasks via caldav.
|
||||
// @description <!-- ReDoc-Inject: <security-definitions> -->
|
||||
|
@ -266,6 +266,16 @@ func registerAPIRoutes(a *echo.Group) {
|
|||
a.PUT("/tasks/:task/relations", taskRelationHandler.CreateWeb)
|
||||
a.DELETE("/tasks/:task/relations", taskRelationHandler.DeleteWeb)
|
||||
|
||||
taskAttachmentHandler := &handler.WebHandler{
|
||||
EmptyStruct: func() handler.CObject {
|
||||
return &models.TaskAttachment{}
|
||||
},
|
||||
}
|
||||
a.GET("/tasks/:task/attachments", taskAttachmentHandler.ReadAllWeb)
|
||||
a.DELETE("/tasks/:task/attachments/:attachment", taskAttachmentHandler.DeleteWeb)
|
||||
a.PUT("/tasks/:task/attachments", apiv1.UploadTaskAttachment)
|
||||
a.GET("/tasks/:task/attachments/:attachment", apiv1.GetTaskAttachment)
|
||||
|
||||
labelHandler := &handler.WebHandler{
|
||||
EmptyStruct: func() handler.CObject {
|
||||
return &models.Label{}
|
||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
16
vendor/github.com/KyleBanks/depth/.gitignore
generated
vendored
Normal file
16
vendor/github.com/KyleBanks/depth/.gitignore
generated
vendored
Normal file
|
@ -0,0 +1,16 @@
|
|||
# Binaries for programs and plugins
|
||||
*.exe
|
||||
*.dll
|
||||
*.so
|
||||
*.dylib
|
||||
|
||||
# Test binary, build with `go test -c`
|
||||
*.test
|
||||
|
||||
# Output of the go coverage tool, specifically when used with LiteIDE
|
||||
*.out
|
||||
|
||||
# Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736
|
||||
.glide/
|
||||
|
||||
bin/
|
9
vendor/github.com/KyleBanks/depth/.travis.yml
generated
vendored
Normal file
9
vendor/github.com/KyleBanks/depth/.travis.yml
generated
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
language: go
|
||||
sudo: false
|
||||
go:
|
||||
- 1.9.x
|
||||
before_install:
|
||||
- go get github.com/mattn/goveralls
|
||||
script:
|
||||
- $HOME/gopath/bin/goveralls -service=travis-ci
|
||||
#script: go test $(go list ./... | grep -v vendor/)
|
21
vendor/github.com/KyleBanks/depth/LICENSE
generated
vendored
Normal file
21
vendor/github.com/KyleBanks/depth/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2017 Kyle Banks
|
||||
|
||||
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.
|
32
vendor/github.com/KyleBanks/depth/Makefile
generated
vendored
Normal file
32
vendor/github.com/KyleBanks/depth/Makefile
generated
vendored
Normal file
|
@ -0,0 +1,32 @@
|
|||
VERSION = 1.2.1
|
||||
|
||||
RELEASE_PKG = ./cmd/depth
|
||||
INSTALL_PKG = $(RELEASE_PKG)
|
||||
|
||||
|
||||
# Remote includes require 'mmake'
|
||||
# github.com/tj/mmake
|
||||
include github.com/KyleBanks/make/go/install
|
||||
include github.com/KyleBanks/make/go/sanity
|
||||
include github.com/KyleBanks/make/go/release
|
||||
include github.com/KyleBanks/make/go/bench
|
||||
include github.com/KyleBanks/make/git/precommit
|
||||
|
||||
# Runs a number of depth commands as examples of what's possible.
|
||||
example: | install
|
||||
depth github.com/KyleBanks/depth/cmd/depth strings ./
|
||||
|
||||
depth -internal strings
|
||||
|
||||
depth -json github.com/KyleBanks/depth/cmd/depth
|
||||
|
||||
depth -test github.com/KyleBanks/depth/cmd/depth
|
||||
|
||||
depth -test -internal strings
|
||||
|
||||
depth -test -internal -max 3 strings
|
||||
|
||||
depth .
|
||||
|
||||
depth ./cmd/depth
|
||||
.PHONY: example
|
232
vendor/github.com/KyleBanks/depth/README.md
generated
vendored
Normal file
232
vendor/github.com/KyleBanks/depth/README.md
generated
vendored
Normal file
|
@ -0,0 +1,232 @@
|
|||
# depth
|
||||
|
||||
[![GoDoc](https://godoc.org/github.com/KyleBanks/depth?status.svg)](https://godoc.org/github.com/KyleBanks/depth)
|
||||
[![Build Status](https://travis-ci.org/KyleBanks/depth.svg?branch=master)](https://travis-ci.org/KyleBanks/depth)
|
||||
[![Go Report Card](https://goreportcard.com/badge/github.com/KyleBanks/depth)](https://goreportcard.com/report/github.com/KyleBanks/depth)
|
||||
[![Coverage Status](https://coveralls.io/repos/github/KyleBanks/depth/badge.svg?branch=master)](https://coveralls.io/github/KyleBanks/depth?branch=master)
|
||||
|
||||
`depth` is tool to retrieve and visualize Go source code dependency trees.
|
||||
|
||||
## Install
|
||||
|
||||
Download the appropriate binary for your platform from the [Releases](https://github.com/KyleBanks/depth/releases) page, or:
|
||||
|
||||
```sh
|
||||
go get github.com/KyleBanks/depth/cmd/depth
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
`depth` can be used as a standalone command-line application, or as a package within your own project.
|
||||
|
||||
### Command-Line
|
||||
|
||||
Simply execute `depth` with one or more package names to visualize. You can use the fully qualified import path of the package, like so:
|
||||
|
||||
```sh
|
||||
$ depth github.com/KyleBanks/depth/cmd/depth
|
||||
github.com/KyleBanks/depth/cmd/depth
|
||||
├ encoding/json
|
||||
├ flag
|
||||
├ fmt
|
||||
├ io
|
||||
├ log
|
||||
├ os
|
||||
├ strings
|
||||
└ github.com/KyleBanks/depth
|
||||
├ fmt
|
||||
├ go/build
|
||||
├ path
|
||||
├ sort
|
||||
└ strings
|
||||
12 dependencies (11 internal, 1 external, 0 testing).
|
||||
```
|
||||
|
||||
Or you can use a relative path, for example:
|
||||
|
||||
```sh
|
||||
$ depth .
|
||||
$ depth ./cmd/depth
|
||||
$ depth ../
|
||||
```
|
||||
|
||||
You can also use `depth` on the Go standard library:
|
||||
|
||||
```sh
|
||||
$ depth strings
|
||||
strings
|
||||
├ errors
|
||||
├ io
|
||||
├ unicode
|
||||
└ unicode/utf8
|
||||
5 dependencies (5 internal, 0 external, 0 testing).
|
||||
```
|
||||
|
||||
Visualizing multiple packages at a time is supported by simply naming the packages you'd like to visualize:
|
||||
|
||||
```sh
|
||||
$ depth strings github.com/KyleBanks/depth
|
||||
strings
|
||||
├ errors
|
||||
├ io
|
||||
├ unicode
|
||||
└ unicode/utf8
|
||||
5 dependencies (5 internal, 0 external, 0 testing).
|
||||
github.com/KyleBanks/depth
|
||||
├ fmt
|
||||
├ go/build
|
||||
├ path
|
||||
├ sort
|
||||
└ strings
|
||||
7 dependencies (7 internal, 0 external, 0 testing).
|
||||
```
|
||||
|
||||
#### `-internal`
|
||||
|
||||
By default, `depth` only resolves the top level of dependencies for standard library packages, however you can use the `-internal` flag to visualize all internal dependencies:
|
||||
|
||||
```sh
|
||||
$ depth -internal strings
|
||||
strings
|
||||
├ errors
|
||||
├ io
|
||||
├ errors
|
||||
└ sync
|
||||
├ internal/race
|
||||
└ unsafe
|
||||
├ runtime
|
||||
├ runtime/internal/atomic
|
||||
└ unsafe
|
||||
├ runtime/internal/sys
|
||||
└ unsafe
|
||||
├ sync/atomic
|
||||
└ unsafe
|
||||
└ unsafe
|
||||
├ unicode
|
||||
└ unicode/utf8
|
||||
12 dependencies (12 internal, 0 external, 0 testing).
|
||||
```
|
||||
|
||||
#### `-max`
|
||||
|
||||
The `-max` flag limits the dependency tree to the maximum depth provided. For example, if you supply `-max 1` on the `depth` package, your output would look like so:
|
||||
|
||||
```
|
||||
$ depth -max 1 github.com/KyleBanks/depth/cmd/depth
|
||||
github.com/KyleBanks/depth/cmd/depth
|
||||
├ encoding/json
|
||||
├ flag
|
||||
├ fmt
|
||||
├ io
|
||||
├ log
|
||||
├ os
|
||||
├ strings
|
||||
└ github.com/KyleBanks/depth
|
||||
7 dependencies (6 internal, 1 external, 0 testing).
|
||||
```
|
||||
|
||||
The `-max` flag is particularly useful in conjunction with the `-internal` flag which can lead to very deep dependency trees.
|
||||
|
||||
#### `-test`
|
||||
|
||||
By default, `depth` ignores dependencies that are only required for testing. However, you can view test dependencies using the `-test` flag:
|
||||
|
||||
```sh
|
||||
$ depth -test strings
|
||||
strings
|
||||
├ bytes
|
||||
├ errors
|
||||
├ fmt
|
||||
├ io
|
||||
├ io/ioutil
|
||||
├ math/rand
|
||||
├ reflect
|
||||
├ sync
|
||||
├ testing
|
||||
├ unicode
|
||||
├ unicode/utf8
|
||||
└ unsafe
|
||||
13 dependencies (13 internal, 0 external, 8 testing).
|
||||
```
|
||||
|
||||
#### `-explain target-package`
|
||||
|
||||
The `-explain` flag instructs `depth` to print import chains in which the
|
||||
`target-package` is found:
|
||||
|
||||
```sh
|
||||
$ depth -explain strings github.com/KyleBanks/depth/cmd/depth
|
||||
github.com/KyleBanks/depth/cmd/depth -> strings
|
||||
github.com/KyleBanks/depth/cmd/depth -> github.com/KyleBanks/depth -> strings
|
||||
```
|
||||
|
||||
#### `-json`
|
||||
|
||||
The `-json` flag instructs `depth` to output dependencies in JSON format:
|
||||
|
||||
```sh
|
||||
$ depth -json github.com/KyleBanks/depth/cmd/depth
|
||||
{
|
||||
"name": "github.com/KyleBanks/depth/cmd/depth",
|
||||
"deps": [
|
||||
{
|
||||
"name": "encoding/json",
|
||||
"internal": true,
|
||||
"deps": null
|
||||
},
|
||||
...
|
||||
{
|
||||
"name": "github.com/KyleBanks/depth",
|
||||
"internal": false,
|
||||
"deps": [
|
||||
{
|
||||
"name": "go/build",
|
||||
"internal": true,
|
||||
"deps": null
|
||||
},
|
||||
...
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Integrating With Your Project
|
||||
|
||||
The `depth` package can easily be used to retrieve the dependency tree for a particular package in your own project. For example, here's how you would retrieve the dependency tree for the `strings` package:
|
||||
|
||||
```go
|
||||
import "github.com/KyleBanks/depth"
|
||||
|
||||
var t depth.Tree
|
||||
err := t.Resolve("strings")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// Output: "'strings' has 4 dependencies."
|
||||
log.Printf("'%v' has %v dependencies.", t.Root.Name, len(t.Root.Deps))
|
||||
```
|
||||
|
||||
For additional customization, simply set the appropriate flags on the `Tree` before resolving:
|
||||
|
||||
```go
|
||||
import "github.com/KyleBanks/depth"
|
||||
|
||||
t := depth.Tree {
|
||||
ResolveInternal: true,
|
||||
ResolveTest: true,
|
||||
MaxDepth: 10,
|
||||
}
|
||||
|
||||
|
||||
err := t.Resolve("strings")
|
||||
```
|
||||
|
||||
## Author
|
||||
|
||||
`depth` was developed by [Kyle Banks](https://twitter.com/kylewbanks).
|
||||
|
||||
## License
|
||||
|
||||
`depth` is available under the [MIT](./LICENSE) license.
|
129
vendor/github.com/KyleBanks/depth/depth.go
generated
vendored
Normal file
129
vendor/github.com/KyleBanks/depth/depth.go
generated
vendored
Normal file
|
@ -0,0 +1,129 @@
|
|||
// Package depth provides the ability to traverse and retrieve Go source code dependencies in the form of
|
||||
// internal and external packages.
|
||||
//
|
||||
// For example, the dependencies of the stdlib `strings` package can be resolved like so:
|
||||
//
|
||||
// import "github.com/KyleBanks/depth"
|
||||
//
|
||||
// var t depth.Tree
|
||||
// err := t.Resolve("strings")
|
||||
// if err != nil {
|
||||
// log.Fatal(err)
|
||||
// }
|
||||
//
|
||||
// // Output: "strings has 4 dependencies."
|
||||
// log.Printf("%v has %v dependencies.", t.Root.Name, len(t.Root.Deps))
|
||||
//
|
||||
// For additional customization, simply set the appropriate flags on the `Tree` before resolving:
|
||||
//
|
||||
// import "github.com/KyleBanks/depth"
|
||||
//
|
||||
// t := depth.Tree {
|
||||
// ResolveInternal: true,
|
||||
// ResolveTest: true,
|
||||
// MaxDepth: 10,
|
||||
// }
|
||||
// err := t.Resolve("strings")
|
||||
package depth
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"go/build"
|
||||
"os"
|
||||
)
|
||||
|
||||
// ErrRootPkgNotResolved is returned when the root Pkg of the Tree cannot be resolved,
|
||||
// typically because it does not exist.
|
||||
var ErrRootPkgNotResolved = errors.New("unable to resolve root package")
|
||||
|
||||
// Importer defines a type that can import a package and return its details.
|
||||
type Importer interface {
|
||||
Import(name, srcDir string, im build.ImportMode) (*build.Package, error)
|
||||
}
|
||||
|
||||
// Tree represents the top level of a Pkg and the configuration used to
|
||||
// initialize and represent its contents.
|
||||
type Tree struct {
|
||||
Root *Pkg
|
||||
|
||||
ResolveInternal bool
|
||||
ResolveTest bool
|
||||
MaxDepth int
|
||||
|
||||
Importer Importer
|
||||
|
||||
importCache map[string]struct{}
|
||||
}
|
||||
|
||||
// Resolve recursively finds all dependencies for the root Pkg name provided,
|
||||
// and the packages it depends on.
|
||||
func (t *Tree) Resolve(name string) error {
|
||||
pwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
t.Root = &Pkg{
|
||||
Name: name,
|
||||
Tree: t,
|
||||
SrcDir: pwd,
|
||||
Test: false,
|
||||
}
|
||||
|
||||
// Reset the import cache each time to ensure a reused Tree doesn't
|
||||
// reuse the same cache.
|
||||
t.importCache = nil
|
||||
|
||||
// Allow custom importers, but use build.Default if none is provided.
|
||||
if t.Importer == nil {
|
||||
t.Importer = &build.Default
|
||||
}
|
||||
|
||||
t.Root.Resolve(t.Importer)
|
||||
if !t.Root.Resolved {
|
||||
return ErrRootPkgNotResolved
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// shouldResolveInternal determines if internal packages should be further resolved beyond the
|
||||
// current parent.
|
||||
//
|
||||
// For example, if the parent Pkg is `github.com/foo/bar` and true is returned, all the
|
||||
// internal dependencies it relies on will be resolved. If for example `strings` is one of those
|
||||
// dependencies, and it is passed as the parent here, false may be returned and its internal
|
||||
// dependencies will not be resolved.
|
||||
func (t *Tree) shouldResolveInternal(parent *Pkg) bool {
|
||||
if t.ResolveInternal {
|
||||
return true
|
||||
}
|
||||
|
||||
return parent == t.Root
|
||||
}
|
||||
|
||||
// isAtMaxDepth returns true when the depth of the Pkg provided is at or beyond the maximum
|
||||
// depth allowed by the tree.
|
||||
//
|
||||
// If the Tree has a MaxDepth of zero, true is never returned.
|
||||
func (t *Tree) isAtMaxDepth(p *Pkg) bool {
|
||||
if t.MaxDepth == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
return p.depth() >= t.MaxDepth
|
||||
}
|
||||
|
||||
// hasSeenImport returns true if the import name provided has already been seen within the tree.
|
||||
// This function only returns false for a name once.
|
||||
func (t *Tree) hasSeenImport(name string) bool {
|
||||
if t.importCache == nil {
|
||||
t.importCache = make(map[string]struct{})
|
||||
}
|
||||
|
||||
if _, ok := t.importCache[name]; ok {
|
||||
return true
|
||||
}
|
||||
t.importCache[name] = struct{}{}
|
||||
return false
|
||||
}
|
184
vendor/github.com/KyleBanks/depth/pkg.go
generated
vendored
Normal file
184
vendor/github.com/KyleBanks/depth/pkg.go
generated
vendored
Normal file
|
@ -0,0 +1,184 @@
|
|||
package depth
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"go/build"
|
||||
"path"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Pkg represents a Go source package, and its dependencies.
|
||||
type Pkg struct {
|
||||
Name string `json:"name"`
|
||||
SrcDir string `json:"-"`
|
||||
|
||||
Internal bool `json:"internal"`
|
||||
Resolved bool `json:"resolved"`
|
||||
Test bool `json:"-"`
|
||||
|
||||
Tree *Tree `json:"-"`
|
||||
Parent *Pkg `json:"-"`
|
||||
Deps []Pkg `json:"deps"`
|
||||
|
||||
Raw *build.Package `json:"-"`
|
||||
}
|
||||
|
||||
// Resolve recursively finds all dependencies for the Pkg and the packages it depends on.
|
||||
func (p *Pkg) Resolve(i Importer) {
|
||||
// Resolved is always true, regardless of if we skip the import,
|
||||
// it is only false if there is an error while importing.
|
||||
p.Resolved = true
|
||||
|
||||
name := p.cleanName()
|
||||
if name == "" {
|
||||
return
|
||||
}
|
||||
|
||||
// Stop resolving imports if we've reached max depth or found a duplicate.
|
||||
var importMode build.ImportMode
|
||||
if p.Tree.hasSeenImport(name) || p.Tree.isAtMaxDepth(p) {
|
||||
importMode = build.FindOnly
|
||||
}
|
||||
|
||||
pkg, err := i.Import(name, p.SrcDir, importMode)
|
||||
if err != nil {
|
||||
// TODO: Check the error type?
|
||||
p.Resolved = false
|
||||
return
|
||||
}
|
||||
p.Raw = pkg
|
||||
|
||||
// Update the name with the fully qualified import path.
|
||||
p.Name = pkg.ImportPath
|
||||
|
||||
// If this is an internal dependency, we may need to skip it.
|
||||
if pkg.Goroot {
|
||||
p.Internal = true
|
||||
if !p.Tree.shouldResolveInternal(p) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
//first we set the regular dependencies, then we add the test dependencies
|
||||
//sharing the same set. This allows us to mark all test-only deps linearly
|
||||
unique := make(map[string]struct{})
|
||||
p.setDeps(i, pkg.Imports, pkg.Dir, unique, false)
|
||||
if p.Tree.ResolveTest {
|
||||
p.setDeps(i, append(pkg.TestImports, pkg.XTestImports...), pkg.Dir, unique, true)
|
||||
}
|
||||
}
|
||||
|
||||
// setDeps takes a slice of import paths and the source directory they are relative to,
|
||||
// and creates the Deps of the Pkg. Each dependency is also further resolved prior to being added
|
||||
// to the Pkg.
|
||||
func (p *Pkg) setDeps(i Importer, imports []string, srcDir string, unique map[string]struct{}, isTest bool) {
|
||||
for _, imp := range imports {
|
||||
// Mostly for testing files where cyclic imports are allowed.
|
||||
if imp == p.Name {
|
||||
continue
|
||||
}
|
||||
|
||||
// Skip duplicates.
|
||||
if _, ok := unique[imp]; ok {
|
||||
continue
|
||||
}
|
||||
unique[imp] = struct{}{}
|
||||
|
||||
p.addDep(i, imp, srcDir, isTest)
|
||||
}
|
||||
|
||||
sort.Sort(byInternalAndName(p.Deps))
|
||||
}
|
||||
|
||||
// addDep creates a Pkg and it's dependencies from an imported package name.
|
||||
func (p *Pkg) addDep(i Importer, name string, srcDir string, isTest bool) {
|
||||
dep := Pkg{
|
||||
Name: name,
|
||||
SrcDir: srcDir,
|
||||
Tree: p.Tree,
|
||||
Parent: p,
|
||||
Test: isTest,
|
||||
}
|
||||
dep.Resolve(i)
|
||||
|
||||
p.Deps = append(p.Deps, dep)
|
||||
}
|
||||
|
||||
// isParent goes recursively up the chain of Pkgs to determine if the name provided is ever a
|
||||
// parent of the current Pkg.
|
||||
func (p *Pkg) isParent(name string) bool {
|
||||
if p.Parent == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
if p.Parent.Name == name {
|
||||
return true
|
||||
}
|
||||
|
||||
return p.Parent.isParent(name)
|
||||
}
|
||||
|
||||
// depth returns the depth of the Pkg within the Tree.
|
||||
func (p *Pkg) depth() int {
|
||||
if p.Parent == nil {
|
||||
return 0
|
||||
}
|
||||
|
||||
return p.Parent.depth() + 1
|
||||
}
|
||||
|
||||
// cleanName returns a cleaned version of the Pkg name used for resolving dependencies.
|
||||
//
|
||||
// If an empty string is returned, dependencies should not be resolved.
|
||||
func (p *Pkg) cleanName() string {
|
||||
name := p.Name
|
||||
|
||||
// C 'package' cannot be resolved.
|
||||
if name == "C" {
|
||||
return ""
|
||||
}
|
||||
|
||||
// Internal golang_org/* packages must be prefixed with vendor/
|
||||
//
|
||||
// Thanks to @davecheney for this:
|
||||
// https://github.com/davecheney/graphpkg/blob/master/main.go#L46
|
||||
if strings.HasPrefix(name, "golang_org") {
|
||||
name = path.Join("vendor", name)
|
||||
}
|
||||
|
||||
return name
|
||||
}
|
||||
|
||||
// String returns a string representation of the Pkg containing the Pkg name and status.
|
||||
func (p *Pkg) String() string {
|
||||
b := bytes.NewBufferString(p.Name)
|
||||
|
||||
if !p.Resolved {
|
||||
b.Write([]byte(" (unresolved)"))
|
||||
}
|
||||
|
||||
return b.String()
|
||||
}
|
||||
|
||||
// byInternalAndName ensures a slice of Pkgs are sorted such that the internal stdlib
|
||||
// packages are always above external packages (ie. github.com/whatever).
|
||||
type byInternalAndName []Pkg
|
||||
|
||||
func (b byInternalAndName) Len() int {
|
||||
return len(b)
|
||||
}
|
||||
|
||||
func (b byInternalAndName) Swap(i, j int) {
|
||||
b[i], b[j] = b[j], b[i]
|
||||
}
|
||||
|
||||
func (b byInternalAndName) Less(i, j int) bool {
|
||||
if b[i].Internal && !b[j].Internal {
|
||||
return true
|
||||
} else if !b[i].Internal && b[j].Internal {
|
||||
return false
|
||||
}
|
||||
|
||||
return b[i].Name < b[j].Name
|
||||
}
|
1
vendor/github.com/alecthomas/template/go.mod
generated
vendored
Normal file
1
vendor/github.com/alecthomas/template/go.mod
generated
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
module github.com/alecthomas/template
|
21
vendor/github.com/cpuguy83/go-md2man/v2/LICENSE.md
generated
vendored
Normal file
21
vendor/github.com/cpuguy83/go-md2man/v2/LICENSE.md
generated
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Brian Goff
|
||||
|
||||
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.
|
14
vendor/github.com/cpuguy83/go-md2man/v2/md2man/md2man.go
generated
vendored
Normal file
14
vendor/github.com/cpuguy83/go-md2man/v2/md2man/md2man.go
generated
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
package md2man
|
||||
|
||||
import (
|
||||
"github.com/russross/blackfriday/v2"
|
||||
)
|
||||
|
||||
// Render converts a markdown document into a roff formatted document.
|
||||
func Render(doc []byte) []byte {
|
||||
renderer := NewRoffRenderer()
|
||||
|
||||
return blackfriday.Run(doc,
|
||||
[]blackfriday.Option{blackfriday.WithRenderer(renderer),
|
||||
blackfriday.WithExtensions(renderer.GetExtensions())}...)
|
||||
}
|
345
vendor/github.com/cpuguy83/go-md2man/v2/md2man/roff.go
generated
vendored
Normal file
345
vendor/github.com/cpuguy83/go-md2man/v2/md2man/roff.go
generated
vendored
Normal file
|
@ -0,0 +1,345 @@
|
|||
package md2man
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/russross/blackfriday/v2"
|
||||
)
|
||||
|
||||
// roffRenderer implements the blackfriday.Renderer interface for creating
|
||||
// roff format (manpages) from markdown text
|
||||
type roffRenderer struct {
|
||||
extensions blackfriday.Extensions
|
||||
listCounters []int
|
||||
firstHeader bool
|
||||
defineTerm bool
|
||||
listDepth int
|
||||
}
|
||||
|
||||
const (
|
||||
titleHeader = ".TH "
|
||||
topLevelHeader = "\n\n.SH "
|
||||
secondLevelHdr = "\n.SH "
|
||||
otherHeader = "\n.SS "
|
||||
crTag = "\n"
|
||||
emphTag = "\\fI"
|
||||
emphCloseTag = "\\fP"
|
||||
strongTag = "\\fB"
|
||||
strongCloseTag = "\\fP"
|
||||
breakTag = "\n.br\n"
|
||||
paraTag = "\n.PP\n"
|
||||
hruleTag = "\n.ti 0\n\\l'\\n(.lu'\n"
|
||||
linkTag = "\n\\[la]"
|
||||
linkCloseTag = "\\[ra]"
|
||||
codespanTag = "\\fB\\fC"
|
||||
codespanCloseTag = "\\fR"
|
||||
codeTag = "\n.PP\n.RS\n\n.nf\n"
|
||||
codeCloseTag = "\n.fi\n.RE\n"
|
||||
quoteTag = "\n.PP\n.RS\n"
|
||||
quoteCloseTag = "\n.RE\n"
|
||||
listTag = "\n.RS\n"
|
||||
listCloseTag = "\n.RE\n"
|
||||
arglistTag = "\n.TP\n"
|
||||
tableStart = "\n.TS\nallbox;\n"
|
||||
tableEnd = ".TE\n"
|
||||
tableCellStart = "T{\n"
|
||||
tableCellEnd = "\nT}\n"
|
||||
)
|
||||
|
||||
// NewRoffRenderer creates a new blackfriday Renderer for generating roff documents
|
||||
// from markdown
|
||||
func NewRoffRenderer() *roffRenderer { // nolint: golint
|
||||
var extensions blackfriday.Extensions
|
||||
|
||||
extensions |= blackfriday.NoIntraEmphasis
|
||||
extensions |= blackfriday.Tables
|
||||
extensions |= blackfriday.FencedCode
|
||||
extensions |= blackfriday.SpaceHeadings
|
||||
extensions |= blackfriday.Footnotes
|
||||
extensions |= blackfriday.Titleblock
|
||||
extensions |= blackfriday.DefinitionLists
|
||||
return &roffRenderer{
|
||||
extensions: extensions,
|
||||
}
|
||||
}
|
||||
|
||||
// GetExtensions returns the list of extensions used by this renderer implementation
|
||||
func (r *roffRenderer) GetExtensions() blackfriday.Extensions {
|
||||
return r.extensions
|
||||
}
|
||||
|
||||
// RenderHeader handles outputting the header at document start
|
||||
func (r *roffRenderer) RenderHeader(w io.Writer, ast *blackfriday.Node) {
|
||||
// disable hyphenation
|
||||
out(w, ".nh\n")
|
||||
}
|
||||
|
||||
// RenderFooter handles outputting the footer at the document end; the roff
|
||||
// renderer has no footer information
|
||||
func (r *roffRenderer) RenderFooter(w io.Writer, ast *blackfriday.Node) {
|
||||
}
|
||||
|
||||
// RenderNode is called for each node in a markdown document; based on the node
|
||||
// type the equivalent roff output is sent to the writer
|
||||
func (r *roffRenderer) RenderNode(w io.Writer, node *blackfriday.Node, entering bool) blackfriday.WalkStatus {
|
||||
|
||||
var walkAction = blackfriday.GoToNext
|
||||
|
||||
switch node.Type {
|
||||
case blackfriday.Text:
|
||||
r.handleText(w, node, entering)
|
||||
case blackfriday.Softbreak:
|
||||
out(w, crTag)
|
||||
case blackfriday.Hardbreak:
|
||||
out(w, breakTag)
|
||||
case blackfriday.Emph:
|
||||
if entering {
|
||||
out(w, emphTag)
|
||||
} else {
|
||||
out(w, emphCloseTag)
|
||||
}
|
||||
case blackfriday.Strong:
|
||||
if entering {
|
||||
out(w, strongTag)
|
||||
} else {
|
||||
out(w, strongCloseTag)
|
||||
}
|
||||
case blackfriday.Link:
|
||||
if !entering {
|
||||
out(w, linkTag+string(node.LinkData.Destination)+linkCloseTag)
|
||||
}
|
||||
case blackfriday.Image:
|
||||
// ignore images
|
||||
walkAction = blackfriday.SkipChildren
|
||||
case blackfriday.Code:
|
||||
out(w, codespanTag)
|
||||
escapeSpecialChars(w, node.Literal)
|
||||
out(w, codespanCloseTag)
|
||||
case blackfriday.Document:
|
||||
break
|
||||
case blackfriday.Paragraph:
|
||||
// roff .PP markers break lists
|
||||
if r.listDepth > 0 {
|
||||
return blackfriday.GoToNext
|
||||
}
|
||||
if entering {
|
||||
out(w, paraTag)
|
||||
} else {
|
||||
out(w, crTag)
|
||||
}
|
||||
case blackfriday.BlockQuote:
|
||||
if entering {
|
||||
out(w, quoteTag)
|
||||
} else {
|
||||
out(w, quoteCloseTag)
|
||||
}
|
||||
case blackfriday.Heading:
|
||||
r.handleHeading(w, node, entering)
|
||||
case blackfriday.HorizontalRule:
|
||||
out(w, hruleTag)
|
||||
case blackfriday.List:
|
||||
r.handleList(w, node, entering)
|
||||
case blackfriday.Item:
|
||||
r.handleItem(w, node, entering)
|
||||
case blackfriday.CodeBlock:
|
||||
out(w, codeTag)
|
||||
escapeSpecialChars(w, node.Literal)
|
||||
out(w, codeCloseTag)
|
||||
case blackfriday.Table:
|
||||
r.handleTable(w, node, entering)
|
||||
case blackfriday.TableCell:
|
||||
r.handleTableCell(w, node, entering)
|
||||
case blackfriday.TableHead:
|
||||
case blackfriday.TableBody:
|
||||
case blackfriday.TableRow:
|
||||
// no action as cell entries do all the nroff formatting
|
||||
return blackfriday.GoToNext
|
||||
default:
|
||||
fmt.Fprintln(os.Stderr, "WARNING: go-md2man does not handle node type "+node.Type.String())
|
||||
}
|
||||
return walkAction
|
||||
}
|
||||
|
||||
func (r *roffRenderer) handleText(w io.Writer, node *blackfriday.Node, entering bool) {
|
||||
var (
|
||||
start, end string
|
||||
)
|
||||
// handle special roff table cell text encapsulation
|
||||
if node.Parent.Type == blackfriday.TableCell {
|
||||
if len(node.Literal) > 30 {
|
||||
start = tableCellStart
|
||||
end = tableCellEnd
|
||||
} else {
|
||||
// end rows that aren't terminated by "tableCellEnd" with a cr if end of row
|
||||
if node.Parent.Next == nil && !node.Parent.IsHeader {
|
||||
end = crTag
|
||||
}
|
||||
}
|
||||
}
|
||||
out(w, start)
|
||||
escapeSpecialChars(w, node.Literal)
|
||||
out(w, end)
|
||||
}
|
||||
|
||||
func (r *roffRenderer) handleHeading(w io.Writer, node *blackfriday.Node, entering bool) {
|
||||
if entering {
|
||||
switch node.Level {
|
||||
case 1:
|
||||
if !r.firstHeader {
|
||||
out(w, titleHeader)
|
||||
r.firstHeader = true
|
||||
break
|
||||
}
|
||||
out(w, topLevelHeader)
|
||||
case 2:
|
||||
out(w, secondLevelHdr)
|
||||
default:
|
||||
out(w, otherHeader)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (r *roffRenderer) handleList(w io.Writer, node *blackfriday.Node, entering bool) {
|
||||
openTag := listTag
|
||||
closeTag := listCloseTag
|
||||
if node.ListFlags&blackfriday.ListTypeDefinition != 0 {
|
||||
// tags for definition lists handled within Item node
|
||||
openTag = ""
|
||||
closeTag = ""
|
||||
}
|
||||
if entering {
|
||||
r.listDepth++
|
||||
if node.ListFlags&blackfriday.ListTypeOrdered != 0 {
|
||||
r.listCounters = append(r.listCounters, 1)
|
||||
}
|
||||
out(w, openTag)
|
||||
} else {
|
||||
if node.ListFlags&blackfriday.ListTypeOrdered != 0 {
|
||||
r.listCounters = r.listCounters[:len(r.listCounters)-1]
|
||||
}
|
||||
out(w, closeTag)
|
||||
r.listDepth--
|
||||
}
|
||||
}
|
||||
|
||||
func (r *roffRenderer) handleItem(w io.Writer, node *blackfriday.Node, entering bool) {
|
||||
if entering {
|
||||
if node.ListFlags&blackfriday.ListTypeOrdered != 0 {
|
||||
out(w, fmt.Sprintf(".IP \"%3d.\" 5\n", r.listCounters[len(r.listCounters)-1]))
|
||||
r.listCounters[len(r.listCounters)-1]++
|
||||
} else if node.ListFlags&blackfriday.ListTypeDefinition != 0 {
|
||||
// state machine for handling terms and following definitions
|
||||
// since blackfriday does not distinguish them properly, nor
|
||||
// does it seperate them into separate lists as it should
|
||||
if !r.defineTerm {
|
||||
out(w, arglistTag)
|
||||
r.defineTerm = true
|
||||
} else {
|
||||
r.defineTerm = false
|
||||
}
|
||||
} else {
|
||||
out(w, ".IP \\(bu 2\n")
|
||||
}
|
||||
} else {
|
||||
out(w, "\n")
|
||||
}
|
||||
}
|
||||
|
||||
func (r *roffRenderer) handleTable(w io.Writer, node *blackfriday.Node, entering bool) {
|
||||
if entering {
|
||||
out(w, tableStart)
|
||||
//call walker to count cells (and rows?) so format section can be produced
|
||||
columns := countColumns(node)
|
||||
out(w, strings.Repeat("l ", columns)+"\n")
|
||||
out(w, strings.Repeat("l ", columns)+".\n")
|
||||
} else {
|
||||
out(w, tableEnd)
|
||||
}
|
||||
}
|
||||
|
||||
func (r *roffRenderer) handleTableCell(w io.Writer, node *blackfriday.Node, entering bool) {
|
||||
var (
|
||||
start, end string
|
||||
)
|
||||
if node.IsHeader {
|
||||
start = codespanTag
|
||||
end = codespanCloseTag
|
||||
}
|
||||
if entering {
|
||||
if node.Prev != nil && node.Prev.Type == blackfriday.TableCell {
|
||||
out(w, "\t"+start)
|
||||
} else {
|
||||
out(w, start)
|
||||
}
|
||||
} else {
|
||||
// need to carriage return if we are at the end of the header row
|
||||
if node.IsHeader && node.Next == nil {
|
||||
end = end + crTag
|
||||
}
|
||||
out(w, end)
|
||||
}
|
||||
}
|
||||
|
||||
// because roff format requires knowing the column count before outputting any table
|
||||
// data we need to walk a table tree and count the columns
|
||||
func countColumns(node *blackfriday.Node) int {
|
||||
var columns int
|
||||
|
||||
node.Walk(func(node *blackfriday.Node, entering bool) blackfriday.WalkStatus {
|
||||
switch node.Type {
|
||||
case blackfriday.TableRow:
|
||||
if !entering {
|
||||
return blackfriday.Terminate
|
||||
}
|
||||
case blackfriday.TableCell:
|
||||
if entering {
|
||||
columns++
|
||||
}
|
||||
default:
|
||||
}
|
||||
return blackfriday.GoToNext
|
||||
})
|
||||
return columns
|
||||
}
|
||||
|
||||
func out(w io.Writer, output string) {
|
||||
io.WriteString(w, output) // nolint: errcheck
|
||||
}
|
||||
|
||||
func needsBackslash(c byte) bool {
|
||||
for _, r := range []byte("-_&\\~") {
|
||||
if c == r {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func escapeSpecialChars(w io.Writer, text []byte) {
|
||||
for i := 0; i < len(text); i++ {
|
||||
// escape initial apostrophe or period
|
||||
if len(text) >= 1 && (text[0] == '\'' || text[0] == '.') {
|
||||
out(w, "\\&")
|
||||
}
|
||||
|
||||
// directly copy normal characters
|
||||
org := i
|
||||
|
||||
for i < len(text) && !needsBackslash(text[i]) {
|
||||
i++
|
||||
}
|
||||
if i > org {
|
||||
w.Write(text[org:i]) // nolint: errcheck
|
||||
}
|
||||
|
||||
// escape a character
|
||||
if i >= len(text) {
|
||||
break
|
||||
}
|
||||
|
||||
w.Write([]byte{'\\', text[i]}) // nolint: errcheck
|
||||
}
|
||||
}
|
10
vendor/github.com/go-openapi/jsonpointer/.travis.yml
generated
vendored
10
vendor/github.com/go-openapi/jsonpointer/.travis.yml
generated
vendored
|
@ -1,15 +1,15 @@
|
|||
after_success:
|
||||
- bash <(curl -s https://codecov.io/bash)
|
||||
go:
|
||||
- '1.9'
|
||||
- 1.10.x
|
||||
- 1.11.x
|
||||
- 1.12.x
|
||||
install:
|
||||
- go get -u github.com/stretchr/testify/assert
|
||||
- go get -u github.com/go-openapi/swag
|
||||
- GO111MODULE=off go get -u gotest.tools/gotestsum
|
||||
env:
|
||||
- GO111MODULE=on
|
||||
language: go
|
||||
notifications:
|
||||
slack:
|
||||
secure: a5VgoiwB1G/AZqzmephPZIhEB9avMlsWSlVnM1dSAtYAwdrQHGTQxAmpOxYIoSPDhWNN5bfZmjd29++UlTwLcHSR+e0kJhH6IfDlsHj/HplNCJ9tyI0zYc7XchtdKgeMxMzBKCzgwFXGSbQGydXTliDNBo0HOzmY3cou/daMFTP60K+offcjS+3LRAYb1EroSRXZqrk1nuF/xDL3792DZUdPMiFR/L/Df6y74D6/QP4sTkTDFQitz4Wy/7jbsfj8dG6qK2zivgV6/l+w4OVjFkxVpPXogDWY10vVXNVynqxfJ7to2d1I9lNCHE2ilBCkWMIPdyJF7hjF8pKW+82yP4EzRh0vu8Xn0HT5MZpQxdRY/YMxNrWaG7SxsoEaO4q5uhgdzAqLYY3TRa7MjIK+7Ur+aqOeTXn6OKwVi0CjvZ6mIU3WUKSwiwkFZMbjRAkSb5CYwMEfGFO/z964xz83qGt6WAtBXNotqCQpTIiKtDHQeLOMfksHImCg6JLhQcWBVxamVgu0G3Pdh8Y6DyPnxraXY95+QDavbjqv7TeYT9T/FNnrkXaTTK0s4iWE5H4ACU0Qvz0wUYgfQrZv0/Hp7V17+rabUwnzYySHCy9SWX/7OV9Cfh31iMp9ZIffr76xmmThtOEqs8TrTtU6BWI3rWwvA9cXQipZTVtL0oswrGw=
|
||||
script:
|
||||
- go test -v -race -cover -coverprofile=coverage.txt -covermode=atomic ./...
|
||||
- gotestsum -f short-verbose -- -race -coverprofile=coverage.txt -covermode=atomic ./...
|
||||
|
|
11
vendor/github.com/go-openapi/jsonpointer/go.mod
generated
vendored
11
vendor/github.com/go-openapi/jsonpointer/go.mod
generated
vendored
|
@ -1,10 +1,9 @@
|
|||
module github.com/go-openapi/jsonpointer
|
||||
|
||||
require (
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/go-openapi/swag v0.17.0
|
||||
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/stretchr/testify v1.2.2
|
||||
gopkg.in/yaml.v2 v2.2.1 // indirect
|
||||
github.com/go-openapi/swag v0.19.5
|
||||
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e // indirect
|
||||
github.com/stretchr/testify v1.3.0
|
||||
)
|
||||
|
||||
go 1.13
|
||||
|
|
27
vendor/github.com/go-openapi/jsonpointer/go.sum
generated
vendored
27
vendor/github.com/go-openapi/jsonpointer/go.sum
generated
vendored
|
@ -1,11 +1,24 @@
|
|||
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/go-openapi/swag v0.17.0 h1:7wu+dZ5k83kvUWeAb+WUkFiUhDzwGqzTR/NhWzeo1JU=
|
||||
github.com/go-openapi/swag v0.17.0/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I=
|
||||
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329 h1:2gxZ0XQIU/5z3Z3bUBu+FXuk2pFbkN6tcwi/pjyaDic=
|
||||
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY=
|
||||
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||
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/mailru/easyjson v0.0.0-20190614124828-94de47d64c63 h1:nTT4s92Dgz2HlrB2NaMgvlfqHH39OgMhA7z3PK7PGD4=
|
||||
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e h1:hB2xlXdHp/pmPZq0y3QnmWAArdw9PqbmotexnWx/FU8=
|
||||
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
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/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
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 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
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/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
|
|
2
vendor/github.com/go-openapi/jsonpointer/pointer.go
generated
vendored
2
vendor/github.com/go-openapi/jsonpointer/pointer.go
generated
vendored
|
@ -135,7 +135,7 @@ func getSingleImpl(node interface{}, decodedToken string, nameProvider *swag.Nam
|
|||
kv := reflect.ValueOf(decodedToken)
|
||||
mv := rValue.MapIndex(kv)
|
||||
|
||||
if mv.IsValid() && !swag.IsZero(mv) {
|
||||
if mv.IsValid() {
|
||||
return mv.Interface(), kind, nil
|
||||
}
|
||||
return nil, kind, fmt.Errorf("object has no key %q", decodedToken)
|
||||
|
|
11
vendor/github.com/go-openapi/jsonreference/.travis.yml
generated
vendored
11
vendor/github.com/go-openapi/jsonreference/.travis.yml
generated
vendored
|
@ -1,16 +1,15 @@
|
|||
after_success:
|
||||
- bash <(curl -s https://codecov.io/bash)
|
||||
go:
|
||||
- '1.9'
|
||||
- 1.10.x
|
||||
- 1.11.x
|
||||
- 1.12.x
|
||||
install:
|
||||
- go get -u github.com/stretchr/testify/assert
|
||||
- go get -u github.com/PuerkitoBio/purell
|
||||
- go get -u github.com/go-openapi/jsonpointer
|
||||
- GO111MODULE=off go get -u gotest.tools/gotestsum
|
||||
env:
|
||||
- GO111MODULE=on
|
||||
language: go
|
||||
notifications:
|
||||
slack:
|
||||
secure: OpQG/36F7DSF00HLm9WZMhyqFCYYyYTsVDObW226cWiR8PWYiNfLZiSEvIzT1Gx4dDjhigKTIqcLhG34CkL5iNXDjm9Yyo2RYhQPlK8NErNqUEXuBqn4RqYHW48VGhEhOyDd4Ei0E2FN5ZbgpvHgtpkdZ6XDi64r3Ac89isP9aPHXQTuv2Jog6b4/OKKiUTftLcTIst0p4Cp3gqOJWf1wnoj+IadWiECNVQT6zb47IYjtyw6+uV8iUjTzdKcRB6Zc6b4Dq7JAg1Zd7Jfxkql3hlKp4PNlRf9Cy7y5iA3G7MLyg3FcPX5z2kmcyPt2jOTRMBWUJ5zIQpOxizAcN8WsT3WWBL5KbuYK6k0PzujrIDLqdxGpNmjkkMfDBT9cKmZpm2FdW+oZgPFJP+oKmAo4u4KJz/vjiPTXgQlN5bmrLuRMCp+AwC5wkIohTqWZVPE2TK6ZSnMYcg/W39s+RP/9mJoyryAvPSpBOLTI+biCgaUCTOAZxNTWpMFc3tPYntc41WWkdKcooZ9JA5DwfcaVFyTGQ3YXz+HvX6G1z/gW0Q/A4dBi9mj2iE1xm7tRTT+4VQ2AXFvSEI1HJpfPgYnwAtwOD1v3Qm2EUHk9sCdtEDR4wVGEPIVn44GnwFMnGKx9JWppMPYwFu3SVDdHt+E+LOlhZUply11Aa+IVrT2KUQ=
|
||||
script:
|
||||
- go test -v -race -cover -coverprofile=coverage.txt -covermode=atomic ./...
|
||||
- gotestsum -f short-verbose -- -race -coverprofile=coverage.txt -covermode=atomic ./...
|
||||
|
|
17
vendor/github.com/go-openapi/jsonreference/go.mod
generated
vendored
17
vendor/github.com/go-openapi/jsonreference/go.mod
generated
vendored
|
@ -1,15 +1,12 @@
|
|||
module github.com/go-openapi/jsonreference
|
||||
|
||||
require (
|
||||
github.com/PuerkitoBio/purell v1.1.0
|
||||
github.com/PuerkitoBio/purell v1.1.1
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.17.0
|
||||
github.com/go-openapi/swag v0.17.0 // indirect
|
||||
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/stretchr/testify v1.2.2
|
||||
golang.org/x/net v0.0.0-20181005035420-146acd28ed58 // indirect
|
||||
golang.org/x/text v0.3.0 // indirect
|
||||
gopkg.in/yaml.v2 v2.2.1 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.19.3
|
||||
github.com/stretchr/testify v1.3.0
|
||||
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297 // indirect
|
||||
golang.org/x/text v0.3.2 // indirect
|
||||
)
|
||||
|
||||
go 1.13
|
||||
|
|
50
vendor/github.com/go-openapi/jsonreference/go.sum
generated
vendored
50
vendor/github.com/go-openapi/jsonreference/go.sum
generated
vendored
|
@ -1,20 +1,44 @@
|
|||
github.com/PuerkitoBio/purell v1.1.0 h1:rmGxhojJlM0tuKtfdvliR84CFHljx9ag64t2xmVkjK4=
|
||||
github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||
github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI=
|
||||
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||
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/go-openapi/jsonpointer v0.17.0 h1:Bpl2DtZ6k7wKqfFs7e+4P08+M9I3FQgn09a1UsRUQbk=
|
||||
github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0=
|
||||
github.com/go-openapi/swag v0.17.0 h1:7wu+dZ5k83kvUWeAb+WUkFiUhDzwGqzTR/NhWzeo1JU=
|
||||
github.com/go-openapi/swag v0.17.0/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I=
|
||||
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329 h1:2gxZ0XQIU/5z3Z3bUBu+FXuk2pFbkN6tcwi/pjyaDic=
|
||||
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/go-openapi/jsonpointer v0.19.2 h1:A9+F4Dc/MCNB5jibxf6rRvOvR/iFgQdyNx9eIhnGqq0=
|
||||
github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
|
||||
github.com/go-openapi/jsonpointer v0.19.3 h1:gihV7YNZK1iK6Tgwwsxo2rJbD1GTbdm72325Bq8FI3w=
|
||||
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||
github.com/go-openapi/swag v0.19.2 h1:jvO6bCMBEilGwMfHhrd61zIID4oIFdwb76V17SM88dE=
|
||||
github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||
github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY=
|
||||
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||
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/mailru/easyjson v0.0.0-20190614124828-94de47d64c63 h1:nTT4s92Dgz2HlrB2NaMgvlfqHH39OgMhA7z3PK7PGD4=
|
||||
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e h1:hB2xlXdHp/pmPZq0y3QnmWAArdw9PqbmotexnWx/FU8=
|
||||
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
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/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
golang.org/x/net v0.0.0-20181005035420-146acd28ed58 h1:otZG8yDCO4LVps5+9bxOeNiCvgmOyt96J3roHTYs7oE=
|
||||
golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
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=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980 h1:dfGZHvZk057jK2MCeWus/TowKpJ8y4AmooUzdBSR9GU=
|
||||
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297 h1:k7pJ2yAPLPgbskkFdhRCsA77k2fySZ1zf2zCjvQCiIM=
|
||||
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
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/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
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/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
|
|
2
vendor/github.com/go-openapi/spec/.golangci.yml
generated
vendored
2
vendor/github.com/go-openapi/spec/.golangci.yml
generated
vendored
|
@ -8,7 +8,7 @@ linters-settings:
|
|||
maligned:
|
||||
suggest-new: true
|
||||
dupl:
|
||||
threshold: 100
|
||||
threshold: 200
|
||||
goconst:
|
||||
min-len: 2
|
||||
min-occurrences: 2
|
||||
|
|
13
vendor/github.com/go-openapi/spec/.travis.yml
generated
vendored
13
vendor/github.com/go-openapi/spec/.travis.yml
generated
vendored
|
@ -1,18 +1,15 @@
|
|||
after_success:
|
||||
- bash <(curl -s https://codecov.io/bash)
|
||||
go:
|
||||
- '1.9'
|
||||
- 1.10.x
|
||||
- 1.11.x
|
||||
- 1.12.x
|
||||
install:
|
||||
- go get -u github.com/stretchr/testify
|
||||
- go get -u github.com/go-openapi/swag
|
||||
- go get -u gopkg.in/yaml.v2
|
||||
- go get -u github.com/go-openapi/jsonpointer
|
||||
- go get -u github.com/go-openapi/jsonreference
|
||||
- GO111MODULE=off go get -u gotest.tools/gotestsum
|
||||
env:
|
||||
- GO111MODULE=on
|
||||
language: go
|
||||
notifications:
|
||||
slack:
|
||||
secure: QUWvCkBBK09GF7YtEvHHVt70JOkdlNBG0nIKu/5qc4/nW5HP8I2w0SEf/XR2je0eED1Qe3L/AfMCWwrEj+IUZc3l4v+ju8X8R3Lomhme0Eb0jd1MTMCuPcBT47YCj0M7RON7vXtbFfm1hFJ/jLe5+9FXz0hpXsR24PJc5ZIi/ogNwkaPqG4BmndzecpSh0vc2FJPZUD9LT0I09REY/vXR0oQAalLkW0asGD5taHZTUZq/kBpsNxaAFrLM23i4mUcf33M5fjLpvx5LRICrX/57XpBrDh2TooBU6Qj3CgoY0uPRYUmSNxbVx1czNzl2JtEpb5yjoxfVPQeg0BvQM00G8LJINISR+ohrjhkZmAqchDupAX+yFrxTtORa78CtnIL6z/aTNlgwwVD8kvL/1pFA/JWYmKDmz93mV/+6wubGzNSQCstzjkFA4/iZEKewKUoRIAi/fxyscP6L/rCpmY/4llZZvrnyTqVbt6URWpopUpH4rwYqreXAtJxJsfBJIeSmUIiDIOMGkCTvyTEW3fWGmGoqWtSHLoaWDyAIGb7azb+KvfpWtEcoPFWfSWU+LGee0A/YsUhBl7ADB9A0CJEuR8q4BPpKpfLwPKSiKSAXL7zDkyjExyhtgqbSl2jS+rKIHOZNL8JkCcTP2MKMVd563C5rC5FMKqu3S9m2b6380E=
|
||||
script:
|
||||
- go test -v -race -cover -coverprofile=coverage.txt -covermode=atomic ./...
|
||||
- gotestsum -f short-verbose -- -race -coverprofile=coverage.txt -covermode=atomic ./...
|
||||
|
|
8
vendor/github.com/go-openapi/spec/bindata.go
generated
vendored
8
vendor/github.com/go-openapi/spec/bindata.go
generated
vendored
|
@ -21,7 +21,7 @@ import (
|
|||
func bindataRead(data []byte, name string) ([]byte, error) {
|
||||
gz, err := gzip.NewReader(bytes.NewBuffer(data))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Read %q: %v", name, err)
|
||||
return nil, fmt.Errorf("read %q: %v", name, err)
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
|
@ -29,7 +29,7 @@ func bindataRead(data []byte, name string) ([]byte, error) {
|
|||
clErr := gz.Close()
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Read %q: %v", name, err)
|
||||
return nil, fmt.Errorf("read %q: %v", name, err)
|
||||
}
|
||||
if clErr != nil {
|
||||
return nil, err
|
||||
|
@ -85,7 +85,7 @@ func jsonschemaDraft04JSON() (*asset, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "jsonschema-draft-04.json", size: 4357, mode: os.FileMode(436), modTime: time.Unix(1540282154, 0)}
|
||||
info := bindataFileInfo{name: "jsonschema-draft-04.json", size: 4357, mode: os.FileMode(0644), modTime: time.Unix(1567900649, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xe1, 0x48, 0x9d, 0xb, 0x47, 0x55, 0xf0, 0x27, 0x93, 0x30, 0x25, 0x91, 0xd3, 0xfc, 0xb8, 0xf0, 0x7b, 0x68, 0x93, 0xa8, 0x2a, 0x94, 0xf2, 0x48, 0x95, 0xf8, 0xe4, 0xed, 0xf1, 0x1b, 0x82, 0xe2}}
|
||||
return a, nil
|
||||
}
|
||||
|
@ -105,7 +105,7 @@ func v2SchemaJSON() (*asset, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "v2/schema.json", size: 40249, mode: os.FileMode(436), modTime: time.Unix(1540282154, 0)}
|
||||
info := bindataFileInfo{name: "v2/schema.json", size: 40249, mode: os.FileMode(0644), modTime: time.Unix(1567900649, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xcb, 0x25, 0x27, 0xe8, 0x46, 0xae, 0x22, 0xc4, 0xf4, 0x8b, 0x1, 0x32, 0x4d, 0x1f, 0xf8, 0xdf, 0x75, 0x15, 0xc8, 0x2d, 0xc7, 0xed, 0xe, 0x7e, 0x0, 0x75, 0xc0, 0xf9, 0xd2, 0x1f, 0x75, 0x57}}
|
||||
return a, nil
|
||||
}
|
||||
|
|
25
vendor/github.com/go-openapi/spec/go.mod
generated
vendored
25
vendor/github.com/go-openapi/spec/go.mod
generated
vendored
|
@ -1,16 +1,17 @@
|
|||
module github.com/go-openapi/spec
|
||||
|
||||
require (
|
||||
github.com/PuerkitoBio/purell v1.1.0 // indirect
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.17.0
|
||||
github.com/go-openapi/jsonreference v0.17.0
|
||||
github.com/go-openapi/swag v0.17.0
|
||||
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/stretchr/testify v1.2.2
|
||||
golang.org/x/net v0.0.0-20181005035420-146acd28ed58 // indirect
|
||||
golang.org/x/text v0.3.0 // indirect
|
||||
gopkg.in/yaml.v2 v2.2.1
|
||||
github.com/go-openapi/jsonpointer v0.19.3
|
||||
github.com/go-openapi/jsonreference v0.19.2
|
||||
github.com/go-openapi/swag v0.19.5
|
||||
github.com/kr/pty v1.1.5 // indirect
|
||||
github.com/stretchr/objx v0.2.0 // indirect
|
||||
github.com/stretchr/testify v1.3.0
|
||||
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8 // indirect
|
||||
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297 // indirect
|
||||
golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f // indirect
|
||||
golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59 // indirect
|
||||
gopkg.in/yaml.v2 v2.2.2
|
||||
)
|
||||
|
||||
go 1.13
|
||||
|
|
64
vendor/github.com/go-openapi/spec/go.sum
generated
vendored
64
vendor/github.com/go-openapi/spec/go.sum
generated
vendored
|
@ -1,22 +1,74 @@
|
|||
github.com/PuerkitoBio/purell v1.1.0 h1:rmGxhojJlM0tuKtfdvliR84CFHljx9ag64t2xmVkjK4=
|
||||
github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||
github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI=
|
||||
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||
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/go-openapi/jsonpointer v0.17.0 h1:Bpl2DtZ6k7wKqfFs7e+4P08+M9I3FQgn09a1UsRUQbk=
|
||||
github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0=
|
||||
github.com/go-openapi/jsonreference v0.17.0 h1:d/o7/fsLWWQZACbihvZxcyLQ59jfUVs7WOJv/ak7T7A=
|
||||
github.com/go-openapi/jsonreference v0.17.0/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg=
|
||||
github.com/go-openapi/swag v0.17.0 h1:7wu+dZ5k83kvUWeAb+WUkFiUhDzwGqzTR/NhWzeo1JU=
|
||||
github.com/go-openapi/swag v0.17.0/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I=
|
||||
github.com/go-openapi/jsonpointer v0.17.0 h1:nH6xp8XdXHx8dqveo0ZuJBluCO2qGrPbDNZ0dwoRHP0=
|
||||
github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
|
||||
github.com/go-openapi/jsonpointer v0.19.0 h1:FTUMcX77w5rQkClIzDtTxvn6Bsa894CcrzNj2MMfeg8=
|
||||
github.com/go-openapi/jsonpointer v0.19.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
|
||||
github.com/go-openapi/jsonpointer v0.19.2 h1:A9+F4Dc/MCNB5jibxf6rRvOvR/iFgQdyNx9eIhnGqq0=
|
||||
github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
|
||||
github.com/go-openapi/jsonpointer v0.19.3 h1:gihV7YNZK1iK6Tgwwsxo2rJbD1GTbdm72325Bq8FI3w=
|
||||
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||
github.com/go-openapi/jsonreference v0.19.0 h1:BqWKpV1dFd+AuiKlgtddwVIFQsuMpxfBDBHGfM2yNpk=
|
||||
github.com/go-openapi/jsonreference v0.19.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
|
||||
github.com/go-openapi/jsonreference v0.19.2 h1:o20suLFB4Ri0tuzpWtyHlh7E7HnkqTNLq6aR6WVNS1w=
|
||||
github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc=
|
||||
github.com/go-openapi/swag v0.17.0 h1:iqrgMg7Q7SvtbWLlltPrkMs0UBJI6oTSs79JFRUi880=
|
||||
github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
|
||||
github.com/go-openapi/swag v0.19.2 h1:jvO6bCMBEilGwMfHhrd61zIID4oIFdwb76V17SM88dE=
|
||||
github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||
github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY=
|
||||
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||
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/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
|
||||
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/mailru/easyjson v0.0.0-20180823135443-60711f1a8329 h1:2gxZ0XQIU/5z3Z3bUBu+FXuk2pFbkN6tcwi/pjyaDic=
|
||||
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63 h1:nTT4s92Dgz2HlrB2NaMgvlfqHH39OgMhA7z3PK7PGD4=
|
||||
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e h1:hB2xlXdHp/pmPZq0y3QnmWAArdw9PqbmotexnWx/FU8=
|
||||
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
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/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
||||
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
|
||||
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=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/net v0.0.0-20181005035420-146acd28ed58 h1:otZG8yDCO4LVps5+9bxOeNiCvgmOyt96J3roHTYs7oE=
|
||||
golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
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/net v0.0.0-20190613194153-d28f0bde5980 h1:dfGZHvZk057jK2MCeWus/TowKpJ8y4AmooUzdBSR9GU=
|
||||
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297 h1:k7pJ2yAPLPgbskkFdhRCsA77k2fySZ1zf2zCjvQCiIM=
|
||||
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/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-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-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||
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/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-20190614205625-5aca471b1d59/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 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
|
|
7
vendor/github.com/go-openapi/spec/items.go
generated
vendored
7
vendor/github.com/go-openapi/spec/items.go
generated
vendored
|
@ -29,6 +29,7 @@ const (
|
|||
// SimpleSchema describe swagger simple schemas for parameters and headers
|
||||
type SimpleSchema struct {
|
||||
Type string `json:"type,omitempty"`
|
||||
Nullable bool `json:"nullable,omitempty"`
|
||||
Format string `json:"format,omitempty"`
|
||||
Items *Items `json:"items,omitempty"`
|
||||
CollectionFormat string `json:"collectionFormat,omitempty"`
|
||||
|
@ -91,6 +92,12 @@ func (i *Items) Typed(tpe, format string) *Items {
|
|||
return i
|
||||
}
|
||||
|
||||
// AsNullable flags this schema as nullable.
|
||||
func (i *Items) AsNullable() *Items {
|
||||
i.Nullable = true
|
||||
return i
|
||||
}
|
||||
|
||||
// CollectionOf a fluent builder method for an array item
|
||||
func (i *Items) CollectionOf(items *Items, format string) *Items {
|
||||
i.Type = jsonArray
|
||||
|
|
7
vendor/github.com/go-openapi/spec/schema.go
generated
vendored
7
vendor/github.com/go-openapi/spec/schema.go
generated
vendored
|
@ -163,6 +163,7 @@ type SchemaProps struct {
|
|||
Schema SchemaURL `json:"-"`
|
||||
Description string `json:"description,omitempty"`
|
||||
Type StringOrArray `json:"type,omitempty"`
|
||||
Nullable bool `json:"nullable,omitempty"`
|
||||
Format string `json:"format,omitempty"`
|
||||
Title string `json:"title,omitempty"`
|
||||
Default interface{} `json:"default,omitempty"`
|
||||
|
@ -302,6 +303,12 @@ func (s *Schema) AddType(tpe, format string) *Schema {
|
|||
return s
|
||||
}
|
||||
|
||||
// AsNullable flags this schema as nullable.
|
||||
func (s *Schema) AsNullable() *Schema {
|
||||
s.Nullable = true
|
||||
return s
|
||||
}
|
||||
|
||||
// CollectionOf a fluent builder method for an array parameter
|
||||
func (s *Schema) CollectionOf(items Schema) *Schema {
|
||||
s.Type = []string{jsonArray}
|
||||
|
|
1
vendor/github.com/go-openapi/spec/schema_loader.go
generated
vendored
1
vendor/github.com/go-openapi/spec/schema_loader.go
generated
vendored
|
@ -160,6 +160,7 @@ func (r *schemaLoader) load(refURL *url.URL) (interface{}, url.URL, bool, error)
|
|||
if !fromCache {
|
||||
b, err := r.loadDoc(normalized)
|
||||
if err != nil {
|
||||
debugLog("unable to load the document: %v", err)
|
||||
return nil, url.URL{}, false, err
|
||||
}
|
||||
|
||||
|
|
124
vendor/github.com/go-openapi/spec/swagger.go
generated
vendored
124
vendor/github.com/go-openapi/spec/swagger.go
generated
vendored
|
@ -15,6 +15,8 @@
|
|||
package spec
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/gob"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
@ -68,6 +70,36 @@ func (s *Swagger) UnmarshalJSON(data []byte) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// GobEncode provides a safe gob encoder for Swagger, including extensions
|
||||
func (s Swagger) GobEncode() ([]byte, error) {
|
||||
var b bytes.Buffer
|
||||
raw := struct {
|
||||
Props SwaggerProps
|
||||
Ext VendorExtensible
|
||||
}{
|
||||
Props: s.SwaggerProps,
|
||||
Ext: s.VendorExtensible,
|
||||
}
|
||||
err := gob.NewEncoder(&b).Encode(raw)
|
||||
return b.Bytes(), err
|
||||
}
|
||||
|
||||
// GobDecode provides a safe gob decoder for Swagger, including extensions
|
||||
func (s *Swagger) GobDecode(b []byte) error {
|
||||
var raw struct {
|
||||
Props SwaggerProps
|
||||
Ext VendorExtensible
|
||||
}
|
||||
buf := bytes.NewBuffer(b)
|
||||
err := gob.NewDecoder(buf).Decode(&raw)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s.SwaggerProps = raw.Props
|
||||
s.VendorExtensible = raw.Ext
|
||||
return nil
|
||||
}
|
||||
|
||||
// SwaggerProps captures the top-level properties of an Api specification
|
||||
//
|
||||
// NOTE: validation rules
|
||||
|
@ -93,6 +125,98 @@ type SwaggerProps struct {
|
|||
ExternalDocs *ExternalDocumentation `json:"externalDocs,omitempty"`
|
||||
}
|
||||
|
||||
type swaggerPropsAlias SwaggerProps
|
||||
|
||||
type gobSwaggerPropsAlias struct {
|
||||
Security []map[string]struct {
|
||||
List []string
|
||||
Pad bool
|
||||
}
|
||||
Alias *swaggerPropsAlias
|
||||
SecurityIsEmpty bool
|
||||
}
|
||||
|
||||
// GobEncode provides a safe gob encoder for SwaggerProps, including empty security requirements
|
||||
func (o SwaggerProps) GobEncode() ([]byte, error) {
|
||||
raw := gobSwaggerPropsAlias{
|
||||
Alias: (*swaggerPropsAlias)(&o),
|
||||
}
|
||||
|
||||
var b bytes.Buffer
|
||||
if o.Security == nil {
|
||||
// nil security requirement
|
||||
err := gob.NewEncoder(&b).Encode(raw)
|
||||
return b.Bytes(), err
|
||||
}
|
||||
|
||||
if len(o.Security) == 0 {
|
||||
// empty, but non-nil security requirement
|
||||
raw.SecurityIsEmpty = true
|
||||
raw.Alias.Security = nil
|
||||
err := gob.NewEncoder(&b).Encode(raw)
|
||||
return b.Bytes(), err
|
||||
}
|
||||
|
||||
raw.Security = make([]map[string]struct {
|
||||
List []string
|
||||
Pad bool
|
||||
}, 0, len(o.Security))
|
||||
for _, req := range o.Security {
|
||||
v := make(map[string]struct {
|
||||
List []string
|
||||
Pad bool
|
||||
}, len(req))
|
||||
for k, val := range req {
|
||||
v[k] = struct {
|
||||
List []string
|
||||
Pad bool
|
||||
}{
|
||||
List: val,
|
||||
}
|
||||
}
|
||||
raw.Security = append(raw.Security, v)
|
||||
}
|
||||
|
||||
err := gob.NewEncoder(&b).Encode(raw)
|
||||
return b.Bytes(), err
|
||||
}
|
||||
|
||||
// GobDecode provides a safe gob decoder for SwaggerProps, including empty security requirements
|
||||
func (o *SwaggerProps) GobDecode(b []byte) error {
|
||||
var raw gobSwaggerPropsAlias
|
||||
|
||||
buf := bytes.NewBuffer(b)
|
||||
err := gob.NewDecoder(buf).Decode(&raw)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if raw.Alias == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
switch {
|
||||
case raw.SecurityIsEmpty:
|
||||
// empty, but non-nil security requirement
|
||||
raw.Alias.Security = []map[string][]string{}
|
||||
case len(raw.Alias.Security) == 0:
|
||||
// nil security requirement
|
||||
raw.Alias.Security = nil
|
||||
default:
|
||||
raw.Alias.Security = make([]map[string][]string, 0, len(raw.Security))
|
||||
for _, req := range raw.Security {
|
||||
v := make(map[string][]string, len(req))
|
||||
for k, val := range req {
|
||||
v[k] = make([]string, 0, len(val.List))
|
||||
v[k] = append(v[k], val.List...)
|
||||
}
|
||||
raw.Alias.Security = append(raw.Alias.Security, v)
|
||||
}
|
||||
}
|
||||
|
||||
*o = *(*SwaggerProps)(raw.Alias)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Dependencies represent a dependencies property
|
||||
type Dependencies map[string]SchemaOrStringArray
|
||||
|
||||
|
|
1
vendor/github.com/go-openapi/swag/.gitignore
generated
vendored
1
vendor/github.com/go-openapi/swag/.gitignore
generated
vendored
|
@ -1,3 +1,4 @@
|
|||
secrets.yml
|
||||
vendor
|
||||
Godeps
|
||||
.idea
|
||||
|
|
11
vendor/github.com/go-openapi/swag/.travis.yml
generated
vendored
11
vendor/github.com/go-openapi/swag/.travis.yml
generated
vendored
|
@ -1,16 +1,15 @@
|
|||
after_success:
|
||||
- bash <(curl -s https://codecov.io/bash)
|
||||
go:
|
||||
- '1.9'
|
||||
- 1.10.x
|
||||
- 1.11.x
|
||||
- 1.12.x
|
||||
install:
|
||||
- go get -u github.com/stretchr/testify
|
||||
- go get -u github.com/mailru/easyjson
|
||||
- go get -u gopkg.in/yaml.v2
|
||||
- GO111MODULE=off go get -u gotest.tools/gotestsum
|
||||
env:
|
||||
- GO111MODULE=on
|
||||
language: go
|
||||
notifications:
|
||||
slack:
|
||||
secure: QUWvCkBBK09GF7YtEvHHVt70JOkdlNBG0nIKu/5qc4/nW5HP8I2w0SEf/XR2je0eED1Qe3L/AfMCWwrEj+IUZc3l4v+ju8X8R3Lomhme0Eb0jd1MTMCuPcBT47YCj0M7RON7vXtbFfm1hFJ/jLe5+9FXz0hpXsR24PJc5ZIi/ogNwkaPqG4BmndzecpSh0vc2FJPZUD9LT0I09REY/vXR0oQAalLkW0asGD5taHZTUZq/kBpsNxaAFrLM23i4mUcf33M5fjLpvx5LRICrX/57XpBrDh2TooBU6Qj3CgoY0uPRYUmSNxbVx1czNzl2JtEpb5yjoxfVPQeg0BvQM00G8LJINISR+ohrjhkZmAqchDupAX+yFrxTtORa78CtnIL6z/aTNlgwwVD8kvL/1pFA/JWYmKDmz93mV/+6wubGzNSQCstzjkFA4/iZEKewKUoRIAi/fxyscP6L/rCpmY/4llZZvrnyTqVbt6URWpopUpH4rwYqreXAtJxJsfBJIeSmUIiDIOMGkCTvyTEW3fWGmGoqWtSHLoaWDyAIGb7azb+KvfpWtEcoPFWfSWU+LGee0A/YsUhBl7ADB9A0CJEuR8q4BPpKpfLwPKSiKSAXL7zDkyjExyhtgqbSl2jS+rKIHOZNL8JkCcTP2MKMVd563C5rC5FMKqu3S9m2b6380E=
|
||||
script:
|
||||
- go test -v -race -cover -coverprofile=coverage.txt -covermode=atomic ./...
|
||||
- gotestsum -f short-verbose -- -race -coverprofile=coverage.txt -covermode=atomic ./...
|
||||
|
|
1
vendor/github.com/go-openapi/swag/README.md
generated
vendored
1
vendor/github.com/go-openapi/swag/README.md
generated
vendored
|
@ -19,5 +19,4 @@ You may also use it standalone for your projects.
|
|||
|
||||
This repo has only few dependencies outside of the standard library:
|
||||
|
||||
* JSON utilities depend on github.com/mailru/easyjson
|
||||
* YAML utilities depend on gopkg.in/yaml.v2
|
||||
|
|
7
vendor/github.com/go-openapi/swag/convert.go
generated
vendored
7
vendor/github.com/go-openapi/swag/convert.go
generated
vendored
|
@ -39,11 +39,12 @@ func IsFloat64AJSONInteger(f float64) bool {
|
|||
diff := math.Abs(f - g)
|
||||
|
||||
// more info: https://floating-point-gui.de/errors/comparison/#look-out-for-edge-cases
|
||||
if f == g { // best case
|
||||
switch {
|
||||
case f == g: // best case
|
||||
return true
|
||||
} else if f == float64(int64(f)) || f == float64(uint64(f)) { // optimistic case
|
||||
case f == float64(int64(f)) || f == float64(uint64(f)): // optimistic case
|
||||
return true
|
||||
} else if f == 0 || g == 0 || diff < math.SmallestNonzeroFloat64 { // very close to 0 values
|
||||
case f == 0 || g == 0 || diff < math.SmallestNonzeroFloat64: // very close to 0 values
|
||||
return diff < (epsilon * math.SmallestNonzeroFloat64)
|
||||
}
|
||||
// check the relative error
|
||||
|
|
1
vendor/github.com/go-openapi/swag/doc.go
generated
vendored
1
vendor/github.com/go-openapi/swag/doc.go
generated
vendored
|
@ -27,7 +27,6 @@ You may also use it standalone for your projects.
|
|||
|
||||
This repo has only few dependencies outside of the standard library:
|
||||
|
||||
* JSON utilities depend on github.com/mailru/easyjson
|
||||
* YAML utilities depend on gopkg.in/yaml.v2
|
||||
*/
|
||||
package swag
|
||||
|
|
13
vendor/github.com/go-openapi/swag/go.mod
generated
vendored
13
vendor/github.com/go-openapi/swag/go.mod
generated
vendored
|
@ -2,8 +2,13 @@ module github.com/go-openapi/swag
|
|||
|
||||
require (
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/stretchr/testify v1.2.2
|
||||
gopkg.in/yaml.v2 v2.2.1
|
||||
github.com/kr/pretty v0.1.0 // indirect
|
||||
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63
|
||||
github.com/stretchr/testify v1.3.0
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
|
||||
gopkg.in/yaml.v2 v2.2.2
|
||||
)
|
||||
|
||||
replace github.com/golang/lint => golang.org/x/lint v0.0.0-20190409202823-959b441ac422
|
||||
|
||||
replace sourcegraph.com/sourcegraph/go-diff => github.com/sourcegraph/go-diff v0.5.1
|
||||
|
|
21
vendor/github.com/go-openapi/swag/go.sum
generated
vendored
21
vendor/github.com/go-openapi/swag/go.sum
generated
vendored
|
@ -1,9 +1,20 @@
|
|||
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/mailru/easyjson v0.0.0-20180823135443-60711f1a8329 h1:2gxZ0XQIU/5z3Z3bUBu+FXuk2pFbkN6tcwi/pjyaDic=
|
||||
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
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/mailru/easyjson v0.0.0-20190614124828-94de47d64c63 h1:nTT4s92Dgz2HlrB2NaMgvlfqHH39OgMhA7z3PK7PGD4=
|
||||
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
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/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
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 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
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/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
|
|
2
vendor/github.com/go-openapi/swag/json.go
generated
vendored
2
vendor/github.com/go-openapi/swag/json.go
generated
vendored
|
@ -99,7 +99,7 @@ func ConcatJSON(blobs ...[]byte) []byte {
|
|||
last := len(blobs) - 1
|
||||
for blobs[last] == nil || bytes.Equal(blobs[last], nullJSON) {
|
||||
// strips trailing null objects
|
||||
last = last - 1
|
||||
last--
|
||||
if last < 0 {
|
||||
// there was nothing but "null"s or nil...
|
||||
return nil
|
||||
|
|
87
vendor/github.com/go-openapi/swag/name_lexem.go
generated
vendored
Normal file
87
vendor/github.com/go-openapi/swag/name_lexem.go
generated
vendored
Normal file
|
@ -0,0 +1,87 @@
|
|||
// Copyright 2015 go-swagger maintainers
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package swag
|
||||
|
||||
import "unicode"
|
||||
|
||||
type (
|
||||
nameLexem interface {
|
||||
GetUnsafeGoName() string
|
||||
GetOriginal() string
|
||||
IsInitialism() bool
|
||||
}
|
||||
|
||||
initialismNameLexem struct {
|
||||
original string
|
||||
matchedInitialism string
|
||||
}
|
||||
|
||||
casualNameLexem struct {
|
||||
original string
|
||||
}
|
||||
)
|
||||
|
||||
func newInitialismNameLexem(original, matchedInitialism string) *initialismNameLexem {
|
||||
return &initialismNameLexem{
|
||||
original: original,
|
||||
matchedInitialism: matchedInitialism,
|
||||
}
|
||||
}
|
||||
|
||||
func newCasualNameLexem(original string) *casualNameLexem {
|
||||
return &casualNameLexem{
|
||||
original: original,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *initialismNameLexem) GetUnsafeGoName() string {
|
||||
return l.matchedInitialism
|
||||
}
|
||||
|
||||
func (l *casualNameLexem) GetUnsafeGoName() string {
|
||||
var first rune
|
||||
var rest string
|
||||
for i, orig := range l.original {
|
||||
if i == 0 {
|
||||
first = orig
|
||||
continue
|
||||
}
|
||||
if i > 0 {
|
||||
rest = l.original[i:]
|
||||
break
|
||||
}
|
||||
}
|
||||
if len(l.original) > 1 {
|
||||
return string(unicode.ToUpper(first)) + lower(rest)
|
||||
}
|
||||
|
||||
return l.original
|
||||
}
|
||||
|
||||
func (l *initialismNameLexem) GetOriginal() string {
|
||||
return l.original
|
||||
}
|
||||
|
||||
func (l *casualNameLexem) GetOriginal() string {
|
||||
return l.original
|
||||
}
|
||||
|
||||
func (l *initialismNameLexem) IsInitialism() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (l *casualNameLexem) IsInitialism() bool {
|
||||
return false
|
||||
}
|
262
vendor/github.com/go-openapi/swag/split.go
generated
vendored
Normal file
262
vendor/github.com/go-openapi/swag/split.go
generated
vendored
Normal file
|
@ -0,0 +1,262 @@
|
|||
// Copyright 2015 go-swagger maintainers
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package swag
|
||||
|
||||
import (
|
||||
"unicode"
|
||||
)
|
||||
|
||||
var nameReplaceTable = map[rune]string{
|
||||
'@': "At ",
|
||||
'&': "And ",
|
||||
'|': "Pipe ",
|
||||
'$': "Dollar ",
|
||||
'!': "Bang ",
|
||||
'-': "",
|
||||
'_': "",
|
||||
}
|
||||
|
||||
type (
|
||||
splitter struct {
|
||||
postSplitInitialismCheck bool
|
||||
initialisms []string
|
||||
}
|
||||
|
||||
splitterOption func(*splitter) *splitter
|
||||
)
|
||||
|
||||
// split calls the splitter; splitter provides more control and post options
|
||||
func split(str string) []string {
|
||||
lexems := newSplitter().split(str)
|
||||
result := make([]string, 0, len(lexems))
|
||||
|
||||
for _, lexem := range lexems {
|
||||
result = append(result, lexem.GetOriginal())
|
||||
}
|
||||
|
||||
return result
|
||||
|
||||
}
|
||||
|
||||
func (s *splitter) split(str string) []nameLexem {
|
||||
return s.toNameLexems(str)
|
||||
}
|
||||
|
||||
func newSplitter(options ...splitterOption) *splitter {
|
||||
splitter := &splitter{
|
||||
postSplitInitialismCheck: false,
|
||||
initialisms: initialisms,
|
||||
}
|
||||
|
||||
for _, option := range options {
|
||||
splitter = option(splitter)
|
||||
}
|
||||
|
||||
return splitter
|
||||
}
|
||||
|
||||
// withPostSplitInitialismCheck allows to catch initialisms after main split process
|
||||
func withPostSplitInitialismCheck(s *splitter) *splitter {
|
||||
s.postSplitInitialismCheck = true
|
||||
return s
|
||||
}
|
||||
|
||||
type (
|
||||
initialismMatch struct {
|
||||
start, end int
|
||||
body []rune
|
||||
complete bool
|
||||
}
|
||||
initialismMatches []*initialismMatch
|
||||
)
|
||||
|
||||
func (s *splitter) toNameLexems(name string) []nameLexem {
|
||||
nameRunes := []rune(name)
|
||||
matches := s.gatherInitialismMatches(nameRunes)
|
||||
return s.mapMatchesToNameLexems(nameRunes, matches)
|
||||
}
|
||||
|
||||
func (s *splitter) gatherInitialismMatches(nameRunes []rune) initialismMatches {
|
||||
matches := make(initialismMatches, 0)
|
||||
|
||||
for currentRunePosition, currentRune := range nameRunes {
|
||||
newMatches := make(initialismMatches, 0, len(matches))
|
||||
|
||||
// check current initialism matches
|
||||
for _, match := range matches {
|
||||
if keepCompleteMatch := match.complete; keepCompleteMatch {
|
||||
newMatches = append(newMatches, match)
|
||||
continue
|
||||
}
|
||||
|
||||
// drop failed match
|
||||
currentMatchRune := match.body[currentRunePosition-match.start]
|
||||
if !s.initialismRuneEqual(currentMatchRune, currentRune) {
|
||||
continue
|
||||
}
|
||||
|
||||
// try to complete ongoing match
|
||||
if currentRunePosition-match.start == len(match.body)-1 {
|
||||
// we are close; the next step is to check the symbol ahead
|
||||
// if it is a small letter, then it is not the end of match
|
||||
// but beginning of the next word
|
||||
|
||||
if currentRunePosition < len(nameRunes)-1 {
|
||||
nextRune := nameRunes[currentRunePosition+1]
|
||||
if newWord := unicode.IsLower(nextRune); newWord {
|
||||
// oh ok, it was the start of a new word
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
match.complete = true
|
||||
match.end = currentRunePosition
|
||||
}
|
||||
|
||||
newMatches = append(newMatches, match)
|
||||
}
|
||||
|
||||
// check for new initialism matches
|
||||
for _, initialism := range s.initialisms {
|
||||
initialismRunes := []rune(initialism)
|
||||
if s.initialismRuneEqual(initialismRunes[0], currentRune) {
|
||||
newMatches = append(newMatches, &initialismMatch{
|
||||
start: currentRunePosition,
|
||||
body: initialismRunes,
|
||||
complete: false,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
matches = newMatches
|
||||
}
|
||||
|
||||
return matches
|
||||
}
|
||||
|
||||
func (s *splitter) mapMatchesToNameLexems(nameRunes []rune, matches initialismMatches) []nameLexem {
|
||||
nameLexems := make([]nameLexem, 0)
|
||||
|
||||
var lastAcceptedMatch *initialismMatch
|
||||
for _, match := range matches {
|
||||
if !match.complete {
|
||||
continue
|
||||
}
|
||||
|
||||
if firstMatch := lastAcceptedMatch == nil; firstMatch {
|
||||
nameLexems = append(nameLexems, s.breakCasualString(nameRunes[:match.start])...)
|
||||
nameLexems = append(nameLexems, s.breakInitialism(string(match.body)))
|
||||
|
||||
lastAcceptedMatch = match
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
if overlappedMatch := match.start <= lastAcceptedMatch.end; overlappedMatch {
|
||||
continue
|
||||
}
|
||||
|
||||
middle := nameRunes[lastAcceptedMatch.end+1 : match.start]
|
||||
nameLexems = append(nameLexems, s.breakCasualString(middle)...)
|
||||
nameLexems = append(nameLexems, s.breakInitialism(string(match.body)))
|
||||
|
||||
lastAcceptedMatch = match
|
||||
}
|
||||
|
||||
// we have not found any accepted matches
|
||||
if lastAcceptedMatch == nil {
|
||||
return s.breakCasualString(nameRunes)
|
||||
}
|
||||
|
||||
if lastAcceptedMatch.end+1 != len(nameRunes) {
|
||||
rest := nameRunes[lastAcceptedMatch.end+1:]
|
||||
nameLexems = append(nameLexems, s.breakCasualString(rest)...)
|
||||
}
|
||||
|
||||
return nameLexems
|
||||
}
|
||||
|
||||
func (s *splitter) initialismRuneEqual(a, b rune) bool {
|
||||
return a == b
|
||||
}
|
||||
|
||||
func (s *splitter) breakInitialism(original string) nameLexem {
|
||||
return newInitialismNameLexem(original, original)
|
||||
}
|
||||
|
||||
func (s *splitter) breakCasualString(str []rune) []nameLexem {
|
||||
segments := make([]nameLexem, 0)
|
||||
currentSegment := ""
|
||||
|
||||
addCasualNameLexem := func(original string) {
|
||||
segments = append(segments, newCasualNameLexem(original))
|
||||
}
|
||||
|
||||
addInitialismNameLexem := func(original, match string) {
|
||||
segments = append(segments, newInitialismNameLexem(original, match))
|
||||
}
|
||||
|
||||
addNameLexem := func(original string) {
|
||||
if s.postSplitInitialismCheck {
|
||||
for _, initialism := range s.initialisms {
|
||||
if upper(initialism) == upper(original) {
|
||||
addInitialismNameLexem(original, initialism)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
addCasualNameLexem(original)
|
||||
}
|
||||
|
||||
for _, rn := range string(str) {
|
||||
if replace, found := nameReplaceTable[rn]; found {
|
||||
if currentSegment != "" {
|
||||
addNameLexem(currentSegment)
|
||||
currentSegment = ""
|
||||
}
|
||||
|
||||
if replace != "" {
|
||||
addNameLexem(replace)
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
if !unicode.In(rn, unicode.L, unicode.M, unicode.N, unicode.Pc) {
|
||||
if currentSegment != "" {
|
||||
addNameLexem(currentSegment)
|
||||
currentSegment = ""
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
if unicode.IsUpper(rn) {
|
||||
if currentSegment != "" {
|
||||
addNameLexem(currentSegment)
|
||||
}
|
||||
currentSegment = ""
|
||||
}
|
||||
|
||||
currentSegment += string(rn)
|
||||
}
|
||||
|
||||
if currentSegment != "" {
|
||||
addNameLexem(currentSegment)
|
||||
}
|
||||
|
||||
return segments
|
||||
}
|
111
vendor/github.com/go-openapi/swag/util.go
generated
vendored
111
vendor/github.com/go-openapi/swag/util.go
generated
vendored
|
@ -15,11 +15,8 @@
|
|||
package swag
|
||||
|
||||
import (
|
||||
"math"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"strings"
|
||||
"sync"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
|
@ -29,15 +26,15 @@ var commonInitialisms *indexOfInitialisms
|
|||
// initialisms is a slice of sorted initialisms
|
||||
var initialisms []string
|
||||
|
||||
var once sync.Once
|
||||
|
||||
var isInitialism func(string) bool
|
||||
|
||||
var (
|
||||
splitRex1 *regexp.Regexp
|
||||
splitRex2 *regexp.Regexp
|
||||
splitReplacer *strings.Replacer
|
||||
)
|
||||
// GoNamePrefixFunc sets an optional rule to prefix go names
|
||||
// which do not start with a letter.
|
||||
//
|
||||
// e.g. to help converting "123" into "{prefix}123"
|
||||
//
|
||||
// The default is to prefix with "X"
|
||||
var GoNamePrefixFunc func(string) string
|
||||
|
||||
func init() {
|
||||
// Taken from https://github.com/golang/lint/blob/3390df4df2787994aea98de825b964ac7944b817/lint.go#L732-L769
|
||||
|
@ -55,6 +52,8 @@ func init() {
|
|||
"HTTP": true,
|
||||
"ID": true,
|
||||
"IP": true,
|
||||
"IPv4": true,
|
||||
"IPv6": true,
|
||||
"JSON": true,
|
||||
"LHS": true,
|
||||
"OAI": true,
|
||||
|
@ -85,15 +84,12 @@ func init() {
|
|||
|
||||
// a thread-safe index of initialisms
|
||||
commonInitialisms = newIndexOfInitialisms().load(configuredInitialisms)
|
||||
initialisms = commonInitialisms.sorted()
|
||||
|
||||
// a test function
|
||||
isInitialism = commonInitialisms.isInitialism
|
||||
}
|
||||
|
||||
func ensureSorted() {
|
||||
initialisms = commonInitialisms.sorted()
|
||||
}
|
||||
|
||||
const (
|
||||
//collectionFormatComma = "csv"
|
||||
collectionFormatSpace = "ssv"
|
||||
|
@ -175,40 +171,6 @@ func (s byInitialism) Less(i, j int) bool {
|
|||
return strings.Compare(s[i], s[j]) > 0
|
||||
}
|
||||
|
||||
// Prepares strings by splitting by caps, spaces, dashes, and underscore
|
||||
func split(str string) []string {
|
||||
// check if consecutive single char things make up an initialism
|
||||
once.Do(func() {
|
||||
splitRex1 = regexp.MustCompile(`(\p{Lu})`)
|
||||
splitRex2 = regexp.MustCompile(`(\pL|\pM|\pN|\p{Pc})+`)
|
||||
splitReplacer = strings.NewReplacer(
|
||||
"@", "At ",
|
||||
"&", "And ",
|
||||
"|", "Pipe ",
|
||||
"$", "Dollar ",
|
||||
"!", "Bang ",
|
||||
"-", " ",
|
||||
"_", " ",
|
||||
)
|
||||
ensureSorted()
|
||||
})
|
||||
|
||||
str = trim(str)
|
||||
|
||||
// Convert dash and underscore to spaces
|
||||
str = splitReplacer.Replace(str)
|
||||
|
||||
// Split when uppercase is found (needed for Snake)
|
||||
str = splitRex1.ReplaceAllString(str, " $1")
|
||||
|
||||
for _, k := range initialisms {
|
||||
str = strings.Replace(str, splitRex1.ReplaceAllString(k, " $1"), " "+k, -1)
|
||||
}
|
||||
// Get the final list of words
|
||||
//words = rex2.FindAllString(str, -1)
|
||||
return splitRex2.FindAllString(str, -1)
|
||||
}
|
||||
|
||||
// Removes leading whitespaces
|
||||
func trim(str string) string {
|
||||
return strings.Trim(str, " ")
|
||||
|
@ -261,30 +223,31 @@ func ToCommandName(name string) string {
|
|||
|
||||
// ToHumanNameLower represents a code name as a human series of words
|
||||
func ToHumanNameLower(name string) string {
|
||||
in := split(name)
|
||||
in := newSplitter(withPostSplitInitialismCheck).split(name)
|
||||
out := make([]string, 0, len(in))
|
||||
|
||||
for _, w := range in {
|
||||
if !isInitialism(upper(w)) {
|
||||
out = append(out, lower(w))
|
||||
if !w.IsInitialism() {
|
||||
out = append(out, lower(w.GetOriginal()))
|
||||
} else {
|
||||
out = append(out, w)
|
||||
out = append(out, w.GetOriginal())
|
||||
}
|
||||
}
|
||||
|
||||
return strings.Join(out, " ")
|
||||
}
|
||||
|
||||
// ToHumanNameTitle represents a code name as a human series of words with the first letters titleized
|
||||
func ToHumanNameTitle(name string) string {
|
||||
in := split(name)
|
||||
out := make([]string, 0, len(in))
|
||||
in := newSplitter(withPostSplitInitialismCheck).split(name)
|
||||
|
||||
out := make([]string, 0, len(in))
|
||||
for _, w := range in {
|
||||
uw := upper(w)
|
||||
if !isInitialism(uw) {
|
||||
out = append(out, Camelize(w))
|
||||
original := w.GetOriginal()
|
||||
if !w.IsInitialism() {
|
||||
out = append(out, Camelize(original))
|
||||
} else {
|
||||
out = append(out, w)
|
||||
out = append(out, original)
|
||||
}
|
||||
}
|
||||
return strings.Join(out, " ")
|
||||
|
@ -319,24 +282,34 @@ func ToVarName(name string) string {
|
|||
|
||||
// ToGoName translates a swagger name which can be underscored or camel cased to a name that golint likes
|
||||
func ToGoName(name string) string {
|
||||
in := split(name)
|
||||
out := make([]string, 0, len(in))
|
||||
lexems := newSplitter(withPostSplitInitialismCheck).split(name)
|
||||
|
||||
for _, w := range in {
|
||||
uw := upper(w)
|
||||
mod := int(math.Min(float64(len(uw)), 2))
|
||||
if !isInitialism(uw) && !isInitialism(uw[:len(uw)-mod]) {
|
||||
uw = Camelize(w)
|
||||
result := ""
|
||||
for _, lexem := range lexems {
|
||||
goName := lexem.GetUnsafeGoName()
|
||||
|
||||
// to support old behavior
|
||||
if lexem.IsInitialism() {
|
||||
goName = upper(goName)
|
||||
}
|
||||
out = append(out, uw)
|
||||
result += goName
|
||||
}
|
||||
|
||||
result := strings.Join(out, "")
|
||||
if len(result) > 0 {
|
||||
if !unicode.IsUpper([]rune(result)[0]) {
|
||||
result = "X" + result
|
||||
// Only prefix with X when the first character isn't an ascii letter
|
||||
first := []rune(result)[0]
|
||||
if !unicode.IsLetter(first) || (first > unicode.MaxASCII && !unicode.IsUpper(first)) {
|
||||
if GoNamePrefixFunc == nil {
|
||||
return "X" + result
|
||||
}
|
||||
result = GoNamePrefixFunc(name) + result
|
||||
}
|
||||
first = []rune(result)[0]
|
||||
if unicode.IsLetter(first) && !unicode.IsUpper(first) {
|
||||
result = string(append([]rune{unicode.ToUpper(first)}, []rune(result)[1:]...))
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
|
|
47
vendor/github.com/go-openapi/swag/yaml.go
generated
vendored
47
vendor/github.com/go-openapi/swag/yaml.go
generated
vendored
|
@ -143,19 +143,43 @@ func (s *JSONMapItem) UnmarshalEasyJSON(in *jlexer.Lexer) {
|
|||
}
|
||||
|
||||
func transformData(input interface{}) (out interface{}, err error) {
|
||||
format := func(t interface{}) (string, error) {
|
||||
switch k := t.(type) {
|
||||
case string:
|
||||
return k, nil
|
||||
case uint:
|
||||
return strconv.FormatUint(uint64(k), 10), nil
|
||||
case uint8:
|
||||
return strconv.FormatUint(uint64(k), 10), nil
|
||||
case uint16:
|
||||
return strconv.FormatUint(uint64(k), 10), nil
|
||||
case uint32:
|
||||
return strconv.FormatUint(uint64(k), 10), nil
|
||||
case uint64:
|
||||
return strconv.FormatUint(k, 10), nil
|
||||
case int:
|
||||
return strconv.Itoa(k), nil
|
||||
case int8:
|
||||
return strconv.FormatInt(int64(k), 10), nil
|
||||
case int16:
|
||||
return strconv.FormatInt(int64(k), 10), nil
|
||||
case int32:
|
||||
return strconv.FormatInt(int64(k), 10), nil
|
||||
case int64:
|
||||
return strconv.FormatInt(k, 10), nil
|
||||
default:
|
||||
return "", fmt.Errorf("unexpected map key type, got: %T", k)
|
||||
}
|
||||
}
|
||||
|
||||
switch in := input.(type) {
|
||||
case yaml.MapSlice:
|
||||
|
||||
o := make(JSONMapSlice, len(in))
|
||||
for i, mi := range in {
|
||||
var nmi JSONMapItem
|
||||
switch k := mi.Key.(type) {
|
||||
case string:
|
||||
nmi.Key = k
|
||||
case int:
|
||||
nmi.Key = strconv.Itoa(k)
|
||||
default:
|
||||
return nil, fmt.Errorf("types don't match expect map key string or int got: %T", mi.Key)
|
||||
if nmi.Key, err = format(mi.Key); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
v, ert := transformData(mi.Value)
|
||||
|
@ -170,13 +194,8 @@ func transformData(input interface{}) (out interface{}, err error) {
|
|||
o := make(JSONMapSlice, 0, len(in))
|
||||
for ke, va := range in {
|
||||
var nmi JSONMapItem
|
||||
switch k := ke.(type) {
|
||||
case string:
|
||||
nmi.Key = k
|
||||
case int:
|
||||
nmi.Key = strconv.Itoa(k)
|
||||
default:
|
||||
return nil, fmt.Errorf("types don't match expect map key string or int got: %T", ke)
|
||||
if nmi.Key, err = format(ke); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
v, ert := transformData(va)
|
||||
|
|
5
vendor/github.com/golang/protobuf/proto/properties.go
generated
vendored
5
vendor/github.com/golang/protobuf/proto/properties.go
generated
vendored
|
@ -38,7 +38,6 @@ package proto
|
|||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strconv"
|
||||
|
@ -194,7 +193,7 @@ func (p *Properties) Parse(s string) {
|
|||
// "bytes,49,opt,name=foo,def=hello!"
|
||||
fields := strings.Split(s, ",") // breaks def=, but handled below.
|
||||
if len(fields) < 2 {
|
||||
fmt.Fprintf(os.Stderr, "proto: tag has too few fields: %q\n", s)
|
||||
log.Printf("proto: tag has too few fields: %q", s)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -214,7 +213,7 @@ func (p *Properties) Parse(s string) {
|
|||
p.WireType = WireBytes
|
||||
// no numeric converter for non-numeric types
|
||||
default:
|
||||
fmt.Fprintf(os.Stderr, "proto: tag has unknown wire type: %q\n", s)
|
||||
log.Printf("proto: tag has unknown wire type: %q", s)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
1
vendor/github.com/labstack/echo/v4/go.sum
generated
vendored
1
vendor/github.com/labstack/echo/v4/go.sum
generated
vendored
|
@ -45,6 +45,7 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||
golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2 h1:T5DasATyLQfmbTpfEXx/IOL9vfjzW6up+ZDkmHvIf2s=
|
||||
golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190609082536-301114b31cce h1:CQakrGkKbydnUmt7cFIlmQ4lNQiqdTPt6xzXij4nYCc=
|
||||
golang.org/x/sys v0.0.0-20190609082536-301114b31cce/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
|
|
2
vendor/github.com/mailru/easyjson/jlexer/lexer.go
generated
vendored
2
vendor/github.com/mailru/easyjson/jlexer/lexer.go
generated
vendored
|
@ -1152,7 +1152,7 @@ func (r *Lexer) Interface() interface{} {
|
|||
} else if r.token.delimValue == '[' {
|
||||
r.consume()
|
||||
|
||||
var ret []interface{}
|
||||
ret := []interface{}{}
|
||||
for !r.IsDelim(']') {
|
||||
ret = append(ret, r.Interface())
|
||||
r.WantComma()
|
||||
|
|
2
vendor/github.com/mattn/go-colorable/go.sum
generated
vendored
2
vendor/github.com/mattn/go-colorable/go.sum
generated
vendored
|
@ -1,4 +1,6 @@
|
|||
github.com/mattn/go-isatty v0.0.5 h1:tHXDdz1cpzGaovsTB+TVB8q90WEokoVmfMqoVcrLUgw=
|
||||
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE=
|
||||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 h1:DH4skfRX4EBpamg7iV4ZlCpblAHI6s6TDM39bFZumv8=
|
||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
|
|
4
vendor/github.com/mattn/go-isatty/go.mod
generated
vendored
4
vendor/github.com/mattn/go-isatty/go.mod
generated
vendored
|
@ -1,3 +1,5 @@
|
|||
module github.com/mattn/go-isatty
|
||||
|
||||
require golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223
|
||||
require golang.org/x/sys v0.0.0-20191008105621-543471e840be
|
||||
|
||||
go 1.14
|
||||
|
|
6
vendor/github.com/mattn/go-isatty/go.sum
generated
vendored
6
vendor/github.com/mattn/go-isatty/go.sum
generated
vendored
|
@ -1,2 +1,4 @@
|
|||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 h1:DH4skfRX4EBpamg7iV4ZlCpblAHI6s6TDM39bFZumv8=
|
||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
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-20191008105621-543471e840be h1:QAcqgptGM8IQBC9K/RC4o+O9YmqEm0diQn9QmZw/0mU=
|
||||
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
|
22
vendor/github.com/mattn/go-isatty/isatty_plan9.go
generated
vendored
Normal file
22
vendor/github.com/mattn/go-isatty/isatty_plan9.go
generated
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
// +build plan9
|
||||
|
||||
package isatty
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
)
|
||||
|
||||
// IsTerminal returns true if the given file descriptor is a terminal.
|
||||
func IsTerminal(fd uintptr) bool {
|
||||
path, err := syscall.Fd2path(fd)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return path == "/dev/cons" || path == "/mnt/term/dev/cons"
|
||||
}
|
||||
|
||||
// IsCygwinTerminal return true if the file descriptor is a cygwin or msys2
|
||||
// terminal. This is also always false on this environment.
|
||||
func IsCygwinTerminal(fd uintptr) bool {
|
||||
return false
|
||||
}
|
39
vendor/github.com/mattn/go-isatty/isatty_windows.go
generated
vendored
39
vendor/github.com/mattn/go-isatty/isatty_windows.go
generated
vendored
|
@ -4,6 +4,7 @@
|
|||
package isatty
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strings"
|
||||
"syscall"
|
||||
"unicode/utf16"
|
||||
|
@ -11,15 +12,18 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
fileNameInfo uintptr = 2
|
||||
fileTypePipe = 3
|
||||
objectNameInfo uintptr = 1
|
||||
fileNameInfo = 2
|
||||
fileTypePipe = 3
|
||||
)
|
||||
|
||||
var (
|
||||
kernel32 = syscall.NewLazyDLL("kernel32.dll")
|
||||
ntdll = syscall.NewLazyDLL("ntdll.dll")
|
||||
procGetConsoleMode = kernel32.NewProc("GetConsoleMode")
|
||||
procGetFileInformationByHandleEx = kernel32.NewProc("GetFileInformationByHandleEx")
|
||||
procGetFileType = kernel32.NewProc("GetFileType")
|
||||
procNtQueryObject = ntdll.NewProc("NtQueryObject")
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
@ -45,7 +49,10 @@ func isCygwinPipeName(name string) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
if token[0] != `\msys` && token[0] != `\cygwin` {
|
||||
if token[0] != `\msys` &&
|
||||
token[0] != `\cygwin` &&
|
||||
token[0] != `\Device\NamedPipe\msys` &&
|
||||
token[0] != `\Device\NamedPipe\cygwin` {
|
||||
return false
|
||||
}
|
||||
|
||||
|
@ -68,11 +75,35 @@ func isCygwinPipeName(name string) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
// getFileNameByHandle use the undocomented ntdll NtQueryObject to get file full name from file handler
|
||||
// since GetFileInformationByHandleEx is not avilable under windows Vista and still some old fashion
|
||||
// guys are using Windows XP, this is a workaround for those guys, it will also work on system from
|
||||
// Windows vista to 10
|
||||
// see https://stackoverflow.com/a/18792477 for details
|
||||
func getFileNameByHandle(fd uintptr) (string, error) {
|
||||
if procNtQueryObject == nil {
|
||||
return "", errors.New("ntdll.dll: NtQueryObject not supported")
|
||||
}
|
||||
|
||||
var buf [4 + syscall.MAX_PATH]uint16
|
||||
var result int
|
||||
r, _, e := syscall.Syscall6(procNtQueryObject.Addr(), 5,
|
||||
fd, objectNameInfo, uintptr(unsafe.Pointer(&buf)), uintptr(2*len(buf)), uintptr(unsafe.Pointer(&result)), 0)
|
||||
if r != 0 {
|
||||
return "", e
|
||||
}
|
||||
return string(utf16.Decode(buf[4 : 4+buf[0]/2])), nil
|
||||
}
|
||||
|
||||
// IsCygwinTerminal() return true if the file descriptor is a cygwin or msys2
|
||||
// terminal.
|
||||
func IsCygwinTerminal(fd uintptr) bool {
|
||||
if procGetFileInformationByHandleEx == nil {
|
||||
return false
|
||||
name, err := getFileNameByHandle(fd)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return isCygwinPipeName(name)
|
||||
}
|
||||
|
||||
// Cygwin/msys's pty is a pipe.
|
||||
|
|
2
vendor/github.com/prometheus/procfs/go.mod
generated
vendored
2
vendor/github.com/prometheus/procfs/go.mod
generated
vendored
|
@ -1 +1,3 @@
|
|||
module github.com/prometheus/procfs
|
||||
|
||||
go 1.12
|
||||
|
|
8
vendor/github.com/russross/blackfriday/v2/.gitignore
generated
vendored
Normal file
8
vendor/github.com/russross/blackfriday/v2/.gitignore
generated
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
*.out
|
||||
*.swp
|
||||
*.8
|
||||
*.6
|
||||
_obj
|
||||
_test*
|
||||
markdown
|
||||
tags
|
17
vendor/github.com/russross/blackfriday/v2/.travis.yml
generated
vendored
Normal file
17
vendor/github.com/russross/blackfriday/v2/.travis.yml
generated
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
sudo: false
|
||||
language: go
|
||||
go:
|
||||
- "1.10.x"
|
||||
- "1.11.x"
|
||||
- tip
|
||||
matrix:
|
||||
fast_finish: true
|
||||
allow_failures:
|
||||
- go: tip
|
||||
install:
|
||||
- # Do nothing. This is needed to prevent default install action "go get -t -v ./..." from happening here (we want it to happen inside script step).
|
||||
script:
|
||||
- go get -t -v ./...
|
||||
- diff -u <(echo -n) <(gofmt -d -s .)
|
||||
- go tool vet .
|
||||
- go test -v ./...
|
29
vendor/github.com/russross/blackfriday/v2/LICENSE.txt
generated
vendored
Normal file
29
vendor/github.com/russross/blackfriday/v2/LICENSE.txt
generated
vendored
Normal file
|
@ -0,0 +1,29 @@
|
|||
Blackfriday is distributed under the Simplified BSD License:
|
||||
|
||||
> Copyright © 2011 Russ Ross
|
||||
> All rights reserved.
|
||||
>
|
||||
> Redistribution and use in source and binary forms, with or without
|
||||
> modification, are permitted provided that the following conditions
|
||||
> are met:
|
||||
>
|
||||
> 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 HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
> INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
> BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
> LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
> CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
> LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
> ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
> POSSIBILITY OF SUCH DAMAGE.
|
291
vendor/github.com/russross/blackfriday/v2/README.md
generated
vendored
Normal file
291
vendor/github.com/russross/blackfriday/v2/README.md
generated
vendored
Normal file
|
@ -0,0 +1,291 @@
|
|||
Blackfriday [![Build Status](https://travis-ci.org/russross/blackfriday.svg?branch=master)](https://travis-ci.org/russross/blackfriday)
|
||||
===========
|
||||
|
||||
Blackfriday is a [Markdown][1] processor implemented in [Go][2]. It
|
||||
is paranoid about its input (so you can safely feed it user-supplied
|
||||
data), it is fast, it supports common extensions (tables, smart
|
||||
punctuation substitutions, etc.), and it is safe for all utf-8
|
||||
(unicode) input.
|
||||
|
||||
HTML output is currently supported, along with Smartypants
|
||||
extensions.
|
||||
|
||||
It started as a translation from C of [Sundown][3].
|
||||
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
Blackfriday is compatible with any modern Go release. With Go 1.7 and git
|
||||
installed:
|
||||
|
||||
go get gopkg.in/russross/blackfriday.v2
|
||||
|
||||
will download, compile, and install the package into your `$GOPATH`
|
||||
directory hierarchy. Alternatively, you can achieve the same if you
|
||||
import it into a project:
|
||||
|
||||
import "gopkg.in/russross/blackfriday.v2"
|
||||
|
||||
and `go get` without parameters.
|
||||
|
||||
|
||||
Versions
|
||||
--------
|
||||
|
||||
Currently maintained and recommended version of Blackfriday is `v2`. It's being
|
||||
developed on its own branch: https://github.com/russross/blackfriday/tree/v2 and the
|
||||
documentation is available at
|
||||
https://godoc.org/gopkg.in/russross/blackfriday.v2.
|
||||
|
||||
It is `go get`-able via via [gopkg.in][6] at `gopkg.in/russross/blackfriday.v2`,
|
||||
but we highly recommend using package management tool like [dep][7] or
|
||||
[Glide][8] and make use of semantic versioning. With package management you
|
||||
should import `github.com/russross/blackfriday` and specify that you're using
|
||||
version 2.0.0.
|
||||
|
||||
Version 2 offers a number of improvements over v1:
|
||||
|
||||
* Cleaned up API
|
||||
* A separate call to [`Parse`][4], which produces an abstract syntax tree for
|
||||
the document
|
||||
* Latest bug fixes
|
||||
* Flexibility to easily add your own rendering extensions
|
||||
|
||||
Potential drawbacks:
|
||||
|
||||
* Our benchmarks show v2 to be slightly slower than v1. Currently in the
|
||||
ballpark of around 15%.
|
||||
* API breakage. If you can't afford modifying your code to adhere to the new API
|
||||
and don't care too much about the new features, v2 is probably not for you.
|
||||
* Several bug fixes are trailing behind and still need to be forward-ported to
|
||||
v2. See issue [#348](https://github.com/russross/blackfriday/issues/348) for
|
||||
tracking.
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
For the most sensible markdown processing, it is as simple as getting your input
|
||||
into a byte slice and calling:
|
||||
|
||||
```go
|
||||
output := blackfriday.Run(input)
|
||||
```
|
||||
|
||||
Your input will be parsed and the output rendered with a set of most popular
|
||||
extensions enabled. If you want the most basic feature set, corresponding with
|
||||
the bare Markdown specification, use:
|
||||
|
||||
```go
|
||||
output := blackfriday.Run(input, blackfriday.WithNoExtensions())
|
||||
```
|
||||
|
||||
### Sanitize untrusted content
|
||||
|
||||
Blackfriday itself does nothing to protect against malicious content. If you are
|
||||
dealing with user-supplied markdown, we recommend running Blackfriday's output
|
||||
through HTML sanitizer such as [Bluemonday][5].
|
||||
|
||||
Here's an example of simple usage of Blackfriday together with Bluemonday:
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/microcosm-cc/bluemonday"
|
||||
"github.com/russross/blackfriday"
|
||||
)
|
||||
|
||||
// ...
|
||||
unsafe := blackfriday.Run(input)
|
||||
html := bluemonday.UGCPolicy().SanitizeBytes(unsafe)
|
||||
```
|
||||
|
||||
### Custom options
|
||||
|
||||
If you want to customize the set of options, use `blackfriday.WithExtensions`,
|
||||
`blackfriday.WithRenderer` and `blackfriday.WithRefOverride`.
|
||||
|
||||
You can also check out `blackfriday-tool` for a more complete example
|
||||
of how to use it. Download and install it using:
|
||||
|
||||
go get github.com/russross/blackfriday-tool
|
||||
|
||||
This is a simple command-line tool that allows you to process a
|
||||
markdown file using a standalone program. You can also browse the
|
||||
source directly on github if you are just looking for some example
|
||||
code:
|
||||
|
||||
* <http://github.com/russross/blackfriday-tool>
|
||||
|
||||
Note that if you have not already done so, installing
|
||||
`blackfriday-tool` will be sufficient to download and install
|
||||
blackfriday in addition to the tool itself. The tool binary will be
|
||||
installed in `$GOPATH/bin`. This is a statically-linked binary that
|
||||
can be copied to wherever you need it without worrying about
|
||||
dependencies and library versions.
|
||||
|
||||
|
||||
Features
|
||||
--------
|
||||
|
||||
All features of Sundown are supported, including:
|
||||
|
||||
* **Compatibility**. The Markdown v1.0.3 test suite passes with
|
||||
the `--tidy` option. Without `--tidy`, the differences are
|
||||
mostly in whitespace and entity escaping, where blackfriday is
|
||||
more consistent and cleaner.
|
||||
|
||||
* **Common extensions**, including table support, fenced code
|
||||
blocks, autolinks, strikethroughs, non-strict emphasis, etc.
|
||||
|
||||
* **Safety**. Blackfriday is paranoid when parsing, making it safe
|
||||
to feed untrusted user input without fear of bad things
|
||||
happening. The test suite stress tests this and there are no
|
||||
known inputs that make it crash. If you find one, please let me
|
||||
know and send me the input that does it.
|
||||
|
||||
NOTE: "safety" in this context means *runtime safety only*. In order to
|
||||
protect yourself against JavaScript injection in untrusted content, see
|
||||
[this example](https://github.com/russross/blackfriday#sanitize-untrusted-content).
|
||||
|
||||
* **Fast processing**. It is fast enough to render on-demand in
|
||||
most web applications without having to cache the output.
|
||||
|
||||
* **Thread safety**. You can run multiple parsers in different
|
||||
goroutines without ill effect. There is no dependence on global
|
||||
shared state.
|
||||
|
||||
* **Minimal dependencies**. Blackfriday only depends on standard
|
||||
library packages in Go. The source code is pretty
|
||||
self-contained, so it is easy to add to any project, including
|
||||
Google App Engine projects.
|
||||
|
||||
* **Standards compliant**. Output successfully validates using the
|
||||
W3C validation tool for HTML 4.01 and XHTML 1.0 Transitional.
|
||||
|
||||
|
||||
Extensions
|
||||
----------
|
||||
|
||||
In addition to the standard markdown syntax, this package
|
||||
implements the following extensions:
|
||||
|
||||
* **Intra-word emphasis supression**. The `_` character is
|
||||
commonly used inside words when discussing code, so having
|
||||
markdown interpret it as an emphasis command is usually the
|
||||
wrong thing. Blackfriday lets you treat all emphasis markers as
|
||||
normal characters when they occur inside a word.
|
||||
|
||||
* **Tables**. Tables can be created by drawing them in the input
|
||||
using a simple syntax:
|
||||
|
||||
```
|
||||
Name | Age
|
||||
--------|------
|
||||
Bob | 27
|
||||
Alice | 23
|
||||
```
|
||||
|
||||
* **Fenced code blocks**. In addition to the normal 4-space
|
||||
indentation to mark code blocks, you can explicitly mark them
|
||||
and supply a language (to make syntax highlighting simple). Just
|
||||
mark it like this:
|
||||
|
||||
```go
|
||||
func getTrue() bool {
|
||||
return true
|
||||
}
|
||||
```
|
||||
|
||||
You can use 3 or more backticks to mark the beginning of the
|
||||
block, and the same number to mark the end of the block.
|
||||
|
||||
* **Definition lists**. A simple definition list is made of a single-line
|
||||
term followed by a colon and the definition for that term.
|
||||
|
||||
Cat
|
||||
: Fluffy animal everyone likes
|
||||
|
||||
Internet
|
||||
: Vector of transmission for pictures of cats
|
||||
|
||||
Terms must be separated from the previous definition by a blank line.
|
||||
|
||||
* **Footnotes**. A marker in the text that will become a superscript number;
|
||||
a footnote definition that will be placed in a list of footnotes at the
|
||||
end of the document. A footnote looks like this:
|
||||
|
||||
This is a footnote.[^1]
|
||||
|
||||
[^1]: the footnote text.
|
||||
|
||||
* **Autolinking**. Blackfriday can find URLs that have not been
|
||||
explicitly marked as links and turn them into links.
|
||||
|
||||
* **Strikethrough**. Use two tildes (`~~`) to mark text that
|
||||
should be crossed out.
|
||||
|
||||
* **Hard line breaks**. With this extension enabled newlines in the input
|
||||
translate into line breaks in the output. This extension is off by default.
|
||||
|
||||
* **Smart quotes**. Smartypants-style punctuation substitution is
|
||||
supported, turning normal double- and single-quote marks into
|
||||
curly quotes, etc.
|
||||
|
||||
* **LaTeX-style dash parsing** is an additional option, where `--`
|
||||
is translated into `–`, and `---` is translated into
|
||||
`—`. This differs from most smartypants processors, which
|
||||
turn a single hyphen into an ndash and a double hyphen into an
|
||||
mdash.
|
||||
|
||||
* **Smart fractions**, where anything that looks like a fraction
|
||||
is translated into suitable HTML (instead of just a few special
|
||||
cases like most smartypant processors). For example, `4/5`
|
||||
becomes `<sup>4</sup>⁄<sub>5</sub>`, which renders as
|
||||
<sup>4</sup>⁄<sub>5</sub>.
|
||||
|
||||
|
||||
Other renderers
|
||||
---------------
|
||||
|
||||
Blackfriday is structured to allow alternative rendering engines. Here
|
||||
are a few of note:
|
||||
|
||||
* [github_flavored_markdown](https://godoc.org/github.com/shurcooL/github_flavored_markdown):
|
||||
provides a GitHub Flavored Markdown renderer with fenced code block
|
||||
highlighting, clickable heading anchor links.
|
||||
|
||||
It's not customizable, and its goal is to produce HTML output
|
||||
equivalent to the [GitHub Markdown API endpoint](https://developer.github.com/v3/markdown/#render-a-markdown-document-in-raw-mode),
|
||||
except the rendering is performed locally.
|
||||
|
||||
* [markdownfmt](https://github.com/shurcooL/markdownfmt): like gofmt,
|
||||
but for markdown.
|
||||
|
||||
* [LaTeX output](https://github.com/Ambrevar/Blackfriday-LaTeX):
|
||||
renders output as LaTeX.
|
||||
|
||||
* [Blackfriday-Confluence](https://github.com/kentaro-m/blackfriday-confluence): provides a [Confluence Wiki Markup](https://confluence.atlassian.com/doc/confluence-wiki-markup-251003035.html) renderer.
|
||||
|
||||
|
||||
Todo
|
||||
----
|
||||
|
||||
* More unit testing
|
||||
* Improve unicode support. It does not understand all unicode
|
||||
rules (about what constitutes a letter, a punctuation symbol,
|
||||
etc.), so it may fail to detect word boundaries correctly in
|
||||
some instances. It is safe on all utf-8 input.
|
||||
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
[Blackfriday is distributed under the Simplified BSD License](LICENSE.txt)
|
||||
|
||||
|
||||
[1]: https://daringfireball.net/projects/markdown/ "Markdown"
|
||||
[2]: https://golang.org/ "Go Language"
|
||||
[3]: https://github.com/vmg/sundown "Sundown"
|
||||
[4]: https://godoc.org/gopkg.in/russross/blackfriday.v2#Parse "Parse func"
|
||||
[5]: https://github.com/microcosm-cc/bluemonday "Bluemonday"
|
||||
[6]: https://labix.org/gopkg.in "gopkg.in"
|
1590
vendor/github.com/russross/blackfriday/v2/block.go
generated
vendored
Normal file
1590
vendor/github.com/russross/blackfriday/v2/block.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
18
vendor/github.com/russross/blackfriday/v2/doc.go
generated
vendored
Normal file
18
vendor/github.com/russross/blackfriday/v2/doc.go
generated
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
// Package blackfriday is a markdown processor.
|
||||
//
|
||||
// It translates plain text with simple formatting rules into an AST, which can
|
||||
// then be further processed to HTML (provided by Blackfriday itself) or other
|
||||
// formats (provided by the community).
|
||||
//
|
||||
// The simplest way to invoke Blackfriday is to call the Run function. It will
|
||||
// take a text input and produce a text output in HTML (or other format).
|
||||
//
|
||||
// A slightly more sophisticated way to use Blackfriday is to create a Markdown
|
||||
// processor and to call Parse, which returns a syntax tree for the input
|
||||
// document. You can leverage Blackfriday's parsing for content extraction from
|
||||
// markdown documents. You can assign a custom renderer and set various options
|
||||
// to the Markdown processor.
|
||||
//
|
||||
// If you're interested in calling Blackfriday from command line, see
|
||||
// https://github.com/russross/blackfriday-tool.
|
||||
package blackfriday
|
34
vendor/github.com/russross/blackfriday/v2/esc.go
generated
vendored
Normal file
34
vendor/github.com/russross/blackfriday/v2/esc.go
generated
vendored
Normal file
|
@ -0,0 +1,34 @@
|
|||
package blackfriday
|
||||
|
||||
import (
|
||||
"html"
|
||||
"io"
|
||||
)
|
||||
|
||||
var htmlEscaper = [256][]byte{
|
||||
'&': []byte("&"),
|
||||
'<': []byte("<"),
|
||||
'>': []byte(">"),
|
||||
'"': []byte("""),
|
||||
}
|
||||
|
||||
func escapeHTML(w io.Writer, s []byte) {
|
||||
var start, end int
|
||||
for end < len(s) {
|
||||
escSeq := htmlEscaper[s[end]]
|
||||
if escSeq != nil {
|
||||
w.Write(s[start:end])
|
||||
w.Write(escSeq)
|
||||
start = end + 1
|
||||
}
|
||||
end++
|
||||
}
|
||||
if start < len(s) && end <= len(s) {
|
||||
w.Write(s[start:end])
|
||||
}
|
||||
}
|
||||
|
||||
func escLink(w io.Writer, text []byte) {
|
||||
unesc := html.UnescapeString(string(text))
|
||||
escapeHTML(w, []byte(unesc))
|
||||
}
|
1
vendor/github.com/russross/blackfriday/v2/go.mod
generated
vendored
Normal file
1
vendor/github.com/russross/blackfriday/v2/go.mod
generated
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
module github.com/russross/blackfriday/v2
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue