mirror of
https://github.com/mattermost/mattermost.git
synced 2026-05-28 04:35:04 -04:00
MM-43753: Module workspaces (#20113)
* MM-43753: Module workspaces Move to module workspaces We make the following changes: - Remove the vendor directory. - Dynamically create the go.work file if it doesn't exist. - Set the MM_SERVER_PATH for enterprise tests. https://mattermost.atlassian.net/browse/MM-43753 ```release-note NONE ``` * Fix missing reference to MM_SERVER_PATH ```release-note NONE ``` * Update test to add another nested dir ```release-note NONE ``` * Have separate script to create go.work file ```release-note NONE ``` Co-authored-by: Mattermod <mattermod@users.noreply.github.com>
This commit is contained in:
parent
cd487c812c
commit
38d0c2bcf3
5048 changed files with 57 additions and 1888164 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
|
@ -25,6 +25,10 @@ config/logging.json
|
|||
# Enterprise imports file
|
||||
imports/imports.go
|
||||
|
||||
# go.work file
|
||||
go.work
|
||||
go.work.sum
|
||||
|
||||
#license files
|
||||
*.license
|
||||
*.mattermost-license
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
run:
|
||||
timeout: 5m
|
||||
modules-download-mode: vendor
|
||||
skip-dirs:
|
||||
- store/storetest/mocks
|
||||
|
||||
|
|
|
|||
26
Makefile
26
Makefile
|
|
@ -111,7 +111,7 @@ DIST_PATH_WIN=$(DIST_ROOT)/windows/mattermost
|
|||
TESTS=.
|
||||
|
||||
# Packages lists
|
||||
TE_PACKAGES=$(shell $(GO) list ./... | grep -v ./data)
|
||||
TE_PACKAGES=$(shell $(GO) list ./...)
|
||||
|
||||
TEMPLATES_DIR=templates
|
||||
|
||||
|
|
@ -138,12 +138,11 @@ ifeq ($(BUILD_ENTERPRISE_READY),true)
|
|||
IGNORE:=$(shell rm -f imports/imports.go)
|
||||
IGNORE:=$(shell cp $(BUILD_ENTERPRISE_DIR)/imports/imports.go imports/)
|
||||
IGNORE:=$(shell rm -f enterprise)
|
||||
IGNORE:=$(shell ln -s $(BUILD_ENTERPRISE_DIR) enterprise)
|
||||
else
|
||||
IGNORE:=$(shell rm -f imports/imports.go)
|
||||
endif
|
||||
|
||||
EE_PACKAGES=$(shell $(GO) list ./enterprise/...)
|
||||
EE_PACKAGES=$(shell $(GO) list $(BUILD_ENTERPRISE_DIR)/...)
|
||||
|
||||
ifeq ($(BUILD_ENTERPRISE_READY),true)
|
||||
ALL_PACKAGES=$(TE_PACKAGES) $(EE_PACKAGES)
|
||||
|
|
@ -256,7 +255,7 @@ golangci-lint: ## Run golangci-lint on codebase
|
|||
$(GOBIN)/golangci-lint run ./...
|
||||
ifeq ($(BUILD_ENTERPRISE_READY),true)
|
||||
ifneq ($(MM_NO_ENTERPRISE_LINT),true)
|
||||
$(GOBIN)/golangci-lint run ./enterprise/...
|
||||
$(GOBIN)/golangci-lint run ../enterprise/...
|
||||
endif
|
||||
endif
|
||||
|
||||
|
|
@ -336,11 +335,16 @@ pluginapi: ## Generates api and hooks glue code for plugins
|
|||
check-prereqs: ## Checks prerequisite software status.
|
||||
./scripts/prereq-check.sh
|
||||
|
||||
check-prereqs-enterprise: ## Checks prerequisite software status for enterprise.
|
||||
check-prereqs-enterprise: setup-go-work ## Checks prerequisite software status for enterprise.
|
||||
ifeq ($(BUILD_ENTERPRISE_READY),true)
|
||||
./scripts/prereq-check-enterprise.sh
|
||||
endif
|
||||
|
||||
setup-go-work: ## Sets up your go.work file
|
||||
ifeq ($(BUILD_ENTERPRISE_READY),true)
|
||||
./scripts/setup_go_work.sh
|
||||
endif
|
||||
|
||||
check-style: golangci-lint plugin-checker vet ## Runs style/lint checks
|
||||
|
||||
|
||||
|
|
@ -469,7 +473,7 @@ validate-go-version: ## Validates the installed version of go against Mattermost
|
|||
build-templates: ## Compile all mjml email templates
|
||||
cd $(TEMPLATES_DIR) && $(MAKE) build
|
||||
|
||||
run-server: prepackaged-binaries validate-go-version start-docker ## Starts the server.
|
||||
run-server: prepackaged-binaries validate-go-version start-docker setup-go-work ## Starts the server.
|
||||
@echo Running mattermost for development
|
||||
|
||||
mkdir -p $(BUILD_WEBAPP_DIR)/dist/files
|
||||
|
|
@ -589,7 +593,7 @@ clean: stop-docker ## Clean up everything except persistent server data.
|
|||
|
||||
cd $(BUILD_WEBAPP_DIR) && $(MAKE) clean
|
||||
|
||||
find . -type d -name data -not -path './vendor/*' | xargs rm -rf
|
||||
find . -type d -name data | xargs rm -rf
|
||||
rm -rf logs
|
||||
|
||||
rm -f mattermost.log
|
||||
|
|
@ -622,7 +626,7 @@ update-dependencies: ## Uses go get -u to update all the dependencies while hold
|
|||
$(GO) mod tidy
|
||||
|
||||
# Copy everything to vendor directory
|
||||
$(GO) mod vendor
|
||||
# $(GO) mod vendor
|
||||
|
||||
# Tidy up
|
||||
$(GO) mod tidy
|
||||
|
|
@ -638,7 +642,7 @@ vet: ## Run mattermost go vet specific checks
|
|||
$(GO) vet -vettool=$(GOBIN)/mattermost-govet $$VET_CMD ./...
|
||||
ifeq ($(BUILD_ENTERPRISE_READY),true)
|
||||
ifneq ($(MM_NO_ENTERPRISE_LINT),true)
|
||||
$(GO) vet -vettool=$(GOBIN)/mattermost-govet -enterpriseLicense -structuredLogging -tFatal ./enterprise/...
|
||||
$(GO) vet -vettool=$(GOBIN)/mattermost-govet -enterpriseLicense -structuredLogging -tFatal ../enterprise/...
|
||||
endif
|
||||
endif
|
||||
|
||||
|
|
@ -666,9 +670,9 @@ gen-serialized: ## Generates serialization methods for hot structs
|
|||
@mv tmp.go ./model/team_member_serial_gen.go
|
||||
|
||||
todo: ## Display TODO and FIXME items in the source code.
|
||||
@! ag --ignore Makefile --ignore-dir vendor --ignore-dir runtime '(TODO|XXX|FIXME|"FIX ME")[: ]+'
|
||||
@! ag --ignore Makefile --ignore-dir runtime '(TODO|XXX|FIXME|"FIX ME")[: ]+'
|
||||
ifeq ($(BUILD_ENTERPRISE_READY),true)
|
||||
@! ag --ignore Makefile --ignore-dir vendor --ignore-dir runtime '(TODO|XXX|FIXME|"FIX ME")[: ]+' enterprise/
|
||||
@! ag --ignore Makefile --ignore-dir runtime '(TODO|XXX|FIXME|"FIX ME")[: ]+' enterprise/
|
||||
endif
|
||||
|
||||
## Help documentation à la https://marmelab.com/blog/2016/02/29/auto-documented-makefile.html
|
||||
|
|
|
|||
|
|
@ -6,18 +6,6 @@ package main
|
|||
import (
|
||||
"os"
|
||||
|
||||
// Enterprise Deps
|
||||
_ "github.com/gorilla/handlers"
|
||||
_ "github.com/hako/durafmt"
|
||||
_ "github.com/hashicorp/memberlist"
|
||||
_ "github.com/mattermost/gosaml2"
|
||||
_ "github.com/mattermost/ldap"
|
||||
_ "github.com/mattermost/rsc/qr"
|
||||
_ "github.com/prometheus/client_golang/prometheus"
|
||||
_ "github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
_ "github.com/tylerb/graceful"
|
||||
_ "gopkg.in/olivere/elastic.v6"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/cmd/mattermost/commands"
|
||||
// Import and register app layer slash commands
|
||||
_ "github.com/mattermost/mattermost-server/v6/app/slashcommands"
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import (
|
|||
|
||||
// TestRunMain can be used to track code coverage in integration tests.
|
||||
// To run this:
|
||||
// go test -coverpkg="<>" -mod=vendor -ldflags '<>' -tags maincoverage -c ./cmd/mattermost/
|
||||
// go test -coverpkg="<>" -ldflags '<>' -tags maincoverage -c ./cmd/mattermost/
|
||||
// ./mattermost.test -test.run="^TestRunMain$" -test.coverprofile=coverage.out
|
||||
// And then run your integration tests.
|
||||
func TestRunMain(t *testing.T) {
|
||||
|
|
|
|||
28
go.mod
28
go.mod
|
|
@ -28,17 +28,13 @@ require (
|
|||
github.com/graph-gophers/dataloader/v6 v6.0.0
|
||||
github.com/graph-gophers/graphql-go v1.3.0
|
||||
github.com/h2non/go-is-svg v0.0.0-20160927212452-35e8c4b0612c
|
||||
github.com/hako/durafmt v0.0.0-20210608085754-5c1018a4e16b
|
||||
github.com/hashicorp/go-hclog v1.2.0
|
||||
github.com/hashicorp/go-plugin v1.4.3
|
||||
github.com/hashicorp/memberlist v0.3.1
|
||||
github.com/jaytaylor/html2text v0.0.0-20211105163654-bc68cce691ba
|
||||
github.com/jmoiron/sqlx v1.3.4
|
||||
github.com/jonboulle/clockwork v0.2.3
|
||||
github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80
|
||||
github.com/lib/pq v1.10.4
|
||||
github.com/mattermost/go-i18n v1.11.1-0.20211013152124-5c415071e404
|
||||
github.com/mattermost/gosaml2 v0.8.1-0.20220428161029-8c99721fdec4
|
||||
github.com/mattermost/gziphandler v0.0.1
|
||||
github.com/mattermost/ldap v0.0.0-20201202150706-ee0e6284187d
|
||||
github.com/mattermost/logr/v2 v2.0.15
|
||||
|
|
@ -51,19 +47,15 @@ require (
|
|||
github.com/opentracing/opentracing-go v1.2.0
|
||||
github.com/pborman/uuid v1.2.1
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/prometheus/client_golang v1.12.1
|
||||
github.com/prometheus/client_model v0.2.0
|
||||
github.com/reflog/dateconstraints v0.2.1
|
||||
github.com/rs/cors v1.8.2
|
||||
github.com/rudderlabs/analytics-go v3.3.2+incompatible
|
||||
github.com/russellhaering/goxmldsig v1.2.0
|
||||
github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd
|
||||
github.com/spf13/cobra v1.4.0
|
||||
github.com/splitio/go-client/v6 v6.1.0
|
||||
github.com/stretchr/testify v1.7.1
|
||||
github.com/throttled/throttled v2.2.5+incompatible
|
||||
github.com/tinylib/msgp v1.1.6
|
||||
github.com/tylerb/graceful v1.2.15
|
||||
github.com/uber/jaeger-client-go v2.30.0+incompatible
|
||||
github.com/uber/jaeger-lib v2.4.1+incompatible
|
||||
github.com/vmihailenco/msgpack/v5 v5.3.5
|
||||
|
|
@ -77,7 +69,6 @@ require (
|
|||
golang.org/x/text v0.3.7
|
||||
golang.org/x/tools v0.1.10
|
||||
gopkg.in/mail.v2 v2.3.1
|
||||
gopkg.in/olivere/elastic.v6 v6.2.37
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
)
|
||||
|
||||
|
|
@ -90,10 +81,7 @@ require (
|
|||
github.com/andybalholm/brotli v1.0.4 // indirect
|
||||
github.com/andybalholm/cascadia v1.3.1 // indirect
|
||||
github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de // indirect
|
||||
github.com/armon/go-metrics v0.3.10 // indirect
|
||||
github.com/aymerick/douceur v0.2.0 // indirect
|
||||
github.com/beevik/etree v1.1.0 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/bits-and-blooms/bitset v1.2.2 // indirect
|
||||
github.com/blevesearch/bleve_index_api v1.0.1 // indirect
|
||||
github.com/blevesearch/go-porterstemmer v1.0.3 // indirect
|
||||
|
|
@ -116,7 +104,6 @@ require (
|
|||
github.com/fatih/color v1.13.0 // indirect
|
||||
github.com/fatih/set v0.2.1 // indirect
|
||||
github.com/felixge/httpsnoop v1.0.2 // indirect
|
||||
github.com/fortytw2/leaktest v1.3.0 // indirect
|
||||
github.com/gigawattio/window v0.0.0-20180317192513-0f5467e35573 // indirect
|
||||
github.com/go-asn1-ber/asn1-ber v1.5.3 // indirect
|
||||
github.com/go-redis/redis/v8 v8.11.5 // indirect
|
||||
|
|
@ -124,35 +111,27 @@ require (
|
|||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/gomodule/redigo v2.0.0+incompatible // indirect
|
||||
github.com/google/btree v1.0.1 // indirect
|
||||
github.com/google/uuid v1.3.0 // indirect
|
||||
github.com/gopherjs/gopherjs v0.0.0-20220221023154-0b2280d3ff96 // indirect
|
||||
github.com/gorilla/css v1.0.0 // indirect
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
github.com/hashicorp/go-immutable-radix v1.3.1 // indirect
|
||||
github.com/hashicorp/go-msgpack v1.1.5 // indirect
|
||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||
github.com/hashicorp/go-sockaddr v1.0.2 // indirect
|
||||
github.com/hashicorp/golang-lru v0.5.4 // indirect
|
||||
github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.0.0 // indirect
|
||||
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/klauspost/compress v1.15.1 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.0.12 // indirect
|
||||
github.com/klauspost/pgzip v1.2.5 // indirect
|
||||
github.com/kr/pretty v0.3.0 // indirect
|
||||
github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect
|
||||
github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect
|
||||
github.com/levigross/exp-html v0.0.0-20120902181939-8df60c69a8f5 // indirect
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/mattermost/xml-roundtrip-validator v0.1.0 // indirect
|
||||
github.com/mattn/go-colorable v0.1.12 // indirect
|
||||
github.com/mattn/go-isatty v0.0.14 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.13 // indirect
|
||||
github.com/mattn/go-sqlite3 v2.0.3+incompatible // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect
|
||||
github.com/miekg/dns v1.1.48 // indirect
|
||||
github.com/minio/md5-simd v1.1.2 // indirect
|
||||
github.com/minio/sha256-simd v1.0.0 // indirect
|
||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||
|
|
@ -163,19 +142,16 @@ require (
|
|||
github.com/nwaples/rardecode v1.1.3 // indirect
|
||||
github.com/oklog/run v1.1.0 // indirect
|
||||
github.com/olekukonko/tablewriter v0.0.5 // indirect
|
||||
github.com/olivere/elastic v6.2.37+incompatible // indirect
|
||||
github.com/otiai10/gosseract/v2 v2.3.1 // indirect
|
||||
github.com/pelletier/go-toml v1.9.4 // indirect
|
||||
github.com/philhofer/fwd v1.1.1 // indirect
|
||||
github.com/pierrec/lz4/v4 v4.1.14 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/prometheus/common v0.33.0 // indirect
|
||||
github.com/prometheus/procfs v0.7.3 // indirect
|
||||
github.com/richardlehane/mscfb v1.0.4 // indirect
|
||||
github.com/richardlehane/msoleps v1.0.1 // indirect
|
||||
github.com/rivo/uniseg v0.2.0 // indirect
|
||||
github.com/rogpeppe/go-internal v1.8.0 // indirect
|
||||
github.com/rs/xid v1.4.0 // indirect
|
||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 // indirect
|
||||
github.com/segmentio/backo-go v0.0.0-20200129164019-23eae7c10bd3 // indirect
|
||||
github.com/sirupsen/logrus v1.8.1 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
|
|
|
|||
90
go.sum
90
go.sum
|
|
@ -75,7 +75,6 @@ github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ
|
|||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/ClickHouse/clickhouse-go v1.4.3/go.mod h1:EaI/sW7Azgz9UATzd5ZdZHRUhHgv5+JMS9NSr2smCJI=
|
||||
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
|
||||
github.com/HdrHistogram/hdrhistogram-go v0.9.0 h1:dpujRju0R4M/QZzcnR1LH1qm+TVG3UzkWdp5tH1WMcg=
|
||||
github.com/HdrHistogram/hdrhistogram-go v0.9.0/go.mod h1:nxrse8/Tzg2tg3DZcZjm6qEclQKK70g0KxO61gFFZD4=
|
||||
github.com/JalfResi/justext v0.0.0-20170829062021-c0282dea7198 h1:8P+AjBhGByCuCX2zTkAf6UY+dj0JczX+t6cSdCSyvfw=
|
||||
|
|
@ -120,7 +119,6 @@ github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuy
|
|||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
|
||||
github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:CgnQgUtFrFz9mxFNtED3jI5tLDjKlOM+oUF/sTk6ps0=
|
||||
github.com/andybalholm/brotli v1.0.1/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
|
||||
github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY=
|
||||
|
|
@ -141,8 +139,6 @@ github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de/go.mod h1:DCaWoU
|
|||
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
|
||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
|
||||
github.com/armon/go-metrics v0.3.10 h1:FR+drcQStOe+32sYyJYyZ7FIdgoGGBnwLl+flodp8Uo=
|
||||
github.com/armon/go-metrics v0.3.10/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc=
|
||||
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
||||
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
|
||||
github.com/avct/uasurfer v0.0.0-20191028135549-26b5daa857f1 h1:9h8f71kuF1pqovnn9h7LTHLEjxzyQaj0j1rQq5nsMM4=
|
||||
|
|
@ -179,12 +175,9 @@ github.com/aws/smithy-go v1.7.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAm
|
|||
github.com/aws/smithy-go v1.8.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E=
|
||||
github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk=
|
||||
github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4=
|
||||
github.com/beevik/etree v1.1.0 h1:T0xke/WvNtMoCqgzPhkX2r4rjY3GDZFi+FjpRZY2Jbs=
|
||||
github.com/beevik/etree v1.1.0/go.mod h1:r8Aw8JqVegEf0w2fDnATrX9VpkMcyFeM0FhwO62wh+A=
|
||||
github.com/beorn7/perks v0.0.0-20160804104726-4c0e84591b9a/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
|
||||
github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932/go.mod h1:NOuUCSz6Q9T7+igc/hlvDOUdtWKryOrtFyIVABv/p7k=
|
||||
|
|
@ -257,8 +250,6 @@ github.com/cilium/ebpf v0.0.0-20200702112145-1c8d4c9ef775/go.mod h1:7cR51M8ViRLI
|
|||
github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs=
|
||||
github.com/cilium/ebpf v0.4.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs=
|
||||
github.com/cilium/ebpf v0.6.2/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs=
|
||||
github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag=
|
||||
github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58/go.mod h1:EOBUe0h4xcZ5GoxqC5SDxFQ8gwyZPKQoEzownBlhI80=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
|
|
@ -455,8 +446,6 @@ github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/
|
|||
github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
|
||||
github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
|
||||
github.com/form3tech-oss/jwt-go v3.2.5+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
|
||||
github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw=
|
||||
github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=
|
||||
github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk=
|
||||
github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY=
|
||||
github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k=
|
||||
|
|
@ -491,13 +480,9 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2
|
|||
github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
|
||||
github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0=
|
||||
github.com/go-latex/latex v0.0.0-20210118124228-b3d85cf34e07/go.mod h1:CO1AlKB2CSIqUrmQPqA0gdRIlnLEY0gK5JGjh37zN5U=
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
|
||||
github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
|
||||
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
|
||||
github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
|
||||
github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
|
||||
|
|
@ -611,8 +596,6 @@ github.com/gomodule/redigo v2.0.0+incompatible h1:K/R+8tc58AaqLkqG2Ol3Qk+DR/TlNu
|
|||
github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4=
|
||||
github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA=
|
||||
github.com/google/flatbuffers v2.0.0+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
|
|
@ -698,25 +681,18 @@ github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFb
|
|||
github.com/h2non/go-is-svg v0.0.0-20160927212452-35e8c4b0612c h1:fEE5/5VNnYUoBOj2I9TP8Jc+a7lge3QWn9DKE7NCwfc=
|
||||
github.com/h2non/go-is-svg v0.0.0-20160927212452-35e8c4b0612c/go.mod h1:ObS/W+h8RYb1Y7fYivughjxojTmIu5iAIjSrSLCLeqE=
|
||||
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4=
|
||||
github.com/hako/durafmt v0.0.0-20210608085754-5c1018a4e16b h1:wDUNC2eKiL35DbLvsDhiblTUXHxcOPwQSCzi7xpQUN4=
|
||||
github.com/hako/durafmt v0.0.0-20210608085754-5c1018a4e16b/go.mod h1:VzxiSdG6j1pi7rwGm/xYI5RbtpBgM8sARDXlvEvxlu0=
|
||||
github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
|
||||
github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
|
||||
github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
|
||||
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
|
||||
github.com/hashicorp/go-hclog v0.14.1/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
|
||||
github.com/hashicorp/go-hclog v1.2.0 h1:La19f8d7WIlm4ogzNHB0JGqs5AUDAZ2UfCY4sJXcJdM=
|
||||
github.com/hashicorp/go-hclog v1.2.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
|
||||
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
|
||||
github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc=
|
||||
github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
|
||||
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
|
||||
github.com/hashicorp/go-msgpack v1.1.5 h1:9byZdVjKTe5mce63pRVNP1L7UAmdHOTEMGehn6KvJWs=
|
||||
github.com/hashicorp/go-msgpack v1.1.5/go.mod h1:gWVc3sv/wbDmR3rQsj1CAktEZzoz1YNK9NfGLXJ69/4=
|
||||
github.com/hashicorp/go-multierror v0.0.0-20161216184304-ed905158d874/go.mod h1:JMRHfdO9jKNzS/+BTlxCjKNQHg/jZAft8U7LloJvN7I=
|
||||
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
|
||||
github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA=
|
||||
|
|
@ -724,14 +700,10 @@ github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+l
|
|||
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
|
||||
github.com/hashicorp/go-plugin v1.4.3 h1:DXmvivbWD5qdiBts9TpBC7BYL1Aia5sxbRgQB+v6UZM=
|
||||
github.com/hashicorp/go-plugin v1.4.3/go.mod h1:5fGEH17QVwTTcR0zV7yhDPLLmFX9YSZ38b18Udy6vYQ=
|
||||
github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs=
|
||||
github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
|
||||
github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
|
||||
github.com/hashicorp/go-sockaddr v1.0.2 h1:ztczhD1jLxIRjVejw8gFomI1BQZOe2WoVOu0SyteCQc=
|
||||
github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A=
|
||||
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
|
||||
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/go-uuid v1.0.1 h1:fv1ep09latC32wFoVwnqcnKJGnMSdBanPczbHAYm1BE=
|
||||
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
|
|
@ -742,8 +714,6 @@ github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T
|
|||
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
|
||||
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
|
||||
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
|
||||
github.com/hashicorp/memberlist v0.3.1 h1:MXgUXLqva1QvpVEDQW1IQLG0wivQAtmFlHRQ+1vWZfM=
|
||||
github.com/hashicorp/memberlist v0.3.1/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE=
|
||||
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
|
||||
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
|
||||
github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87 h1:xixZ2bWeofWV68J+x6AzmKuVM/JWCQwkWm6GW/MUR6I=
|
||||
|
|
@ -824,24 +794,15 @@ github.com/jmoiron/sqlx v1.3.4 h1:wv+0IJZfL5z0uZoUjlpKgHkgaFSYD+r9CfrXjEXsO7w=
|
|||
github.com/jmoiron/sqlx v1.3.4/go.mod h1:2BljVx/86SuTyjE+aPYlHCTNvZrnJXghYGpNiXLBMCQ=
|
||||
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
|
||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||
github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8=
|
||||
github.com/jonboulle/clockwork v0.2.3 h1:N1FyPPFU62shxAPCrBvOMoqlr6gt7bAYKDASFu+JFaE=
|
||||
github.com/jonboulle/clockwork v0.2.3/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8=
|
||||
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
|
||||
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/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
|
||||
github.com/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=
|
||||
github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=
|
||||
github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k=
|
||||
|
|
@ -913,16 +874,12 @@ github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN
|
|||
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/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
|
||||
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
|
||||
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE=
|
||||
github.com/markbates/pkger v0.15.1/go.mod h1:0JoVlrol20BSywW79rN3kdFFsE5xYM+rSCQDXbLhiuI=
|
||||
github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0=
|
||||
github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho=
|
||||
github.com/mattermost/go-i18n v1.11.1-0.20211013152124-5c415071e404 h1:Khvh6waxG1cHc4Cz5ef9n3XVCxRWpAKUtqg9PJl5+y8=
|
||||
github.com/mattermost/go-i18n v1.11.1-0.20211013152124-5c415071e404/go.mod h1:RyS7FDNQlzF1PsjbJWHRI35exqaKGSO9qD4iv8QjE34=
|
||||
github.com/mattermost/gosaml2 v0.8.1-0.20220428161029-8c99721fdec4 h1:y102PXr0vul3Dcw1xP4fs6R3lFL2kyLsC3qI6lsgCVQ=
|
||||
github.com/mattermost/gosaml2 v0.8.1-0.20220428161029-8c99721fdec4/go.mod h1:1nMAdE2Psxaz+pj79Oytayi+hC3aZUi3SmJQlIe+sLM=
|
||||
github.com/mattermost/gziphandler v0.0.1 h1:uXHcXF5agnQ6bXabvpiwwwZOlCYoa7mKHH0lxns/o8w=
|
||||
github.com/mattermost/gziphandler v0.0.1/go.mod h1:CvvZR7sXqhj81V2swXuQY7T04Ccc89u7W7pHNPKev8g=
|
||||
github.com/mattermost/ldap v0.0.0-20201202150706-ee0e6284187d h1:/RJ/UV7M5c7L2TQ0KNm4yZxxFvC1nvRz/gY/Daa35aI=
|
||||
|
|
@ -933,8 +890,6 @@ github.com/mattermost/morph v0.0.0-20220401091636-39f834798da8 h1:gwliVjCTqAC01m
|
|||
github.com/mattermost/morph v0.0.0-20220401091636-39f834798da8/go.mod h1:jxM3g1bx+k2Thz7jofcHguBS8TZn5Pc+o5MGmORObhw=
|
||||
github.com/mattermost/rsc v0.0.0-20160330161541-bbaefb05eaa0 h1:G9tL6JXRBMzjuD1kkBtcnd42kUiT6QDwxfFYu7adM6o=
|
||||
github.com/mattermost/rsc v0.0.0-20160330161541-bbaefb05eaa0/go.mod h1:nV5bfVpT//+B1RPD2JvRnxbkLmJEYXmRaaVl15fsXjs=
|
||||
github.com/mattermost/xml-roundtrip-validator v0.1.0 h1:RXbVD2UAl7A7nOTR4u7E3ILa4IbtvKBHw64LDsmu9hU=
|
||||
github.com/mattermost/xml-roundtrip-validator v0.1.0/go.mod h1:qccnGMcpgwcNaBnxqpJpWWUiPNr5H3O8eDgGV9gT5To=
|
||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
|
||||
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||
|
|
@ -969,7 +924,6 @@ github.com/mattn/go-sqlite3 v1.14.9/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A
|
|||
github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U=
|
||||
github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
|
||||
github.com/mholt/archiver/v3 v3.5.1 h1:rDjOBX9JSF5BvoJGvjqK479aL70qh9DIpZCl+k7Clwo=
|
||||
github.com/mholt/archiver/v3 v3.5.1/go.mod h1:e3dqJ7H78uzsRSEACH1joayhuSyhnonssnDhppzS1L4=
|
||||
|
|
@ -977,9 +931,6 @@ github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00v
|
|||
github.com/microcosm-cc/bluemonday v1.0.18 h1:6HcxvXDAi3ARt3slx6nTesbvorIc3QeTzBNRvWktHBo=
|
||||
github.com/microcosm-cc/bluemonday v1.0.18/go.mod h1:Z0r70sCuXHig8YpBzCc5eGHAap2K7e/u082ZUpDRRqM=
|
||||
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||
github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso=
|
||||
github.com/miekg/dns v1.1.48 h1:Ucfr7IIVyMBz4lRE8qmGUuZ4Wt3/ZGu9hmcMT3Uu4tQ=
|
||||
github.com/miekg/dns v1.1.48/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME=
|
||||
github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
|
||||
github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34=
|
||||
github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM=
|
||||
|
|
@ -996,7 +947,6 @@ github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77/go.
|
|||
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
|
||||
github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU=
|
||||
github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8=
|
||||
github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
|
||||
github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
|
||||
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
|
||||
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
|
|
@ -1025,7 +975,6 @@ github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8m
|
|||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||
github.com/mutecomm/go-sqlcipher/v4 v4.4.0/go.mod h1:PyN04SaWalavxRGH9E8ZftG6Ju7rsPrGmQRjrEaVpiY=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
|
||||
github.com/nakagami/firebirdsql v0.0.0-20190310045651-3c02a58cfed8/go.mod h1:86wM1zFnC6/uDBfZGNwB65O+pR2OFi5q/YQaEUid1qA=
|
||||
github.com/ncw/swift v1.0.47/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM=
|
||||
|
|
@ -1046,8 +995,6 @@ github.com/olekukonko/tablewriter v0.0.0-20180506121414-d4647c9c7a84/go.mod h1:v
|
|||
github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FWnp+qbPhuoO21uA=
|
||||
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
|
||||
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
|
||||
github.com/olivere/elastic v6.2.37+incompatible h1:UfSGJem5czY+x/LqxgeCBgjDn6St+z8OnsCuxwD3L0U=
|
||||
github.com/olivere/elastic v6.2.37+incompatible/go.mod h1:J+q1zQJTgAz9woqsbVRqGeB5G1iqDKVBWLNSYW8yfJ8=
|
||||
github.com/onsi/ginkgo v0.0.0-20151202141238-7f8ab55aaf3b/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
|
|
@ -1107,8 +1054,6 @@ github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT9
|
|||
github.com/otiai10/mint v1.3.2 h1:VYWnrP5fXmz1MXvjuUvcBrXSjGE6xjON+axB/UrpO3E=
|
||||
github.com/otiai10/mint v1.3.2/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc=
|
||||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||
github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY=
|
||||
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
|
||||
github.com/pborman/uuid v1.2.1 h1:+ZZIw58t/ozdjRaXh/3awHfmWRbzYxJoAdNJxe/3pvw=
|
||||
github.com/pborman/uuid v1.2.1/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
|
||||
|
|
@ -1146,16 +1091,11 @@ github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXP
|
|||
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
|
||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||
github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g=
|
||||
github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU=
|
||||
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
|
||||
github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
|
||||
github.com/prometheus/client_golang v1.12.1 h1:ZiaPsmm9uiBeaSMRznKsCDNtPCS0T3JVDGF+06gjBzk=
|
||||
github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
|
||||
github.com/prometheus/client_model v0.0.0-20171117100541-99fa1f4be8e5/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=
|
||||
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/common v0.0.0-20180110214958-89604d197083/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||
github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||
|
|
@ -1163,12 +1103,7 @@ github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7q
|
|||
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc=
|
||||
github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4=
|
||||
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
||||
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
|
||||
github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
|
||||
github.com/prometheus/common v0.33.0 h1:rHgav/0a6+uYgGdNt3jwz8FNSesO/Hsang3O0T9A5SE=
|
||||
github.com/prometheus/common v0.33.0/go.mod h1:gB3sOl7P0TvJabZpLY5uQMpUqRCPPCyRLCZYc7JZTNE=
|
||||
github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
|
|
@ -1181,8 +1116,6 @@ github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+Gx
|
|||
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||
github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
|
||||
github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU=
|
||||
github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
|
||||
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
||||
github.com/reflog/dateconstraints v0.2.1 h1:Hz1n2Q1vEm0Rj5gciDQcCN1iPBwfFjxUJy32NknGP/s=
|
||||
github.com/reflog/dateconstraints v0.2.1/go.mod h1:Ax8AxTBcJc3E/oVS2hd2j7RDM/5MDtuPwuR7lIHtPLo=
|
||||
|
|
@ -1213,8 +1146,6 @@ github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OK
|
|||
github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc=
|
||||
github.com/rudderlabs/analytics-go v3.3.2+incompatible h1:bDajEJTYhfHjNYxbQFMA/2dHlOjyeSgxS7GPIdMZ52Q=
|
||||
github.com/rudderlabs/analytics-go v3.3.2+incompatible/go.mod h1:LF8/ty9kUX4PTY3l5c97K3nZZaX5Hwsvt+NBaRL/f30=
|
||||
github.com/russellhaering/goxmldsig v1.2.0 h1:Y6GTTc9Un5hCxSzVz4UIWQ/zuVwDvzJk80guqzwx6Vg=
|
||||
github.com/russellhaering/goxmldsig v1.2.0/go.mod h1:gM4MDENBQf7M+V824SGfyIUVFWydB7n0KkEubVJl+Tw=
|
||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
|
|
@ -1222,11 +1153,9 @@ github.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58/go.mod h1:6lfF
|
|||
github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd h1:CmH9+J6ZSsIjUK3dcGsnCnO41eRBOnY12zwkn5qVwgc=
|
||||
github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd/go.mod h1:hPqNNc0+uJM6H+SuU8sEs5K5IQeKccPqeSjfgcKGgPk=
|
||||
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||
github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||
github.com/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4=
|
||||
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||
github.com/scylladb/termtables v0.0.0-20191203121021-c4c0b6d42ff4/go.mod h1:C1a7PQSMz9NShzorzCiG2fk9+xuCgLkPeCvMHYR2OWg=
|
||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I=
|
||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
||||
github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo=
|
||||
github.com/segmentio/backo-go v0.0.0-20200129164019-23eae7c10bd3 h1:ZuhckGJ10ulaKkdvJtiAqsLTiPrLaXSdnVgXJKJkTxE=
|
||||
|
|
@ -1340,9 +1269,6 @@ github.com/tinylib/msgp v1.1.6 h1:i+SbKraHhnrf9M5MYmvQhFnbLhAXSDWF8WWsuyRdocw=
|
|||
github.com/tinylib/msgp v1.1.6/go.mod h1:75BAfg2hauQhs3qedfdDZmWAPcFMAvJE5b9rGOMufyw=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
|
||||
github.com/tylerb/graceful v1.2.15 h1:B0x01Y8fsJpogzZTkDg6BDi6eMf03s01lEKGdrv83oA=
|
||||
github.com/tylerb/graceful v1.2.15/go.mod h1:LPYTbOYmUTdabwRt0TGhLllQ0MUNbs0Y5q1WXJOI9II=
|
||||
github.com/uber/jaeger-client-go v2.30.0+incompatible h1:D6wyKGCecFaSRUpo8lCVbaOOb6ThwMmTEbhRwtKR97o=
|
||||
github.com/uber/jaeger-client-go v2.30.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
|
||||
github.com/uber/jaeger-lib v2.4.1+incompatible h1:td4jdvLcExb4cBISKIpHuGoVXh+dVKhn2Um6rjCsSsg=
|
||||
|
|
@ -1449,7 +1375,6 @@ golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8U
|
|||
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
|
|
@ -1545,7 +1470,6 @@ golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLL
|
|||
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/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-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191112182307-2180aed22343/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
|
|
@ -1576,15 +1500,12 @@ golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLd
|
|||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210505024714-0287a6fb4125/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210916014120-12bc252f5db8/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211013171255-e13a2654a71e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.0.0-20220403103023-749bd193bc2b h1:vI32FkLJNAWtGD4BwkThwEy6XS7ZLLMHkSkYfF8M0W0=
|
||||
golang.org/x/net v0.0.0-20220403103023-749bd193bc2b/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/oauth2 v0.0.0-20180227000427-d7d64896b5ff/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
|
|
@ -1604,7 +1525,6 @@ golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ
|
|||
golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
|
||||
golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
|
|
@ -1655,8 +1575,6 @@ golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
|
@ -1688,7 +1606,6 @@ golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200817155316-9781c653f443/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
|
@ -1719,7 +1636,6 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||
golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
|
|
@ -1731,7 +1647,6 @@ golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211013075003-97ac67df715c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220403205710-6acee93ad0eb h1:PVGECzEo9Y3uOidtkHGdd347NjLtITfJFO9BxFpmRoo=
|
||||
golang.org/x/sys v0.0.0-20220403205710-6acee93ad0eb/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
|
|
@ -1767,7 +1682,6 @@ golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3
|
|||
golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190420181800-aa740d480789/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190424220101-1e8e1cfdf96b/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
|
|
@ -1780,7 +1694,6 @@ golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgw
|
|||
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20190927191325-030b2cf1153e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
|
|
@ -1827,7 +1740,6 @@ golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
|||
golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.10 h1:QjFRCZxdOhBJ/UNgnBZLbNV13DlbnK0quyivTnXJM20=
|
||||
golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E=
|
||||
golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
|
|
@ -2020,8 +1932,6 @@ gopkg.in/mail.v2 v2.3.1/go.mod h1:htwXN1Qh09vZJ1NVKxQqHPBaCBbzKhp5GzuJEA4VJWw=
|
|||
gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
|
||||
gopkg.in/olivere/elastic.v6 v6.2.37 h1:y1SqAL8MJvKckEOo3aZ+Ie0TDIYjrItZ9WBN3VzhoRM=
|
||||
gopkg.in/olivere/elastic.v6 v6.2.37/go.mod h1:2cTT8Z+/LcArSWpCgvZqBgt3VOqXiy7v00w12Lz8bd4=
|
||||
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
||||
gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
|
||||
gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
|
||||
|
|
|
|||
|
|
@ -8,4 +8,4 @@ check_prereq()
|
|||
|
||||
echo "Checking enterprise prerequisites"
|
||||
|
||||
check_prereq 'xmlsec1'
|
||||
check_prereq 'xmlsec1'
|
||||
|
|
@ -35,7 +35,7 @@ echo "Checking prerequisites"
|
|||
|
||||
REQUIREDNODEVERSION=16.0.0
|
||||
REQUIREDNPMVERSION=7.10.0
|
||||
REQUIREDGOVERSION=1.14.0
|
||||
REQUIREDGOVERSION=1.18.0
|
||||
REQUIREDDOCKERVERSION=17.0
|
||||
|
||||
NODEVERSION=$(sed 's/v//' <<< $(node -v))
|
||||
|
|
|
|||
13
scripts/setup_go_work.sh
Executable file
13
scripts/setup_go_work.sh
Executable file
|
|
@ -0,0 +1,13 @@
|
|||
#!/bin/bash
|
||||
|
||||
if [[ ! -f "go.work" ]] ;
|
||||
then
|
||||
echo "Creating a go.work file"
|
||||
cat >go.work <<EOL
|
||||
go 1.18
|
||||
|
||||
use ./
|
||||
|
||||
use ../enterprise
|
||||
EOL
|
||||
fi
|
||||
|
|
@ -13,12 +13,13 @@ TIMEOUT=$7
|
|||
COVERMODE=$8
|
||||
|
||||
PACKAGES_COMMA=$(echo $PACKAGES | tr ' ' ',')
|
||||
export MM_SERVER_PATH=$PWD
|
||||
|
||||
echo "Packages to test: $PACKAGES"
|
||||
echo "GOFLAGS: $GOFLAGS"
|
||||
|
||||
find . -name 'cprofile*.out' -exec sh -c 'rm "{}"' \;
|
||||
find . -type d -name data -not -path './vendor/*' -not -path './data' | xargs rm -rf
|
||||
find . -type d -name data -not -path './data' | xargs rm -rf
|
||||
|
||||
$GO test $GOFLAGS -run=$TESTS $TESTFLAGS -v -timeout=$TIMEOUT -covermode=$COVERMODE -coverpkg=$PACKAGES_COMMA -exec $DIR/test-xprog.sh $PACKAGES 2>&1 > >( tee output )
|
||||
EXIT_STATUS=$?
|
||||
|
|
|
|||
|
|
@ -38,26 +38,8 @@ type testResourceDetails struct {
|
|||
action int8
|
||||
}
|
||||
|
||||
// getCommonBaseSearchPaths() is a custom version of what fileutils exposes. At some point, consolidate.
|
||||
func getCommonBaseSearchPaths() []string {
|
||||
paths := []string{
|
||||
".",
|
||||
"..",
|
||||
"../..",
|
||||
"../../..",
|
||||
"../../../..",
|
||||
}
|
||||
|
||||
// this enables the server to be used in tests from a different repository
|
||||
if mmPath := os.Getenv("MM_SERVER_PATH"); mmPath != "" {
|
||||
paths = append(paths, mmPath)
|
||||
}
|
||||
|
||||
return paths
|
||||
}
|
||||
|
||||
func findFile(path string) string {
|
||||
return fileutils.FindPath(path, getCommonBaseSearchPaths(), func(fileInfo os.FileInfo) bool {
|
||||
return fileutils.FindPath(path, fileutils.CommonBaseSearchPaths(), func(fileInfo os.FileInfo) bool {
|
||||
return !fileInfo.IsDir()
|
||||
})
|
||||
}
|
||||
|
|
@ -72,7 +54,7 @@ func findDir(dir string) (string, bool) {
|
|||
return path.Dir(srcPath), true
|
||||
}
|
||||
|
||||
found := fileutils.FindPath(dir, getCommonBaseSearchPaths(), func(fileInfo os.FileInfo) bool {
|
||||
found := fileutils.FindPath(dir, fileutils.CommonBaseSearchPaths(), func(fileInfo os.FileInfo) bool {
|
||||
return fileInfo.IsDir()
|
||||
})
|
||||
if found == "" {
|
||||
|
|
|
|||
|
|
@ -8,14 +8,22 @@ import (
|
|||
"path/filepath"
|
||||
)
|
||||
|
||||
var (
|
||||
commonBaseSearchPaths = []string{
|
||||
func CommonBaseSearchPaths() []string {
|
||||
paths := []string{
|
||||
".",
|
||||
"..",
|
||||
"../..",
|
||||
"../../..",
|
||||
"../../../..",
|
||||
}
|
||||
)
|
||||
|
||||
// this enables the server to be used in tests from a different repository
|
||||
if mmPath := os.Getenv("MM_SERVER_PATH"); mmPath != "" {
|
||||
paths = append(paths, mmPath)
|
||||
}
|
||||
|
||||
return paths
|
||||
}
|
||||
|
||||
func findPath(path string, baseSearchPaths []string, workingDirFirst bool, filter func(os.FileInfo) bool) string {
|
||||
if filepath.IsAbs(path) {
|
||||
|
|
@ -79,7 +87,7 @@ func FindPath(path string, baseSearchPaths []string, filter func(os.FileInfo) bo
|
|||
// FindFile looks for the given file in nearby ancestors relative to the current working
|
||||
// directory as well as the directory of the executable.
|
||||
func FindFile(path string) string {
|
||||
return FindPath(path, commonBaseSearchPaths, func(fileInfo os.FileInfo) bool {
|
||||
return FindPath(path, CommonBaseSearchPaths(), func(fileInfo os.FileInfo) bool {
|
||||
return !fileInfo.IsDir()
|
||||
})
|
||||
}
|
||||
|
|
@ -87,7 +95,7 @@ func FindFile(path string) string {
|
|||
// fileutils.FindDir looks for the given directory in nearby ancestors relative to the current working
|
||||
// directory as well as the directory of the executable, falling back to `./` if not found.
|
||||
func FindDir(dir string) (string, bool) {
|
||||
found := FindPath(dir, commonBaseSearchPaths, func(fileInfo os.FileInfo) bool {
|
||||
found := FindPath(dir, CommonBaseSearchPaths(), func(fileInfo os.FileInfo) bool {
|
||||
return fileInfo.IsDir()
|
||||
})
|
||||
if found == "" {
|
||||
|
|
@ -100,7 +108,7 @@ func FindDir(dir string) (string, bool) {
|
|||
// FindDirRelBinary looks for the given directory in nearby ancestors relative to the
|
||||
// directory of the executable, then relative to the working directory, falling back to `./` if not found.
|
||||
func FindDirRelBinary(dir string) (string, bool) {
|
||||
found := findPath(dir, commonBaseSearchPaths, false, func(fileInfo os.FileInfo) bool {
|
||||
found := findPath(dir, CommonBaseSearchPaths(), false, func(fileInfo os.FileInfo) bool {
|
||||
return fileInfo.IsDir()
|
||||
})
|
||||
if found == "" {
|
||||
|
|
|
|||
|
|
@ -100,10 +100,10 @@ func TestFindFile(t *testing.T) {
|
|||
filePathResolved,
|
||||
},
|
||||
{
|
||||
fmt.Sprintf("%s: can't find from four nesting levels deep", fileName),
|
||||
fmt.Sprintf("%s: quadruple-nested subdirectory of containing directory", fileName),
|
||||
&tmpDir5,
|
||||
fileName,
|
||||
"",
|
||||
filePath,
|
||||
},
|
||||
}...)
|
||||
}
|
||||
|
|
|
|||
3
vendor/code.sajari.com/docconv/.gitignore
generated
vendored
3
vendor/code.sajari.com/docconv/.gitignore
generated
vendored
|
|
@ -1,3 +0,0 @@
|
|||
|
||||
sajari-convert
|
||||
*tests/
|
||||
21
vendor/code.sajari.com/docconv/LICENSE
generated
vendored
21
vendor/code.sajari.com/docconv/LICENSE
generated
vendored
|
|
@ -1,21 +0,0 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Sajari Pty Ltd
|
||||
|
||||
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.
|
||||
143
vendor/code.sajari.com/docconv/README.md
generated
vendored
143
vendor/code.sajari.com/docconv/README.md
generated
vendored
|
|
@ -1,143 +0,0 @@
|
|||
# docconv
|
||||
|
||||
[](https://pkg.go.dev/code.sajari.com/docconv)
|
||||
[](https://github.com/sajari/docconv/actions)
|
||||
[](https://goreportcard.com/report/code.sajari.com/docconv)
|
||||
[](https://sourcegraph.com/github.com/sajari/docconv)
|
||||
|
||||
A Go wrapper library to convert PDF, DOC, DOCX, XML, HTML, RTF, ODT, Pages documents and images (see optional dependencies below) to plain text.
|
||||
|
||||
> **Note for returning users:** the Go import path for this package changed to `code.sajari.com/docconv`.
|
||||
|
||||
## Installation
|
||||
|
||||
If you haven't setup Go before, you first need to [install Go](https://golang.org/doc/install).
|
||||
|
||||
To fetch and build the code:
|
||||
|
||||
$ go get code.sajari.com/docconv/...
|
||||
|
||||
This will also build the command line tool `docd` into `$GOPATH/bin`. Make sure that `$GOPATH/bin` is in your `PATH` environment variable.
|
||||
|
||||
## Dependencies
|
||||
|
||||
tidy, wv, popplerutils, unrtf, https://github.com/JalfResi/justext
|
||||
|
||||
Example install of dependencies (not all systems):
|
||||
|
||||
$ sudo apt-get install poppler-utils wv unrtf tidy
|
||||
$ go get github.com/JalfResi/justext
|
||||
|
||||
### Optional dependencies
|
||||
|
||||
To add image support to the `docconv` library you first need to [install and build gosseract](https://github.com/otiai10/gosseract/tree/v2.2.4).
|
||||
|
||||
Now you can add `-tags ocr` to any `go` command when building/fetching/testing `docconv` to include support for processing images:
|
||||
|
||||
$ go get -tags ocr code.sajari.com/docconv/...
|
||||
|
||||
This may complain on macOS, which you can fix by installing [tesseract](https://tesseract-ocr.github.io) via brew:
|
||||
|
||||
$ brew install tesseract
|
||||
|
||||
## docd tool
|
||||
|
||||
The `docd` tool runs as either:
|
||||
|
||||
1. a service on port 8888 (by default)
|
||||
|
||||
Documents can be sent as a multipart POST request and the plain text (body) and meta information are then returned as a JSON object.
|
||||
|
||||
2. a service exposed from within a Docker container
|
||||
|
||||
This also runs as a service, but from within a Docker container.
|
||||
Official images are published at https://hub.docker.com/r/sajari/docd.
|
||||
|
||||
Optionally you can build it yourself:
|
||||
|
||||
```
|
||||
cd docd
|
||||
docker build -t docd .
|
||||
```
|
||||
|
||||
3. via the command line.
|
||||
|
||||
Documents can be sent as an argument, e.g.
|
||||
|
||||
$ docd -input document.pdf
|
||||
|
||||
### Optional flags
|
||||
|
||||
- `addr` - the bind address for the HTTP server, default is ":8888"
|
||||
- `log-level`
|
||||
- 0: errors & critical info
|
||||
- 1: inclues 0 and logs each request as well
|
||||
- 2: include 1 and logs the response payloads
|
||||
- `readability-length-low` - sets the readability length low if the ?readability=1 parameter is set
|
||||
- `readability-length-high` - sets the readability length high if the ?readability=1 parameter is set
|
||||
- `readability-stopwords-low` - sets the readability stopwords low if the ?readability=1 parameter is set
|
||||
- `readability-stopwords-high` - sets the readability stopwords high if the ?readability=1 parameter is set
|
||||
- `readability-max-link-density` - sets the readability max link density if the ?readability=1 parameter is set
|
||||
- `readability-max-heading-distance` - sets the readability max heading distance if the ?readability=1 parameter is set
|
||||
- `readability-use-classes` - comma separated list of readability classes to use if the ?readability=1 parameter is set
|
||||
|
||||
### How to start the service
|
||||
|
||||
$ # This will only log errors and critical info
|
||||
$ docd -log-level 0
|
||||
|
||||
$ # This will run on port 8000 and log each request
|
||||
$ docd -addr :8000 -log-level 1
|
||||
|
||||
## Example usage (code)
|
||||
|
||||
Some basic code is shown below, but normally you would accept the file by HTTP or open it from the file system.
|
||||
|
||||
This should be enough to get you started though.
|
||||
|
||||
### Use case 1: run locally
|
||||
|
||||
> Note: this assumes you have the [dependencies](#dependencies) installed.
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"code.sajari.com/docconv"
|
||||
)
|
||||
|
||||
func main() {
|
||||
res, err := docconv.ConvertPath("your-file.pdf")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
fmt.Println(res)
|
||||
}
|
||||
```
|
||||
|
||||
### Use case 2: request over the network
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"code.sajari.com/docconv/client"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Create a new client, using the default endpoint (localhost:8888)
|
||||
c := client.New()
|
||||
|
||||
res, err := client.ConvertPath(c, "your-file.pdf")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
fmt.Println(res)
|
||||
}
|
||||
```
|
||||
111
vendor/code.sajari.com/docconv/doc.go
generated
vendored
111
vendor/code.sajari.com/docconv/doc.go
generated
vendored
|
|
@ -1,111 +0,0 @@
|
|||
package docconv
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"time"
|
||||
|
||||
"github.com/richardlehane/mscfb"
|
||||
"github.com/richardlehane/msoleps"
|
||||
)
|
||||
|
||||
// ConvertDoc converts an MS Word .doc to text.
|
||||
func ConvertDoc(r io.Reader) (string, map[string]string, error) {
|
||||
f, err := NewLocalFile(r)
|
||||
if err != nil {
|
||||
return "", nil, fmt.Errorf("error creating local file: %v", err)
|
||||
}
|
||||
defer f.Done()
|
||||
|
||||
// Meta data
|
||||
mc := make(chan map[string]string, 1)
|
||||
go func() {
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
log.Printf("panic when reading doc format: %v", e)
|
||||
}
|
||||
}()
|
||||
|
||||
meta := make(map[string]string)
|
||||
|
||||
doc, err := mscfb.New(f)
|
||||
if err != nil {
|
||||
log.Printf("ConvertDoc: could not read doc: %v", err)
|
||||
}
|
||||
|
||||
props := msoleps.New()
|
||||
for entry, err := doc.Next(); err == nil; entry, err = doc.Next() {
|
||||
if msoleps.IsMSOLEPS(entry.Initial) {
|
||||
if oerr := props.Reset(doc); oerr != nil {
|
||||
log.Printf("ConvertDoc: could not reset props: %v", oerr)
|
||||
break
|
||||
}
|
||||
|
||||
for _, prop := range props.Property {
|
||||
meta[prop.Name] = prop.String()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const defaultTimeFormat = "2006-01-02 15:04:05.999999999 -0700 MST"
|
||||
|
||||
// Convert parsed meta
|
||||
if tmp, ok := meta["LastSaveTime"]; ok {
|
||||
if t, err := time.Parse(defaultTimeFormat, tmp); err == nil {
|
||||
meta["ModifiedDate"] = fmt.Sprintf("%d", t.Unix())
|
||||
}
|
||||
}
|
||||
if tmp, ok := meta["CreateTime"]; ok {
|
||||
if t, err := time.Parse(defaultTimeFormat, tmp); err == nil {
|
||||
meta["CreatedDate"] = fmt.Sprintf("%d", t.Unix())
|
||||
}
|
||||
}
|
||||
|
||||
mc <- meta
|
||||
}()
|
||||
|
||||
// Document body
|
||||
bc := make(chan string, 1)
|
||||
go func() {
|
||||
|
||||
// Save output to a file
|
||||
outputFile, err := ioutil.TempFile("/tmp", "sajari-convert-")
|
||||
if err != nil {
|
||||
// TODO: Remove this.
|
||||
log.Println("TempFile Out:", err)
|
||||
return
|
||||
}
|
||||
defer os.Remove(outputFile.Name())
|
||||
|
||||
err = exec.Command("wvText", f.Name(), outputFile.Name()).Run()
|
||||
if err != nil {
|
||||
// TODO: Remove this.
|
||||
log.Println("wvText:", err)
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
_, err = buf.ReadFrom(outputFile)
|
||||
if err != nil {
|
||||
// TODO: Remove this.
|
||||
log.Println("wvText:", err)
|
||||
}
|
||||
|
||||
bc <- buf.String()
|
||||
}()
|
||||
|
||||
// TODO: Should errors in either of the above Goroutines stop things from progressing?
|
||||
body := <-bc
|
||||
meta := <-mc
|
||||
|
||||
// TODO: Check for errors instead of len(body) == 0?
|
||||
if len(body) == 0 {
|
||||
f.Seek(0, 0)
|
||||
return ConvertDocx(f)
|
||||
}
|
||||
return body, meta, nil
|
||||
}
|
||||
145
vendor/code.sajari.com/docconv/docconv.go
generated
vendored
145
vendor/code.sajari.com/docconv/docconv.go
generated
vendored
|
|
@ -1,145 +0,0 @@
|
|||
package docconv // import "code.sajari.com/docconv"
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Response payload sent back to the requestor
|
||||
type Response struct {
|
||||
Body string `json:"body"`
|
||||
Meta map[string]string `json:"meta"`
|
||||
MSecs uint32 `json:"msecs"`
|
||||
Error string `json:"error"`
|
||||
}
|
||||
|
||||
// MimeTypeByExtension returns a mimetype for the given extension, or
|
||||
// application/octet-stream if none can be determined.
|
||||
func MimeTypeByExtension(filename string) string {
|
||||
switch strings.ToLower(path.Ext(filename)) {
|
||||
case ".doc":
|
||||
return "application/msword"
|
||||
case ".docx":
|
||||
return "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
|
||||
case ".odt":
|
||||
return "application/vnd.oasis.opendocument.text"
|
||||
case ".pages":
|
||||
return "application/vnd.apple.pages"
|
||||
case ".pdf":
|
||||
return "application/pdf"
|
||||
case ".pptx":
|
||||
return "application/vnd.openxmlformats-officedocument.presentationml.presentation"
|
||||
case ".rtf":
|
||||
return "application/rtf"
|
||||
case ".xml":
|
||||
return "text/xml"
|
||||
case ".xhtml", ".html", ".htm":
|
||||
return "text/html"
|
||||
case ".jpg", ".jpeg", ".jpe", ".jfif", ".jfif-tbnl":
|
||||
return "image/jpeg"
|
||||
case ".png":
|
||||
return "image/png"
|
||||
case ".tif":
|
||||
return "image/tif"
|
||||
case ".tiff":
|
||||
return "image/tiff"
|
||||
case ".txt":
|
||||
return "text/plain"
|
||||
}
|
||||
return "application/octet-stream"
|
||||
}
|
||||
|
||||
// Convert a file to plain text.
|
||||
func Convert(r io.Reader, mimeType string, readability bool) (*Response, error) {
|
||||
start := time.Now()
|
||||
|
||||
var body string
|
||||
var meta map[string]string
|
||||
var err error
|
||||
switch mimeType {
|
||||
case "application/msword", "application/vnd.ms-word":
|
||||
body, meta, err = ConvertDoc(r)
|
||||
|
||||
case "application/vnd.openxmlformats-officedocument.wordprocessingml.document":
|
||||
body, meta, err = ConvertDocx(r)
|
||||
|
||||
case "application/vnd.openxmlformats-officedocument.presentationml.presentation":
|
||||
body, meta, err = ConvertPptx(r)
|
||||
|
||||
case "application/vnd.oasis.opendocument.text":
|
||||
body, meta, err = ConvertODT(r)
|
||||
|
||||
case "application/vnd.apple.pages", "application/x-iwork-pages-sffpages":
|
||||
body, meta, err = ConvertPages(r)
|
||||
|
||||
case "application/pdf":
|
||||
body, meta, err = ConvertPDF(r)
|
||||
|
||||
case "application/rtf", "application/x-rtf", "text/rtf", "text/richtext":
|
||||
body, meta, err = ConvertRTF(r)
|
||||
|
||||
case "text/html":
|
||||
body, meta, err = ConvertHTML(r, readability)
|
||||
|
||||
case "text/url":
|
||||
body, meta, err = ConvertURL(r, readability)
|
||||
|
||||
case "text/xml", "application/xml":
|
||||
body, meta, err = ConvertXML(r)
|
||||
|
||||
case "image/jpeg", "image/png", "image/tif", "image/tiff":
|
||||
body, meta, err = ConvertImage(r)
|
||||
|
||||
case "text/plain":
|
||||
var b []byte
|
||||
b, err = ioutil.ReadAll(r)
|
||||
body = string(b)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error converting data: %v", err)
|
||||
}
|
||||
|
||||
return &Response{
|
||||
Body: strings.TrimSpace(body),
|
||||
Meta: meta,
|
||||
MSecs: uint32(time.Since(start) / time.Millisecond),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ConvertPath converts a local path to text.
|
||||
func ConvertPath(path string) (*Response, error) {
|
||||
mimeType := MimeTypeByExtension(path)
|
||||
|
||||
f, err := os.Open(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
return Convert(f, mimeType, true)
|
||||
}
|
||||
|
||||
// ConvertPathReadability converts a local path to text, with the given readability
|
||||
// option.
|
||||
func ConvertPathReadability(path string, readability bool) ([]byte, error) {
|
||||
mimeType := MimeTypeByExtension(path)
|
||||
|
||||
f, err := os.Open(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
data, err := Convert(f, mimeType, readability)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return json.Marshal(data)
|
||||
}
|
||||
155
vendor/code.sajari.com/docconv/docx.go
generated
vendored
155
vendor/code.sajari.com/docconv/docx.go
generated
vendored
|
|
@ -1,155 +0,0 @@
|
|||
package docconv
|
||||
|
||||
import (
|
||||
"archive/zip"
|
||||
"bytes"
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
||||
type typeOverride struct {
|
||||
XMLName xml.Name `xml:"Override"`
|
||||
ContentType string `xml:"ContentType,attr"`
|
||||
PartName string `xml:"PartName,attr"`
|
||||
}
|
||||
|
||||
type contentTypeDefinition struct {
|
||||
XMLName xml.Name `xml:"Types"`
|
||||
Overrides []typeOverride `xml:"Override"`
|
||||
}
|
||||
|
||||
// ConvertDocx converts an MS Word docx file to text.
|
||||
func ConvertDocx(r io.Reader) (string, map[string]string, error) {
|
||||
var size int64
|
||||
|
||||
// Common case: if the reader is a file (or trivial wrapper), avoid
|
||||
// loading it all into memory.
|
||||
var ra io.ReaderAt
|
||||
if f, ok := r.(interface {
|
||||
io.ReaderAt
|
||||
Stat() (os.FileInfo, error)
|
||||
}); ok {
|
||||
si, err := f.Stat()
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
size = si.Size()
|
||||
ra = f
|
||||
} else {
|
||||
b, err := ioutil.ReadAll(r)
|
||||
if err != nil {
|
||||
return "", nil, nil
|
||||
}
|
||||
size = int64(len(b))
|
||||
ra = bytes.NewReader(b)
|
||||
}
|
||||
|
||||
zr, err := zip.NewReader(ra, size)
|
||||
if err != nil {
|
||||
return "", nil, fmt.Errorf("error unzipping data: %v", err)
|
||||
}
|
||||
|
||||
zipFiles := mapZipFiles(zr.File)
|
||||
|
||||
contentTypeDefinition, err := getContentTypeDefinition(zipFiles["[Content_Types].xml"])
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
|
||||
meta := make(map[string]string)
|
||||
var textHeader, textBody, textFooter string
|
||||
for _, override := range contentTypeDefinition.Overrides {
|
||||
f := zipFiles[override.PartName]
|
||||
|
||||
switch {
|
||||
case override.ContentType == "application/vnd.openxmlformats-package.core-properties+xml":
|
||||
rc, err := f.Open()
|
||||
if err != nil {
|
||||
return "", nil, fmt.Errorf("error opening '%v' from archive: %v", f.Name, err)
|
||||
}
|
||||
defer rc.Close()
|
||||
|
||||
meta, err = XMLToMap(rc)
|
||||
if err != nil {
|
||||
return "", nil, fmt.Errorf("error parsing '%v': %v", f.Name, err)
|
||||
}
|
||||
|
||||
if tmp, ok := meta["modified"]; ok {
|
||||
if t, err := time.Parse(time.RFC3339, tmp); err == nil {
|
||||
meta["ModifiedDate"] = fmt.Sprintf("%d", t.Unix())
|
||||
}
|
||||
}
|
||||
if tmp, ok := meta["created"]; ok {
|
||||
if t, err := time.Parse(time.RFC3339, tmp); err == nil {
|
||||
meta["CreatedDate"] = fmt.Sprintf("%d", t.Unix())
|
||||
}
|
||||
}
|
||||
case override.ContentType == "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml":
|
||||
body, err := parseDocxText(f)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
textBody += body + "\n"
|
||||
case override.ContentType == "application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml":
|
||||
footer, err := parseDocxText(f)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
textFooter += footer + "\n"
|
||||
case override.ContentType == "application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml":
|
||||
header, err := parseDocxText(f)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
textHeader += header + "\n"
|
||||
}
|
||||
|
||||
}
|
||||
return textHeader + "\n" + textBody + "\n" + textFooter, meta, nil
|
||||
}
|
||||
|
||||
func getContentTypeDefinition(zf *zip.File) (*contentTypeDefinition, error) {
|
||||
f, err := zf.Open()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
x := &contentTypeDefinition{}
|
||||
if err := xml.NewDecoder(f).Decode(x); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return x, nil
|
||||
}
|
||||
|
||||
func mapZipFiles(files []*zip.File) map[string]*zip.File {
|
||||
filesMap := make(map[string]*zip.File, 2*len(files))
|
||||
for _, f := range files {
|
||||
filesMap[f.Name] = f
|
||||
filesMap["/"+f.Name] = f
|
||||
}
|
||||
return filesMap
|
||||
}
|
||||
|
||||
func parseDocxText(f *zip.File) (string, error) {
|
||||
r, err := f.Open()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("error opening '%v' from archive: %v", f.Name, err)
|
||||
}
|
||||
defer r.Close()
|
||||
|
||||
text, err := DocxXMLToText(r)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("error parsing '%v': %v", f.Name, err)
|
||||
}
|
||||
return text, nil
|
||||
}
|
||||
|
||||
// DocxXMLToText converts Docx XML into plain text.
|
||||
func DocxXMLToText(r io.Reader) (string, error) {
|
||||
return XMLToText(r, []string{"br", "p", "tab"}, []string{"instrText", "script"}, true)
|
||||
}
|
||||
191
vendor/code.sajari.com/docconv/html.go
generated
vendored
191
vendor/code.sajari.com/docconv/html.go
generated
vendored
|
|
@ -1,191 +0,0 @@
|
|||
// +build !appengine
|
||||
|
||||
package docconv
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"log"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/net/html"
|
||||
|
||||
"github.com/JalfResi/justext"
|
||||
)
|
||||
|
||||
// ConvertHTML converts HTML into text.
|
||||
func ConvertHTML(r io.Reader, readability bool) (string, map[string]string, error) {
|
||||
meta := make(map[string]string)
|
||||
|
||||
buf := new(bytes.Buffer)
|
||||
_, err := buf.ReadFrom(r)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
|
||||
cleanXML, err := Tidy(buf, false)
|
||||
if err != nil {
|
||||
log.Println("Tidy:", err)
|
||||
// Tidy failed, so we now manually tokenize instead
|
||||
clean := cleanHTML(buf, true)
|
||||
cleanXML = []byte(clean)
|
||||
// TODO: remove this log
|
||||
log.Println("Cleaned HTML using Golang tokenizer")
|
||||
}
|
||||
|
||||
if readability {
|
||||
cleanXML = HTMLReadability(bytes.NewReader(cleanXML))
|
||||
}
|
||||
return HTMLToText(bytes.NewReader(cleanXML)), meta, nil
|
||||
}
|
||||
|
||||
var acceptedHTMLTags = [...]string{
|
||||
"div", "p", "br", "span", "body", "head", "html", "ul", "ol", "li", "dl", "dt", "dd", "a", "form", "article",
|
||||
"section", "table", "tr", "td", "tbody", "thead", "th", "tfoot", "col", "colgroup", "caption", "form", "input",
|
||||
"title", "h1", "h2", "h3", "h4", "h5", "h6", "meta", "strong", "cite", "em", "address", "abbr", "acronym",
|
||||
"blockquote", "q", "pre", "samp", "select", "fieldset", "legend", "button", "option", "textarea", "label",
|
||||
}
|
||||
|
||||
// Tests for known friendly HTML parameters that tidy is unlikely to choke on
|
||||
func acceptedHTMLTag(tagName string) bool {
|
||||
for _, tag := range acceptedHTMLTags {
|
||||
if tag == tagName {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Removes scripts, comments, styles and parameters from HTML.
|
||||
// Also removes made up tags, e.g. <fb:like>
|
||||
// Can keep head elements or not. Typically not much in there.
|
||||
func cleanHTML(r io.Reader, all bool) string {
|
||||
output := ""
|
||||
if !all {
|
||||
output = "<html><head></head>"
|
||||
}
|
||||
mainSection := false
|
||||
junkSection := false
|
||||
|
||||
d := html.NewTokenizer(r)
|
||||
for {
|
||||
// token type
|
||||
tokenType := d.Next()
|
||||
if tokenType == html.ErrorToken {
|
||||
return output
|
||||
}
|
||||
token := d.Token()
|
||||
|
||||
switch tokenType {
|
||||
case html.StartTagToken: // <tag>
|
||||
if token.Data == "body" || (token.Data == "html" && all) {
|
||||
mainSection = true
|
||||
}
|
||||
if !acceptedHTMLTag(token.Data) {
|
||||
junkSection = true
|
||||
}
|
||||
|
||||
if !junkSection && mainSection {
|
||||
output += "<" + token.Data + ">"
|
||||
}
|
||||
|
||||
case html.TextToken: // text between start and end tag
|
||||
if !junkSection && mainSection {
|
||||
output += token.Data
|
||||
}
|
||||
|
||||
case html.EndTagToken: // </tag>
|
||||
if !junkSection && mainSection {
|
||||
output += "</" + token.Data + ">"
|
||||
}
|
||||
if !acceptedHTMLTag(token.Data) {
|
||||
junkSection = false
|
||||
}
|
||||
|
||||
case html.SelfClosingTagToken: // <tag/>
|
||||
if !junkSection && mainSection {
|
||||
output += "<" + token.Data + " />" // TODO: Can probably keep attributes from the meta tags
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// HTMLReadabilityOptions is a type which defines parameters that are passed to the justext package.
|
||||
// TODO: Improve this!
|
||||
type HTMLReadabilityOptions struct {
|
||||
LengthLow int
|
||||
LengthHigh int
|
||||
StopwordsLow float64
|
||||
StopwordsHigh float64
|
||||
MaxLinkDensity float64
|
||||
MaxHeadingDistance int
|
||||
ReadabilityUseClasses string
|
||||
}
|
||||
|
||||
// HTMLReadabilityOptionsValues are the global settings used for HTMLReadability.
|
||||
// TODO: Remove this from global state.
|
||||
var HTMLReadabilityOptionsValues HTMLReadabilityOptions
|
||||
|
||||
// HTMLReadability extracts the readable text in an HTML document
|
||||
func HTMLReadability(r io.Reader) []byte {
|
||||
jr := justext.NewReader(r)
|
||||
|
||||
// TODO: Improve this!
|
||||
jr.Stoplist = readabilityStopList
|
||||
jr.LengthLow = HTMLReadabilityOptionsValues.LengthLow
|
||||
jr.LengthHigh = HTMLReadabilityOptionsValues.LengthHigh
|
||||
jr.StopwordsLow = HTMLReadabilityOptionsValues.StopwordsLow
|
||||
jr.StopwordsHigh = HTMLReadabilityOptionsValues.StopwordsHigh
|
||||
jr.MaxLinkDensity = HTMLReadabilityOptionsValues.MaxLinkDensity
|
||||
jr.MaxHeadingDistance = HTMLReadabilityOptionsValues.MaxHeadingDistance
|
||||
|
||||
paragraphSet, err := jr.ReadAll()
|
||||
if err != nil {
|
||||
log.Println("Justext:", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
useClasses := strings.SplitN(HTMLReadabilityOptionsValues.ReadabilityUseClasses, ",", 10)
|
||||
|
||||
output := ""
|
||||
for _, paragraph := range paragraphSet {
|
||||
for _, class := range useClasses {
|
||||
if paragraph.CfClass == class {
|
||||
output += paragraph.Text + "\n"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return []byte(output)
|
||||
}
|
||||
|
||||
// HTMLToText converts HTML to plain text.
|
||||
func HTMLToText(input io.Reader) string {
|
||||
text, _ := XMLToText(input, []string{"br", "p", "h1", "h2", "h3", "h4"}, []string{}, false)
|
||||
return text
|
||||
}
|
||||
|
||||
var readabilityStopList = map[string]bool{"and": true, "the": true, "a": true, "about": true, "above": true, "across": true, "after": true, "afterwards": true, "again": true, "against": true, "all": true, "almost": true, "alone": true,
|
||||
"along": true, "already": true, "also": true, "although": true, "always": true, "am": true, "among": true, "amongst": true, "amoungst": true, "amount": true, "an": true, "another": true, "any": true,
|
||||
"anyhow": true, "anyone": true, "anything": true, "anyway": true, "anywhere": true, "are": true, "around": true, "as": true, "at": true, "back": true, "be": true, "became": true, "because": true,
|
||||
"become": true, "becomes": true, "becoming": true, "been": true, "before": true, "beforehand": true, "behind": true, "being": true, "below": true, "beside": true, "besides": true, "between": true,
|
||||
"beyond": true, "both": true, "bottom": true, "but": true, "by": true, "can": true, "cannot": true, "cant": true, "co": true, "con": true, "could": true, "couldnt": true, "cry": true,
|
||||
"de": true, "describe": true, "detail": true, "do": true, "done": true, "down": true, "due": true, "during": true, "each": true, "eg": true, "eight": true, "either": true, "eleven": true, "else": true,
|
||||
"elsewhere": true, "empty": true, "enough": true, "etc": true, "even": true, "ever": true, "every": true, "everyone": true, "everything": true, "everywhere": true, "except": true, "few": true,
|
||||
"fifteen": true, "fify": true, "fill": true, "find": true, "fire": true, "first": true, "five": true, "for": true, "former": true, "formerly": true, "forty": true, "found": true, "four": true, "from": true,
|
||||
"front": true, "full": true, "further": true, "get": true, "give": true, "go": true, "had": true, "has": true, "hasnt": true, "have": true, "he": true, "hence": true, "her": true, "here": true, "hereafter": true,
|
||||
"hereby": true, "herein": true, "hereupon": true, "hers": true, "herself": true, "him": true, "himself": true, "his": true, "how": true, "however": true, "hundred": true, "ie": true, "if": true, "in": true,
|
||||
"inc": true, "indeed": true, "interest": true, "into": true, "is": true, "it": true, "its": true, "itself": true, "keep": true, "last": true, "latter": true, "latterly": true, "least": true, "less": true,
|
||||
"ltd": true, "made": true, "many": true, "may": true, "me": true, "meanwhile": true, "might": true, "mill": true, "mine": true, "more": true, "moreover": true, "most": true, "mostly": true, "move": true,
|
||||
"much": true, "must": true, "my": true, "myself": true, "name": true, "namely": true, "neither": true, "never": true, "nevertheless": true, "next": true, "nine": true, "no": true, "nobody": true,
|
||||
"none": true, "noone": true, "nor": true, "not": true, "nothing": true, "now": true, "nowhere": true, "of": true, "off": true, "often": true, "on": true, "once": true, "one": true, "only": true, "onto": true,
|
||||
"or": true, "other": true, "others": true, "otherwise": true, "our": true, "ours": true, "ourselves": true, "out": true, "over": true, "own": true, "part": true, "per": true, "perhaps": true,
|
||||
"please": true, "put": true, "rather": true, "re": true, "same": true, "see": true, "seem": true, "seemed": true, "seeming": true, "seems": true, "serious": true, "several": true, "she": true,
|
||||
"should": true, "show": true, "side": true, "since": true, "sincere": true, "six": true, "sixty": true, "so": true, "some": true, "somehow": true, "someone": true, "something": true, "sometime": true,
|
||||
"sometimes": true, "somewhere": true, "still": true, "such": true, "take": true, "ten": true, "than": true, "that": true, "their": true, "them": true, "themselves": true,
|
||||
"then": true, "thence": true, "there": true, "thereafter": true, "thereby": true, "therefore": true, "therein": true, "thereupon": true, "these": true, "they": true, "thickv": true, "thin": true,
|
||||
"third": true, "this": true, "those": true, "though": true, "three": true, "through": true, "throughout": true, "thru": true, "thus": true, "to": true, "together": true, "too": true, "top": true,
|
||||
"toward": true, "towards": true, "twelve": true, "twenty": true, "two": true, "un": true, "under": true, "until": true, "up": true, "upon": true, "us": true, "very": true, "via": true, "was": true, "we": true,
|
||||
"well": true, "were": true, "what": true, "whatever": true, "when": true, "whence": true, "whenever": true, "where": true, "whereafter": true, "whereas": true, "whereby": true, "wherein": true,
|
||||
"whereupon": true, "wherever": true, "whether": true, "which": true, "while": true, "whither": true, "who": true, "whoever": true, "whole": true, "whom": true, "whose": true, "why": true, "will": true,
|
||||
"with": true, "within": true, "without": true, "would": true, "yet": true, "you": true, "your": true, "youre": true, "yours": true, "yourself": true, "yourselves": true, "www": true, "com": true, "http": true}
|
||||
18
vendor/code.sajari.com/docconv/html_appengine.go
generated
vendored
18
vendor/code.sajari.com/docconv/html_appengine.go
generated
vendored
|
|
@ -1,18 +0,0 @@
|
|||
// +build appengine
|
||||
|
||||
package docconv
|
||||
|
||||
import (
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
)
|
||||
|
||||
func HTMLReadability(r io.Reader) []byte {
|
||||
b, err := ioutil.ReadAll(r)
|
||||
if err != nil {
|
||||
log.Printf("HTMLReadability: %v", err)
|
||||
return nil
|
||||
}
|
||||
return b
|
||||
}
|
||||
587
vendor/code.sajari.com/docconv/iWork/TSPArchiveMessages.pb.go
generated
vendored
587
vendor/code.sajari.com/docconv/iWork/TSPArchiveMessages.pb.go
generated
vendored
|
|
@ -1,587 +0,0 @@
|
|||
// Code generated by protoc-gen-go.
|
||||
// source: TSPArchiveMessages.proto
|
||||
// DO NOT EDIT!
|
||||
|
||||
/*
|
||||
Package TSP is a generated protocol buffer package.
|
||||
|
||||
It is generated from these files:
|
||||
TSPArchiveMessages.proto
|
||||
TSPDatabaseMessages.proto
|
||||
TSPMessages.proto
|
||||
|
||||
It has these top-level messages:
|
||||
ArchiveInfo
|
||||
MessageInfo
|
||||
FieldInfo
|
||||
FieldPath
|
||||
ComponentInfo
|
||||
ComponentExternalReference
|
||||
ComponentDataReference
|
||||
PackageMetadata
|
||||
PasteboardMetadata
|
||||
DataInfo
|
||||
ViewStateMetadata
|
||||
*/
|
||||
package TSP
|
||||
|
||||
import proto "github.com/golang/protobuf/proto"
|
||||
import math "math"
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = math.Inf
|
||||
|
||||
type FieldInfo_Type int32
|
||||
|
||||
const (
|
||||
FieldInfo_Value FieldInfo_Type = 0
|
||||
FieldInfo_ObjectReference FieldInfo_Type = 1
|
||||
FieldInfo_DataReference FieldInfo_Type = 2
|
||||
FieldInfo_Message FieldInfo_Type = 3
|
||||
)
|
||||
|
||||
var FieldInfo_Type_name = map[int32]string{
|
||||
0: "Value",
|
||||
1: "ObjectReference",
|
||||
2: "DataReference",
|
||||
3: "Message",
|
||||
}
|
||||
var FieldInfo_Type_value = map[string]int32{
|
||||
"Value": 0,
|
||||
"ObjectReference": 1,
|
||||
"DataReference": 2,
|
||||
"Message": 3,
|
||||
}
|
||||
|
||||
func (x FieldInfo_Type) Enum() *FieldInfo_Type {
|
||||
p := new(FieldInfo_Type)
|
||||
*p = x
|
||||
return p
|
||||
}
|
||||
func (x FieldInfo_Type) String() string {
|
||||
return proto.EnumName(FieldInfo_Type_name, int32(x))
|
||||
}
|
||||
func (x *FieldInfo_Type) UnmarshalJSON(data []byte) error {
|
||||
value, err := proto.UnmarshalJSONEnum(FieldInfo_Type_value, data, "FieldInfo_Type")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*x = FieldInfo_Type(value)
|
||||
return nil
|
||||
}
|
||||
|
||||
type FieldInfo_Rule int32
|
||||
|
||||
const (
|
||||
FieldInfo_IgnoreAndDrop FieldInfo_Rule = 0
|
||||
FieldInfo_IgnoreAndPreserve FieldInfo_Rule = 1
|
||||
FieldInfo_MustUnderstand FieldInfo_Rule = 2
|
||||
FieldInfo_NotSupported FieldInfo_Rule = -1
|
||||
)
|
||||
|
||||
var FieldInfo_Rule_name = map[int32]string{
|
||||
0: "IgnoreAndDrop",
|
||||
1: "IgnoreAndPreserve",
|
||||
2: "MustUnderstand",
|
||||
-1: "NotSupported",
|
||||
}
|
||||
var FieldInfo_Rule_value = map[string]int32{
|
||||
"IgnoreAndDrop": 0,
|
||||
"IgnoreAndPreserve": 1,
|
||||
"MustUnderstand": 2,
|
||||
"NotSupported": -1,
|
||||
}
|
||||
|
||||
func (x FieldInfo_Rule) Enum() *FieldInfo_Rule {
|
||||
p := new(FieldInfo_Rule)
|
||||
*p = x
|
||||
return p
|
||||
}
|
||||
func (x FieldInfo_Rule) String() string {
|
||||
return proto.EnumName(FieldInfo_Rule_name, int32(x))
|
||||
}
|
||||
func (x *FieldInfo_Rule) UnmarshalJSON(data []byte) error {
|
||||
value, err := proto.UnmarshalJSONEnum(FieldInfo_Rule_value, data, "FieldInfo_Rule")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*x = FieldInfo_Rule(value)
|
||||
return nil
|
||||
}
|
||||
|
||||
type ArchiveInfo struct {
|
||||
Identifier *uint64 `protobuf:"varint,1,opt,name=identifier" json:"identifier,omitempty"`
|
||||
MessageInfos []*MessageInfo `protobuf:"bytes,2,rep,name=message_infos" json:"message_infos,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *ArchiveInfo) Reset() { *m = ArchiveInfo{} }
|
||||
func (m *ArchiveInfo) String() string { return proto.CompactTextString(m) }
|
||||
func (*ArchiveInfo) ProtoMessage() {}
|
||||
|
||||
func (m *ArchiveInfo) GetIdentifier() uint64 {
|
||||
if m != nil && m.Identifier != nil {
|
||||
return *m.Identifier
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *ArchiveInfo) GetMessageInfos() []*MessageInfo {
|
||||
if m != nil {
|
||||
return m.MessageInfos
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type MessageInfo struct {
|
||||
Type *uint32 `protobuf:"varint,1,req,name=type" json:"type,omitempty"`
|
||||
Version []uint32 `protobuf:"varint,2,rep,packed,name=version" json:"version,omitempty"`
|
||||
Length *uint32 `protobuf:"varint,3,req,name=length" json:"length,omitempty"`
|
||||
FieldInfos []*FieldInfo `protobuf:"bytes,4,rep,name=field_infos" json:"field_infos,omitempty"`
|
||||
ObjectReferences []uint64 `protobuf:"varint,5,rep,packed,name=object_references" json:"object_references,omitempty"`
|
||||
DataReferences []uint64 `protobuf:"varint,6,rep,packed,name=data_references" json:"data_references,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *MessageInfo) Reset() { *m = MessageInfo{} }
|
||||
func (m *MessageInfo) String() string { return proto.CompactTextString(m) }
|
||||
func (*MessageInfo) ProtoMessage() {}
|
||||
|
||||
func (m *MessageInfo) GetType() uint32 {
|
||||
if m != nil && m.Type != nil {
|
||||
return *m.Type
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *MessageInfo) GetVersion() []uint32 {
|
||||
if m != nil {
|
||||
return m.Version
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *MessageInfo) GetLength() uint32 {
|
||||
if m != nil && m.Length != nil {
|
||||
return *m.Length
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *MessageInfo) GetFieldInfos() []*FieldInfo {
|
||||
if m != nil {
|
||||
return m.FieldInfos
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *MessageInfo) GetObjectReferences() []uint64 {
|
||||
if m != nil {
|
||||
return m.ObjectReferences
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *MessageInfo) GetDataReferences() []uint64 {
|
||||
if m != nil {
|
||||
return m.DataReferences
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type FieldInfo struct {
|
||||
Path *FieldPath `protobuf:"bytes,1,req,name=path" json:"path,omitempty"`
|
||||
Type *FieldInfo_Type `protobuf:"varint,2,opt,name=type,enum=TSP.FieldInfo_Type,def=0" json:"type,omitempty"`
|
||||
Rule *FieldInfo_Rule `protobuf:"varint,3,opt,name=rule,enum=TSP.FieldInfo_Rule,def=0" json:"rule,omitempty"`
|
||||
ObjectReferences []uint64 `protobuf:"varint,4,rep,packed,name=object_references" json:"object_references,omitempty"`
|
||||
DataReferences []uint64 `protobuf:"varint,5,rep,packed,name=data_references" json:"data_references,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *FieldInfo) Reset() { *m = FieldInfo{} }
|
||||
func (m *FieldInfo) String() string { return proto.CompactTextString(m) }
|
||||
func (*FieldInfo) ProtoMessage() {}
|
||||
|
||||
const Default_FieldInfo_Type FieldInfo_Type = FieldInfo_Value
|
||||
const Default_FieldInfo_Rule FieldInfo_Rule = FieldInfo_IgnoreAndDrop
|
||||
|
||||
func (m *FieldInfo) GetPath() *FieldPath {
|
||||
if m != nil {
|
||||
return m.Path
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *FieldInfo) GetType() FieldInfo_Type {
|
||||
if m != nil && m.Type != nil {
|
||||
return *m.Type
|
||||
}
|
||||
return Default_FieldInfo_Type
|
||||
}
|
||||
|
||||
func (m *FieldInfo) GetRule() FieldInfo_Rule {
|
||||
if m != nil && m.Rule != nil {
|
||||
return *m.Rule
|
||||
}
|
||||
return Default_FieldInfo_Rule
|
||||
}
|
||||
|
||||
func (m *FieldInfo) GetObjectReferences() []uint64 {
|
||||
if m != nil {
|
||||
return m.ObjectReferences
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *FieldInfo) GetDataReferences() []uint64 {
|
||||
if m != nil {
|
||||
return m.DataReferences
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type FieldPath struct {
|
||||
Path []uint32 `protobuf:"varint,1,rep,packed,name=path" json:"path,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *FieldPath) Reset() { *m = FieldPath{} }
|
||||
func (m *FieldPath) String() string { return proto.CompactTextString(m) }
|
||||
func (*FieldPath) ProtoMessage() {}
|
||||
|
||||
func (m *FieldPath) GetPath() []uint32 {
|
||||
if m != nil {
|
||||
return m.Path
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ComponentInfo struct {
|
||||
Identifier *uint64 `protobuf:"varint,1,req,name=identifier" json:"identifier,omitempty"`
|
||||
PreferredLocator *string `protobuf:"bytes,2,req,name=preferred_locator" json:"preferred_locator,omitempty"`
|
||||
Locator *string `protobuf:"bytes,3,opt,name=locator" json:"locator,omitempty"`
|
||||
ReadVersion []uint32 `protobuf:"varint,4,rep,packed,name=read_version" json:"read_version,omitempty"`
|
||||
WriteVersion []uint32 `protobuf:"varint,5,rep,packed,name=write_version" json:"write_version,omitempty"`
|
||||
ExternalReferences []*ComponentExternalReference `protobuf:"bytes,6,rep,name=external_references" json:"external_references,omitempty"`
|
||||
DataReferences []*ComponentDataReference `protobuf:"bytes,7,rep,name=data_references" json:"data_references,omitempty"`
|
||||
AllowsDuplicatesOutsideOfDocumentPackage *bool `protobuf:"varint,8,opt,name=allows_duplicates_outside_of_document_package,def=0" json:"allows_duplicates_outside_of_document_package,omitempty"`
|
||||
DirtiesDocumentPackage *bool `protobuf:"varint,9,opt,name=dirties_document_package,def=1" json:"dirties_document_package,omitempty"`
|
||||
IsStoredOutsideObjectArchive *bool `protobuf:"varint,10,opt,name=is_stored_outside_object_archive,def=0" json:"is_stored_outside_object_archive,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *ComponentInfo) Reset() { *m = ComponentInfo{} }
|
||||
func (m *ComponentInfo) String() string { return proto.CompactTextString(m) }
|
||||
func (*ComponentInfo) ProtoMessage() {}
|
||||
|
||||
const Default_ComponentInfo_AllowsDuplicatesOutsideOfDocumentPackage bool = false
|
||||
const Default_ComponentInfo_DirtiesDocumentPackage bool = true
|
||||
const Default_ComponentInfo_IsStoredOutsideObjectArchive bool = false
|
||||
|
||||
func (m *ComponentInfo) GetIdentifier() uint64 {
|
||||
if m != nil && m.Identifier != nil {
|
||||
return *m.Identifier
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *ComponentInfo) GetPreferredLocator() string {
|
||||
if m != nil && m.PreferredLocator != nil {
|
||||
return *m.PreferredLocator
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *ComponentInfo) GetLocator() string {
|
||||
if m != nil && m.Locator != nil {
|
||||
return *m.Locator
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *ComponentInfo) GetReadVersion() []uint32 {
|
||||
if m != nil {
|
||||
return m.ReadVersion
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *ComponentInfo) GetWriteVersion() []uint32 {
|
||||
if m != nil {
|
||||
return m.WriteVersion
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *ComponentInfo) GetExternalReferences() []*ComponentExternalReference {
|
||||
if m != nil {
|
||||
return m.ExternalReferences
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *ComponentInfo) GetDataReferences() []*ComponentDataReference {
|
||||
if m != nil {
|
||||
return m.DataReferences
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *ComponentInfo) GetAllowsDuplicatesOutsideOfDocumentPackage() bool {
|
||||
if m != nil && m.AllowsDuplicatesOutsideOfDocumentPackage != nil {
|
||||
return *m.AllowsDuplicatesOutsideOfDocumentPackage
|
||||
}
|
||||
return Default_ComponentInfo_AllowsDuplicatesOutsideOfDocumentPackage
|
||||
}
|
||||
|
||||
func (m *ComponentInfo) GetDirtiesDocumentPackage() bool {
|
||||
if m != nil && m.DirtiesDocumentPackage != nil {
|
||||
return *m.DirtiesDocumentPackage
|
||||
}
|
||||
return Default_ComponentInfo_DirtiesDocumentPackage
|
||||
}
|
||||
|
||||
func (m *ComponentInfo) GetIsStoredOutsideObjectArchive() bool {
|
||||
if m != nil && m.IsStoredOutsideObjectArchive != nil {
|
||||
return *m.IsStoredOutsideObjectArchive
|
||||
}
|
||||
return Default_ComponentInfo_IsStoredOutsideObjectArchive
|
||||
}
|
||||
|
||||
type ComponentExternalReference struct {
|
||||
ComponentIdentifier *uint64 `protobuf:"varint,1,req,name=component_identifier" json:"component_identifier,omitempty"`
|
||||
ObjectIdentifier *uint64 `protobuf:"varint,2,opt,name=object_identifier" json:"object_identifier,omitempty"`
|
||||
IsWeak *bool `protobuf:"varint,3,opt,name=is_weak" json:"is_weak,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *ComponentExternalReference) Reset() { *m = ComponentExternalReference{} }
|
||||
func (m *ComponentExternalReference) String() string { return proto.CompactTextString(m) }
|
||||
func (*ComponentExternalReference) ProtoMessage() {}
|
||||
|
||||
func (m *ComponentExternalReference) GetComponentIdentifier() uint64 {
|
||||
if m != nil && m.ComponentIdentifier != nil {
|
||||
return *m.ComponentIdentifier
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *ComponentExternalReference) GetObjectIdentifier() uint64 {
|
||||
if m != nil && m.ObjectIdentifier != nil {
|
||||
return *m.ObjectIdentifier
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *ComponentExternalReference) GetIsWeak() bool {
|
||||
if m != nil && m.IsWeak != nil {
|
||||
return *m.IsWeak
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type ComponentDataReference struct {
|
||||
DataIdentifier *uint64 `protobuf:"varint,1,req,name=data_identifier" json:"data_identifier,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *ComponentDataReference) Reset() { *m = ComponentDataReference{} }
|
||||
func (m *ComponentDataReference) String() string { return proto.CompactTextString(m) }
|
||||
func (*ComponentDataReference) ProtoMessage() {}
|
||||
|
||||
func (m *ComponentDataReference) GetDataIdentifier() uint64 {
|
||||
if m != nil && m.DataIdentifier != nil {
|
||||
return *m.DataIdentifier
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type PackageMetadata struct {
|
||||
LastObjectIdentifier *uint64 `protobuf:"varint,1,req,name=last_object_identifier" json:"last_object_identifier,omitempty"`
|
||||
Components []*ComponentInfo `protobuf:"bytes,3,rep,name=components" json:"components,omitempty"`
|
||||
Datas []*DataInfo `protobuf:"bytes,4,rep,name=datas" json:"datas,omitempty"`
|
||||
ReadVersion []uint32 `protobuf:"varint,5,rep,packed,name=read_version" json:"read_version,omitempty"`
|
||||
WriteVersion []uint32 `protobuf:"varint,6,rep,packed,name=write_version" json:"write_version,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *PackageMetadata) Reset() { *m = PackageMetadata{} }
|
||||
func (m *PackageMetadata) String() string { return proto.CompactTextString(m) }
|
||||
func (*PackageMetadata) ProtoMessage() {}
|
||||
|
||||
func (m *PackageMetadata) GetLastObjectIdentifier() uint64 {
|
||||
if m != nil && m.LastObjectIdentifier != nil {
|
||||
return *m.LastObjectIdentifier
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *PackageMetadata) GetComponents() []*ComponentInfo {
|
||||
if m != nil {
|
||||
return m.Components
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *PackageMetadata) GetDatas() []*DataInfo {
|
||||
if m != nil {
|
||||
return m.Datas
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *PackageMetadata) GetReadVersion() []uint32 {
|
||||
if m != nil {
|
||||
return m.ReadVersion
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *PackageMetadata) GetWriteVersion() []uint32 {
|
||||
if m != nil {
|
||||
return m.WriteVersion
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type PasteboardMetadata struct {
|
||||
Version []uint32 `protobuf:"varint,1,rep,packed,name=version" json:"version,omitempty"`
|
||||
AppName *string `protobuf:"bytes,2,req,name=app_name" json:"app_name,omitempty"`
|
||||
Datas []*DataInfo `protobuf:"bytes,3,rep,name=datas" json:"datas,omitempty"`
|
||||
SourceDocumentUuid *string `protobuf:"bytes,4,opt,name=source_document_uuid" json:"source_document_uuid,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *PasteboardMetadata) Reset() { *m = PasteboardMetadata{} }
|
||||
func (m *PasteboardMetadata) String() string { return proto.CompactTextString(m) }
|
||||
func (*PasteboardMetadata) ProtoMessage() {}
|
||||
|
||||
func (m *PasteboardMetadata) GetVersion() []uint32 {
|
||||
if m != nil {
|
||||
return m.Version
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *PasteboardMetadata) GetAppName() string {
|
||||
if m != nil && m.AppName != nil {
|
||||
return *m.AppName
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *PasteboardMetadata) GetDatas() []*DataInfo {
|
||||
if m != nil {
|
||||
return m.Datas
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *PasteboardMetadata) GetSourceDocumentUuid() string {
|
||||
if m != nil && m.SourceDocumentUuid != nil {
|
||||
return *m.SourceDocumentUuid
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type DataInfo struct {
|
||||
Identifier *uint64 `protobuf:"varint,1,req,name=identifier" json:"identifier,omitempty"`
|
||||
Digest []byte `protobuf:"bytes,2,req,name=digest" json:"digest,omitempty"`
|
||||
PreferredFileName *string `protobuf:"bytes,3,req,name=preferred_file_name" json:"preferred_file_name,omitempty"`
|
||||
FileName *string `protobuf:"bytes,4,opt,name=file_name" json:"file_name,omitempty"`
|
||||
DocumentResourceLocator *string `protobuf:"bytes,5,opt,name=document_resource_locator" json:"document_resource_locator,omitempty"`
|
||||
SourceBookmarkData []byte `protobuf:"bytes,6,opt,name=source_bookmark_data" json:"source_bookmark_data,omitempty"`
|
||||
PasteboardExternalFilePath *string `protobuf:"bytes,99,opt,name=pasteboard_external_file_path" json:"pasteboard_external_file_path,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *DataInfo) Reset() { *m = DataInfo{} }
|
||||
func (m *DataInfo) String() string { return proto.CompactTextString(m) }
|
||||
func (*DataInfo) ProtoMessage() {}
|
||||
|
||||
func (m *DataInfo) GetIdentifier() uint64 {
|
||||
if m != nil && m.Identifier != nil {
|
||||
return *m.Identifier
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *DataInfo) GetDigest() []byte {
|
||||
if m != nil {
|
||||
return m.Digest
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *DataInfo) GetPreferredFileName() string {
|
||||
if m != nil && m.PreferredFileName != nil {
|
||||
return *m.PreferredFileName
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *DataInfo) GetFileName() string {
|
||||
if m != nil && m.FileName != nil {
|
||||
return *m.FileName
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *DataInfo) GetDocumentResourceLocator() string {
|
||||
if m != nil && m.DocumentResourceLocator != nil {
|
||||
return *m.DocumentResourceLocator
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *DataInfo) GetSourceBookmarkData() []byte {
|
||||
if m != nil {
|
||||
return m.SourceBookmarkData
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *DataInfo) GetPasteboardExternalFilePath() string {
|
||||
if m != nil && m.PasteboardExternalFilePath != nil {
|
||||
return *m.PasteboardExternalFilePath
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type ViewStateMetadata struct {
|
||||
Version []uint32 `protobuf:"varint,1,rep,packed,name=version" json:"version,omitempty"`
|
||||
DocumentVersionUuid *string `protobuf:"bytes,2,req,name=document_version_uuid" json:"document_version_uuid,omitempty"`
|
||||
Component *ComponentInfo `protobuf:"bytes,3,req,name=component" json:"component,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *ViewStateMetadata) Reset() { *m = ViewStateMetadata{} }
|
||||
func (m *ViewStateMetadata) String() string { return proto.CompactTextString(m) }
|
||||
func (*ViewStateMetadata) ProtoMessage() {}
|
||||
|
||||
func (m *ViewStateMetadata) GetVersion() []uint32 {
|
||||
if m != nil {
|
||||
return m.Version
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *ViewStateMetadata) GetDocumentVersionUuid() string {
|
||||
if m != nil && m.DocumentVersionUuid != nil {
|
||||
return *m.DocumentVersionUuid
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *ViewStateMetadata) GetComponent() *ComponentInfo {
|
||||
if m != nil {
|
||||
return m.Component
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterEnum("TSP.FieldInfo_Type", FieldInfo_Type_name, FieldInfo_Type_value)
|
||||
proto.RegisterEnum("TSP.FieldInfo_Rule", FieldInfo_Rule_name, FieldInfo_Rule_value)
|
||||
}
|
||||
150
vendor/code.sajari.com/docconv/iWork/TSPDatabaseMessages.pb.go
generated
vendored
150
vendor/code.sajari.com/docconv/iWork/TSPDatabaseMessages.pb.go
generated
vendored
|
|
@ -1,150 +0,0 @@
|
|||
// Code generated by protoc-gen-go.
|
||||
// source: TSPDatabaseMessages.proto
|
||||
// DO NOT EDIT!
|
||||
|
||||
package TSP
|
||||
|
||||
import proto "github.com/golang/protobuf/proto"
|
||||
import math "math"
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = math.Inf
|
||||
|
||||
type DatabaseImageDataArchive_ImageType int32
|
||||
|
||||
const (
|
||||
DatabaseImageDataArchive_unknown DatabaseImageDataArchive_ImageType = 0
|
||||
DatabaseImageDataArchive_bitmap DatabaseImageDataArchive_ImageType = 1
|
||||
DatabaseImageDataArchive_pdf DatabaseImageDataArchive_ImageType = 2
|
||||
)
|
||||
|
||||
var DatabaseImageDataArchive_ImageType_name = map[int32]string{
|
||||
0: "unknown",
|
||||
1: "bitmap",
|
||||
2: "pdf",
|
||||
}
|
||||
var DatabaseImageDataArchive_ImageType_value = map[string]int32{
|
||||
"unknown": 0,
|
||||
"bitmap": 1,
|
||||
"pdf": 2,
|
||||
}
|
||||
|
||||
func (x DatabaseImageDataArchive_ImageType) Enum() *DatabaseImageDataArchive_ImageType {
|
||||
p := new(DatabaseImageDataArchive_ImageType)
|
||||
*p = x
|
||||
return p
|
||||
}
|
||||
func (x DatabaseImageDataArchive_ImageType) String() string {
|
||||
return proto.EnumName(DatabaseImageDataArchive_ImageType_name, int32(x))
|
||||
}
|
||||
func (x *DatabaseImageDataArchive_ImageType) UnmarshalJSON(data []byte) error {
|
||||
value, err := proto.UnmarshalJSONEnum(DatabaseImageDataArchive_ImageType_value, data, "DatabaseImageDataArchive_ImageType")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*x = DatabaseImageDataArchive_ImageType(value)
|
||||
return nil
|
||||
}
|
||||
|
||||
type DatabaseData struct {
|
||||
Data *DataReference `protobuf:"bytes,1,req,name=data" json:"data,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *DatabaseData) Reset() { *m = DatabaseData{} }
|
||||
func (m *DatabaseData) String() string { return proto.CompactTextString(m) }
|
||||
func (*DatabaseData) ProtoMessage() {}
|
||||
|
||||
func (m *DatabaseData) GetData() *DataReference {
|
||||
if m != nil {
|
||||
return m.Data
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type DatabaseDataArchive struct {
|
||||
Data *Reference `protobuf:"bytes,1,opt,name=data" json:"data,omitempty"`
|
||||
AppRelativePath *string `protobuf:"bytes,2,opt,name=app_relative_path" json:"app_relative_path,omitempty"`
|
||||
DisplayName *string `protobuf:"bytes,3,req,name=display_name" json:"display_name,omitempty"`
|
||||
Length *uint64 `protobuf:"varint,4,opt,name=length" json:"length,omitempty"`
|
||||
Hash *uint32 `protobuf:"varint,5,opt,name=hash" json:"hash,omitempty"`
|
||||
Sharable *bool `protobuf:"varint,6,req,name=sharable,def=1" json:"sharable,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *DatabaseDataArchive) Reset() { *m = DatabaseDataArchive{} }
|
||||
func (m *DatabaseDataArchive) String() string { return proto.CompactTextString(m) }
|
||||
func (*DatabaseDataArchive) ProtoMessage() {}
|
||||
|
||||
const Default_DatabaseDataArchive_Sharable bool = true
|
||||
|
||||
func (m *DatabaseDataArchive) GetData() *Reference {
|
||||
if m != nil {
|
||||
return m.Data
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *DatabaseDataArchive) GetAppRelativePath() string {
|
||||
if m != nil && m.AppRelativePath != nil {
|
||||
return *m.AppRelativePath
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *DatabaseDataArchive) GetDisplayName() string {
|
||||
if m != nil && m.DisplayName != nil {
|
||||
return *m.DisplayName
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *DatabaseDataArchive) GetLength() uint64 {
|
||||
if m != nil && m.Length != nil {
|
||||
return *m.Length
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *DatabaseDataArchive) GetHash() uint32 {
|
||||
if m != nil && m.Hash != nil {
|
||||
return *m.Hash
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *DatabaseDataArchive) GetSharable() bool {
|
||||
if m != nil && m.Sharable != nil {
|
||||
return *m.Sharable
|
||||
}
|
||||
return Default_DatabaseDataArchive_Sharable
|
||||
}
|
||||
|
||||
type DatabaseImageDataArchive struct {
|
||||
Super *DatabaseDataArchive `protobuf:"bytes,1,req,name=super" json:"super,omitempty"`
|
||||
Type *DatabaseImageDataArchive_ImageType `protobuf:"varint,2,req,name=type,enum=TSP.DatabaseImageDataArchive_ImageType" json:"type,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *DatabaseImageDataArchive) Reset() { *m = DatabaseImageDataArchive{} }
|
||||
func (m *DatabaseImageDataArchive) String() string { return proto.CompactTextString(m) }
|
||||
func (*DatabaseImageDataArchive) ProtoMessage() {}
|
||||
|
||||
func (m *DatabaseImageDataArchive) GetSuper() *DatabaseDataArchive {
|
||||
if m != nil {
|
||||
return m.Super
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *DatabaseImageDataArchive) GetType() DatabaseImageDataArchive_ImageType {
|
||||
if m != nil && m.Type != nil {
|
||||
return *m.Type
|
||||
}
|
||||
return DatabaseImageDataArchive_unknown
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterEnum("TSP.DatabaseImageDataArchive_ImageType", DatabaseImageDataArchive_ImageType_name, DatabaseImageDataArchive_ImageType_value)
|
||||
}
|
||||
524
vendor/code.sajari.com/docconv/iWork/TSPMessages.pb.go
generated
vendored
524
vendor/code.sajari.com/docconv/iWork/TSPMessages.pb.go
generated
vendored
|
|
@ -1,524 +0,0 @@
|
|||
// Code generated by protoc-gen-go.
|
||||
// source: TSPMessages.proto
|
||||
// DO NOT EDIT!
|
||||
|
||||
package TSP
|
||||
|
||||
import proto "github.com/golang/protobuf/proto"
|
||||
import math "math"
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = math.Inf
|
||||
|
||||
type Color_ColorModel int32
|
||||
|
||||
const (
|
||||
Color_rgb Color_ColorModel = 1
|
||||
Color_cmyk Color_ColorModel = 2
|
||||
Color_white Color_ColorModel = 3
|
||||
)
|
||||
|
||||
var Color_ColorModel_name = map[int32]string{
|
||||
1: "rgb",
|
||||
2: "cmyk",
|
||||
3: "white",
|
||||
}
|
||||
var Color_ColorModel_value = map[string]int32{
|
||||
"rgb": 1,
|
||||
"cmyk": 2,
|
||||
"white": 3,
|
||||
}
|
||||
|
||||
func (x Color_ColorModel) Enum() *Color_ColorModel {
|
||||
p := new(Color_ColorModel)
|
||||
*p = x
|
||||
return p
|
||||
}
|
||||
func (x Color_ColorModel) String() string {
|
||||
return proto.EnumName(Color_ColorModel_name, int32(x))
|
||||
}
|
||||
func (x *Color_ColorModel) UnmarshalJSON(data []byte) error {
|
||||
value, err := proto.UnmarshalJSONEnum(Color_ColorModel_value, data, "Color_ColorModel")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*x = Color_ColorModel(value)
|
||||
return nil
|
||||
}
|
||||
|
||||
type Path_ElementType int32
|
||||
|
||||
const (
|
||||
Path_moveTo Path_ElementType = 1
|
||||
Path_lineTo Path_ElementType = 2
|
||||
Path_quadCurveTo Path_ElementType = 3
|
||||
Path_curveTo Path_ElementType = 4
|
||||
Path_closeSubpath Path_ElementType = 5
|
||||
)
|
||||
|
||||
var Path_ElementType_name = map[int32]string{
|
||||
1: "moveTo",
|
||||
2: "lineTo",
|
||||
3: "quadCurveTo",
|
||||
4: "curveTo",
|
||||
5: "closeSubpath",
|
||||
}
|
||||
var Path_ElementType_value = map[string]int32{
|
||||
"moveTo": 1,
|
||||
"lineTo": 2,
|
||||
"quadCurveTo": 3,
|
||||
"curveTo": 4,
|
||||
"closeSubpath": 5,
|
||||
}
|
||||
|
||||
func (x Path_ElementType) Enum() *Path_ElementType {
|
||||
p := new(Path_ElementType)
|
||||
*p = x
|
||||
return p
|
||||
}
|
||||
func (x Path_ElementType) String() string {
|
||||
return proto.EnumName(Path_ElementType_name, int32(x))
|
||||
}
|
||||
func (x *Path_ElementType) UnmarshalJSON(data []byte) error {
|
||||
value, err := proto.UnmarshalJSONEnum(Path_ElementType_value, data, "Path_ElementType")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*x = Path_ElementType(value)
|
||||
return nil
|
||||
}
|
||||
|
||||
type Reference struct {
|
||||
Identifier *uint64 `protobuf:"varint,1,req,name=identifier" json:"identifier,omitempty"`
|
||||
DeprecatedType *int32 `protobuf:"varint,2,opt,name=deprecated_type" json:"deprecated_type,omitempty"`
|
||||
DeprecatedIsExternal *bool `protobuf:"varint,3,opt,name=deprecated_is_external" json:"deprecated_is_external,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *Reference) Reset() { *m = Reference{} }
|
||||
func (m *Reference) String() string { return proto.CompactTextString(m) }
|
||||
func (*Reference) ProtoMessage() {}
|
||||
|
||||
func (m *Reference) GetIdentifier() uint64 {
|
||||
if m != nil && m.Identifier != nil {
|
||||
return *m.Identifier
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *Reference) GetDeprecatedType() int32 {
|
||||
if m != nil && m.DeprecatedType != nil {
|
||||
return *m.DeprecatedType
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *Reference) GetDeprecatedIsExternal() bool {
|
||||
if m != nil && m.DeprecatedIsExternal != nil {
|
||||
return *m.DeprecatedIsExternal
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type DataReference struct {
|
||||
Identifier *uint64 `protobuf:"varint,1,req,name=identifier" json:"identifier,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *DataReference) Reset() { *m = DataReference{} }
|
||||
func (m *DataReference) String() string { return proto.CompactTextString(m) }
|
||||
func (*DataReference) ProtoMessage() {}
|
||||
|
||||
func (m *DataReference) GetIdentifier() uint64 {
|
||||
if m != nil && m.Identifier != nil {
|
||||
return *m.Identifier
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type Point struct {
|
||||
X *float32 `protobuf:"fixed32,1,req,name=x" json:"x,omitempty"`
|
||||
Y *float32 `protobuf:"fixed32,2,req,name=y" json:"y,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *Point) Reset() { *m = Point{} }
|
||||
func (m *Point) String() string { return proto.CompactTextString(m) }
|
||||
func (*Point) ProtoMessage() {}
|
||||
|
||||
func (m *Point) GetX() float32 {
|
||||
if m != nil && m.X != nil {
|
||||
return *m.X
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *Point) GetY() float32 {
|
||||
if m != nil && m.Y != nil {
|
||||
return *m.Y
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type Size struct {
|
||||
Width *float32 `protobuf:"fixed32,1,req,name=width" json:"width,omitempty"`
|
||||
Height *float32 `protobuf:"fixed32,2,req,name=height" json:"height,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *Size) Reset() { *m = Size{} }
|
||||
func (m *Size) String() string { return proto.CompactTextString(m) }
|
||||
func (*Size) ProtoMessage() {}
|
||||
|
||||
func (m *Size) GetWidth() float32 {
|
||||
if m != nil && m.Width != nil {
|
||||
return *m.Width
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *Size) GetHeight() float32 {
|
||||
if m != nil && m.Height != nil {
|
||||
return *m.Height
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type Range struct {
|
||||
Location *uint32 `protobuf:"varint,1,req,name=location" json:"location,omitempty"`
|
||||
Length *uint32 `protobuf:"varint,2,req,name=length" json:"length,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *Range) Reset() { *m = Range{} }
|
||||
func (m *Range) String() string { return proto.CompactTextString(m) }
|
||||
func (*Range) ProtoMessage() {}
|
||||
|
||||
func (m *Range) GetLocation() uint32 {
|
||||
if m != nil && m.Location != nil {
|
||||
return *m.Location
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *Range) GetLength() uint32 {
|
||||
if m != nil && m.Length != nil {
|
||||
return *m.Length
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type Date struct {
|
||||
Seconds *float64 `protobuf:"fixed64,1,req,name=seconds" json:"seconds,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *Date) Reset() { *m = Date{} }
|
||||
func (m *Date) String() string { return proto.CompactTextString(m) }
|
||||
func (*Date) ProtoMessage() {}
|
||||
|
||||
func (m *Date) GetSeconds() float64 {
|
||||
if m != nil && m.Seconds != nil {
|
||||
return *m.Seconds
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type IndexSet struct {
|
||||
Ranges []*Range `protobuf:"bytes,1,rep,name=ranges" json:"ranges,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *IndexSet) Reset() { *m = IndexSet{} }
|
||||
func (m *IndexSet) String() string { return proto.CompactTextString(m) }
|
||||
func (*IndexSet) ProtoMessage() {}
|
||||
|
||||
func (m *IndexSet) GetRanges() []*Range {
|
||||
if m != nil {
|
||||
return m.Ranges
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Color struct {
|
||||
Model *Color_ColorModel `protobuf:"varint,1,req,name=model,enum=TSP.Color_ColorModel" json:"model,omitempty"`
|
||||
R *float32 `protobuf:"fixed32,3,opt,name=r" json:"r,omitempty"`
|
||||
G *float32 `protobuf:"fixed32,4,opt,name=g" json:"g,omitempty"`
|
||||
B *float32 `protobuf:"fixed32,5,opt,name=b" json:"b,omitempty"`
|
||||
A *float32 `protobuf:"fixed32,6,opt,name=a,def=1" json:"a,omitempty"`
|
||||
C *float32 `protobuf:"fixed32,7,opt,name=c" json:"c,omitempty"`
|
||||
M *float32 `protobuf:"fixed32,8,opt,name=m" json:"m,omitempty"`
|
||||
Y *float32 `protobuf:"fixed32,9,opt,name=y" json:"y,omitempty"`
|
||||
K *float32 `protobuf:"fixed32,10,opt,name=k" json:"k,omitempty"`
|
||||
W *float32 `protobuf:"fixed32,11,opt,name=w" json:"w,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *Color) Reset() { *m = Color{} }
|
||||
func (m *Color) String() string { return proto.CompactTextString(m) }
|
||||
func (*Color) ProtoMessage() {}
|
||||
|
||||
const Default_Color_A float32 = 1
|
||||
|
||||
func (m *Color) GetModel() Color_ColorModel {
|
||||
if m != nil && m.Model != nil {
|
||||
return *m.Model
|
||||
}
|
||||
return Color_rgb
|
||||
}
|
||||
|
||||
func (m *Color) GetR() float32 {
|
||||
if m != nil && m.R != nil {
|
||||
return *m.R
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *Color) GetG() float32 {
|
||||
if m != nil && m.G != nil {
|
||||
return *m.G
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *Color) GetB() float32 {
|
||||
if m != nil && m.B != nil {
|
||||
return *m.B
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *Color) GetA() float32 {
|
||||
if m != nil && m.A != nil {
|
||||
return *m.A
|
||||
}
|
||||
return Default_Color_A
|
||||
}
|
||||
|
||||
func (m *Color) GetC() float32 {
|
||||
if m != nil && m.C != nil {
|
||||
return *m.C
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *Color) GetM() float32 {
|
||||
if m != nil && m.M != nil {
|
||||
return *m.M
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *Color) GetY() float32 {
|
||||
if m != nil && m.Y != nil {
|
||||
return *m.Y
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *Color) GetK() float32 {
|
||||
if m != nil && m.K != nil {
|
||||
return *m.K
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *Color) GetW() float32 {
|
||||
if m != nil && m.W != nil {
|
||||
return *m.W
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type Path struct {
|
||||
Elements []*Path_Element `protobuf:"bytes,1,rep,name=elements" json:"elements,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *Path) Reset() { *m = Path{} }
|
||||
func (m *Path) String() string { return proto.CompactTextString(m) }
|
||||
func (*Path) ProtoMessage() {}
|
||||
|
||||
func (m *Path) GetElements() []*Path_Element {
|
||||
if m != nil {
|
||||
return m.Elements
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Path_Element struct {
|
||||
Type *Path_ElementType `protobuf:"varint,1,req,name=type,enum=TSP.Path_ElementType" json:"type,omitempty"`
|
||||
Points []*Point `protobuf:"bytes,2,rep,name=points" json:"points,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *Path_Element) Reset() { *m = Path_Element{} }
|
||||
func (m *Path_Element) String() string { return proto.CompactTextString(m) }
|
||||
func (*Path_Element) ProtoMessage() {}
|
||||
|
||||
func (m *Path_Element) GetType() Path_ElementType {
|
||||
if m != nil && m.Type != nil {
|
||||
return *m.Type
|
||||
}
|
||||
return Path_moveTo
|
||||
}
|
||||
|
||||
func (m *Path_Element) GetPoints() []*Point {
|
||||
if m != nil {
|
||||
return m.Points
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ReferenceDictionary struct {
|
||||
Entries []*ReferenceDictionary_Entry `protobuf:"bytes,1,rep,name=entries" json:"entries,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *ReferenceDictionary) Reset() { *m = ReferenceDictionary{} }
|
||||
func (m *ReferenceDictionary) String() string { return proto.CompactTextString(m) }
|
||||
func (*ReferenceDictionary) ProtoMessage() {}
|
||||
|
||||
func (m *ReferenceDictionary) GetEntries() []*ReferenceDictionary_Entry {
|
||||
if m != nil {
|
||||
return m.Entries
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ReferenceDictionary_Entry struct {
|
||||
Key *Reference `protobuf:"bytes,1,req,name=key" json:"key,omitempty"`
|
||||
Value *Reference `protobuf:"bytes,2,req,name=value" json:"value,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *ReferenceDictionary_Entry) Reset() { *m = ReferenceDictionary_Entry{} }
|
||||
func (m *ReferenceDictionary_Entry) String() string { return proto.CompactTextString(m) }
|
||||
func (*ReferenceDictionary_Entry) ProtoMessage() {}
|
||||
|
||||
func (m *ReferenceDictionary_Entry) GetKey() *Reference {
|
||||
if m != nil {
|
||||
return m.Key
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *ReferenceDictionary_Entry) GetValue() *Reference {
|
||||
if m != nil {
|
||||
return m.Value
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type PasteboardObject struct {
|
||||
Stylesheet *Reference `protobuf:"bytes,1,opt,name=stylesheet" json:"stylesheet,omitempty"`
|
||||
Drawables []*Reference `protobuf:"bytes,2,rep,name=drawables" json:"drawables,omitempty"`
|
||||
Styles []*Reference `protobuf:"bytes,3,rep,name=styles" json:"styles,omitempty"`
|
||||
Theme *Reference `protobuf:"bytes,4,opt,name=theme" json:"theme,omitempty"`
|
||||
WpStorage *Reference `protobuf:"bytes,5,opt,name=wp_storage" json:"wp_storage,omitempty"`
|
||||
GuideStorage *Reference `protobuf:"bytes,9,opt,name=guide_storage" json:"guide_storage,omitempty"`
|
||||
AppNativeObject *Reference `protobuf:"bytes,6,opt,name=app_native_object" json:"app_native_object,omitempty"`
|
||||
IsTextPrimary *bool `protobuf:"varint,7,opt,name=is_text_primary,def=0" json:"is_text_primary,omitempty"`
|
||||
IsSmart *bool `protobuf:"varint,8,opt,name=is_smart,def=0" json:"is_smart,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *PasteboardObject) Reset() { *m = PasteboardObject{} }
|
||||
func (m *PasteboardObject) String() string { return proto.CompactTextString(m) }
|
||||
func (*PasteboardObject) ProtoMessage() {}
|
||||
|
||||
const Default_PasteboardObject_IsTextPrimary bool = false
|
||||
const Default_PasteboardObject_IsSmart bool = false
|
||||
|
||||
func (m *PasteboardObject) GetStylesheet() *Reference {
|
||||
if m != nil {
|
||||
return m.Stylesheet
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *PasteboardObject) GetDrawables() []*Reference {
|
||||
if m != nil {
|
||||
return m.Drawables
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *PasteboardObject) GetStyles() []*Reference {
|
||||
if m != nil {
|
||||
return m.Styles
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *PasteboardObject) GetTheme() *Reference {
|
||||
if m != nil {
|
||||
return m.Theme
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *PasteboardObject) GetWpStorage() *Reference {
|
||||
if m != nil {
|
||||
return m.WpStorage
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *PasteboardObject) GetGuideStorage() *Reference {
|
||||
if m != nil {
|
||||
return m.GuideStorage
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *PasteboardObject) GetAppNativeObject() *Reference {
|
||||
if m != nil {
|
||||
return m.AppNativeObject
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *PasteboardObject) GetIsTextPrimary() bool {
|
||||
if m != nil && m.IsTextPrimary != nil {
|
||||
return *m.IsTextPrimary
|
||||
}
|
||||
return Default_PasteboardObject_IsTextPrimary
|
||||
}
|
||||
|
||||
func (m *PasteboardObject) GetIsSmart() bool {
|
||||
if m != nil && m.IsSmart != nil {
|
||||
return *m.IsSmart
|
||||
}
|
||||
return Default_PasteboardObject_IsSmart
|
||||
}
|
||||
|
||||
type ObjectContainer struct {
|
||||
Identifier *uint32 `protobuf:"varint,1,opt,name=identifier" json:"identifier,omitempty"`
|
||||
Objects []*Reference `protobuf:"bytes,2,rep,name=objects" json:"objects,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *ObjectContainer) Reset() { *m = ObjectContainer{} }
|
||||
func (m *ObjectContainer) String() string { return proto.CompactTextString(m) }
|
||||
func (*ObjectContainer) ProtoMessage() {}
|
||||
|
||||
func (m *ObjectContainer) GetIdentifier() uint32 {
|
||||
if m != nil && m.Identifier != nil {
|
||||
return *m.Identifier
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *ObjectContainer) GetObjects() []*Reference {
|
||||
if m != nil {
|
||||
return m.Objects
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterEnum("TSP.Color_ColorModel", Color_ColorModel_name, Color_ColorModel_value)
|
||||
proto.RegisterEnum("TSP.Path_ElementType", Path_ElementType_name, Path_ElementType_value)
|
||||
}
|
||||
17
vendor/code.sajari.com/docconv/image.go
generated
vendored
17
vendor/code.sajari.com/docconv/image.go
generated
vendored
|
|
@ -1,17 +0,0 @@
|
|||
// +build !ocr
|
||||
|
||||
package docconv
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
// ConvertImage converts images to text.
|
||||
// Requires gosseract (ocr build tag).
|
||||
func ConvertImage(r io.Reader) (string, map[string]string, error) {
|
||||
return "", nil, fmt.Errorf("docconv not built with `ocr` build tag")
|
||||
}
|
||||
|
||||
// SetImageLanguages sets the languages parameter passed to gosseract.
|
||||
func SetImageLanguages(...string) {}
|
||||
51
vendor/code.sajari.com/docconv/image_ocr.go
generated
vendored
51
vendor/code.sajari.com/docconv/image_ocr.go
generated
vendored
|
|
@ -1,51 +0,0 @@
|
|||
// +build ocr
|
||||
|
||||
package docconv
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"sync"
|
||||
|
||||
"github.com/otiai10/gosseract/v2"
|
||||
)
|
||||
|
||||
var config = struct {
|
||||
langs []string
|
||||
sync.Mutex
|
||||
}{
|
||||
langs: []string{"eng"},
|
||||
}
|
||||
|
||||
func SetImageLanguages(l ...string) {
|
||||
config.Lock()
|
||||
config.langs = l
|
||||
config.Unlock()
|
||||
}
|
||||
|
||||
// ConvertImage converts images to text.
|
||||
// Requires gosseract.
|
||||
func ConvertImage(r io.Reader) (string, map[string]string, error) {
|
||||
f, err := NewLocalFile(r)
|
||||
if err != nil {
|
||||
return "", nil, fmt.Errorf("error creating local file: %v", err)
|
||||
}
|
||||
defer f.Done()
|
||||
|
||||
meta := make(map[string]string)
|
||||
|
||||
client := gosseract.NewClient()
|
||||
defer client.Close()
|
||||
|
||||
config.Lock()
|
||||
defer config.Unlock()
|
||||
|
||||
client.SetLanguage(config.langs...)
|
||||
client.SetImage(f.Name())
|
||||
text, err := client.Text()
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
|
||||
return text, meta, nil
|
||||
}
|
||||
51
vendor/code.sajari.com/docconv/local.go
generated
vendored
51
vendor/code.sajari.com/docconv/local.go
generated
vendored
|
|
@ -1,51 +0,0 @@
|
|||
package docconv
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
)
|
||||
|
||||
// LocalFile is a type which wraps an *os.File. See NewLocalFile for more details.
|
||||
type LocalFile struct {
|
||||
*os.File
|
||||
|
||||
unlink bool
|
||||
}
|
||||
|
||||
// NewLocalFile ensures that there is a file which contains the data provided by r. If r is
|
||||
// actually an instance of *os.File then this file is used, otherwise a temporary file is
|
||||
// created and the data from r copied into it. Callers must call Done() when
|
||||
// the LocalFile is no longer needed to ensure all resources are cleaned up.
|
||||
func NewLocalFile(r io.Reader) (*LocalFile, error) {
|
||||
if f, ok := r.(*os.File); ok {
|
||||
return &LocalFile{
|
||||
File: f,
|
||||
}, nil
|
||||
}
|
||||
|
||||
f, err := ioutil.TempFile(os.TempDir(), "docconv")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error creating temporary file: %v", err)
|
||||
}
|
||||
_, err = io.Copy(f, r)
|
||||
if err != nil {
|
||||
f.Close()
|
||||
os.Remove(f.Name())
|
||||
return nil, fmt.Errorf("error copying data into temporary file: %v", err)
|
||||
}
|
||||
|
||||
return &LocalFile{
|
||||
File: f,
|
||||
unlink: true,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Done cleans up all resources.
|
||||
func (l *LocalFile) Done() {
|
||||
l.Close()
|
||||
if l.unlink {
|
||||
os.Remove(l.Name())
|
||||
}
|
||||
}
|
||||
69
vendor/code.sajari.com/docconv/odt.go
generated
vendored
69
vendor/code.sajari.com/docconv/odt.go
generated
vendored
|
|
@ -1,69 +0,0 @@
|
|||
package docconv
|
||||
|
||||
import (
|
||||
"archive/zip"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"time"
|
||||
)
|
||||
|
||||
// ConvertODT converts a ODT file to text
|
||||
func ConvertODT(r io.Reader) (string, map[string]string, error) {
|
||||
meta := make(map[string]string)
|
||||
var textBody string
|
||||
|
||||
b, err := ioutil.ReadAll(r)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
zr, err := zip.NewReader(bytes.NewReader(b), int64(len(b)))
|
||||
if err != nil {
|
||||
return "", nil, fmt.Errorf("error unzipping data: %v", err)
|
||||
}
|
||||
|
||||
for _, f := range zr.File {
|
||||
switch f.Name {
|
||||
case "meta.xml":
|
||||
rc, err := f.Open()
|
||||
if err != nil {
|
||||
return "", nil, fmt.Errorf("error extracting '%v' from archive: %v", f.Name, err)
|
||||
}
|
||||
defer rc.Close()
|
||||
|
||||
info, err := XMLToMap(rc)
|
||||
if err != nil {
|
||||
return "", nil, fmt.Errorf("error parsing '%v': %v", f.Name, err)
|
||||
}
|
||||
|
||||
if tmp, ok := info["creator"]; ok {
|
||||
meta["Author"] = tmp
|
||||
}
|
||||
if tmp, ok := info["date"]; ok {
|
||||
if t, err := time.Parse("2006-01-02T15:04:05", tmp); err == nil {
|
||||
meta["ModifiedDate"] = fmt.Sprintf("%d", t.Unix())
|
||||
}
|
||||
}
|
||||
if tmp, ok := info["creation-date"]; ok {
|
||||
if t, err := time.Parse("2006-01-02T15:04:05", tmp); err == nil {
|
||||
meta["CreatedDate"] = fmt.Sprintf("%d", t.Unix())
|
||||
}
|
||||
}
|
||||
|
||||
case "content.xml":
|
||||
rc, err := f.Open()
|
||||
if err != nil {
|
||||
return "", nil, fmt.Errorf("error extracting '%v' from archive: %v", f.Name, err)
|
||||
}
|
||||
defer rc.Close()
|
||||
|
||||
textBody, err = XMLToText(rc, []string{"br", "p", "tab"}, []string{}, true)
|
||||
if err != nil {
|
||||
return "", nil, fmt.Errorf("error parsing '%v': %v", f.Name, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return textBody, meta, nil
|
||||
}
|
||||
69
vendor/code.sajari.com/docconv/pages.go
generated
vendored
69
vendor/code.sajari.com/docconv/pages.go
generated
vendored
|
|
@ -1,69 +0,0 @@
|
|||
package docconv
|
||||
|
||||
import (
|
||||
"archive/zip"
|
||||
"bufio"
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
|
||||
"github.com/golang/protobuf/proto"
|
||||
|
||||
TSP "code.sajari.com/docconv/iWork"
|
||||
"code.sajari.com/docconv/snappy"
|
||||
)
|
||||
|
||||
// ConvertPages converts a Pages file to text.
|
||||
func ConvertPages(r io.Reader) (string, map[string]string, error) {
|
||||
meta := make(map[string]string)
|
||||
var textBody string
|
||||
|
||||
b, err := ioutil.ReadAll(r)
|
||||
if err != nil {
|
||||
return "", nil, fmt.Errorf("error reading data: %v", err)
|
||||
}
|
||||
|
||||
zr, err := zip.NewReader(bytes.NewReader(b), int64(len(b)))
|
||||
if err != nil {
|
||||
return "", nil, fmt.Errorf("error unzipping data: %v", err)
|
||||
}
|
||||
|
||||
for _, f := range zr.File {
|
||||
if strings.HasSuffix(f.Name, "Preview.pdf") {
|
||||
// There is a preview PDF version we can use
|
||||
if rc, err := f.Open(); err == nil {
|
||||
return ConvertPDF(rc)
|
||||
}
|
||||
}
|
||||
if f.Name == "index.xml" {
|
||||
// There's an XML version we can use
|
||||
if rc, err := f.Open(); err == nil {
|
||||
return ConvertXML(rc)
|
||||
}
|
||||
}
|
||||
if f.Name == "Index/Document.iwa" {
|
||||
rc, _ := f.Open()
|
||||
defer rc.Close()
|
||||
bReader := bufio.NewReader(snappy.NewReader(io.MultiReader(strings.NewReader("\xff\x06\x00\x00sNaPpY"), rc)))
|
||||
|
||||
// Ignore error.
|
||||
// NOTE: This error was unchecked. Need to revisit this to see if it
|
||||
// should be acted on.
|
||||
archiveLength, _ := binary.ReadVarint(bReader)
|
||||
|
||||
// Ignore error.
|
||||
// NOTE: This error was unchecked. Need to revisit this to see if it
|
||||
// should be acted on.
|
||||
archiveInfoData, _ := ioutil.ReadAll(io.LimitReader(bReader, archiveLength))
|
||||
|
||||
archiveInfo := &TSP.ArchiveInfo{}
|
||||
err = proto.Unmarshal(archiveInfoData, archiveInfo)
|
||||
fmt.Println("archiveInfo:", archiveInfo, err)
|
||||
}
|
||||
}
|
||||
|
||||
return textBody, meta, nil
|
||||
}
|
||||
30
vendor/code.sajari.com/docconv/pdf.go
generated
vendored
30
vendor/code.sajari.com/docconv/pdf.go
generated
vendored
|
|
@ -1,30 +0,0 @@
|
|||
// +build !ocr
|
||||
|
||||
package docconv
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
func ConvertPDF(r io.Reader) (string, map[string]string, error) {
|
||||
|
||||
f, err := NewLocalFile(r)
|
||||
if err != nil {
|
||||
return "", nil, fmt.Errorf("error creating local file: %v", err)
|
||||
}
|
||||
defer f.Done()
|
||||
|
||||
bodyResult, metaResult, convertErr := ConvertPDFText(f.Name())
|
||||
if convertErr != nil {
|
||||
return "", nil, convertErr
|
||||
}
|
||||
if bodyResult.err != nil {
|
||||
return "", nil, bodyResult.err
|
||||
}
|
||||
if metaResult.err != nil {
|
||||
return "", nil, metaResult.err
|
||||
}
|
||||
return bodyResult.body, metaResult.meta, nil
|
||||
|
||||
}
|
||||
161
vendor/code.sajari.com/docconv/pdf_ocr.go
generated
vendored
161
vendor/code.sajari.com/docconv/pdf_ocr.go
generated
vendored
|
|
@ -1,161 +0,0 @@
|
|||
// +build ocr
|
||||
|
||||
package docconv
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var (
|
||||
exts = []string{".jpg", ".tif", ".tiff", ".png", ".pbm"}
|
||||
)
|
||||
|
||||
func compareExt(ext string, exts []string) bool {
|
||||
for _, e := range exts {
|
||||
if ext == e {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func cleanupTemp(tmpDir string) {
|
||||
err := os.RemoveAll(tmpDir)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
}
|
||||
|
||||
func ConvertPDFImages(path string) (BodyResult, error) {
|
||||
bodyResult := BodyResult{}
|
||||
|
||||
tmp, err := ioutil.TempDir(os.TempDir(), "tmp-imgs-")
|
||||
if err != nil {
|
||||
bodyResult.err = err
|
||||
return bodyResult, err
|
||||
}
|
||||
tmpDir := fmt.Sprintf("%s/", tmp)
|
||||
|
||||
defer cleanupTemp(tmpDir)
|
||||
|
||||
_, err = exec.Command("pdfimages", "-j", path, tmpDir).Output()
|
||||
if err != nil {
|
||||
return bodyResult, err
|
||||
}
|
||||
|
||||
filePaths := []string{}
|
||||
|
||||
walkFunc := func(path string, info os.FileInfo, err error) error {
|
||||
path, err = filepath.Abs(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if compareExt(filepath.Ext(path), exts) {
|
||||
filePaths = append(filePaths, path)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
filepath.Walk(tmpDir, walkFunc)
|
||||
|
||||
fileLength := len(filePaths)
|
||||
|
||||
if fileLength < 1 {
|
||||
return bodyResult, nil
|
||||
}
|
||||
|
||||
var wg sync.WaitGroup
|
||||
|
||||
data := make(chan string, fileLength)
|
||||
|
||||
wg.Add(fileLength)
|
||||
|
||||
for _, p := range filePaths {
|
||||
go func(pathFile string) {
|
||||
defer wg.Done()
|
||||
f, err := os.Open(pathFile)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
defer f.Close()
|
||||
out, _, err := ConvertImage(f)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
data <- out
|
||||
|
||||
}(p)
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
|
||||
close(data)
|
||||
|
||||
for str := range data {
|
||||
bodyResult.body += str + " "
|
||||
}
|
||||
|
||||
return bodyResult, nil
|
||||
}
|
||||
|
||||
// PdfHasImage verify if `path` (PDF) has images
|
||||
func PDFHasImage(path string) bool {
|
||||
cmd := "pdffonts -l 5 %s | tail -n +3 | cut -d' ' -f1 | sort | uniq"
|
||||
out, err := exec.Command("bash", "-c", fmt.Sprintf(cmd, path)).Output()
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return false
|
||||
}
|
||||
if string(out) == "" {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func ConvertPDF(r io.Reader) (string, map[string]string, error) {
|
||||
f, err := NewLocalFile(r)
|
||||
if err != nil {
|
||||
return "", nil, fmt.Errorf("error creating local file: %v", err)
|
||||
}
|
||||
defer f.Done()
|
||||
|
||||
bodyResult, metaResult, textConvertErr := ConvertPDFText(f.Name())
|
||||
if textConvertErr != nil {
|
||||
return "", nil, textConvertErr
|
||||
}
|
||||
if bodyResult.err != nil {
|
||||
return "", nil, bodyResult.err
|
||||
}
|
||||
if metaResult.err != nil {
|
||||
return "", nil, metaResult.err
|
||||
}
|
||||
|
||||
if !PDFHasImage(f.Name()) {
|
||||
return bodyResult.body, metaResult.meta, nil
|
||||
}
|
||||
|
||||
imageConvertResult, imageConvertErr := ConvertPDFImages(f.Name())
|
||||
if imageConvertErr != nil {
|
||||
log.Println(imageConvertErr)
|
||||
return bodyResult.body, metaResult.meta, nil
|
||||
}
|
||||
if imageConvertResult.err != nil {
|
||||
log.Println(imageConvertResult.err)
|
||||
return bodyResult.body, metaResult.meta, nil
|
||||
}
|
||||
|
||||
fullBody := strings.Join([]string{bodyResult.body, imageConvertResult.body}, " ")
|
||||
|
||||
return fullBody, metaResult.meta, nil
|
||||
|
||||
}
|
||||
84
vendor/code.sajari.com/docconv/pdf_text.go
generated
vendored
84
vendor/code.sajari.com/docconv/pdf_text.go
generated
vendored
|
|
@ -1,84 +0,0 @@
|
|||
package docconv
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Meta data
|
||||
type MetaResult struct {
|
||||
meta map[string]string
|
||||
err error
|
||||
}
|
||||
|
||||
type BodyResult struct {
|
||||
body string
|
||||
err error
|
||||
}
|
||||
|
||||
// Convert PDF
|
||||
|
||||
func ConvertPDFText(path string) (BodyResult, MetaResult, error) {
|
||||
metaResult := MetaResult{meta: make(map[string]string)}
|
||||
bodyResult := BodyResult{}
|
||||
mr := make(chan MetaResult, 1)
|
||||
go func() {
|
||||
metaStr, err := exec.Command("pdfinfo", path).Output()
|
||||
if err != nil {
|
||||
metaResult.err = err
|
||||
mr <- metaResult
|
||||
return
|
||||
}
|
||||
|
||||
// Parse meta output
|
||||
for _, line := range strings.Split(string(metaStr), "\n") {
|
||||
if parts := strings.SplitN(line, ":", 2); len(parts) > 1 {
|
||||
metaResult.meta[strings.TrimSpace(parts[0])] = strings.TrimSpace(parts[1])
|
||||
}
|
||||
}
|
||||
|
||||
// Convert parsed meta
|
||||
if x, ok := metaResult.meta["ModDate"]; ok {
|
||||
if t, ok := pdfTimeLayouts.Parse(x); ok {
|
||||
metaResult.meta["ModifiedDate"] = fmt.Sprintf("%d", t.Unix())
|
||||
}
|
||||
}
|
||||
if x, ok := metaResult.meta["CreationDate"]; ok {
|
||||
if t, ok := pdfTimeLayouts.Parse(x); ok {
|
||||
metaResult.meta["CreatedDate"] = fmt.Sprintf("%d", t.Unix())
|
||||
}
|
||||
}
|
||||
|
||||
mr <- metaResult
|
||||
}()
|
||||
|
||||
br := make(chan BodyResult, 1)
|
||||
go func() {
|
||||
body, err := exec.Command("pdftotext", "-q", "-nopgbrk", "-enc", "UTF-8", "-eol", "unix", path, "-").Output()
|
||||
if err != nil {
|
||||
bodyResult.err = err
|
||||
}
|
||||
|
||||
bodyResult.body = string(body)
|
||||
|
||||
br <- bodyResult
|
||||
}()
|
||||
|
||||
return <-br, <-mr, nil
|
||||
}
|
||||
|
||||
var pdfTimeLayouts = timeLayouts{time.ANSIC, "Mon Jan _2 15:04:05 2006 MST"}
|
||||
|
||||
type timeLayouts []string
|
||||
|
||||
func (tl timeLayouts) Parse(x string) (time.Time, bool) {
|
||||
for _, layout := range tl {
|
||||
t, err := time.Parse(layout, x)
|
||||
if err == nil {
|
||||
return t, true
|
||||
}
|
||||
}
|
||||
return time.Time{}, false
|
||||
}
|
||||
67
vendor/code.sajari.com/docconv/pptx.go
generated
vendored
67
vendor/code.sajari.com/docconv/pptx.go
generated
vendored
|
|
@ -1,67 +0,0 @@
|
|||
package docconv
|
||||
|
||||
import (
|
||||
"archive/zip"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ConvertPptx converts an MS PowerPoint pptx file to text.
|
||||
func ConvertPptx(r io.Reader) (string, map[string]string, error) {
|
||||
var size int64
|
||||
|
||||
// Common case: if the reader is a file (or trivial wrapper), avoid
|
||||
// loading it all into memory.
|
||||
var ra io.ReaderAt
|
||||
if f, ok := r.(interface {
|
||||
io.ReaderAt
|
||||
Stat() (os.FileInfo, error)
|
||||
}); ok {
|
||||
si, err := f.Stat()
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
size = si.Size()
|
||||
ra = f
|
||||
} else {
|
||||
b, err := ioutil.ReadAll(r)
|
||||
if err != nil {
|
||||
return "", nil, nil
|
||||
}
|
||||
size = int64(len(b))
|
||||
ra = bytes.NewReader(b)
|
||||
}
|
||||
|
||||
zr, err := zip.NewReader(ra, size)
|
||||
if err != nil {
|
||||
return "", nil, fmt.Errorf("could not unzip: %v", err)
|
||||
}
|
||||
|
||||
zipFiles := mapZipFiles(zr.File)
|
||||
|
||||
contentTypeDefinition, err := getContentTypeDefinition(zipFiles["[Content_Types].xml"])
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
|
||||
meta := make(map[string]string)
|
||||
var textBody string
|
||||
for _, override := range contentTypeDefinition.Overrides {
|
||||
f := zipFiles[override.PartName]
|
||||
|
||||
switch override.ContentType {
|
||||
case "application/vnd.openxmlformats-officedocument.presentationml.slide+xml",
|
||||
"application/vnd.openxmlformats-officedocument.drawingml.diagramData+xml":
|
||||
body, err := parseDocxText(f)
|
||||
if err != nil {
|
||||
return "", nil, fmt.Errorf("could not parse pptx: %v", err)
|
||||
}
|
||||
textBody += body + "\n"
|
||||
}
|
||||
}
|
||||
return strings.TrimSuffix(textBody, "\n"), meta, nil
|
||||
}
|
||||
52
vendor/code.sajari.com/docconv/rtf.go
generated
vendored
52
vendor/code.sajari.com/docconv/rtf.go
generated
vendored
|
|
@ -1,52 +0,0 @@
|
|||
package docconv
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// ConvertRTF converts RTF files to text.
|
||||
func ConvertRTF(r io.Reader) (string, map[string]string, error) {
|
||||
f, err := NewLocalFile(r)
|
||||
if err != nil {
|
||||
return "", nil, fmt.Errorf("error creating local file: %v", err)
|
||||
}
|
||||
defer f.Done()
|
||||
|
||||
var output string
|
||||
tmpOutput, err := exec.Command("unrtf", "--nopict", "--text", f.Name()).Output()
|
||||
if err != nil {
|
||||
return "", nil, fmt.Errorf("unrtf error: %v", err)
|
||||
}
|
||||
|
||||
// Step through content looking for meta data and stripping out comments
|
||||
meta := make(map[string]string)
|
||||
for _, line := range strings.Split(string(tmpOutput), "\n") {
|
||||
if parts := strings.SplitN(line, ":", 2); len(parts) > 1 {
|
||||
meta[strings.TrimSpace(parts[0])] = strings.TrimSpace(parts[1])
|
||||
}
|
||||
if !strings.HasPrefix(line, "### ") {
|
||||
output += line + "\n"
|
||||
}
|
||||
}
|
||||
|
||||
// Identify meta data
|
||||
if tmp, ok := meta["AUTHOR"]; ok {
|
||||
meta["Author"] = tmp
|
||||
}
|
||||
if tmp, ok := meta["### creation date"]; ok {
|
||||
if t, err := time.Parse("02 January 2006 15:04", tmp); err == nil {
|
||||
meta["CreatedDate"] = fmt.Sprintf("%d", t.Unix())
|
||||
}
|
||||
}
|
||||
if tmp, ok := meta["### revision date"]; ok {
|
||||
if t, err := time.Parse("02 January 2006 15:04", tmp); err == nil {
|
||||
meta["ModifiedDate"] = fmt.Sprintf("%d", t.Unix())
|
||||
}
|
||||
}
|
||||
|
||||
return output, meta, nil
|
||||
}
|
||||
27
vendor/code.sajari.com/docconv/snappy/LICENSE
generated
vendored
27
vendor/code.sajari.com/docconv/snappy/LICENSE
generated
vendored
|
|
@ -1,27 +0,0 @@
|
|||
Copyright (c) 2011 The Snappy-Go Authors. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Google Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
13
vendor/code.sajari.com/docconv/snappy/README
generated
vendored
13
vendor/code.sajari.com/docconv/snappy/README
generated
vendored
|
|
@ -1,13 +0,0 @@
|
|||
This is a Snappy library for the Go programming language that has been modified to work with Apple files, which fail to set CRC checks and stream identifiers. This version is a total hack, so if you want to use snappy for other projects **DO NOT USE THIS VERSION**. Use the proper version as per below:
|
||||
|
||||
To download and install from source:
|
||||
$ go get code.google.com/p/snappy-go/snappy
|
||||
|
||||
|
||||
|
||||
Unless otherwise noted, the Snappy-Go source files are distributed
|
||||
under the BSD-style license found in the LICENSE file.
|
||||
|
||||
Contributions should follow the same procedure as for the Go project:
|
||||
http://golang.org/doc/contribute.html
|
||||
|
||||
297
vendor/code.sajari.com/docconv/snappy/decode.go
generated
vendored
297
vendor/code.sajari.com/docconv/snappy/decode.go
generated
vendored
|
|
@ -1,297 +0,0 @@
|
|||
// Copyright 2011 The Snappy-Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package snappy
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"io"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrCorrupt reports that the input is invalid.
|
||||
ErrCorrupt = errors.New("snappy: corrupt input")
|
||||
// ErrUnsupported reports that the input isn't supported.
|
||||
ErrUnsupported = errors.New("snappy: unsupported input")
|
||||
)
|
||||
|
||||
// DecodedLen returns the length of the decoded block.
|
||||
func DecodedLen(src []byte) (int, error) {
|
||||
v, _, err := decodedLen(src)
|
||||
return v, err
|
||||
}
|
||||
|
||||
// decodedLen returns the length of the decoded block and the number of bytes
|
||||
// that the length header occupied.
|
||||
func decodedLen(src []byte) (blockLen, headerLen int, err error) {
|
||||
v, n := binary.Uvarint(src)
|
||||
if n == 0 {
|
||||
return 0, 0, ErrCorrupt
|
||||
}
|
||||
if uint64(int(v)) != v {
|
||||
return 0, 0, errors.New("snappy: decoded block is too large")
|
||||
}
|
||||
return int(v), n, nil
|
||||
}
|
||||
|
||||
// Decode returns the decoded form of src. The returned slice may be a sub-
|
||||
// slice of dst if dst was large enough to hold the entire decoded block.
|
||||
// Otherwise, a newly allocated slice will be returned.
|
||||
// It is valid to pass a nil dst.
|
||||
func Decode(dst, src []byte) ([]byte, error) {
|
||||
dLen, s, err := decodedLen(src)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(dst) < dLen {
|
||||
dst = make([]byte, dLen)
|
||||
}
|
||||
|
||||
var d, offset, length int
|
||||
for s < len(src) {
|
||||
switch src[s] & 0x03 {
|
||||
case tagLiteral:
|
||||
x := uint(src[s] >> 2)
|
||||
switch {
|
||||
case x < 60:
|
||||
s += 1
|
||||
case x == 60:
|
||||
s += 2
|
||||
if s > len(src) {
|
||||
return nil, ErrCorrupt
|
||||
}
|
||||
x = uint(src[s-1])
|
||||
case x == 61:
|
||||
s += 3
|
||||
if s > len(src) {
|
||||
return nil, ErrCorrupt
|
||||
}
|
||||
x = uint(src[s-2]) | uint(src[s-1])<<8
|
||||
case x == 62:
|
||||
s += 4
|
||||
if s > len(src) {
|
||||
return nil, ErrCorrupt
|
||||
}
|
||||
x = uint(src[s-3]) | uint(src[s-2])<<8 | uint(src[s-1])<<16
|
||||
case x == 63:
|
||||
s += 5
|
||||
if s > len(src) {
|
||||
return nil, ErrCorrupt
|
||||
}
|
||||
x = uint(src[s-4]) | uint(src[s-3])<<8 | uint(src[s-2])<<16 | uint(src[s-1])<<24
|
||||
}
|
||||
length = int(x + 1)
|
||||
if length <= 0 {
|
||||
return nil, errors.New("snappy: unsupported literal length")
|
||||
}
|
||||
if length > len(dst)-d || length > len(src)-s {
|
||||
return nil, ErrCorrupt
|
||||
}
|
||||
copy(dst[d:], src[s:s+length])
|
||||
d += length
|
||||
s += length
|
||||
continue
|
||||
|
||||
case tagCopy1:
|
||||
s += 2
|
||||
if s > len(src) {
|
||||
return nil, ErrCorrupt
|
||||
}
|
||||
length = 4 + int(src[s-2])>>2&0x7
|
||||
offset = int(src[s-2])&0xe0<<3 | int(src[s-1])
|
||||
|
||||
case tagCopy2:
|
||||
s += 3
|
||||
if s > len(src) {
|
||||
return nil, ErrCorrupt
|
||||
}
|
||||
length = 1 + int(src[s-3])>>2
|
||||
offset = int(src[s-2]) | int(src[s-1])<<8
|
||||
|
||||
case tagCopy4:
|
||||
return nil, errors.New("snappy: unsupported COPY_4 tag")
|
||||
}
|
||||
|
||||
end := d + length
|
||||
if offset > d || end > len(dst) {
|
||||
return nil, ErrCorrupt
|
||||
}
|
||||
for ; d < end; d++ {
|
||||
dst[d] = dst[d-offset]
|
||||
}
|
||||
}
|
||||
if d != dLen {
|
||||
return nil, ErrCorrupt
|
||||
}
|
||||
return dst[:d], nil
|
||||
}
|
||||
|
||||
// NewReader returns a new Reader that decompresses from r, using the framing
|
||||
// format described at
|
||||
// https://code.google.com/p/snappy/source/browse/trunk/framing_format.txt
|
||||
func NewReader(r io.Reader) *Reader {
|
||||
return &Reader{
|
||||
r: r,
|
||||
decoded: make([]byte, maxUncompressedChunkLen),
|
||||
buf: make([]byte, MaxEncodedLen(maxUncompressedChunkLen)+checksumSize),
|
||||
}
|
||||
}
|
||||
|
||||
// Reader is an io.Reader than can read Snappy-compressed bytes.
|
||||
type Reader struct {
|
||||
r io.Reader
|
||||
err error
|
||||
decoded []byte
|
||||
buf []byte
|
||||
// decoded[i:j] contains decoded bytes that have not yet been passed on.
|
||||
i, j int
|
||||
readHeader bool
|
||||
}
|
||||
|
||||
// Reset discards any buffered data, resets all state, and switches the Snappy
|
||||
// reader to read from r. This permits reusing a Reader rather than allocating
|
||||
// a new one.
|
||||
func (r *Reader) Reset(reader io.Reader) {
|
||||
r.r = reader
|
||||
r.err = nil
|
||||
r.i = 0
|
||||
r.j = 0
|
||||
r.readHeader = false
|
||||
}
|
||||
|
||||
func (r *Reader) readFull(p []byte) (ok bool) {
|
||||
if _, r.err = io.ReadFull(r.r, p); r.err != nil {
|
||||
if r.err == io.ErrUnexpectedEOF {
|
||||
r.err = ErrCorrupt
|
||||
}
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Read satisfies the io.Reader interface.
|
||||
func (r *Reader) Read(p []byte) (int, error) {
|
||||
if r.err != nil {
|
||||
return 0, r.err
|
||||
}
|
||||
for {
|
||||
if r.i < r.j {
|
||||
n := copy(p, r.decoded[r.i:r.j])
|
||||
r.i += n
|
||||
return n, nil
|
||||
}
|
||||
if !r.readFull(r.buf[:4]) {
|
||||
return 0, r.err
|
||||
}
|
||||
chunkType := r.buf[0]
|
||||
if !r.readHeader {
|
||||
if chunkType != chunkTypeStreamIdentifier {
|
||||
r.err = ErrCorrupt
|
||||
return 0, r.err
|
||||
}
|
||||
r.readHeader = true
|
||||
}
|
||||
chunkLen := int(r.buf[1]) | int(r.buf[2])<<8 | int(r.buf[3])<<16
|
||||
if chunkLen > len(r.buf) {
|
||||
r.err = ErrUnsupported
|
||||
return 0, r.err
|
||||
}
|
||||
|
||||
// The chunk types are specified at
|
||||
// https://code.google.com/p/snappy/source/browse/trunk/framing_format.txt
|
||||
switch chunkType {
|
||||
case chunkTypeCompressedData:
|
||||
// Section 4.2. Compressed data (chunk type 0x00).
|
||||
/*
|
||||
if chunkLen < checksumSize {
|
||||
r.err = ErrCorrupt
|
||||
return 0, r.err
|
||||
}
|
||||
*/
|
||||
buf := r.buf[:chunkLen]
|
||||
if !r.readFull(buf) {
|
||||
return 0, r.err
|
||||
}
|
||||
/*
|
||||
checksum := uint32(buf[0]) | uint32(buf[1])<<8 | uint32(buf[2])<<16 | uint32(buf[3])<<24
|
||||
buf = buf[checksumSize:]
|
||||
*/
|
||||
n, err := DecodedLen(buf)
|
||||
if err != nil {
|
||||
r.err = err
|
||||
return 0, r.err
|
||||
}
|
||||
if n > len(r.decoded) {
|
||||
r.err = ErrCorrupt
|
||||
return 0, r.err
|
||||
}
|
||||
if _, err := Decode(r.decoded, buf); err != nil {
|
||||
r.err = err
|
||||
return 0, r.err
|
||||
}
|
||||
/*
|
||||
if crc(r.decoded[:n]) != checksum {
|
||||
r.err = ErrCorrupt
|
||||
return 0, r.err
|
||||
}
|
||||
*/
|
||||
r.i, r.j = 0, n
|
||||
continue
|
||||
|
||||
case chunkTypeUncompressedData:
|
||||
// Section 4.3. Uncompressed data (chunk type 0x01).
|
||||
if chunkLen < checksumSize {
|
||||
r.err = ErrCorrupt
|
||||
return 0, r.err
|
||||
}
|
||||
buf := r.buf[:checksumSize]
|
||||
if !r.readFull(buf) {
|
||||
return 0, r.err
|
||||
}
|
||||
checksum := uint32(buf[0]) | uint32(buf[1])<<8 | uint32(buf[2])<<16 | uint32(buf[3])<<24
|
||||
// Read directly into r.decoded instead of via r.buf.
|
||||
n := chunkLen - checksumSize
|
||||
if !r.readFull(r.decoded[:n]) {
|
||||
return 0, r.err
|
||||
}
|
||||
if crc(r.decoded[:n]) != checksum {
|
||||
r.err = ErrCorrupt
|
||||
return 0, r.err
|
||||
}
|
||||
r.i, r.j = 0, n
|
||||
continue
|
||||
|
||||
case chunkTypeStreamIdentifier:
|
||||
// Section 4.1. Stream identifier (chunk type 0xff).
|
||||
if chunkLen != len(magicBody) {
|
||||
r.err = ErrCorrupt
|
||||
return 0, r.err
|
||||
}
|
||||
if !r.readFull(r.buf[:len(magicBody)]) {
|
||||
return 0, r.err
|
||||
}
|
||||
for i := 0; i < len(magicBody); i++ {
|
||||
if r.buf[i] != magicBody[i] {
|
||||
r.err = ErrCorrupt
|
||||
return 0, r.err
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if chunkType <= 0x7f {
|
||||
// Section 4.5. Reserved unskippable chunks (chunk types 0x02-0x7f).
|
||||
r.err = ErrUnsupported
|
||||
return 0, r.err
|
||||
|
||||
} else {
|
||||
// Section 4.4 Padding (chunk type 0xfe).
|
||||
// Section 4.6. Reserved skippable chunks (chunk types 0x80-0xfd).
|
||||
if !r.readFull(r.buf[:chunkLen]) {
|
||||
return 0, r.err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
258
vendor/code.sajari.com/docconv/snappy/encode.go
generated
vendored
258
vendor/code.sajari.com/docconv/snappy/encode.go
generated
vendored
|
|
@ -1,258 +0,0 @@
|
|||
// Copyright 2011 The Snappy-Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package snappy
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"io"
|
||||
)
|
||||
|
||||
// We limit how far copy back-references can go, the same as the C++ code.
|
||||
const maxOffset = 1 << 15
|
||||
|
||||
// emitLiteral writes a literal chunk and returns the number of bytes written.
|
||||
func emitLiteral(dst, lit []byte) int {
|
||||
i, n := 0, uint(len(lit)-1)
|
||||
switch {
|
||||
case n < 60:
|
||||
dst[0] = uint8(n)<<2 | tagLiteral
|
||||
i = 1
|
||||
case n < 1<<8:
|
||||
dst[0] = 60<<2 | tagLiteral
|
||||
dst[1] = uint8(n)
|
||||
i = 2
|
||||
case n < 1<<16:
|
||||
dst[0] = 61<<2 | tagLiteral
|
||||
dst[1] = uint8(n)
|
||||
dst[2] = uint8(n >> 8)
|
||||
i = 3
|
||||
case n < 1<<24:
|
||||
dst[0] = 62<<2 | tagLiteral
|
||||
dst[1] = uint8(n)
|
||||
dst[2] = uint8(n >> 8)
|
||||
dst[3] = uint8(n >> 16)
|
||||
i = 4
|
||||
case int64(n) < 1<<32:
|
||||
dst[0] = 63<<2 | tagLiteral
|
||||
dst[1] = uint8(n)
|
||||
dst[2] = uint8(n >> 8)
|
||||
dst[3] = uint8(n >> 16)
|
||||
dst[4] = uint8(n >> 24)
|
||||
i = 5
|
||||
default:
|
||||
panic("snappy: source buffer is too long")
|
||||
}
|
||||
if copy(dst[i:], lit) != len(lit) {
|
||||
panic("snappy: destination buffer is too short")
|
||||
}
|
||||
return i + len(lit)
|
||||
}
|
||||
|
||||
// emitCopy writes a copy chunk and returns the number of bytes written.
|
||||
func emitCopy(dst []byte, offset, length int) int {
|
||||
i := 0
|
||||
for length > 0 {
|
||||
x := length - 4
|
||||
if 0 <= x && x < 1<<3 && offset < 1<<11 {
|
||||
dst[i+0] = uint8(offset>>8)&0x07<<5 | uint8(x)<<2 | tagCopy1
|
||||
dst[i+1] = uint8(offset)
|
||||
i += 2
|
||||
break
|
||||
}
|
||||
|
||||
x = length
|
||||
if x > 1<<6 {
|
||||
x = 1 << 6
|
||||
}
|
||||
dst[i+0] = uint8(x-1)<<2 | tagCopy2
|
||||
dst[i+1] = uint8(offset)
|
||||
dst[i+2] = uint8(offset >> 8)
|
||||
i += 3
|
||||
length -= x
|
||||
}
|
||||
return i
|
||||
}
|
||||
|
||||
// Encode returns the encoded form of src. The returned slice may be a sub-
|
||||
// slice of dst if dst was large enough to hold the entire encoded block.
|
||||
// Otherwise, a newly allocated slice will be returned.
|
||||
// It is valid to pass a nil dst.
|
||||
func Encode(dst, src []byte) ([]byte, error) {
|
||||
if n := MaxEncodedLen(len(src)); len(dst) < n {
|
||||
dst = make([]byte, n)
|
||||
}
|
||||
|
||||
// The block starts with the varint-encoded length of the decompressed bytes.
|
||||
d := binary.PutUvarint(dst, uint64(len(src)))
|
||||
|
||||
// Return early if src is short.
|
||||
if len(src) <= 4 {
|
||||
if len(src) != 0 {
|
||||
d += emitLiteral(dst[d:], src)
|
||||
}
|
||||
return dst[:d], nil
|
||||
}
|
||||
|
||||
// Initialize the hash table. Its size ranges from 1<<8 to 1<<14 inclusive.
|
||||
const maxTableSize = 1 << 14
|
||||
shift, tableSize := uint(32-8), 1<<8
|
||||
for tableSize < maxTableSize && tableSize < len(src) {
|
||||
shift--
|
||||
tableSize *= 2
|
||||
}
|
||||
var table [maxTableSize]int
|
||||
|
||||
// Iterate over the source bytes.
|
||||
var (
|
||||
s int // The iterator position.
|
||||
t int // The last position with the same hash as s.
|
||||
lit int // The start position of any pending literal bytes.
|
||||
)
|
||||
for s+3 < len(src) {
|
||||
// Update the hash table.
|
||||
b0, b1, b2, b3 := src[s], src[s+1], src[s+2], src[s+3]
|
||||
h := uint32(b0) | uint32(b1)<<8 | uint32(b2)<<16 | uint32(b3)<<24
|
||||
p := &table[(h*0x1e35a7bd)>>shift]
|
||||
// We need to to store values in [-1, inf) in table. To save
|
||||
// some initialization time, (re)use the table's zero value
|
||||
// and shift the values against this zero: add 1 on writes,
|
||||
// subtract 1 on reads.
|
||||
t, *p = *p-1, s+1
|
||||
// If t is invalid or src[s:s+4] differs from src[t:t+4], accumulate a literal byte.
|
||||
if t < 0 || s-t >= maxOffset || b0 != src[t] || b1 != src[t+1] || b2 != src[t+2] || b3 != src[t+3] {
|
||||
s++
|
||||
continue
|
||||
}
|
||||
// Otherwise, we have a match. First, emit any pending literal bytes.
|
||||
if lit != s {
|
||||
d += emitLiteral(dst[d:], src[lit:s])
|
||||
}
|
||||
// Extend the match to be as long as possible.
|
||||
s0 := s
|
||||
s, t = s+4, t+4
|
||||
for s < len(src) && src[s] == src[t] {
|
||||
s++
|
||||
t++
|
||||
}
|
||||
// Emit the copied bytes.
|
||||
d += emitCopy(dst[d:], s-t, s-s0)
|
||||
lit = s
|
||||
}
|
||||
|
||||
// Emit any final pending literal bytes and return.
|
||||
if lit != len(src) {
|
||||
d += emitLiteral(dst[d:], src[lit:])
|
||||
}
|
||||
return dst[:d], nil
|
||||
}
|
||||
|
||||
// MaxEncodedLen returns the maximum length of a snappy block, given its
|
||||
// uncompressed length.
|
||||
func MaxEncodedLen(srcLen int) int {
|
||||
// Compressed data can be defined as:
|
||||
// compressed := item* literal*
|
||||
// item := literal* copy
|
||||
//
|
||||
// The trailing literal sequence has a space blowup of at most 62/60
|
||||
// since a literal of length 60 needs one tag byte + one extra byte
|
||||
// for length information.
|
||||
//
|
||||
// Item blowup is trickier to measure. Suppose the "copy" op copies
|
||||
// 4 bytes of data. Because of a special check in the encoding code,
|
||||
// we produce a 4-byte copy only if the offset is < 65536. Therefore
|
||||
// the copy op takes 3 bytes to encode, and this type of item leads
|
||||
// to at most the 62/60 blowup for representing literals.
|
||||
//
|
||||
// Suppose the "copy" op copies 5 bytes of data. If the offset is big
|
||||
// enough, it will take 5 bytes to encode the copy op. Therefore the
|
||||
// worst case here is a one-byte literal followed by a five-byte copy.
|
||||
// That is, 6 bytes of input turn into 7 bytes of "compressed" data.
|
||||
//
|
||||
// This last factor dominates the blowup, so the final estimate is:
|
||||
return 32 + srcLen + srcLen/6
|
||||
}
|
||||
|
||||
// NewWriter returns a new Writer that compresses to w, using the framing
|
||||
// format described at
|
||||
// https://code.google.com/p/snappy/source/browse/trunk/framing_format.txt
|
||||
func NewWriter(w io.Writer) *Writer {
|
||||
return &Writer{
|
||||
w: w,
|
||||
enc: make([]byte, MaxEncodedLen(maxUncompressedChunkLen)),
|
||||
}
|
||||
}
|
||||
|
||||
// Writer is an io.Writer than can write Snappy-compressed bytes.
|
||||
type Writer struct {
|
||||
w io.Writer
|
||||
err error
|
||||
enc []byte
|
||||
buf [checksumSize + chunkHeaderSize]byte
|
||||
wroteHeader bool
|
||||
}
|
||||
|
||||
// Reset discards the writer's state and switches the Snappy writer to write to
|
||||
// w. This permits reusing a Writer rather than allocating a new one.
|
||||
func (w *Writer) Reset(writer io.Writer) {
|
||||
w.w = writer
|
||||
w.err = nil
|
||||
w.wroteHeader = false
|
||||
}
|
||||
|
||||
// Write satisfies the io.Writer interface.
|
||||
func (w *Writer) Write(p []byte) (n int, errRet error) {
|
||||
if w.err != nil {
|
||||
return 0, w.err
|
||||
}
|
||||
if !w.wroteHeader {
|
||||
copy(w.enc, magicChunk)
|
||||
if _, err := w.w.Write(w.enc[:len(magicChunk)]); err != nil {
|
||||
w.err = err
|
||||
return n, err
|
||||
}
|
||||
w.wroteHeader = true
|
||||
}
|
||||
for len(p) > 0 {
|
||||
var uncompressed []byte
|
||||
if len(p) > maxUncompressedChunkLen {
|
||||
uncompressed, p = p[:maxUncompressedChunkLen], p[maxUncompressedChunkLen:]
|
||||
} else {
|
||||
uncompressed, p = p, nil
|
||||
}
|
||||
checksum := crc(uncompressed)
|
||||
|
||||
// Compress the buffer, discarding the result if the improvement
|
||||
// isn't at least 12.5%.
|
||||
chunkType := uint8(chunkTypeCompressedData)
|
||||
chunkBody, err := Encode(w.enc, uncompressed)
|
||||
if err != nil {
|
||||
w.err = err
|
||||
return n, err
|
||||
}
|
||||
if len(chunkBody) >= len(uncompressed)-len(uncompressed)/8 {
|
||||
chunkType, chunkBody = chunkTypeUncompressedData, uncompressed
|
||||
}
|
||||
|
||||
chunkLen := 4 + len(chunkBody)
|
||||
w.buf[0] = chunkType
|
||||
w.buf[1] = uint8(chunkLen >> 0)
|
||||
w.buf[2] = uint8(chunkLen >> 8)
|
||||
w.buf[3] = uint8(chunkLen >> 16)
|
||||
w.buf[4] = uint8(checksum >> 0)
|
||||
w.buf[5] = uint8(checksum >> 8)
|
||||
w.buf[6] = uint8(checksum >> 16)
|
||||
w.buf[7] = uint8(checksum >> 24)
|
||||
if _, err = w.w.Write(w.buf[:]); err != nil {
|
||||
w.err = err
|
||||
return n, err
|
||||
}
|
||||
if _, err = w.w.Write(chunkBody); err != nil {
|
||||
w.err = err
|
||||
return n, err
|
||||
}
|
||||
n += len(uncompressed)
|
||||
}
|
||||
return n, nil
|
||||
}
|
||||
68
vendor/code.sajari.com/docconv/snappy/snappy.go
generated
vendored
68
vendor/code.sajari.com/docconv/snappy/snappy.go
generated
vendored
|
|
@ -1,68 +0,0 @@
|
|||
// Copyright 2011 The Snappy-Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package snappy implements the snappy block-based compression format.
|
||||
// It aims for very high speeds and reasonable compression.
|
||||
//
|
||||
// The C++ snappy implementation is at http://code.google.com/p/snappy/
|
||||
package snappy
|
||||
|
||||
import (
|
||||
"hash/crc32"
|
||||
)
|
||||
|
||||
/*
|
||||
Each encoded block begins with the varint-encoded length of the decoded data,
|
||||
followed by a sequence of chunks. Chunks begin and end on byte boundaries. The
|
||||
first byte of each chunk is broken into its 2 least and 6 most significant bits
|
||||
called l and m: l ranges in [0, 4) and m ranges in [0, 64). l is the chunk tag.
|
||||
Zero means a literal tag. All other values mean a copy tag.
|
||||
|
||||
For literal tags:
|
||||
- If m < 60, the next 1 + m bytes are literal bytes.
|
||||
- Otherwise, let n be the little-endian unsigned integer denoted by the next
|
||||
m - 59 bytes. The next 1 + n bytes after that are literal bytes.
|
||||
|
||||
For copy tags, length bytes are copied from offset bytes ago, in the style of
|
||||
Lempel-Ziv compression algorithms. In particular:
|
||||
- For l == 1, the offset ranges in [0, 1<<11) and the length in [4, 12).
|
||||
The length is 4 + the low 3 bits of m. The high 3 bits of m form bits 8-10
|
||||
of the offset. The next byte is bits 0-7 of the offset.
|
||||
- For l == 2, the offset ranges in [0, 1<<16) and the length in [1, 65).
|
||||
The length is 1 + m. The offset is the little-endian unsigned integer
|
||||
denoted by the next 2 bytes.
|
||||
- For l == 3, this tag is a legacy format that is no longer supported.
|
||||
*/
|
||||
const (
|
||||
tagLiteral = 0x00
|
||||
tagCopy1 = 0x01
|
||||
tagCopy2 = 0x02
|
||||
tagCopy4 = 0x03
|
||||
)
|
||||
|
||||
const (
|
||||
checksumSize = 4
|
||||
chunkHeaderSize = 4
|
||||
magicChunk = "\xff\x06\x00\x00" + magicBody
|
||||
magicBody = "sNaPpY"
|
||||
// https://code.google.com/p/snappy/source/browse/trunk/framing_format.txt says
|
||||
// that "the uncompressed data in a chunk must be no longer than 65536 bytes".
|
||||
maxUncompressedChunkLen = 65536
|
||||
)
|
||||
|
||||
const (
|
||||
chunkTypeCompressedData = 0x00
|
||||
chunkTypeUncompressedData = 0x01
|
||||
chunkTypePadding = 0xfe
|
||||
chunkTypeStreamIdentifier = 0xff
|
||||
)
|
||||
|
||||
var crcTable = crc32.MakeTable(crc32.Castagnoli)
|
||||
|
||||
// crc implements the checksum specified in section 3 of
|
||||
// https://code.google.com/p/snappy/source/browse/trunk/framing_format.txt
|
||||
func crc(b []byte) uint32 {
|
||||
c := crc32.Update(0, crcTable, b)
|
||||
return uint32(c>>15|c<<17) + 0xa282ead8
|
||||
}
|
||||
32
vendor/code.sajari.com/docconv/tidy.go
generated
vendored
32
vendor/code.sajari.com/docconv/tidy.go
generated
vendored
|
|
@ -1,32 +0,0 @@
|
|||
package docconv
|
||||
|
||||
import (
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
)
|
||||
|
||||
// Tidy attempts to tidy up XML.
|
||||
// Errors & warnings are deliberately suppressed as underlying tools
|
||||
// throw warnings very easily.
|
||||
func Tidy(r io.Reader, xmlIn bool) ([]byte, error) {
|
||||
f, err := ioutil.TempFile(os.TempDir(), "docconv")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer os.Remove(f.Name())
|
||||
io.Copy(f, r)
|
||||
|
||||
var output []byte
|
||||
if xmlIn {
|
||||
output, err = exec.Command("tidy", "-xml", "-numeric", "-asxml", "-quiet", "-utf8", f.Name()).Output()
|
||||
} else {
|
||||
output, err = exec.Command("tidy", "-numeric", "-asxml", "-quiet", "-utf8", f.Name()).Output()
|
||||
}
|
||||
|
||||
if err != nil && err.Error() != "exit status 1" {
|
||||
return nil, err
|
||||
}
|
||||
return output, nil
|
||||
}
|
||||
31
vendor/code.sajari.com/docconv/url.go
generated
vendored
31
vendor/code.sajari.com/docconv/url.go
generated
vendored
|
|
@ -1,31 +0,0 @@
|
|||
package docconv
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
|
||||
"github.com/advancedlogic/GoOse"
|
||||
)
|
||||
|
||||
// ConvertURL fetches the HTML page at the URL given in the io.Reader.
|
||||
func ConvertURL(input io.Reader, readability bool) (string, map[string]string, error) {
|
||||
meta := make(map[string]string)
|
||||
|
||||
buf := new(bytes.Buffer)
|
||||
_, err := buf.ReadFrom(input)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
|
||||
g := goose.New()
|
||||
article, err := g.ExtractFromURL(buf.String())
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
|
||||
meta["title"] = article.Title
|
||||
meta["description"] = article.MetaDescription
|
||||
meta["image"] = article.TopImage
|
||||
|
||||
return article.CleanedText, meta, nil
|
||||
}
|
||||
98
vendor/code.sajari.com/docconv/xml.go
generated
vendored
98
vendor/code.sajari.com/docconv/xml.go
generated
vendored
|
|
@ -1,98 +0,0 @@
|
|||
package docconv
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
// ConvertXML converts an XML file to text.
|
||||
func ConvertXML(r io.Reader) (string, map[string]string, error) {
|
||||
meta := make(map[string]string)
|
||||
cleanXML, err := Tidy(r, true)
|
||||
if err != nil {
|
||||
return "", nil, fmt.Errorf("tidy error: %v", err)
|
||||
}
|
||||
result, err := XMLToText(bytes.NewReader(cleanXML), []string{}, []string{}, true)
|
||||
if err != nil {
|
||||
return "", nil, fmt.Errorf("error from XMLToText: %v", err)
|
||||
}
|
||||
return result, meta, nil
|
||||
}
|
||||
|
||||
// XMLToText converts XML to plain text given how to treat elements.
|
||||
func XMLToText(r io.Reader, breaks []string, skip []string, strict bool) (string, error) {
|
||||
var result string
|
||||
|
||||
dec := xml.NewDecoder(r)
|
||||
dec.Strict = strict
|
||||
for {
|
||||
t, err := dec.Token()
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
return "", err
|
||||
}
|
||||
|
||||
switch v := t.(type) {
|
||||
case xml.CharData:
|
||||
result += string(v)
|
||||
case xml.StartElement:
|
||||
for _, breakElement := range breaks {
|
||||
if v.Name.Local == breakElement {
|
||||
result += "\n"
|
||||
}
|
||||
}
|
||||
for _, skipElement := range skip {
|
||||
if v.Name.Local == skipElement {
|
||||
depth := 1
|
||||
for {
|
||||
t, err := dec.Token()
|
||||
if err != nil {
|
||||
// An io.EOF here is actually an error.
|
||||
return "", err
|
||||
}
|
||||
|
||||
switch t.(type) {
|
||||
case xml.StartElement:
|
||||
depth++
|
||||
case xml.EndElement:
|
||||
depth--
|
||||
}
|
||||
|
||||
if depth == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// XMLToMap converts XML to a nested string map.
|
||||
func XMLToMap(r io.Reader) (map[string]string, error) {
|
||||
m := make(map[string]string)
|
||||
dec := xml.NewDecoder(r)
|
||||
var tagName string
|
||||
for {
|
||||
t, err := dec.Token()
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
switch v := t.(type) {
|
||||
case xml.StartElement:
|
||||
tagName = string(v.Name.Local)
|
||||
case xml.CharData:
|
||||
m[tagName] = string(v)
|
||||
}
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
32
vendor/github.com/JalfResi/justext/.gitignore
generated
vendored
32
vendor/github.com/JalfResi/justext/.gitignore
generated
vendored
|
|
@ -1,32 +0,0 @@
|
|||
|
||||
src/_go_.6
|
||||
|
||||
src/_obj/ourscienceistight/gojustext.a
|
||||
|
||||
src/example/_go_.6
|
||||
|
||||
src/example/gojustext
|
||||
|
||||
src/main.go_old
|
||||
|
||||
src/.DS_Store
|
||||
|
||||
src/stoplists/.DS_Store
|
||||
|
||||
src/example/*.html
|
||||
|
||||
src/example/*.htm
|
||||
|
||||
src/stoplists/*.txt
|
||||
|
||||
src/example/hp-envy-14-spectre-review
|
||||
|
||||
src/example/t.txt
|
||||
|
||||
src/example/t2.txt
|
||||
|
||||
gojustext
|
||||
|
||||
gojustext.sublime-project
|
||||
|
||||
gojustext.sublime-workspace
|
||||
48
vendor/github.com/JalfResi/justext/README.md
generated
vendored
48
vendor/github.com/JalfResi/justext/README.md
generated
vendored
|
|
@ -1,48 +0,0 @@
|
|||
justext
|
||||
=======
|
||||
|
||||
A Go package that implements the JusText boilerplate removal algorithm (http://code.google.com/p/justext/)
|
||||
|
||||
## Install
|
||||
|
||||
go get github.com/JalfResi/justext
|
||||
|
||||
And import:
|
||||
|
||||
import "github.com/JalfResi/justext"
|
||||
|
||||
## Usage
|
||||
|
||||
Supports all stoplist files available at http://code.google.com/p/justext/source/browse/#svn%2Ftrunk%2Fjustext%2Fstoplists
|
||||
|
||||
Justext expects valid HTML; it is your responsability to ensure that valid HTML is passed to Justext. To make things easier
|
||||
I have written a CGO wrapper around libtidy which you can find here: [github.com/JalfResi/GoTidy](https://github.com/JalfResi/GoTidy)
|
||||
In the future, once exp/html is part of the standard packages I will refactor JusText to accept only valid HTML documents/strings.
|
||||
|
||||
Justext use the reader-writer idiom, alowing you to setup the reader with a common configuration and just pump out
|
||||
articles to the writer.
|
||||
|
||||
Example usage:
|
||||
|
||||
// Create a justext reader from another reader
|
||||
reader := justext.NewReader(os.Stdin)
|
||||
|
||||
// Configure the reader
|
||||
reader.LengthLow = 70
|
||||
reader.LengthHigh = 200
|
||||
reader.Stoplist = stoplist // The stoplist map[string]bool
|
||||
reader.StopwordsLow = 0.3
|
||||
reader.StopwordsHigh = 0.32
|
||||
reader.MaxLinkDensity = 0.2
|
||||
reader.MaxHeadingDistance = 200
|
||||
reader.NoHeadings = false
|
||||
|
||||
// Read from the reader to generate a paragraph set
|
||||
paragraphSet, _ := reader.ReadAll()
|
||||
|
||||
// Create a writer from another writer
|
||||
writer := justext.NewWriter(os.Stdout)
|
||||
// Write the paragraph set to the writer
|
||||
writer.WriteAll(paragraphSet)
|
||||
|
||||
|
||||
3
vendor/github.com/JalfResi/justext/TODO.txt
generated
vendored
3
vendor/github.com/JalfResi/justext/TODO.txt
generated
vendored
|
|
@ -1,3 +0,0 @@
|
|||
TODO
|
||||
====
|
||||
- Stoplists need to be separtae subpackages (use the init() package method of registration)
|
||||
66
vendor/github.com/JalfResi/justext/classifyParagraphs.go
generated
vendored
66
vendor/github.com/JalfResi/justext/classifyParagraphs.go
generated
vendored
|
|
@ -1,66 +0,0 @@
|
|||
package justext
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var findHeadings *regexp.Regexp = regexp.MustCompile("(^h[123456]|.h[123456])")
|
||||
var copyrightChar *regexp.Regexp = regexp.MustCompile("(\u0161|©)")
|
||||
var findSelect *regexp.Regexp = regexp.MustCompile("(^select|.select)")
|
||||
|
||||
func classifyParagraphs(paragraphs []*Paragraph, stoplist map[string]bool, lengthLow int, lengthHigh int, stopwordsLow float64, stopwordsHigh float64, maxLinkDensity float64, noHeadings bool) {
|
||||
for _, paragraph := range paragraphs {
|
||||
var length int = len(paragraph.Text)
|
||||
var stopwordCount int = 0
|
||||
for _, word := range strings.Split(paragraph.Text, " ") {
|
||||
if _, ok := stoplist[word]; ok {
|
||||
stopwordCount += 1
|
||||
}
|
||||
}
|
||||
|
||||
var stopwordDensity float64 = 0.0
|
||||
var linkDensity float64 = 0.0
|
||||
var wordCount int = paragraph.WordCount
|
||||
|
||||
if wordCount > 0 {
|
||||
stopwordDensity = 1.0 * float64(stopwordCount) / float64(wordCount)
|
||||
linkDensity = float64(paragraph.LinkedCharCount) / float64(length)
|
||||
}
|
||||
|
||||
paragraph.StopwordCount = stopwordCount
|
||||
paragraph.StopwordDensity = stopwordDensity
|
||||
paragraph.LinkDensity = linkDensity
|
||||
paragraph.Heading = bool(!noHeadings && findHeadings.MatchString(paragraph.DomPath))
|
||||
|
||||
if linkDensity > maxLinkDensity {
|
||||
paragraph.CfClass = "bad"
|
||||
} else if copyrightChar.MatchString(paragraph.Text) {
|
||||
paragraph.CfClass = "bad"
|
||||
} else if findSelect.MatchString(paragraph.DomPath) {
|
||||
paragraph.CfClass = "bad"
|
||||
} else {
|
||||
if length < lengthLow {
|
||||
if paragraph.LinkedCharCount > 0 {
|
||||
paragraph.CfClass = "bad"
|
||||
} else {
|
||||
paragraph.CfClass = "short"
|
||||
}
|
||||
} else {
|
||||
if stopwordDensity >= stopwordsHigh {
|
||||
if length > lengthHigh {
|
||||
paragraph.CfClass = "good"
|
||||
} else {
|
||||
paragraph.CfClass = "neargood"
|
||||
}
|
||||
} else {
|
||||
if stopwordDensity >= stopwordsLow {
|
||||
paragraph.CfClass = "neargood"
|
||||
} else {
|
||||
paragraph.CfClass = "bad"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
50
vendor/github.com/JalfResi/justext/defaultTemplate.go
generated
vendored
50
vendor/github.com/JalfResi/justext/defaultTemplate.go
generated
vendored
|
|
@ -1,50 +0,0 @@
|
|||
package justext
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
"io"
|
||||
"reflect"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
var _DefaultTemplate = "" +
|
||||
"\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x74\x90\x3d\x6e\xc4\x20" +
|
||||
"\x10\x46\x6b\xfb\x14\xc8\x4a\x8d\xfb\x08\x53\x24\x45\x92\x26\x8a" +
|
||||
"\x14\x5f\x60\x6c\x88\x41\xc2\x80\x80\x22\x2b\xc4\xdd\x17\xc3\x7a" +
|
||||
"\xff\xb4\x5b\x81\xde\x3c\xe6\x1b\x86\x88\xb0\x2a\xda\x92\xc9\xb0" +
|
||||
"\x03\x6d\x63\x7c\xd1\xe6\xcd\x48\xc5\x9d\x55\x10\x38\x7a\x1d\x10" +
|
||||
"\xfe\xbe\x26\x29\x65\xc9\x81\x5e\x38\xc2\x3f\xe0\x60\x71\x60\x85" +
|
||||
"\xcf\xb4\x89\x51\xfe\xa1\x2f\xff\x61\x0c\x43\xf8\x5d\x81\x2f\xb4" +
|
||||
"\x62\xfc\xc9\x81\x49\xbd\x14\xd2\x10\x41\x63\x1c\x9d\x5c\x7f\x2d" +
|
||||
"\xcc\xb9\xcf\xc8\xff\x43\x4a\xa4\x17\xb4\xf8\x5c\x79\x7e\x12\xed" +
|
||||
"\x63\xd1\xd2\x5c\xac\xae\x66\x35\xfb\xfc\xa8\xe4\x69\x13\xd0\xed" +
|
||||
"\x4f\xf6\x86\x68\xde\x26\x1b\xba\xe9\x52\xea\x9e\x85\xdc\x25\x94" +
|
||||
"\xcb\x7e\x92\xbe\x6e\x2c\x4f\xbd\x2d\xf0\x18\x00\x00\xff\xff\x2c" +
|
||||
"\xc5\xf5\x5d\x47\x01\x00\x00"
|
||||
|
||||
// DefaultTemplate returns the binary data for a given file.
|
||||
func DefaultTemplate() []byte {
|
||||
// This bit of black magic ensures we do not get
|
||||
// unneccesary memcpy's and can read directly from
|
||||
// the .rodata section.
|
||||
var empty [0]byte
|
||||
sx := (*reflect.StringHeader)(unsafe.Pointer(&_DefaultTemplate))
|
||||
b := empty[:]
|
||||
bx := (*reflect.SliceHeader)(unsafe.Pointer(&b))
|
||||
bx.Data = sx.Data
|
||||
bx.Len = len(_DefaultTemplate)
|
||||
bx.Cap = bx.Len
|
||||
|
||||
gz, err := gzip.NewReader(bytes.NewBuffer(b))
|
||||
|
||||
if err != nil {
|
||||
panic("Decompression failed: " + err.Error())
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
io.Copy(&buf, gz)
|
||||
gz.Close()
|
||||
|
||||
return buf.Bytes()
|
||||
}
|
||||
181
vendor/github.com/JalfResi/justext/detailedTemplate.go
generated
vendored
181
vendor/github.com/JalfResi/justext/detailedTemplate.go
generated
vendored
|
|
@ -1,181 +0,0 @@
|
|||
package justext
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
"io"
|
||||
"reflect"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
var _DetailedTemplate = "" +
|
||||
"\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xe4\x59\x59\x73\xe2\x3a" +
|
||||
"\xf6\x7f\x4e\x3e\x85\xff\xfc\x6f\x4d\x27\x45\x9a\x1d\x02\x09\x64" +
|
||||
"\xc6\x18\x13\x76\x02\x06\x02\x99\x9a\xea\x12\xb6\x6c\x14\xaf\xb1" +
|
||||
"\x65\x8c\xc9\xf0\xdd\x47\x32\x66\x0b\x24\x4d\xcf\x43\xdf\x5b\x35" +
|
||||
"\xbc\xd8\x3e\x3a\xfb\xf9\x49\x3a\x12\xc5\x19\xd6\xb5\x87\xcb\xa2" +
|
||||
"\x83\x7d\x0d\x3e\x5c\x5e\xfc\x03\xe9\x96\x69\x63\xc6\xb5\xb5\xab" +
|
||||
"\x19\xc6\xd6\x5d\x3c\x2e\x9b\x06\x76\x62\x8a\x69\x2a\x1a\x04\x16" +
|
||||
"\x72\x62\xa2\xa9\xc7\x45\xc7\xf9\xbb\x0c\x74\xa4\xf9\xa5\xae\x05" +
|
||||
"\x8d\xa8\x00\x0c\xe7\x2e\x93\x48\xdc\xa4\x13\x89\xbf\x39\xee\xd4" +
|
||||
"\x81\xb8\xa4\x01\x8c\x8c\x1b\xd1\xb7\x91\xa6\x21\xf1\x3b\x5c\xe0" +
|
||||
"\xed\xc7\x8d\x62\x43\xa8\x06\xa4\x39\x82\xd8\x00\x3a\x74\xe0\x4d" +
|
||||
"\x20\x40\x89\xd7\xf7\x97\x17\x97\x17\x53\x53\xf2\x2f\x2f\xde\x2f" +
|
||||
"\x2f\x2e\xa8\x0b\xdf\xd7\xe6\xee\x98\x6f\xd4\x20\x43\x0d\x7e\xbb" +
|
||||
"\x61\x1c\xf2\xf8\xee\x40\x1b\xc9\xf7\x1b\x3e\x0f\x22\x65\x86\xef" +
|
||||
"\x18\xe2\xc9\x3d\x43\x88\x3a\xb0\x15\xa2\x56\x83\x32\x21\x02\x17" +
|
||||
"\x9b\xf7\x3b\xa2\xbd\x66\xdd\x50\x3d\x24\xe1\xd9\x1d\x93\x4f\x24" +
|
||||
"\xac\x05\xf9\x5e\x5d\x5e\x5e\x38\x16\x30\x62\x0e\x36\x2d\xcf\xb4" +
|
||||
"\x25\x86\x3a\x83\x89\x83\xdf\x25\x28\x9a\x36\x71\xd7\x34\xee\x18" +
|
||||
"\xd7\x90\xa0\xad\x21\x03\x86\x22\x16\x4d\x96\x74\xc3\x58\xb1\x19" +
|
||||
"\x04\x12\x32\x14\xfa\x3a\x05\x81\x34\x43\x7e\xa1\x95\x6c\x76\x6d" +
|
||||
"\x85\x92\x02\x9d\x40\x43\x0a\x51\xf7\xea\x3a\x18\xc9\x7e\x38\x12" +
|
||||
"\x3a\x4a\x1c\xb8\x63\x52\x5b\xfe\x90\x3a\x35\x31\x36\xf5\xfd\x01" +
|
||||
"\x0b\x48\xd4\x62\x18\x6d\xfa\x88\x1e\x06\x9c\xde\xc6\x77\xe4\xec" +
|
||||
"\xc6\xcb\x29\x10\x55\xc5\x36\x49\x70\xdf\x45\x53\x33\xed\x3b\xe6" +
|
||||
"\xff\x45\x59\xdc\x4a\xed\x71\x1f\xa6\x3d\x13\xa6\x3d\x20\x3a\x68" +
|
||||
"\x09\xef\x98\x64\x2c\x0d\xf5\xad\xe4\x5e\x26\x4e\xd8\x90\x25\x29" +
|
||||
"\xe4\x94\xd0\x3c\x66\x01\x1b\x28\x36\xb0\x66\x3f\x24\x88\x01\xd2" +
|
||||
"\x9c\x0f\x39\x4c\x65\x76\x39\x94\x35\x13\x10\xfb\x41\x84\x21\x49" +
|
||||
"\x42\x8e\xa5\x01\x82\x19\xc3\xdc\x56\xe7\xb4\x5a\x0c\xa6\x1a\xdc" +
|
||||
"\xba\x45\x4a\x0d\x6d\xea\x92\x06\x2c\x87\x04\xb0\x79\x3b\x43\x05" +
|
||||
"\xde\x06\x77\x58\x8a\xe3\x12\x85\xa5\xd8\x0d\xac\xcd\x92\x74\x59" +
|
||||
"\x0b\xc6\x31\x35\x24\x91\x6c\xc8\xf2\x57\x36\x83\xda\xad\x0d\xdf" +
|
||||
"\x7c\xc6\xb2\x29\xd4\x89\x08\x0f\x4c\x15\xe4\xc2\x97\xa6\x68\xd9" +
|
||||
"\x7e\xa6\x43\x06\xe0\x4c\x77\x19\x6c\x9f\xe9\x31\xb6\xbf\x40\xcb" +
|
||||
"\xf9\x4e\x7f\xa9\x66\xe7\x77\x0c\xfa\xd0\x24\xeb\x4b\xb8\xee\xac" +
|
||||
"\x21\x45\x2b\x78\xff\x71\x25\xf9\x9e\x24\x40\xdf\x11\x83\x09\xba" +
|
||||
"\x9e\x56\x17\x5b\xd8\x4d\x35\x53\x54\xf7\x16\x96\x74\x72\xcd\x30" +
|
||||
"\x0b\xe7\x4a\x2a\xb3\xfe\xde\x73\xc9\x86\x16\xa4\x36\x0d\x33\x7c" +
|
||||
"\xfd\x30\x8e\x74\xa0\x10\x44\xd2\xf5\x59\x02\x18\xdc\x05\xdf\x71" +
|
||||
"\xcb\x50\xee\xa7\xc0\x81\xb9\xcc\x0d\x1a\x95\xbb\x7d\x2f\xd1\x7c" +
|
||||
"\x54\x4c\x96\xfc\x3a\xc2\x70\xc6\x0f\x15\xf2\x56\xce\xd3\xef\x3e" +
|
||||
"\xc7\x4e\xe8\x53\xb3\x6a\x52\x83\x52\x1b\x09\x8d\xef\x8d\xfa\x99" +
|
||||
"\xd4\x5b\x6a\x34\xee\xa5\x2b\x6d\xd6\xe7\x17\x3e\xdb\xe3\xde\xf8" +
|
||||
"\x1e\xab\xf3\xc1\x93\x43\x7c\xaf\x8c\xc2\x77\x87\xef\xb5\x5f\x0b" +
|
||||
"\x62\xa3\x8d\x9b\x53\x0c\x52\x42\x27\x5a\x49\xe4\x07\xc6\xb8\x76" +
|
||||
"\x9b\x03\xcd\x54\x35\x31\x9d\x98\xcf\x03\x55\x74\xb3\xf5\x45\x4b" +
|
||||
"\x5d\xf0\x6d\xae\x96\xb5\xa6\x3d\x76\x24\x69\x28\xa3\x2d\x13\xc3" +
|
||||
"\x7a\xaf\xde\x86\xd9\xa7\xbe\xe8\xf3\x6d\x1f\xa4\x9f\xd2\xec\x5b" +
|
||||
"\x53\x10\xdc\xe9\xe8\x09\x18\x8b\xaa\x66\xc1\x16\x18\xa3\x7e\x79" +
|
||||
"\xf8\x72\xcb\xab\x13\x7b\xde\x19\xbd\xb1\xd5\x41\x6e\x22\x8d\x27" +
|
||||
"\xed\xc9\x68\x24\x24\xeb\x8f\x2f\xc9\x49\x33\xca\xc7\x1f\xcb\xe2" +
|
||||
"\x04\xd5\x52\xb5\xea\xf8\x35\x5b\xad\x8d\xbb\x99\x6a\x66\x91\x6b" +
|
||||
"\x45\x93\xaf\xb7\xac\x50\x43\x9e\x33\x28\x3c\xb5\x66\xfd\xf9\x4b" +
|
||||
"\x27\x6a\x44\x0b\x2e\x1a\x62\x81\xef\xcb\x4e\x74\xdc\x99\xb0\x9c" +
|
||||
"\x97\xcc\x0f\xa7\xdd\x64\xe7\xcd\x86\x6a\xf2\x79\x6e\xcd\xa3\x65" +
|
||||
"\xf1\x55\x4d\x34\x52\x95\xd6\x44\x28\x24\x6a\xe5\x6a\x05\x60\x2e" +
|
||||
"\xaf\xf8\x8b\xac\x06\xe2\x51\x3b\x5d\x4b\xb3\x03\xbe\xda\x7d\x92" +
|
||||
"\x2b\xad\xaa\xfb\xda\xcd\x65\xdc\xe6\xa0\xba\x30\x3b\xe9\x27\xcb" +
|
||||
"\xc8\x38\x6f\x78\xc9\xdd\xbe\xe9\xa3\x7c\x42\x97\x04\x77\xe0\x4d" +
|
||||
"\xbb\x59\x3d\xe5\x8e\x86\x80\xeb\x75\xc1\x70\x2c\x88\x42\x83\x2b" +
|
||||
"\x14\x16\x8e\x5d\x90\x0a\xf5\x42\x2a\xee\x2f\x9b\x8b\x81\xee\xb9" +
|
||||
"\x43\x0f\x3e\xaa\xb5\x78\x5a\x2d\x64\x66\x15\x29\xe5\x2f\xec\x11" +
|
||||
"\x6c\x69\x62\xa7\xc7\x06\xa5\xe9\x0f\xb3\xbc\xad\x36\x14\x45\x29" +
|
||||
"\x95\xae\xf7\x10\x2a\x6a\xa6\x03\xa5\xf3\x31\xfa\x57\x06\xe4\x24" +
|
||||
"\x04\x24\xf7\xe6\x83\x32\xa5\x4e\xf9\x10\x90\x76\xea\xb9\x22\xa6" +
|
||||
"\xf9\x3a\xeb\x3f\x2e\x3d\x5e\x68\xe8\xbc\xa0\xd6\x39\x5e\x18\xb2" +
|
||||
"\x1c\x6f\xb1\x1e\x37\x44\x93\x19\xaf\x4f\xca\xdc\xc0\x01\x8b\x2e" +
|
||||
"\x28\x74\x32\x6c\x34\x8e\x53\x8d\xc7\xbc\x5b\x4e\xfa\xb2\x66\xbd" +
|
||||
"\xf8\x46\x3a\x2d\xc7\x93\xc3\x44\xed\x51\x9d\x73\x76\xaa\x30\xcd" +
|
||||
"\xb3\xe3\x72\xbf\x10\x2d\xeb\x70\xc2\xa2\x42\x2d\x9a\xcb\x03\x9c" +
|
||||
"\xeb\xb3\x48\xf7\xf3\xcd\xc6\x30\xdb\xcf\x9a\x23\xb9\x65\x56\xfb" +
|
||||
"\x39\x76\x32\x07\xe5\x7c\xc3\x7a\x75\xf9\xa1\x1d\x9d\x22\x24\xa4" +
|
||||
"\x9b\x29\xce\x8c\x3e\xce\xbd\x6a\x45\x89\xf2\x26\xa8\x44\xf9\xc4" +
|
||||
"\xb2\xae\xbe\x2e\x15\xd9\x06\x99\xda\xeb\x74\xb1\xe4\xf8\xe9\x22" +
|
||||
"\xa5\xd4\xb3\xea\x20\xd1\x2b\xa8\xcf\x0d\xdb\xee\x8d\x9e\x0c\x61" +
|
||||
"\xf6\xfa\xe2\xc5\xdd\x4e\x4e\xe8\xcc\xf3\x8e\xe1\xd7\x6e\xcb\x09" +
|
||||
"\xa9\x2b\xd8\x04\x65\xec\x52\xe8\x69\xfa\x14\x5a\x4b\x47\xf4\xa2" +
|
||||
"\x65\xde\x29\xf4\x58\xac\x76\x9f\x47\x39\xb8\x18\xc1\xf2\x4b\x56" +
|
||||
"\xab\x22\xfc\xc8\xdb\xb9\x96\xd9\x83\x75\xa1\x3e\x00\xa3\x51\xc3" +
|
||||
"\x18\x71\xee\x4b\xed\x16\x4b\x2d\x6d\xda\xec\xea\x6d\x37\x3a\x98" +
|
||||
"\xf5\x75\x1b\x8f\x5b\x5a\xd9\xd1\x0c\x33\xda\x28\x2c\x5e\x26\x96" +
|
||||
"\xe8\x77\xd9\xbe\xef\x67\xd8\x9a\xb1\x48\x35\xe7\xb3\xee\x5b\xbd" +
|
||||
"\x62\xa9\xac\x17\xf7\xf8\x0a\x28\x24\x97\x5c\x62\x32\x6e\xb6\x9a" +
|
||||
"\xaa\x69\xf0\x60\xd4\x66\x5f\x8c\x4e\x54\xc9\x65\x35\x38\xcb\x3e" +
|
||||
"\xd5\x13\x4e\x35\xa9\x3b\x8f\xd6\x78\x1e\x97\x85\x6e\xf6\x6d\x7a" +
|
||||
"\x2b\x4d\x92\xfd\xf4\xab\xe5\x56\xd5\x4c\x6b\x68\xd8\x05\x2b\x21" +
|
||||
"\xb6\xf2\x05\x2e\xeb\x95\x73\x95\x44\x66\x6e\xd4\xe1\x30\xd9\xd2" +
|
||||
"\x59\xcf\x91\xd5\xb6\xe4\x55\xab\xfd\x84\x37\x1f\xa6\x33\x12\x1a" +
|
||||
"\xa6\x9b\xf1\xd9\xf3\xb8\xde\x02\xd1\x38\x07\x86\xcb\x0c\x8e\xa3" +
|
||||
"\x46\x5c\xa9\xbc\xc8\x5a\x5a\x2f\xe4\xc4\x71\xdb\xfb\x0c\xec\xc5" +
|
||||
"\x78\xd8\x96\x16\x1d\xd1\x46\x16\x26\xfd\xa9\xec\x1a\x22\xed\xba" +
|
||||
"\x18\x67\x66\x7a\x3f\x80\x34\x07\x86\x08\xa5\xab\xeb\xcd\xe2\xbe" +
|
||||
"\xa1\xfc\x30\x2d\xca\xe6\x30\x25\x46\x32\x45\x57\x87\x06\x8e\x29" +
|
||||
"\x10\xf3\x1a\xa4\xaf\x65\xbf\x2e\x5d\x45\x3e\xf2\x46\xae\xef\x4f" +
|
||||
"\x2b\x89\x05\x6e\xc4\xc2\x59\x44\x54\x46\x82\x79\x14\x09\xd9\x0f" +
|
||||
"\x5c\xf9\x41\x1a\x41\xf5\x2b\xab\xc7\xdc\x5b\xbb\xc7\x43\xc7\x96" +
|
||||
"\x69\x27\xb3\x31\x3c\x43\x12\x3c\xdf\xf0\x31\xf7\xd6\xf0\xf1\xd0" +
|
||||
"\xb1\xe1\x48\xb8\xfe\x6c\x2b\x70\x20\xf4\xdb\x2b\xb0\x9f\x87\xdf" +
|
||||
"\x5a\x80\x3f\x25\xf9\x9b\x68\x0f\x0a\x80\x4d\x85\x1c\xc9\x7e\x4c" +
|
||||
"\x4d\xa4\x41\x9b\x70\x62\xf2\xee\x92\x03\x81\xb1\x2e\xc6\xc5\x7a" +
|
||||
"\xbc\xbc\x1b\xfe\xca\xc1\x23\xe6\xc0\xbf\x0b\x24\x33\x57\x47\x43" +
|
||||
"\x31\x51\x03\x8e\xd3\x21\x87\xb6\x18\x22\x67\x9f\x45\x57\xbe\x8a" +
|
||||
"\x6c\x77\xa5\xc8\x35\xf3\x7f\x25\xb2\xf3\xac\x7d\x38\x76\x62\x27" +
|
||||
"\x4c\x03\x0b\xdb\x2d\x1a\x1b\xd9\x85\x68\x26\xf6\xc2\xb9\x0a\x5c" +
|
||||
"\x58\x31\x50\x73\xe0\xb9\xda\x42\x27\x02\x7d\x41\x39\x8f\xf5\x9d" +
|
||||
"\xc2\xf1\x01\xd7\xae\x83\x0f\xfb\xc9\x4f\x40\xec\x94\xfd\x01\x50" +
|
||||
"\xa8\xf1\xab\x88\xb5\xad\xa7\x6c\xda\xcc\xd5\x1c\xd8\x0c\x2a\x91" +
|
||||
"\x93\x10\x2a\xee\xb4\xc4\x34\x68\x28\x78\x46\x88\xd1\xe8\xd6\x08" +
|
||||
"\xfd\x51\xee\x2d\x1b\xb1\xb5\x13\xf9\x27\xfa\xd7\xfd\x8e\x8f\x56" +
|
||||
"\x63\x3b\x76\xaa\x0a\xa4\xdf\x3d\xc8\x3f\xb3\xf7\xdb\x09\x7e\x39" +
|
||||
"\x99\xe8\x6f\xb5\x7e\x5d\xed\x01\x74\x1f\x65\x67\x81\xfd\xa3\xc0" +
|
||||
"\x21\xde\x3f\x8e\x9e\x31\xc1\x7f\xc5\x83\x93\x02\x87\xd3\xfc\xe7" +
|
||||
"\x1e\x1c\x4d\xb8\x63\x3c\xfd\xcf\x21\xe5\x73\x94\xfc\x39\x35\x3a" +
|
||||
"\xda\x0e\x7f\x3b\x4e\x4f\xa3\xe4\xe8\x28\xba\xab\xc6\x0d\x63\x49" +
|
||||
"\x48\x3a\x86\xce\xf6\x22\xe1\x73\x8f\x03\xc1\xfb\x4f\xe4\x3e\xed" +
|
||||
"\x52\x98\xb5\xc0\x2f\x41\x62\x57\xe5\x8f\x60\xd8\xb5\xfe\x1c\x3d" +
|
||||
"\x3d\x53\x3b\xf4\xfc\xbc\x29\x02\x5d\xab\x7f\x4d\x98\x9c\xe1\x4f" +
|
||||
"\xf7\x16\x7f\x89\x1c\xae\x01\xf6\x1b\x52\x28\x49\xff\x7d\x0a\x45" +
|
||||
"\x59\x8c\x6c\x3a\xe6\xb0\x53\x2e\xd2\xdb\x53\xd2\x30\x17\x25\x34" +
|
||||
"\x67\x90\x54\x3a\xb1\xc1\x33\x41\x00\xa5\xbd\x5d\x93\x31\x0d\x51" +
|
||||
"\x43\xa2\xba\xe1\x3e\xd9\x5b\x44\x1e\x8a\x71\xa2\xf4\xe1\xf2\xfd" +
|
||||
"\xdd\x06\x86\x02\x99\x3f\x82\xf0\x6f\x98\x3f\x2c\xe6\xae\xc4\xc4" +
|
||||
"\x9e\xb6\x4b\xd2\x6a\xb5\x67\xdf\x92\xde\xdf\xd7\x9c\xab\xd5\xd6" +
|
||||
"\xf4\x89\xfb\xbd\x77\x92\xe4\x58\x6d\x7d\x05\xb4\x5a\x85\x77\x41" +
|
||||
"\xef\xef\xd0\x90\x56\x2b\x32\x1a\xe3\xa8\x24\x55\x11\xa4\xa3\x14" +
|
||||
"\xd9\x9c\x6d\x83\x2b\xbe\xc8\xc3\x05\xd9\xe1\x8b\xc1\x95\xcf\x03" +
|
||||
"\x6d\x01\x8a\xd8\x0e\x9e\xe4\x45\x7a\xa8\x22\x03\x68\x6b\xd3\x77" +
|
||||
"\x4c\x31\x4e\x28\x94\xba\xd3\x19\x90\x02\xa9\x78\x28\x76\x20\xce" +
|
||||
"\x99\x46\x70\x4f\x2b\xdb\x10\x9e\xd4\x22\x9f\xa7\x27\x0c\xee\x50" +
|
||||
"\x78\x1b\xf1\x4f\x84\x5b\xc1\xc6\xc0\x5c\x21\x83\x11\x67\x24\x7b" +
|
||||
"\x22\x86\xb6\x73\x7d\xa0\x8b\xec\x1d\x4c\x6c\x40\x3c\xfd\xa9\xb2" +
|
||||
"\x8e\x4b\xce\x9e\x36\x63\xca\x7b\xba\x18\x0f\x11\xfd\x74\xad\xfb" +
|
||||
"\x10\x5e\x8b\x90\xa0\xc4\x11\x46\x8e\xa0\xef\xe7\xca\x29\x3f\x23" +
|
||||
"\x41\xc3\x41\xd8\x3f\xd6\x54\x59\x0f\xfc\x82\x8b\xf4\x02\xfe\x83" +
|
||||
"\x4b\xcf\x84\x74\x9e\x33\x3b\x35\xf4\x2e\xff\x94\x2e\x21\xbc\xe3" +
|
||||
"\x3f\x4f\x9f\xb0\xd1\x72\x3a\xc2\x8d\xb2\x33\xa3\xa4\x17\xcc\xf4" +
|
||||
"\x8f\x86\x52\x24\x15\xa1\xe2\x15\x53\x7f\x02\x78\x76\x42\x8c\x3c" +
|
||||
"\x43\x6c\xaf\x27\x21\x81\x7b\xd1\xda\xcc\xa6\xf3\xe7\x8e\x69\xe8" +
|
||||
"\xa6\xeb\x40\x73\x0e\xed\x52\xe4\x93\x0d\x0b\xcf\x90\x73\xc3\x7c" +
|
||||
"\xdb\x9f\xb7\xdf\xae\xef\x77\xb2\x2e\x2e\x45\x3e\x59\xa7\x3f\x11" +
|
||||
"\x25\xa1\x0d\x6c\xa4\x0b\x16\x10\xe1\x1a\xa1\xcc\xbf\x99\x36\xb0" +
|
||||
"\xd5\x4d\xba\x82\xb9\x63\xd1\x95\x25\x70\x99\x2c\x67\xeb\x55\xac" +
|
||||
"\x18\x0f\xfe\xa6\xfa\x4f\x00\x00\x00\xff\xff\xdb\x07\xd3\x5c\xad" +
|
||||
"\x1a\x00\x00"
|
||||
|
||||
// DetailedTemplate returns the binary data for a given file.
|
||||
func DetailedTemplate() []byte {
|
||||
// This bit of black magic ensures we do not get
|
||||
// unneccesary memcpy's and can read directly from
|
||||
// the .rodata section.
|
||||
var empty [0]byte
|
||||
sx := (*reflect.StringHeader)(unsafe.Pointer(&_DetailedTemplate))
|
||||
b := empty[:]
|
||||
bx := (*reflect.SliceHeader)(unsafe.Pointer(&b))
|
||||
bx.Data = sx.Data
|
||||
bx.Len = len(_DetailedTemplate)
|
||||
bx.Cap = bx.Len
|
||||
|
||||
gz, err := gzip.NewReader(bytes.NewBuffer(b))
|
||||
|
||||
if err != nil {
|
||||
panic("Decompression failed: " + err.Error())
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
io.Copy(&buf, gz)
|
||||
gz.Close()
|
||||
|
||||
return buf.Bytes()
|
||||
}
|
||||
89
vendor/github.com/JalfResi/justext/htmlRenderer.go
generated
vendored
89
vendor/github.com/JalfResi/justext/htmlRenderer.go
generated
vendored
|
|
@ -1,89 +0,0 @@
|
|||
package justext
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"strings"
|
||||
|
||||
"github.com/levigross/exp-html"
|
||||
)
|
||||
|
||||
/**
|
||||
This should be a separate package!
|
||||
And it should be a Writer!
|
||||
*/
|
||||
|
||||
var selfClosingTags = map[string]bool{
|
||||
"area": true,
|
||||
"base": true,
|
||||
"basefont": true,
|
||||
"br": true,
|
||||
"hr": true,
|
||||
"input": true,
|
||||
"img": true,
|
||||
"link": true,
|
||||
"meta": true,
|
||||
}
|
||||
|
||||
// nodesToString loops over a node tree and generate HTML string
|
||||
// Should be moved into html/utils package
|
||||
func nodesToString(node *html.Node) string {
|
||||
var response string = ""
|
||||
|
||||
switch node.Type {
|
||||
case html.TextNode:
|
||||
response = html.EscapeString(strings.TrimSpace(node.Data))
|
||||
|
||||
case html.ElementNode, html.DoctypeNode:
|
||||
var att string = ""
|
||||
if len(node.Attr) > 0 {
|
||||
for _, a := range node.Attr {
|
||||
att = fmt.Sprintf("%s %s=\"%s\"", att, a.Key, a.Val)
|
||||
}
|
||||
}
|
||||
|
||||
if _, ok := selfClosingTags[node.Data]; ok {
|
||||
return fmt.Sprintf("<%s%s>", node.Data, att)
|
||||
}
|
||||
|
||||
var content string = ""
|
||||
if len(node.Child) > 0 {
|
||||
for _, n := range node.Child {
|
||||
content = fmt.Sprintf("%s%s", content, nodesToString(n))
|
||||
}
|
||||
}
|
||||
response = fmt.Sprintf("<%s%s>%s</%s>", node.Data, att, content, node.Data)
|
||||
|
||||
case html.DocumentNode:
|
||||
if len(node.Child) > 0 {
|
||||
for _, n := range node.Child {
|
||||
response = nodesToString(n)
|
||||
}
|
||||
}
|
||||
|
||||
case html.CommentNode:
|
||||
// ignore
|
||||
|
||||
default:
|
||||
log.Printf("Unhandled node: %s", nodeTypeToString(node))
|
||||
}
|
||||
return response
|
||||
}
|
||||
|
||||
func nodeTypeToString(n *html.Node) (t string) {
|
||||
switch n.Type {
|
||||
case html.ErrorNode:
|
||||
t = "Error"
|
||||
case html.TextNode:
|
||||
t = "Text"
|
||||
case html.DocumentNode:
|
||||
t = "Document"
|
||||
case html.ElementNode:
|
||||
t = "Element"
|
||||
case html.CommentNode:
|
||||
t = "Comment"
|
||||
case html.DoctypeNode:
|
||||
t = "Doctype"
|
||||
}
|
||||
return t
|
||||
}
|
||||
160
vendor/github.com/JalfResi/justext/paragraphObjectModel.go
generated
vendored
160
vendor/github.com/JalfResi/justext/paragraphObjectModel.go
generated
vendored
|
|
@ -1,160 +0,0 @@
|
|||
package justext
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/levigross/exp-html"
|
||||
"io"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
paragraphTags = map[string]bool{
|
||||
"blockquote": true,
|
||||
"caption": true,
|
||||
"center": true,
|
||||
"col": true,
|
||||
"colgroup": true,
|
||||
"dd": true,
|
||||
"div": true,
|
||||
"dl": true,
|
||||
"dt": true,
|
||||
"fieldset": true,
|
||||
"form": true,
|
||||
"legend": true,
|
||||
"optgroup": true,
|
||||
"option": true,
|
||||
"p": true,
|
||||
"pre": true,
|
||||
"table": true,
|
||||
"td": true,
|
||||
"textarea": true,
|
||||
"tfoot": true,
|
||||
"th": true,
|
||||
"thead": true,
|
||||
"tr": true,
|
||||
"ul": true,
|
||||
"li": true,
|
||||
"h1": true,
|
||||
"h2": true,
|
||||
"h3": true,
|
||||
"h4": true,
|
||||
"h5": true,
|
||||
"h6": true,
|
||||
}
|
||||
matchWhiteSpace *regexp.Regexp = regexp.MustCompile("[\n\r\t]+")
|
||||
)
|
||||
|
||||
type Paragraph struct {
|
||||
DomPath string
|
||||
TextNodes []string
|
||||
WordCount int
|
||||
LinkedCharCount int
|
||||
TagCount int
|
||||
Text string
|
||||
StopwordCount int
|
||||
StopwordDensity float64
|
||||
LinkDensity float64
|
||||
Heading bool
|
||||
CfClass string
|
||||
Class string
|
||||
}
|
||||
|
||||
func paragraphObjectModel(htmlStr string) ([]*Paragraph, error) {
|
||||
|
||||
var dom []string
|
||||
var paragraphs []*Paragraph
|
||||
var paragraph *Paragraph = &Paragraph{WordCount: 0, LinkedCharCount: 0, TagCount: 0}
|
||||
var link bool = false
|
||||
var br bool = false
|
||||
var matchToDoErrors *regexp.Regexp = regexp.MustCompile("^html: TODO: ")
|
||||
|
||||
var startNewParagraph func()
|
||||
startNewParagraph = func() {
|
||||
if len(paragraph.TextNodes) != 0 {
|
||||
paragraph.Text = strings.TrimSpace(matchWhiteSpace.ReplaceAllString(strings.Join(paragraph.TextNodes, " "), " "))
|
||||
paragraphs = append(paragraphs, paragraph)
|
||||
}
|
||||
paragraph = &Paragraph{
|
||||
DomPath: strings.Join(dom, "."),
|
||||
WordCount: 0,
|
||||
LinkedCharCount: 0,
|
||||
TagCount: 0,
|
||||
}
|
||||
}
|
||||
|
||||
z := html.NewTokenizer(strings.NewReader(htmlStr))
|
||||
|
||||
for {
|
||||
tt := z.Next()
|
||||
switch tt {
|
||||
|
||||
case html.ErrorToken:
|
||||
if z.Err() == io.EOF {
|
||||
return paragraphs, nil
|
||||
}
|
||||
if matchToDoErrors.MatchString(fmt.Sprintf("%s", z.Err())) {
|
||||
return nil, z.Err()
|
||||
}
|
||||
continue
|
||||
|
||||
case html.StartTagToken:
|
||||
tmpName, _ := z.TagName()
|
||||
name := string(tmpName)
|
||||
//log.Println("Matched start tag: ", name)
|
||||
dom = append(dom, name)
|
||||
_, ok := paragraphTags[name]
|
||||
if ok || (name == "br" && br) {
|
||||
if name == "br" {
|
||||
paragraph.TagCount--
|
||||
}
|
||||
startNewParagraph()
|
||||
} else {
|
||||
if name == "br" {
|
||||
br = true
|
||||
} else {
|
||||
br = false
|
||||
}
|
||||
if name == "a" {
|
||||
link = true
|
||||
}
|
||||
paragraph.TagCount++
|
||||
}
|
||||
|
||||
case html.EndTagToken:
|
||||
tmpName, _ := z.TagName()
|
||||
name := string(tmpName)
|
||||
//log.Println("Matched end tag: ", name)
|
||||
dom = dom[0 : len(dom)-1]
|
||||
if _, ok := paragraphTags[name]; ok {
|
||||
startNewParagraph()
|
||||
}
|
||||
if name == "a" {
|
||||
link = false
|
||||
}
|
||||
|
||||
case html.TextToken:
|
||||
text := strings.TrimSpace(string(z.Text()))
|
||||
e := 15
|
||||
if len(text) < e {
|
||||
e = len(text)
|
||||
}
|
||||
//log.Println("Matched text: ", text[:e], "...")
|
||||
if text == "" {
|
||||
continue
|
||||
}
|
||||
text = strings.TrimSpace(matchWhiteSpace.ReplaceAllString(text, " "))
|
||||
paragraph.TextNodes = append(paragraph.TextNodes, text)
|
||||
words := strings.Split(text, " ")
|
||||
paragraph.WordCount += len(words)
|
||||
if link {
|
||||
paragraph.LinkedCharCount += len(text)
|
||||
}
|
||||
br = false
|
||||
|
||||
}
|
||||
}
|
||||
startNewParagraph()
|
||||
|
||||
return paragraphs, nil
|
||||
}
|
||||
111
vendor/github.com/JalfResi/justext/preprocess.go
generated
vendored
111
vendor/github.com/JalfResi/justext/preprocess.go
generated
vendored
|
|
@ -1,111 +0,0 @@
|
|||
package justext
|
||||
|
||||
import (
|
||||
"github.com/levigross/exp-html"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func preprocess(htmlStr, encoding, defaultEncoding, encErrors string) (*html.Node, error) {
|
||||
|
||||
root, err := html.Parse(strings.NewReader(htmlStr))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
addKwTags(root)
|
||||
removeElements(root, []string{"head", "script", "style"})
|
||||
|
||||
return root, nil
|
||||
}
|
||||
|
||||
type nodeIterator func(n *html.Node)
|
||||
|
||||
func nodeIter(n *html.Node, f nodeIterator) {
|
||||
f(n)
|
||||
for _, c := range n.Child {
|
||||
nodeIter(c, f)
|
||||
}
|
||||
}
|
||||
|
||||
func addKwTags(root *html.Node) *html.Node {
|
||||
var blankText *regexp.Regexp = regexp.MustCompile("^[\n\r\t ]*$")
|
||||
var nodesWithText []*html.Node
|
||||
|
||||
var markTextAndTail nodeIterator
|
||||
markTextAndTail = func(node *html.Node) {
|
||||
if node.Type != html.CommentNode || node.Type != html.DoctypeNode {
|
||||
if node.Type == html.TextNode {
|
||||
nodesWithText = append(nodesWithText, node)
|
||||
}
|
||||
}
|
||||
}
|
||||
nodeIter(root, markTextAndTail)
|
||||
|
||||
for _, node := range nodesWithText {
|
||||
if blankText.MatchString(node.Data) {
|
||||
node.Data = ""
|
||||
} else {
|
||||
kw := &html.Node{
|
||||
Parent: nil,
|
||||
Type: html.ElementNode,
|
||||
Data: "kw",
|
||||
}
|
||||
node2 := CopyNode(node, true)
|
||||
kw.Child = append(kw.Child, node2)
|
||||
insertNode(node, kw)
|
||||
node.Parent.Remove(node)
|
||||
}
|
||||
}
|
||||
|
||||
return root
|
||||
}
|
||||
|
||||
func removeElements(root *html.Node, elementsToRemove []string) {
|
||||
var toBeRemoved []*html.Node
|
||||
var markRemovableNodes = func(node *html.Node) {
|
||||
if node.Type == html.ElementNode {
|
||||
for _, nodeName := range elementsToRemove {
|
||||
if node.Data == nodeName {
|
||||
toBeRemoved = append(toBeRemoved, node)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
nodeIter(root, markRemovableNodes)
|
||||
|
||||
for _, node := range toBeRemoved {
|
||||
node.Parent.Remove(node)
|
||||
}
|
||||
}
|
||||
|
||||
// insertsNode inserts a Node in a Node tree at the position of another node.
|
||||
// Should be moved into html/utils package
|
||||
func insertNode(originalNode *html.Node, newNode *html.Node) {
|
||||
slice := originalNode.Parent.Child
|
||||
for position, n := range slice {
|
||||
if n == originalNode {
|
||||
originalNode.Parent.Child = append(slice[:position], append([]*html.Node{newNode}, slice[position:]...)...)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func CopyNode(node *html.Node, deep bool) *html.Node {
|
||||
newNode := &html.Node{
|
||||
Type: node.Type,
|
||||
Data: node.Data,
|
||||
}
|
||||
|
||||
if deep && len(node.Child) > 0 {
|
||||
for _, n := range node.Child {
|
||||
newNode.Child = append(newNode.Child, CopyNode(n, true))
|
||||
}
|
||||
}
|
||||
|
||||
for _, i := range node.Attr {
|
||||
newNode.Attr = append(newNode.Attr, html.Attribute{Key: i.Key, Val: i.Val})
|
||||
}
|
||||
|
||||
return newNode
|
||||
}
|
||||
98
vendor/github.com/JalfResi/justext/reader.go
generated
vendored
98
vendor/github.com/JalfResi/justext/reader.go
generated
vendored
|
|
@ -1,98 +0,0 @@
|
|||
package justext
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/levigross/exp-html"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Reader struct {
|
||||
LengthLow int
|
||||
LengthHigh int
|
||||
Stoplist map[string]bool
|
||||
StopwordsLow float64
|
||||
StopwordsHigh float64
|
||||
MaxLinkDensity float64
|
||||
MaxHeadingDistance int
|
||||
NoHeadings bool
|
||||
r io.Reader
|
||||
}
|
||||
|
||||
func NewReader(r io.Reader) *Reader {
|
||||
return &Reader{
|
||||
LengthLow: 70,
|
||||
LengthHigh: 200,
|
||||
StopwordsLow: 0.30,
|
||||
StopwordsHigh: 0.32,
|
||||
MaxLinkDensity: 0.2,
|
||||
MaxHeadingDistance: 200,
|
||||
NoHeadings: false,
|
||||
r: r,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Reader) ReadAll() ([]*Paragraph, error) {
|
||||
in, err := ioutil.ReadAll(r.r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
root, err := preprocess(string(in), "utf-8", "utf-8", "errors")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if root == nil {
|
||||
return nil, errors.New("Preprocess has resulted in nil")
|
||||
}
|
||||
|
||||
htmlSource := nodesToString(root)
|
||||
if len(htmlSource) == 0 {
|
||||
return nil, errors.New("MAIN: perprocess has returned an empty string")
|
||||
}
|
||||
|
||||
p, err := paragraphObjectModel(htmlSource)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if p == nil {
|
||||
return nil, errors.New("MAIN: P is nil")
|
||||
}
|
||||
|
||||
classifyParagraphs(p, r.Stoplist, r.LengthLow, r.LengthHigh, r.StopwordsLow, r.StopwordsHigh, r.MaxLinkDensity, r.NoHeadings)
|
||||
reviseParagraphClassification(p, r.MaxHeadingDistance)
|
||||
|
||||
return p, nil
|
||||
}
|
||||
|
||||
func dumpNodes(n *html.Node, tab int, exploreChildNodes bool) string {
|
||||
var childNodes string = ""
|
||||
if exploreChildNodes == true {
|
||||
if len(n.Child) > 0 {
|
||||
for _, c := range n.Child {
|
||||
childNodes = fmt.Sprintf("%s%s\n", childNodes, dumpNodes(c, tab+1, true))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var t string
|
||||
switch n.Type {
|
||||
case html.ErrorNode:
|
||||
t = "Err"
|
||||
case html.TextNode:
|
||||
t = "T"
|
||||
case html.DocumentNode:
|
||||
t = "D"
|
||||
case html.ElementNode:
|
||||
t = "E"
|
||||
case html.CommentNode:
|
||||
t = "C"
|
||||
case html.DoctypeNode:
|
||||
t = "Dt"
|
||||
}
|
||||
|
||||
tabStr := strings.Repeat(" ", tab)
|
||||
return fmt.Sprintf("%s%s:%s\n%s", tabStr, t, strings.TrimSpace(strings.Replace(n.Data, "\n", "", -1)), childNodes)
|
||||
}
|
||||
118
vendor/github.com/JalfResi/justext/reviseParagraphClassification.go
generated
vendored
118
vendor/github.com/JalfResi/justext/reviseParagraphClassification.go
generated
vendored
|
|
@ -1,118 +0,0 @@
|
|||
package justext
|
||||
|
||||
// Context-sensitive paragraph classification. Assumes that classify_pragraphs has already been called.
|
||||
func reviseParagraphClassification(paragraphs []*Paragraph, maxHeadingDistance int) {
|
||||
|
||||
// Copy classes
|
||||
for _, paragraph := range paragraphs {
|
||||
paragraph.Class = paragraph.CfClass
|
||||
}
|
||||
|
||||
// Good headings
|
||||
var j int = 0
|
||||
var distance int
|
||||
for i, paragraph := range paragraphs {
|
||||
if !(paragraph.Heading && paragraph.Class == "short") {
|
||||
continue
|
||||
}
|
||||
|
||||
j = i + 1
|
||||
distance = 0
|
||||
|
||||
for j < len(paragraphs) && distance <= maxHeadingDistance {
|
||||
if paragraphs[j].Class == "good" {
|
||||
paragraph.Class = "neargood"
|
||||
break
|
||||
}
|
||||
distance += len(paragraphs[j].Text)
|
||||
j += 1
|
||||
}
|
||||
}
|
||||
|
||||
// Classify short
|
||||
var newClasses []string = make([]string, len(paragraphs))
|
||||
for i, paragraph := range paragraphs {
|
||||
if paragraph.Class != "short" {
|
||||
continue
|
||||
}
|
||||
|
||||
var prevNeighbour string = getPrevNeighbour(i, paragraphs, true)
|
||||
var nextNeighbour string = getNextNeighbour(i, paragraphs, true)
|
||||
|
||||
var neighbours map[string]bool = make(map[string]bool)
|
||||
neighbours[prevNeighbour] = true
|
||||
neighbours[nextNeighbour] = true
|
||||
|
||||
if _, ok := neighbours["good"]; ok && len(neighbours) == 1 {
|
||||
newClasses[i] = "good"
|
||||
} else if _, ok := neighbours["bad"]; ok && len(neighbours) == 1 {
|
||||
newClasses[i] = "bad"
|
||||
// neighbours must contain both good and bad
|
||||
} else if (prevNeighbour == "bad" && getPrevNeighbour(i, paragraphs, false) == "neargood") || (nextNeighbour == "bad" && getNextNeighbour(i, paragraphs, false) == "neargood") {
|
||||
newClasses[i] = "good"
|
||||
} else {
|
||||
newClasses[i] = "bad"
|
||||
}
|
||||
}
|
||||
|
||||
for i, c := range newClasses {
|
||||
if c != "" {
|
||||
paragraphs[i].Class = c
|
||||
}
|
||||
}
|
||||
|
||||
// revise neargood
|
||||
for i, paragraph := range paragraphs {
|
||||
if paragraph.Class != "neargood" {
|
||||
continue
|
||||
}
|
||||
|
||||
var prevNeighbour string = getPrevNeighbour(i, paragraphs, true)
|
||||
var nextNeighbour string = getNextNeighbour(i, paragraphs, true)
|
||||
|
||||
if prevNeighbour == "bad" && nextNeighbour == "bad" {
|
||||
paragraph.Class = "bad"
|
||||
} else {
|
||||
paragraph.Class = "good"
|
||||
}
|
||||
}
|
||||
|
||||
// more good headings
|
||||
for i, paragraph := range paragraphs {
|
||||
if !(paragraph.Heading && paragraph.Class == "bad" && paragraph.CfClass != "bad") {
|
||||
continue
|
||||
}
|
||||
j = i + 1
|
||||
distance = 0
|
||||
for j < len(paragraphs) && distance <= maxHeadingDistance {
|
||||
if paragraphs[j].Class == "good" {
|
||||
paragraph.Class = "good"
|
||||
break
|
||||
}
|
||||
distance += len(paragraphs[j].Text)
|
||||
j += 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func getPrevNeighbour(i int, paragraphs []*Paragraph, ignoreNeargood bool) string {
|
||||
return getNeighbour(i, paragraphs, ignoreNeargood, -1, -1)
|
||||
}
|
||||
|
||||
func getNextNeighbour(i int, paragraphs []*Paragraph, ignoreNeargood bool) string {
|
||||
return getNeighbour(i, paragraphs, ignoreNeargood, 1, len(paragraphs))
|
||||
}
|
||||
|
||||
func getNeighbour(i int, paragraphs []*Paragraph, ignoreNeargood bool, inc int, boundary int) string {
|
||||
for i+inc != boundary {
|
||||
i += inc
|
||||
var c string = paragraphs[i].Class
|
||||
if c == "good" || c == "bad" {
|
||||
return c
|
||||
}
|
||||
if c == "neargood" && !ignoreNeargood {
|
||||
return c
|
||||
}
|
||||
}
|
||||
return "bad"
|
||||
}
|
||||
158
vendor/github.com/JalfResi/justext/stoplists.go
generated
vendored
158
vendor/github.com/JalfResi/justext/stoplists.go
generated
vendored
|
|
@ -1,158 +0,0 @@
|
|||
package justext
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
)
|
||||
|
||||
type ResourceFunc func() ([]byte, error)
|
||||
|
||||
var stoplists = map[string]ResourceFunc{}
|
||||
|
||||
func RegisterStoplist(name string, resourceFunc ResourceFunc) {
|
||||
stoplists[name] = resourceFunc
|
||||
}
|
||||
|
||||
/*
|
||||
{
|
||||
"Afrikaans": AfrikaansStoplist,
|
||||
"Albanian": AlbanianStoplist,
|
||||
"Arabic": ArabicStoplist,
|
||||
"Aragonese": AragoneseStoplist,
|
||||
"Armenian": ArmenianStoplist,
|
||||
"Aromanian": AromanianStoplist,
|
||||
"Asturian": AsturianStoplist,
|
||||
"Azerbaijani": AzerbaijaniStoplist,
|
||||
"Basque": BasqueStoplist,
|
||||
"Belarusian": BelarusianStoplist,
|
||||
"Belarusian_Taraskievica": Belarusian_TaraskievicaStoplist,
|
||||
"Bengali": BengaliStoplist,
|
||||
"Bishnupriya_Manipuri": Bishnupriya_ManipuriStoplist,
|
||||
"Bosnian": BosnianStoplist,
|
||||
"Breton": BretonStoplist,
|
||||
"Bulgarian": BulgarianStoplist,
|
||||
"Catalan": CatalanStoplist,
|
||||
"Cebuano": CebuanoStoplist,
|
||||
"Chuvash": ChuvashStoplist,
|
||||
"Croatian": CroatianStoplist,
|
||||
"Czech": CzechStoplist,
|
||||
"Danish": DanishStoplist,
|
||||
"Dutch": DutchStoplist,
|
||||
"English": EnglishStoplist,
|
||||
"Esperanto": EsperantoStoplist,
|
||||
"Estonian": EstonianStoplist,
|
||||
"Finnish": FinnishStoplist,
|
||||
"French": FrenchStoplist,
|
||||
"Galician": GalicianStoplist,
|
||||
"Georgian": GeorgianStoplist,
|
||||
"German": GermanStoplist,
|
||||
"Greek": GreekStoplist,
|
||||
"Gujarati": GujaratiStoplist,
|
||||
"Haitian": HaitianStoplist,
|
||||
"Hebrew": HebrewStoplist,
|
||||
"Hindi": HindiStoplist,
|
||||
"Hungarian": HungarianStoplist,
|
||||
"Icelandic": IcelandicStoplist,
|
||||
"Ido": IdoStoplist,
|
||||
"Igbo": IgboStoplist,
|
||||
"Indonesian": IndonesianStoplist,
|
||||
"Irish": IrishStoplist,
|
||||
"Italian": ItalianStoplist,
|
||||
"Javanese": JavaneseStoplist,
|
||||
"Kannada": KannadaStoplist,
|
||||
"Kazakh": KazakhStoplist,
|
||||
"Korean": KoreanStoplist,
|
||||
"Kurdish": KurdishStoplist,
|
||||
"Kyrgyz": KyrgyzStoplist,
|
||||
"Latin": LatinStoplist,
|
||||
"Latvian": LatvianStoplist,
|
||||
"Lithuanian": LithuanianStoplist,
|
||||
"Lombard": LombardStoplist,
|
||||
"Low_Saxon": Low_SaxonStoplist,
|
||||
"Luxembourgish": LuxembourgishStoplist,
|
||||
"Macedonian": MacedonianStoplist,
|
||||
"Malay": MalayStoplist,
|
||||
"Malayalam": MalayalamStoplist,
|
||||
"Maltese": MalteseStoplist,
|
||||
"Marathi": MarathiStoplist,
|
||||
"Neapolitan": NeapolitanStoplist,
|
||||
"Nepali": NepaliStoplist,
|
||||
"Newar": NewarStoplist,
|
||||
"Norwegian_Bokmal": Norwegian_BokmalStoplist,
|
||||
"Norwegian_Nynorsk": Norwegian_NynorskStoplist,
|
||||
"Occitan": OccitanStoplist,
|
||||
"Persian": PersianStoplist,
|
||||
"Piedmontese": PiedmonteseStoplist,
|
||||
"Polish": PolishStoplist,
|
||||
"Portuguese": PortugueseStoplist,
|
||||
"Quechua": QuechuaStoplist,
|
||||
"Romanian": RomanianStoplist,
|
||||
"Russian": RussianStoplist,
|
||||
"Samogitian": SamogitianStoplist,
|
||||
"Serbian": SerbianStoplist,
|
||||
"Serbo_Croatian": Serbo_CroatianStoplist,
|
||||
"Sicilian": SicilianStoplist,
|
||||
"Simple_English": Simple_EnglishStoplist,
|
||||
"Slovak": SlovakStoplist,
|
||||
"Slovenian": SlovenianStoplist,
|
||||
"Spanish": SpanishStoplist,
|
||||
"Sundanese": SundaneseStoplist,
|
||||
"Swahili": SwahiliStoplist,
|
||||
"Swedish": SwedishStoplist,
|
||||
"Tagalog": TagalogStoplist,
|
||||
"Tamil": TamilStoplist,
|
||||
"Telugu": TeluguStoplist,
|
||||
"Turkish": TurkishStoplist,
|
||||
"Turkmen": TurkmenStoplist,
|
||||
"Ukrainian": UkrainianStoplist,
|
||||
"Urdu": UrduStoplist,
|
||||
"Uzbek": UzbekStoplist,
|
||||
"Vietnamese": VietnameseStoplist,
|
||||
"Volapuk": VolapukStoplist,
|
||||
"Walloon": WalloonStoplist,
|
||||
"Waray_Waray": Waray_WarayStoplist,
|
||||
"Welsh": WelshStoplist,
|
||||
"West_Frisian": West_FrisianStoplist,
|
||||
"Western_Panjabi": Western_PanjabiStoplist,
|
||||
"Yoruba": YorubaStoplist,
|
||||
}
|
||||
*/
|
||||
|
||||
func ReadStoplist(filename string) (map[string]bool, error) {
|
||||
data, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
db := bytes.Split(data, []uint8("\n"))
|
||||
|
||||
// Convert to map
|
||||
var list = make(map[string]bool)
|
||||
for _, val := range db {
|
||||
list[string(val)] = true
|
||||
}
|
||||
|
||||
return list, nil
|
||||
}
|
||||
|
||||
func GetStoplist(language string) (map[string]bool, error) {
|
||||
if _, ok := stoplists[language]; !ok {
|
||||
return nil, errors.New(fmt.Sprintf("Language %s not supported", language))
|
||||
}
|
||||
|
||||
data, err := stoplists[language]()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
db := bytes.Split(data, []uint8("\n"))
|
||||
|
||||
// Convert to map
|
||||
var list = make(map[string]bool)
|
||||
for _, val := range db {
|
||||
list[string(val)] = true
|
||||
}
|
||||
|
||||
return list, nil
|
||||
}
|
||||
161
vendor/github.com/JalfResi/justext/writer.go
generated
vendored
161
vendor/github.com/JalfResi/justext/writer.go
generated
vendored
|
|
@ -1,161 +0,0 @@
|
|||
package justext
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"strings"
|
||||
"text/template"
|
||||
)
|
||||
|
||||
// NOTE:
|
||||
// Make a new type:
|
||||
// type JusText []paragraphs
|
||||
|
||||
const (
|
||||
MODE_DEFAULT = 1
|
||||
MODE_DETAILED = 2
|
||||
)
|
||||
|
||||
type Writer struct {
|
||||
Mode int
|
||||
NoBoilerplate bool
|
||||
Stoplist map[string]bool
|
||||
w io.Writer
|
||||
}
|
||||
|
||||
func NewWriter(w io.Writer) *Writer {
|
||||
return &Writer{
|
||||
Mode: MODE_DEFAULT,
|
||||
NoBoilerplate: true,
|
||||
w: w,
|
||||
}
|
||||
}
|
||||
|
||||
func (w *Writer) WriteAll(paragraphs []*Paragraph) error {
|
||||
switch w.Mode {
|
||||
case MODE_DEFAULT:
|
||||
return w.outputDefault(paragraphs)
|
||||
break
|
||||
|
||||
case MODE_DETAILED:
|
||||
return w.outputDetailed(paragraphs)
|
||||
break
|
||||
|
||||
default:
|
||||
return errors.New("Unrecognised mode")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func IsGood(args ...interface{}) (result bool) {
|
||||
result = true
|
||||
for _, val := range args {
|
||||
if val != "good" {
|
||||
result = false
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (w *Writer) outputDefault(paragraphs []*Paragraph) error {
|
||||
templateData := DefaultTemplate()
|
||||
t := template.New("default")
|
||||
t.Funcs(template.FuncMap{"TrimSpace": strings.TrimSpace})
|
||||
t.Funcs(template.FuncMap{"IsGood": IsGood})
|
||||
|
||||
templ, err := t.Parse(string(templateData))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var data = struct {
|
||||
Paragraphs []*Paragraph
|
||||
NoBoilerplate bool
|
||||
}{paragraphs, w.NoBoilerplate}
|
||||
|
||||
return templ.Execute(w.w, data)
|
||||
}
|
||||
|
||||
func (w *Writer) outputDetailed(paragraphs []*Paragraph) error {
|
||||
templateData := DetailedTemplate()
|
||||
var markStopwords func(args ...interface{}) string
|
||||
markStopwords = func(args ...interface{}) string {
|
||||
|
||||
var output string = ""
|
||||
words := strings.Split(args[0].(string), " ")
|
||||
for _, word := range words {
|
||||
if _, ok := w.Stoplist[strings.TrimSpace(word)]; ok {
|
||||
output = fmt.Sprintf("%s<span class=\"stopword\">%s</span> ", output, word)
|
||||
} else {
|
||||
output = fmt.Sprintf("%s%s ", output, word)
|
||||
}
|
||||
}
|
||||
|
||||
return output
|
||||
}
|
||||
|
||||
t := template.New("detailed")
|
||||
t.Funcs(template.FuncMap{"TrimSpace": strings.TrimSpace})
|
||||
t.Funcs(template.FuncMap{"MarkStopwords": markStopwords})
|
||||
|
||||
templ, err := t.Parse(string(templateData))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var data = struct {
|
||||
Paragraphs []*Paragraph
|
||||
}{paragraphs}
|
||||
|
||||
return templ.Execute(w.w, data)
|
||||
}
|
||||
|
||||
func (w *Writer) OutputDebug(paragraphs []*Paragraph) {
|
||||
for _, paragraph := range paragraphs {
|
||||
log.Println(paragraph.DomPath)
|
||||
log.Println("\tfinal class: ", paragraph.Class)
|
||||
log.Println("\tcontext-free class: ", paragraph.CfClass)
|
||||
log.Println("\theading: ", paragraph.Heading)
|
||||
log.Println("\tlength (in characters): ", len(paragraph.Text))
|
||||
log.Println("\tnumber of characters with links: ", paragraph.LinkedCharCount)
|
||||
log.Println("\tlink density: ", paragraph.LinkDensity)
|
||||
log.Println("\tnumber of words: ", paragraph.WordCount)
|
||||
log.Println("\tnumber of stop words: ", paragraph.StopwordCount)
|
||||
log.Println("\tstop word density: ", paragraph.StopwordDensity)
|
||||
}
|
||||
}
|
||||
|
||||
// TO-DO:
|
||||
// Need an output feature that returns a de-duped space separated text file of all the
|
||||
// words in the output document sans-boilerplate. Also needs option to exclude stoplist
|
||||
// words from that output too.
|
||||
|
||||
// TO-DO:
|
||||
// Need an output feature that returns the content of a stop list (or do we just make
|
||||
// the function getStoplist public? Might be a lot easier...)
|
||||
|
||||
/*
|
||||
func (w *Writer) outputKrdwrd(paragraphs []*Paragraph) (output string) {
|
||||
for _, paragraph := range paragraphs {
|
||||
var cls int
|
||||
if paragraph.Class == "good" || paragraph.Class == "neargood" {
|
||||
if paragraph.Heading {
|
||||
cls = 2
|
||||
} else {
|
||||
cls = 3
|
||||
}
|
||||
} else {
|
||||
cls = 1
|
||||
}
|
||||
for _, textNode := range paragraph.TextNodes {
|
||||
output = fmt.Sprintf("%s%i\t%s", output, cls, strings.TrimSpace(textNode))
|
||||
}
|
||||
}
|
||||
|
||||
return output
|
||||
}
|
||||
*/
|
||||
1
vendor/github.com/Masterminds/semver/v3/.gitignore
generated
vendored
1
vendor/github.com/Masterminds/semver/v3/.gitignore
generated
vendored
|
|
@ -1 +0,0 @@
|
|||
_fuzz/
|
||||
26
vendor/github.com/Masterminds/semver/v3/.golangci.yml
generated
vendored
26
vendor/github.com/Masterminds/semver/v3/.golangci.yml
generated
vendored
|
|
@ -1,26 +0,0 @@
|
|||
run:
|
||||
deadline: 2m
|
||||
|
||||
linters:
|
||||
disable-all: true
|
||||
enable:
|
||||
- deadcode
|
||||
- dupl
|
||||
- errcheck
|
||||
- gofmt
|
||||
- goimports
|
||||
- golint
|
||||
- gosimple
|
||||
- govet
|
||||
- ineffassign
|
||||
- misspell
|
||||
- nakedret
|
||||
- structcheck
|
||||
- unused
|
||||
- varcheck
|
||||
|
||||
linters-settings:
|
||||
gofmt:
|
||||
simplify: true
|
||||
dupl:
|
||||
threshold: 400
|
||||
194
vendor/github.com/Masterminds/semver/v3/CHANGELOG.md
generated
vendored
194
vendor/github.com/Masterminds/semver/v3/CHANGELOG.md
generated
vendored
|
|
@ -1,194 +0,0 @@
|
|||
# Changelog
|
||||
|
||||
## 3.1.1 (2020-11-23)
|
||||
|
||||
### Fixed
|
||||
|
||||
- #158: Fixed issue with generated regex operation order that could cause problem
|
||||
|
||||
## 3.1.0 (2020-04-15)
|
||||
|
||||
### Added
|
||||
|
||||
- #131: Add support for serializing/deserializing SQL (thanks @ryancurrah)
|
||||
|
||||
### Changed
|
||||
|
||||
- #148: More accurate validation messages on constraints
|
||||
|
||||
## 3.0.3 (2019-12-13)
|
||||
|
||||
### Fixed
|
||||
|
||||
- #141: Fixed issue with <= comparison
|
||||
|
||||
## 3.0.2 (2019-11-14)
|
||||
|
||||
### Fixed
|
||||
|
||||
- #134: Fixed broken constraint checking with ^0.0 (thanks @krmichelos)
|
||||
|
||||
## 3.0.1 (2019-09-13)
|
||||
|
||||
### Fixed
|
||||
|
||||
- #125: Fixes issue with module path for v3
|
||||
|
||||
## 3.0.0 (2019-09-12)
|
||||
|
||||
This is a major release of the semver package which includes API changes. The Go
|
||||
API is compatible with ^1. The Go API was not changed because many people are using
|
||||
`go get` without Go modules for their applications and API breaking changes cause
|
||||
errors which we have or would need to support.
|
||||
|
||||
The changes in this release are the handling based on the data passed into the
|
||||
functions. These are described in the added and changed sections below.
|
||||
|
||||
### Added
|
||||
|
||||
- StrictNewVersion function. This is similar to NewVersion but will return an
|
||||
error if the version passed in is not a strict semantic version. For example,
|
||||
1.2.3 would pass but v1.2.3 or 1.2 would fail because they are not strictly
|
||||
speaking semantic versions. This function is faster, performs fewer operations,
|
||||
and uses fewer allocations than NewVersion.
|
||||
- Fuzzing has been performed on NewVersion, StrictNewVersion, and NewConstraint.
|
||||
The Makefile contains the operations used. For more information on you can start
|
||||
on Wikipedia at https://en.wikipedia.org/wiki/Fuzzing
|
||||
- Now using Go modules
|
||||
|
||||
### Changed
|
||||
|
||||
- NewVersion has proper prerelease and metadata validation with error messages
|
||||
to signal an issue with either of them
|
||||
- ^ now operates using a similar set of rules to npm/js and Rust/Cargo. If the
|
||||
version is >=1 the ^ ranges works the same as v1. For major versions of 0 the
|
||||
rules have changed. The minor version is treated as the stable version unless
|
||||
a patch is specified and then it is equivalent to =. One difference from npm/js
|
||||
is that prereleases there are only to a specific version (e.g. 1.2.3).
|
||||
Prereleases here look over multiple versions and follow semantic version
|
||||
ordering rules. This pattern now follows along with the expected and requested
|
||||
handling of this packaged by numerous users.
|
||||
|
||||
## 1.5.0 (2019-09-11)
|
||||
|
||||
### Added
|
||||
|
||||
- #103: Add basic fuzzing for `NewVersion()` (thanks @jesse-c)
|
||||
|
||||
### Changed
|
||||
|
||||
- #82: Clarify wildcard meaning in range constraints and update tests for it (thanks @greysteil)
|
||||
- #83: Clarify caret operator range for pre-1.0.0 dependencies (thanks @greysteil)
|
||||
- #72: Adding docs comment pointing to vert for a cli
|
||||
- #71: Update the docs on pre-release comparator handling
|
||||
- #89: Test with new go versions (thanks @thedevsaddam)
|
||||
- #87: Added $ to ValidPrerelease for better validation (thanks @jeremycarroll)
|
||||
|
||||
### Fixed
|
||||
|
||||
- #78: Fix unchecked error in example code (thanks @ravron)
|
||||
- #70: Fix the handling of pre-releases and the 0.0.0 release edge case
|
||||
- #97: Fixed copyright file for proper display on GitHub
|
||||
- #107: Fix handling prerelease when sorting alphanum and num
|
||||
- #109: Fixed where Validate sometimes returns wrong message on error
|
||||
|
||||
## 1.4.2 (2018-04-10)
|
||||
|
||||
### Changed
|
||||
|
||||
- #72: Updated the docs to point to vert for a console appliaction
|
||||
- #71: Update the docs on pre-release comparator handling
|
||||
|
||||
### Fixed
|
||||
|
||||
- #70: Fix the handling of pre-releases and the 0.0.0 release edge case
|
||||
|
||||
## 1.4.1 (2018-04-02)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed #64: Fix pre-release precedence issue (thanks @uudashr)
|
||||
|
||||
## 1.4.0 (2017-10-04)
|
||||
|
||||
### Changed
|
||||
|
||||
- #61: Update NewVersion to parse ints with a 64bit int size (thanks @zknill)
|
||||
|
||||
## 1.3.1 (2017-07-10)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed #57: number comparisons in prerelease sometimes inaccurate
|
||||
|
||||
## 1.3.0 (2017-05-02)
|
||||
|
||||
### Added
|
||||
|
||||
- #45: Added json (un)marshaling support (thanks @mh-cbon)
|
||||
- Stability marker. See https://masterminds.github.io/stability/
|
||||
|
||||
### Fixed
|
||||
|
||||
- #51: Fix handling of single digit tilde constraint (thanks @dgodd)
|
||||
|
||||
### Changed
|
||||
|
||||
- #55: The godoc icon moved from png to svg
|
||||
|
||||
## 1.2.3 (2017-04-03)
|
||||
|
||||
### Fixed
|
||||
|
||||
- #46: Fixed 0.x.x and 0.0.x in constraints being treated as *
|
||||
|
||||
## Release 1.2.2 (2016-12-13)
|
||||
|
||||
### Fixed
|
||||
|
||||
- #34: Fixed issue where hyphen range was not working with pre-release parsing.
|
||||
|
||||
## Release 1.2.1 (2016-11-28)
|
||||
|
||||
### Fixed
|
||||
|
||||
- #24: Fixed edge case issue where constraint "> 0" does not handle "0.0.1-alpha"
|
||||
properly.
|
||||
|
||||
## Release 1.2.0 (2016-11-04)
|
||||
|
||||
### Added
|
||||
|
||||
- #20: Added MustParse function for versions (thanks @adamreese)
|
||||
- #15: Added increment methods on versions (thanks @mh-cbon)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Issue #21: Per the SemVer spec (section 9) a pre-release is unstable and
|
||||
might not satisfy the intended compatibility. The change here ignores pre-releases
|
||||
on constraint checks (e.g., ~ or ^) when a pre-release is not part of the
|
||||
constraint. For example, `^1.2.3` will ignore pre-releases while
|
||||
`^1.2.3-alpha` will include them.
|
||||
|
||||
## Release 1.1.1 (2016-06-30)
|
||||
|
||||
### Changed
|
||||
|
||||
- Issue #9: Speed up version comparison performance (thanks @sdboyer)
|
||||
- Issue #8: Added benchmarks (thanks @sdboyer)
|
||||
- Updated Go Report Card URL to new location
|
||||
- Updated Readme to add code snippet formatting (thanks @mh-cbon)
|
||||
- Updating tagging to v[SemVer] structure for compatibility with other tools.
|
||||
|
||||
## Release 1.1.0 (2016-03-11)
|
||||
|
||||
- Issue #2: Implemented validation to provide reasons a versions failed a
|
||||
constraint.
|
||||
|
||||
## Release 1.0.1 (2015-12-31)
|
||||
|
||||
- Fixed #1: * constraint failing on valid versions.
|
||||
|
||||
## Release 1.0.0 (2015-10-20)
|
||||
|
||||
- Initial release
|
||||
19
vendor/github.com/Masterminds/semver/v3/LICENSE.txt
generated
vendored
19
vendor/github.com/Masterminds/semver/v3/LICENSE.txt
generated
vendored
|
|
@ -1,19 +0,0 @@
|
|||
Copyright (C) 2014-2019, Matt Butcher and Matt Farina
|
||||
|
||||
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.
|
||||
37
vendor/github.com/Masterminds/semver/v3/Makefile
generated
vendored
37
vendor/github.com/Masterminds/semver/v3/Makefile
generated
vendored
|
|
@ -1,37 +0,0 @@
|
|||
GOPATH=$(shell go env GOPATH)
|
||||
GOLANGCI_LINT=$(GOPATH)/bin/golangci-lint
|
||||
GOFUZZBUILD = $(GOPATH)/bin/go-fuzz-build
|
||||
GOFUZZ = $(GOPATH)/bin/go-fuzz
|
||||
|
||||
.PHONY: lint
|
||||
lint: $(GOLANGCI_LINT)
|
||||
@echo "==> Linting codebase"
|
||||
@$(GOLANGCI_LINT) run
|
||||
|
||||
.PHONY: test
|
||||
test:
|
||||
@echo "==> Running tests"
|
||||
GO111MODULE=on go test -v
|
||||
|
||||
.PHONY: test-cover
|
||||
test-cover:
|
||||
@echo "==> Running Tests with coverage"
|
||||
GO111MODULE=on go test -cover .
|
||||
|
||||
.PHONY: fuzz
|
||||
fuzz: $(GOFUZZBUILD) $(GOFUZZ)
|
||||
@echo "==> Fuzz testing"
|
||||
$(GOFUZZBUILD)
|
||||
$(GOFUZZ) -workdir=_fuzz
|
||||
|
||||
$(GOLANGCI_LINT):
|
||||
# Install golangci-lint. The configuration for it is in the .golangci.yml
|
||||
# file in the root of the repository
|
||||
echo ${GOPATH}
|
||||
curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(GOPATH)/bin v1.17.1
|
||||
|
||||
$(GOFUZZBUILD):
|
||||
cd / && go get -u github.com/dvyukov/go-fuzz/go-fuzz-build
|
||||
|
||||
$(GOFUZZ):
|
||||
cd / && go get -u github.com/dvyukov/go-fuzz/go-fuzz github.com/dvyukov/go-fuzz/go-fuzz-dep
|
||||
244
vendor/github.com/Masterminds/semver/v3/README.md
generated
vendored
244
vendor/github.com/Masterminds/semver/v3/README.md
generated
vendored
|
|
@ -1,244 +0,0 @@
|
|||
# SemVer
|
||||
|
||||
The `semver` package provides the ability to work with [Semantic Versions](http://semver.org) in Go. Specifically it provides the ability to:
|
||||
|
||||
* Parse semantic versions
|
||||
* Sort semantic versions
|
||||
* Check if a semantic version fits within a set of constraints
|
||||
* Optionally work with a `v` prefix
|
||||
|
||||
[](https://masterminds.github.io/stability/active.html)
|
||||
[](https://github.com/Masterminds/semver/actions)
|
||||
[](https://pkg.go.dev/github.com/Masterminds/semver/v3)
|
||||
[](https://goreportcard.com/report/github.com/Masterminds/semver)
|
||||
|
||||
If you are looking for a command line tool for version comparisons please see
|
||||
[vert](https://github.com/Masterminds/vert) which uses this library.
|
||||
|
||||
## Package Versions
|
||||
|
||||
There are three major versions fo the `semver` package.
|
||||
|
||||
* 3.x.x is the new stable and active version. This version is focused on constraint
|
||||
compatibility for range handling in other tools from other languages. It has
|
||||
a similar API to the v1 releases. The development of this version is on the master
|
||||
branch. The documentation for this version is below.
|
||||
* 2.x was developed primarily for [dep](https://github.com/golang/dep). There are
|
||||
no tagged releases and the development was performed by [@sdboyer](https://github.com/sdboyer).
|
||||
There are API breaking changes from v1. This version lives on the [2.x branch](https://github.com/Masterminds/semver/tree/2.x).
|
||||
* 1.x.x is the most widely used version with numerous tagged releases. This is the
|
||||
previous stable and is still maintained for bug fixes. The development, to fix
|
||||
bugs, occurs on the release-1 branch. You can read the documentation [here](https://github.com/Masterminds/semver/blob/release-1/README.md).
|
||||
|
||||
## Parsing Semantic Versions
|
||||
|
||||
There are two functions that can parse semantic versions. The `StrictNewVersion`
|
||||
function only parses valid version 2 semantic versions as outlined in the
|
||||
specification. The `NewVersion` function attempts to coerce a version into a
|
||||
semantic version and parse it. For example, if there is a leading v or a version
|
||||
listed without all 3 parts (e.g. `v1.2`) it will attempt to coerce it into a valid
|
||||
semantic version (e.g., 1.2.0). In both cases a `Version` object is returned
|
||||
that can be sorted, compared, and used in constraints.
|
||||
|
||||
When parsing a version an error is returned if there is an issue parsing the
|
||||
version. For example,
|
||||
|
||||
v, err := semver.NewVersion("1.2.3-beta.1+build345")
|
||||
|
||||
The version object has methods to get the parts of the version, compare it to
|
||||
other versions, convert the version back into a string, and get the original
|
||||
string. Getting the original string is useful if the semantic version was coerced
|
||||
into a valid form.
|
||||
|
||||
## Sorting Semantic Versions
|
||||
|
||||
A set of versions can be sorted using the `sort` package from the standard library.
|
||||
For example,
|
||||
|
||||
```go
|
||||
raw := []string{"1.2.3", "1.0", "1.3", "2", "0.4.2",}
|
||||
vs := make([]*semver.Version, len(raw))
|
||||
for i, r := range raw {
|
||||
v, err := semver.NewVersion(r)
|
||||
if err != nil {
|
||||
t.Errorf("Error parsing version: %s", err)
|
||||
}
|
||||
|
||||
vs[i] = v
|
||||
}
|
||||
|
||||
sort.Sort(semver.Collection(vs))
|
||||
```
|
||||
|
||||
## Checking Version Constraints
|
||||
|
||||
There are two methods for comparing versions. One uses comparison methods on
|
||||
`Version` instances and the other uses `Constraints`. There are some important
|
||||
differences to notes between these two methods of comparison.
|
||||
|
||||
1. When two versions are compared using functions such as `Compare`, `LessThan`,
|
||||
and others it will follow the specification and always include prereleases
|
||||
within the comparison. It will provide an answer that is valid with the
|
||||
comparison section of the spec at https://semver.org/#spec-item-11
|
||||
2. When constraint checking is used for checks or validation it will follow a
|
||||
different set of rules that are common for ranges with tools like npm/js
|
||||
and Rust/Cargo. This includes considering prereleases to be invalid if the
|
||||
ranges does not include one. If you want to have it include pre-releases a
|
||||
simple solution is to include `-0` in your range.
|
||||
3. Constraint ranges can have some complex rules including the shorthand use of
|
||||
~ and ^. For more details on those see the options below.
|
||||
|
||||
There are differences between the two methods or checking versions because the
|
||||
comparison methods on `Version` follow the specification while comparison ranges
|
||||
are not part of the specification. Different packages and tools have taken it
|
||||
upon themselves to come up with range rules. This has resulted in differences.
|
||||
For example, npm/js and Cargo/Rust follow similar patterns while PHP has a
|
||||
different pattern for ^. The comparison features in this package follow the
|
||||
npm/js and Cargo/Rust lead because applications using it have followed similar
|
||||
patters with their versions.
|
||||
|
||||
Checking a version against version constraints is one of the most featureful
|
||||
parts of the package.
|
||||
|
||||
```go
|
||||
c, err := semver.NewConstraint(">= 1.2.3")
|
||||
if err != nil {
|
||||
// Handle constraint not being parsable.
|
||||
}
|
||||
|
||||
v, err := semver.NewVersion("1.3")
|
||||
if err != nil {
|
||||
// Handle version not being parsable.
|
||||
}
|
||||
// Check if the version meets the constraints. The a variable will be true.
|
||||
a := c.Check(v)
|
||||
```
|
||||
|
||||
### Basic Comparisons
|
||||
|
||||
There are two elements to the comparisons. First, a comparison string is a list
|
||||
of space or comma separated AND comparisons. These are then separated by || (OR)
|
||||
comparisons. For example, `">= 1.2 < 3.0.0 || >= 4.2.3"` is looking for a
|
||||
comparison that's greater than or equal to 1.2 and less than 3.0.0 or is
|
||||
greater than or equal to 4.2.3.
|
||||
|
||||
The basic comparisons are:
|
||||
|
||||
* `=`: equal (aliased to no operator)
|
||||
* `!=`: not equal
|
||||
* `>`: greater than
|
||||
* `<`: less than
|
||||
* `>=`: greater than or equal to
|
||||
* `<=`: less than or equal to
|
||||
|
||||
### Working With Prerelease Versions
|
||||
|
||||
Pre-releases, for those not familiar with them, are used for software releases
|
||||
prior to stable or generally available releases. Examples of prereleases include
|
||||
development, alpha, beta, and release candidate releases. A prerelease may be
|
||||
a version such as `1.2.3-beta.1` while the stable release would be `1.2.3`. In the
|
||||
order of precedence, prereleases come before their associated releases. In this
|
||||
example `1.2.3-beta.1 < 1.2.3`.
|
||||
|
||||
According to the Semantic Version specification prereleases may not be
|
||||
API compliant with their release counterpart. It says,
|
||||
|
||||
> A pre-release version indicates that the version is unstable and might not satisfy the intended compatibility requirements as denoted by its associated normal version.
|
||||
|
||||
SemVer comparisons using constraints without a prerelease comparator will skip
|
||||
prerelease versions. For example, `>=1.2.3` will skip prereleases when looking
|
||||
at a list of releases while `>=1.2.3-0` will evaluate and find prereleases.
|
||||
|
||||
The reason for the `0` as a pre-release version in the example comparison is
|
||||
because pre-releases can only contain ASCII alphanumerics and hyphens (along with
|
||||
`.` separators), per the spec. Sorting happens in ASCII sort order, again per the
|
||||
spec. The lowest character is a `0` in ASCII sort order
|
||||
(see an [ASCII Table](http://www.asciitable.com/))
|
||||
|
||||
Understanding ASCII sort ordering is important because A-Z comes before a-z. That
|
||||
means `>=1.2.3-BETA` will return `1.2.3-alpha`. What you might expect from case
|
||||
sensitivity doesn't apply here. This is due to ASCII sort ordering which is what
|
||||
the spec specifies.
|
||||
|
||||
### Hyphen Range Comparisons
|
||||
|
||||
There are multiple methods to handle ranges and the first is hyphens ranges.
|
||||
These look like:
|
||||
|
||||
* `1.2 - 1.4.5` which is equivalent to `>= 1.2 <= 1.4.5`
|
||||
* `2.3.4 - 4.5` which is equivalent to `>= 2.3.4 <= 4.5`
|
||||
|
||||
### Wildcards In Comparisons
|
||||
|
||||
The `x`, `X`, and `*` characters can be used as a wildcard character. This works
|
||||
for all comparison operators. When used on the `=` operator it falls
|
||||
back to the patch level comparison (see tilde below). For example,
|
||||
|
||||
* `1.2.x` is equivalent to `>= 1.2.0, < 1.3.0`
|
||||
* `>= 1.2.x` is equivalent to `>= 1.2.0`
|
||||
* `<= 2.x` is equivalent to `< 3`
|
||||
* `*` is equivalent to `>= 0.0.0`
|
||||
|
||||
### Tilde Range Comparisons (Patch)
|
||||
|
||||
The tilde (`~`) comparison operator is for patch level ranges when a minor
|
||||
version is specified and major level changes when the minor number is missing.
|
||||
For example,
|
||||
|
||||
* `~1.2.3` is equivalent to `>= 1.2.3, < 1.3.0`
|
||||
* `~1` is equivalent to `>= 1, < 2`
|
||||
* `~2.3` is equivalent to `>= 2.3, < 2.4`
|
||||
* `~1.2.x` is equivalent to `>= 1.2.0, < 1.3.0`
|
||||
* `~1.x` is equivalent to `>= 1, < 2`
|
||||
|
||||
### Caret Range Comparisons (Major)
|
||||
|
||||
The caret (`^`) comparison operator is for major level changes once a stable
|
||||
(1.0.0) release has occurred. Prior to a 1.0.0 release the minor versions acts
|
||||
as the API stability level. This is useful when comparisons of API versions as a
|
||||
major change is API breaking. For example,
|
||||
|
||||
* `^1.2.3` is equivalent to `>= 1.2.3, < 2.0.0`
|
||||
* `^1.2.x` is equivalent to `>= 1.2.0, < 2.0.0`
|
||||
* `^2.3` is equivalent to `>= 2.3, < 3`
|
||||
* `^2.x` is equivalent to `>= 2.0.0, < 3`
|
||||
* `^0.2.3` is equivalent to `>=0.2.3 <0.3.0`
|
||||
* `^0.2` is equivalent to `>=0.2.0 <0.3.0`
|
||||
* `^0.0.3` is equivalent to `>=0.0.3 <0.0.4`
|
||||
* `^0.0` is equivalent to `>=0.0.0 <0.1.0`
|
||||
* `^0` is equivalent to `>=0.0.0 <1.0.0`
|
||||
|
||||
## Validation
|
||||
|
||||
In addition to testing a version against a constraint, a version can be validated
|
||||
against a constraint. When validation fails a slice of errors containing why a
|
||||
version didn't meet the constraint is returned. For example,
|
||||
|
||||
```go
|
||||
c, err := semver.NewConstraint("<= 1.2.3, >= 1.4")
|
||||
if err != nil {
|
||||
// Handle constraint not being parseable.
|
||||
}
|
||||
|
||||
v, err := semver.NewVersion("1.3")
|
||||
if err != nil {
|
||||
// Handle version not being parseable.
|
||||
}
|
||||
|
||||
// Validate a version against a constraint.
|
||||
a, msgs := c.Validate(v)
|
||||
// a is false
|
||||
for _, m := range msgs {
|
||||
fmt.Println(m)
|
||||
|
||||
// Loops over the errors which would read
|
||||
// "1.3 is greater than 1.2.3"
|
||||
// "1.3 is less than 1.4"
|
||||
}
|
||||
```
|
||||
|
||||
## Contribute
|
||||
|
||||
If you find an issue or want to contribute please file an [issue](https://github.com/Masterminds/semver/issues)
|
||||
or [create a pull request](https://github.com/Masterminds/semver/pulls).
|
||||
24
vendor/github.com/Masterminds/semver/v3/collection.go
generated
vendored
24
vendor/github.com/Masterminds/semver/v3/collection.go
generated
vendored
|
|
@ -1,24 +0,0 @@
|
|||
package semver
|
||||
|
||||
// Collection is a collection of Version instances and implements the sort
|
||||
// interface. See the sort package for more details.
|
||||
// https://golang.org/pkg/sort/
|
||||
type Collection []*Version
|
||||
|
||||
// Len returns the length of a collection. The number of Version instances
|
||||
// on the slice.
|
||||
func (c Collection) Len() int {
|
||||
return len(c)
|
||||
}
|
||||
|
||||
// Less is needed for the sort interface to compare two Version objects on the
|
||||
// slice. If checks if one is less than the other.
|
||||
func (c Collection) Less(i, j int) bool {
|
||||
return c[i].LessThan(c[j])
|
||||
}
|
||||
|
||||
// Swap is needed for the sort interface to replace the Version objects
|
||||
// at two different positions in the slice.
|
||||
func (c Collection) Swap(i, j int) {
|
||||
c[i], c[j] = c[j], c[i]
|
||||
}
|
||||
568
vendor/github.com/Masterminds/semver/v3/constraints.go
generated
vendored
568
vendor/github.com/Masterminds/semver/v3/constraints.go
generated
vendored
|
|
@ -1,568 +0,0 @@
|
|||
package semver
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Constraints is one or more constraint that a semantic version can be
|
||||
// checked against.
|
||||
type Constraints struct {
|
||||
constraints [][]*constraint
|
||||
}
|
||||
|
||||
// NewConstraint returns a Constraints instance that a Version instance can
|
||||
// be checked against. If there is a parse error it will be returned.
|
||||
func NewConstraint(c string) (*Constraints, error) {
|
||||
|
||||
// Rewrite - ranges into a comparison operation.
|
||||
c = rewriteRange(c)
|
||||
|
||||
ors := strings.Split(c, "||")
|
||||
or := make([][]*constraint, len(ors))
|
||||
for k, v := range ors {
|
||||
|
||||
// TODO: Find a way to validate and fetch all the constraints in a simpler form
|
||||
|
||||
// Validate the segment
|
||||
if !validConstraintRegex.MatchString(v) {
|
||||
return nil, fmt.Errorf("improper constraint: %s", v)
|
||||
}
|
||||
|
||||
cs := findConstraintRegex.FindAllString(v, -1)
|
||||
if cs == nil {
|
||||
cs = append(cs, v)
|
||||
}
|
||||
result := make([]*constraint, len(cs))
|
||||
for i, s := range cs {
|
||||
pc, err := parseConstraint(s)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result[i] = pc
|
||||
}
|
||||
or[k] = result
|
||||
}
|
||||
|
||||
o := &Constraints{constraints: or}
|
||||
return o, nil
|
||||
}
|
||||
|
||||
// Check tests if a version satisfies the constraints.
|
||||
func (cs Constraints) Check(v *Version) bool {
|
||||
// TODO(mattfarina): For v4 of this library consolidate the Check and Validate
|
||||
// functions as the underlying functions make that possible now.
|
||||
// loop over the ORs and check the inner ANDs
|
||||
for _, o := range cs.constraints {
|
||||
joy := true
|
||||
for _, c := range o {
|
||||
if check, _ := c.check(v); !check {
|
||||
joy = false
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if joy {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// Validate checks if a version satisfies a constraint. If not a slice of
|
||||
// reasons for the failure are returned in addition to a bool.
|
||||
func (cs Constraints) Validate(v *Version) (bool, []error) {
|
||||
// loop over the ORs and check the inner ANDs
|
||||
var e []error
|
||||
|
||||
// Capture the prerelease message only once. When it happens the first time
|
||||
// this var is marked
|
||||
var prerelesase bool
|
||||
for _, o := range cs.constraints {
|
||||
joy := true
|
||||
for _, c := range o {
|
||||
// Before running the check handle the case there the version is
|
||||
// a prerelease and the check is not searching for prereleases.
|
||||
if c.con.pre == "" && v.pre != "" {
|
||||
if !prerelesase {
|
||||
em := fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v)
|
||||
e = append(e, em)
|
||||
prerelesase = true
|
||||
}
|
||||
joy = false
|
||||
|
||||
} else {
|
||||
|
||||
if _, err := c.check(v); err != nil {
|
||||
e = append(e, err)
|
||||
joy = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if joy {
|
||||
return true, []error{}
|
||||
}
|
||||
}
|
||||
|
||||
return false, e
|
||||
}
|
||||
|
||||
func (cs Constraints) String() string {
|
||||
buf := make([]string, len(cs.constraints))
|
||||
var tmp bytes.Buffer
|
||||
|
||||
for k, v := range cs.constraints {
|
||||
tmp.Reset()
|
||||
vlen := len(v)
|
||||
for kk, c := range v {
|
||||
tmp.WriteString(c.string())
|
||||
|
||||
// Space separate the AND conditions
|
||||
if vlen > 1 && kk < vlen-1 {
|
||||
tmp.WriteString(" ")
|
||||
}
|
||||
}
|
||||
buf[k] = tmp.String()
|
||||
}
|
||||
|
||||
return strings.Join(buf, " || ")
|
||||
}
|
||||
|
||||
var constraintOps map[string]cfunc
|
||||
var constraintRegex *regexp.Regexp
|
||||
var constraintRangeRegex *regexp.Regexp
|
||||
|
||||
// Used to find individual constraints within a multi-constraint string
|
||||
var findConstraintRegex *regexp.Regexp
|
||||
|
||||
// Used to validate an segment of ANDs is valid
|
||||
var validConstraintRegex *regexp.Regexp
|
||||
|
||||
const cvRegex string = `v?([0-9|x|X|\*]+)(\.[0-9|x|X|\*]+)?(\.[0-9|x|X|\*]+)?` +
|
||||
`(-([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?` +
|
||||
`(\+([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?`
|
||||
|
||||
func init() {
|
||||
constraintOps = map[string]cfunc{
|
||||
"": constraintTildeOrEqual,
|
||||
"=": constraintTildeOrEqual,
|
||||
"!=": constraintNotEqual,
|
||||
">": constraintGreaterThan,
|
||||
"<": constraintLessThan,
|
||||
">=": constraintGreaterThanEqual,
|
||||
"=>": constraintGreaterThanEqual,
|
||||
"<=": constraintLessThanEqual,
|
||||
"=<": constraintLessThanEqual,
|
||||
"~": constraintTilde,
|
||||
"~>": constraintTilde,
|
||||
"^": constraintCaret,
|
||||
}
|
||||
|
||||
ops := `=||!=|>|<|>=|=>|<=|=<|~|~>|\^`
|
||||
|
||||
constraintRegex = regexp.MustCompile(fmt.Sprintf(
|
||||
`^\s*(%s)\s*(%s)\s*$`,
|
||||
ops,
|
||||
cvRegex))
|
||||
|
||||
constraintRangeRegex = regexp.MustCompile(fmt.Sprintf(
|
||||
`\s*(%s)\s+-\s+(%s)\s*`,
|
||||
cvRegex, cvRegex))
|
||||
|
||||
findConstraintRegex = regexp.MustCompile(fmt.Sprintf(
|
||||
`(%s)\s*(%s)`,
|
||||
ops,
|
||||
cvRegex))
|
||||
|
||||
validConstraintRegex = regexp.MustCompile(fmt.Sprintf(
|
||||
`^(\s*(%s)\s*(%s)\s*\,?)+$`,
|
||||
ops,
|
||||
cvRegex))
|
||||
}
|
||||
|
||||
// An individual constraint
|
||||
type constraint struct {
|
||||
// The version used in the constraint check. For example, if a constraint
|
||||
// is '<= 2.0.0' the con a version instance representing 2.0.0.
|
||||
con *Version
|
||||
|
||||
// The original parsed version (e.g., 4.x from != 4.x)
|
||||
orig string
|
||||
|
||||
// The original operator for the constraint
|
||||
origfunc string
|
||||
|
||||
// When an x is used as part of the version (e.g., 1.x)
|
||||
minorDirty bool
|
||||
dirty bool
|
||||
patchDirty bool
|
||||
}
|
||||
|
||||
// Check if a version meets the constraint
|
||||
func (c *constraint) check(v *Version) (bool, error) {
|
||||
return constraintOps[c.origfunc](v, c)
|
||||
}
|
||||
|
||||
// String prints an individual constraint into a string
|
||||
func (c *constraint) string() string {
|
||||
return c.origfunc + c.orig
|
||||
}
|
||||
|
||||
type cfunc func(v *Version, c *constraint) (bool, error)
|
||||
|
||||
func parseConstraint(c string) (*constraint, error) {
|
||||
if len(c) > 0 {
|
||||
m := constraintRegex.FindStringSubmatch(c)
|
||||
if m == nil {
|
||||
return nil, fmt.Errorf("improper constraint: %s", c)
|
||||
}
|
||||
|
||||
cs := &constraint{
|
||||
orig: m[2],
|
||||
origfunc: m[1],
|
||||
}
|
||||
|
||||
ver := m[2]
|
||||
minorDirty := false
|
||||
patchDirty := false
|
||||
dirty := false
|
||||
if isX(m[3]) || m[3] == "" {
|
||||
ver = "0.0.0"
|
||||
dirty = true
|
||||
} else if isX(strings.TrimPrefix(m[4], ".")) || m[4] == "" {
|
||||
minorDirty = true
|
||||
dirty = true
|
||||
ver = fmt.Sprintf("%s.0.0%s", m[3], m[6])
|
||||
} else if isX(strings.TrimPrefix(m[5], ".")) || m[5] == "" {
|
||||
dirty = true
|
||||
patchDirty = true
|
||||
ver = fmt.Sprintf("%s%s.0%s", m[3], m[4], m[6])
|
||||
}
|
||||
|
||||
con, err := NewVersion(ver)
|
||||
if err != nil {
|
||||
|
||||
// The constraintRegex should catch any regex parsing errors. So,
|
||||
// we should never get here.
|
||||
return nil, errors.New("constraint Parser Error")
|
||||
}
|
||||
|
||||
cs.con = con
|
||||
cs.minorDirty = minorDirty
|
||||
cs.patchDirty = patchDirty
|
||||
cs.dirty = dirty
|
||||
|
||||
return cs, nil
|
||||
}
|
||||
|
||||
// The rest is the special case where an empty string was passed in which
|
||||
// is equivalent to * or >=0.0.0
|
||||
con, err := StrictNewVersion("0.0.0")
|
||||
if err != nil {
|
||||
|
||||
// The constraintRegex should catch any regex parsing errors. So,
|
||||
// we should never get here.
|
||||
return nil, errors.New("constraint Parser Error")
|
||||
}
|
||||
|
||||
cs := &constraint{
|
||||
con: con,
|
||||
orig: c,
|
||||
origfunc: "",
|
||||
minorDirty: false,
|
||||
patchDirty: false,
|
||||
dirty: true,
|
||||
}
|
||||
return cs, nil
|
||||
}
|
||||
|
||||
// Constraint functions
|
||||
func constraintNotEqual(v *Version, c *constraint) (bool, error) {
|
||||
if c.dirty {
|
||||
|
||||
// If there is a pre-release on the version but the constraint isn't looking
|
||||
// for them assume that pre-releases are not compatible. See issue 21 for
|
||||
// more details.
|
||||
if v.Prerelease() != "" && c.con.Prerelease() == "" {
|
||||
return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v)
|
||||
}
|
||||
|
||||
if c.con.Major() != v.Major() {
|
||||
return true, nil
|
||||
}
|
||||
if c.con.Minor() != v.Minor() && !c.minorDirty {
|
||||
return true, nil
|
||||
} else if c.minorDirty {
|
||||
return false, fmt.Errorf("%s is equal to %s", v, c.orig)
|
||||
} else if c.con.Patch() != v.Patch() && !c.patchDirty {
|
||||
return true, nil
|
||||
} else if c.patchDirty {
|
||||
// Need to handle prereleases if present
|
||||
if v.Prerelease() != "" || c.con.Prerelease() != "" {
|
||||
eq := comparePrerelease(v.Prerelease(), c.con.Prerelease()) != 0
|
||||
if eq {
|
||||
return true, nil
|
||||
}
|
||||
return false, fmt.Errorf("%s is equal to %s", v, c.orig)
|
||||
}
|
||||
return false, fmt.Errorf("%s is equal to %s", v, c.orig)
|
||||
}
|
||||
}
|
||||
|
||||
eq := v.Equal(c.con)
|
||||
if eq {
|
||||
return false, fmt.Errorf("%s is equal to %s", v, c.orig)
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func constraintGreaterThan(v *Version, c *constraint) (bool, error) {
|
||||
|
||||
// If there is a pre-release on the version but the constraint isn't looking
|
||||
// for them assume that pre-releases are not compatible. See issue 21 for
|
||||
// more details.
|
||||
if v.Prerelease() != "" && c.con.Prerelease() == "" {
|
||||
return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v)
|
||||
}
|
||||
|
||||
var eq bool
|
||||
|
||||
if !c.dirty {
|
||||
eq = v.Compare(c.con) == 1
|
||||
if eq {
|
||||
return true, nil
|
||||
}
|
||||
return false, fmt.Errorf("%s is less than or equal to %s", v, c.orig)
|
||||
}
|
||||
|
||||
if v.Major() > c.con.Major() {
|
||||
return true, nil
|
||||
} else if v.Major() < c.con.Major() {
|
||||
return false, fmt.Errorf("%s is less than or equal to %s", v, c.orig)
|
||||
} else if c.minorDirty {
|
||||
// This is a range case such as >11. When the version is something like
|
||||
// 11.1.0 is it not > 11. For that we would need 12 or higher
|
||||
return false, fmt.Errorf("%s is less than or equal to %s", v, c.orig)
|
||||
} else if c.patchDirty {
|
||||
// This is for ranges such as >11.1. A version of 11.1.1 is not greater
|
||||
// which one of 11.2.1 is greater
|
||||
eq = v.Minor() > c.con.Minor()
|
||||
if eq {
|
||||
return true, nil
|
||||
}
|
||||
return false, fmt.Errorf("%s is less than or equal to %s", v, c.orig)
|
||||
}
|
||||
|
||||
// If we have gotten here we are not comparing pre-preleases and can use the
|
||||
// Compare function to accomplish that.
|
||||
eq = v.Compare(c.con) == 1
|
||||
if eq {
|
||||
return true, nil
|
||||
}
|
||||
return false, fmt.Errorf("%s is less than or equal to %s", v, c.orig)
|
||||
}
|
||||
|
||||
func constraintLessThan(v *Version, c *constraint) (bool, error) {
|
||||
// If there is a pre-release on the version but the constraint isn't looking
|
||||
// for them assume that pre-releases are not compatible. See issue 21 for
|
||||
// more details.
|
||||
if v.Prerelease() != "" && c.con.Prerelease() == "" {
|
||||
return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v)
|
||||
}
|
||||
|
||||
eq := v.Compare(c.con) < 0
|
||||
if eq {
|
||||
return true, nil
|
||||
}
|
||||
return false, fmt.Errorf("%s is greater than or equal to %s", v, c.orig)
|
||||
}
|
||||
|
||||
func constraintGreaterThanEqual(v *Version, c *constraint) (bool, error) {
|
||||
|
||||
// If there is a pre-release on the version but the constraint isn't looking
|
||||
// for them assume that pre-releases are not compatible. See issue 21 for
|
||||
// more details.
|
||||
if v.Prerelease() != "" && c.con.Prerelease() == "" {
|
||||
return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v)
|
||||
}
|
||||
|
||||
eq := v.Compare(c.con) >= 0
|
||||
if eq {
|
||||
return true, nil
|
||||
}
|
||||
return false, fmt.Errorf("%s is less than %s", v, c.orig)
|
||||
}
|
||||
|
||||
func constraintLessThanEqual(v *Version, c *constraint) (bool, error) {
|
||||
// If there is a pre-release on the version but the constraint isn't looking
|
||||
// for them assume that pre-releases are not compatible. See issue 21 for
|
||||
// more details.
|
||||
if v.Prerelease() != "" && c.con.Prerelease() == "" {
|
||||
return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v)
|
||||
}
|
||||
|
||||
var eq bool
|
||||
|
||||
if !c.dirty {
|
||||
eq = v.Compare(c.con) <= 0
|
||||
if eq {
|
||||
return true, nil
|
||||
}
|
||||
return false, fmt.Errorf("%s is greater than %s", v, c.orig)
|
||||
}
|
||||
|
||||
if v.Major() > c.con.Major() {
|
||||
return false, fmt.Errorf("%s is greater than %s", v, c.orig)
|
||||
} else if v.Major() == c.con.Major() && v.Minor() > c.con.Minor() && !c.minorDirty {
|
||||
return false, fmt.Errorf("%s is greater than %s", v, c.orig)
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// ~*, ~>* --> >= 0.0.0 (any)
|
||||
// ~2, ~2.x, ~2.x.x, ~>2, ~>2.x ~>2.x.x --> >=2.0.0, <3.0.0
|
||||
// ~2.0, ~2.0.x, ~>2.0, ~>2.0.x --> >=2.0.0, <2.1.0
|
||||
// ~1.2, ~1.2.x, ~>1.2, ~>1.2.x --> >=1.2.0, <1.3.0
|
||||
// ~1.2.3, ~>1.2.3 --> >=1.2.3, <1.3.0
|
||||
// ~1.2.0, ~>1.2.0 --> >=1.2.0, <1.3.0
|
||||
func constraintTilde(v *Version, c *constraint) (bool, error) {
|
||||
// If there is a pre-release on the version but the constraint isn't looking
|
||||
// for them assume that pre-releases are not compatible. See issue 21 for
|
||||
// more details.
|
||||
if v.Prerelease() != "" && c.con.Prerelease() == "" {
|
||||
return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v)
|
||||
}
|
||||
|
||||
if v.LessThan(c.con) {
|
||||
return false, fmt.Errorf("%s is less than %s", v, c.orig)
|
||||
}
|
||||
|
||||
// ~0.0.0 is a special case where all constraints are accepted. It's
|
||||
// equivalent to >= 0.0.0.
|
||||
if c.con.Major() == 0 && c.con.Minor() == 0 && c.con.Patch() == 0 &&
|
||||
!c.minorDirty && !c.patchDirty {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
if v.Major() != c.con.Major() {
|
||||
return false, fmt.Errorf("%s does not have same major version as %s", v, c.orig)
|
||||
}
|
||||
|
||||
if v.Minor() != c.con.Minor() && !c.minorDirty {
|
||||
return false, fmt.Errorf("%s does not have same major and minor version as %s", v, c.orig)
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// When there is a .x (dirty) status it automatically opts in to ~. Otherwise
|
||||
// it's a straight =
|
||||
func constraintTildeOrEqual(v *Version, c *constraint) (bool, error) {
|
||||
// If there is a pre-release on the version but the constraint isn't looking
|
||||
// for them assume that pre-releases are not compatible. See issue 21 for
|
||||
// more details.
|
||||
if v.Prerelease() != "" && c.con.Prerelease() == "" {
|
||||
return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v)
|
||||
}
|
||||
|
||||
if c.dirty {
|
||||
return constraintTilde(v, c)
|
||||
}
|
||||
|
||||
eq := v.Equal(c.con)
|
||||
if eq {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
return false, fmt.Errorf("%s is not equal to %s", v, c.orig)
|
||||
}
|
||||
|
||||
// ^* --> (any)
|
||||
// ^1.2.3 --> >=1.2.3 <2.0.0
|
||||
// ^1.2 --> >=1.2.0 <2.0.0
|
||||
// ^1 --> >=1.0.0 <2.0.0
|
||||
// ^0.2.3 --> >=0.2.3 <0.3.0
|
||||
// ^0.2 --> >=0.2.0 <0.3.0
|
||||
// ^0.0.3 --> >=0.0.3 <0.0.4
|
||||
// ^0.0 --> >=0.0.0 <0.1.0
|
||||
// ^0 --> >=0.0.0 <1.0.0
|
||||
func constraintCaret(v *Version, c *constraint) (bool, error) {
|
||||
// If there is a pre-release on the version but the constraint isn't looking
|
||||
// for them assume that pre-releases are not compatible. See issue 21 for
|
||||
// more details.
|
||||
if v.Prerelease() != "" && c.con.Prerelease() == "" {
|
||||
return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v)
|
||||
}
|
||||
|
||||
// This less than handles prereleases
|
||||
if v.LessThan(c.con) {
|
||||
return false, fmt.Errorf("%s is less than %s", v, c.orig)
|
||||
}
|
||||
|
||||
var eq bool
|
||||
|
||||
// ^ when the major > 0 is >=x.y.z < x+1
|
||||
if c.con.Major() > 0 || c.minorDirty {
|
||||
|
||||
// ^ has to be within a major range for > 0. Everything less than was
|
||||
// filtered out with the LessThan call above. This filters out those
|
||||
// that greater but not within the same major range.
|
||||
eq = v.Major() == c.con.Major()
|
||||
if eq {
|
||||
return true, nil
|
||||
}
|
||||
return false, fmt.Errorf("%s does not have same major version as %s", v, c.orig)
|
||||
}
|
||||
|
||||
// ^ when the major is 0 and minor > 0 is >=0.y.z < 0.y+1
|
||||
if c.con.Major() == 0 && v.Major() > 0 {
|
||||
return false, fmt.Errorf("%s does not have same major version as %s", v, c.orig)
|
||||
}
|
||||
// If the con Minor is > 0 it is not dirty
|
||||
if c.con.Minor() > 0 || c.patchDirty {
|
||||
eq = v.Minor() == c.con.Minor()
|
||||
if eq {
|
||||
return true, nil
|
||||
}
|
||||
return false, fmt.Errorf("%s does not have same minor version as %s. Expected minor versions to match when constraint major version is 0", v, c.orig)
|
||||
}
|
||||
|
||||
// At this point the major is 0 and the minor is 0 and not dirty. The patch
|
||||
// is not dirty so we need to check if they are equal. If they are not equal
|
||||
eq = c.con.Patch() == v.Patch()
|
||||
if eq {
|
||||
return true, nil
|
||||
}
|
||||
return false, fmt.Errorf("%s does not equal %s. Expect version and constraint to equal when major and minor versions are 0", v, c.orig)
|
||||
}
|
||||
|
||||
func isX(x string) bool {
|
||||
switch x {
|
||||
case "x", "*", "X":
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func rewriteRange(i string) string {
|
||||
m := constraintRangeRegex.FindAllStringSubmatch(i, -1)
|
||||
if m == nil {
|
||||
return i
|
||||
}
|
||||
o := i
|
||||
for _, v := range m {
|
||||
t := fmt.Sprintf(">= %s, <= %s", v[1], v[11])
|
||||
o = strings.Replace(o, v[0], t, 1)
|
||||
}
|
||||
|
||||
return o
|
||||
}
|
||||
184
vendor/github.com/Masterminds/semver/v3/doc.go
generated
vendored
184
vendor/github.com/Masterminds/semver/v3/doc.go
generated
vendored
|
|
@ -1,184 +0,0 @@
|
|||
/*
|
||||
Package semver provides the ability to work with Semantic Versions (http://semver.org) in Go.
|
||||
|
||||
Specifically it provides the ability to:
|
||||
|
||||
* Parse semantic versions
|
||||
* Sort semantic versions
|
||||
* Check if a semantic version fits within a set of constraints
|
||||
* Optionally work with a `v` prefix
|
||||
|
||||
Parsing Semantic Versions
|
||||
|
||||
There are two functions that can parse semantic versions. The `StrictNewVersion`
|
||||
function only parses valid version 2 semantic versions as outlined in the
|
||||
specification. The `NewVersion` function attempts to coerce a version into a
|
||||
semantic version and parse it. For example, if there is a leading v or a version
|
||||
listed without all 3 parts (e.g. 1.2) it will attempt to coerce it into a valid
|
||||
semantic version (e.g., 1.2.0). In both cases a `Version` object is returned
|
||||
that can be sorted, compared, and used in constraints.
|
||||
|
||||
When parsing a version an optional error can be returned if there is an issue
|
||||
parsing the version. For example,
|
||||
|
||||
v, err := semver.NewVersion("1.2.3-beta.1+b345")
|
||||
|
||||
The version object has methods to get the parts of the version, compare it to
|
||||
other versions, convert the version back into a string, and get the original
|
||||
string. For more details please see the documentation
|
||||
at https://godoc.org/github.com/Masterminds/semver.
|
||||
|
||||
Sorting Semantic Versions
|
||||
|
||||
A set of versions can be sorted using the `sort` package from the standard library.
|
||||
For example,
|
||||
|
||||
raw := []string{"1.2.3", "1.0", "1.3", "2", "0.4.2",}
|
||||
vs := make([]*semver.Version, len(raw))
|
||||
for i, r := range raw {
|
||||
v, err := semver.NewVersion(r)
|
||||
if err != nil {
|
||||
t.Errorf("Error parsing version: %s", err)
|
||||
}
|
||||
|
||||
vs[i] = v
|
||||
}
|
||||
|
||||
sort.Sort(semver.Collection(vs))
|
||||
|
||||
Checking Version Constraints and Comparing Versions
|
||||
|
||||
There are two methods for comparing versions. One uses comparison methods on
|
||||
`Version` instances and the other is using Constraints. There are some important
|
||||
differences to notes between these two methods of comparison.
|
||||
|
||||
1. When two versions are compared using functions such as `Compare`, `LessThan`,
|
||||
and others it will follow the specification and always include prereleases
|
||||
within the comparison. It will provide an answer valid with the comparison
|
||||
spec section at https://semver.org/#spec-item-11
|
||||
2. When constraint checking is used for checks or validation it will follow a
|
||||
different set of rules that are common for ranges with tools like npm/js
|
||||
and Rust/Cargo. This includes considering prereleases to be invalid if the
|
||||
ranges does not include on. If you want to have it include pre-releases a
|
||||
simple solution is to include `-0` in your range.
|
||||
3. Constraint ranges can have some complex rules including the shorthard use of
|
||||
~ and ^. For more details on those see the options below.
|
||||
|
||||
There are differences between the two methods or checking versions because the
|
||||
comparison methods on `Version` follow the specification while comparison ranges
|
||||
are not part of the specification. Different packages and tools have taken it
|
||||
upon themselves to come up with range rules. This has resulted in differences.
|
||||
For example, npm/js and Cargo/Rust follow similar patterns which PHP has a
|
||||
different pattern for ^. The comparison features in this package follow the
|
||||
npm/js and Cargo/Rust lead because applications using it have followed similar
|
||||
patters with their versions.
|
||||
|
||||
Checking a version against version constraints is one of the most featureful
|
||||
parts of the package.
|
||||
|
||||
c, err := semver.NewConstraint(">= 1.2.3")
|
||||
if err != nil {
|
||||
// Handle constraint not being parsable.
|
||||
}
|
||||
|
||||
v, err := semver.NewVersion("1.3")
|
||||
if err != nil {
|
||||
// Handle version not being parsable.
|
||||
}
|
||||
// Check if the version meets the constraints. The a variable will be true.
|
||||
a := c.Check(v)
|
||||
|
||||
Basic Comparisons
|
||||
|
||||
There are two elements to the comparisons. First, a comparison string is a list
|
||||
of comma or space separated AND comparisons. These are then separated by || (OR)
|
||||
comparisons. For example, `">= 1.2 < 3.0.0 || >= 4.2.3"` is looking for a
|
||||
comparison that's greater than or equal to 1.2 and less than 3.0.0 or is
|
||||
greater than or equal to 4.2.3. This can also be written as
|
||||
`">= 1.2, < 3.0.0 || >= 4.2.3"`
|
||||
|
||||
The basic comparisons are:
|
||||
|
||||
* `=`: equal (aliased to no operator)
|
||||
* `!=`: not equal
|
||||
* `>`: greater than
|
||||
* `<`: less than
|
||||
* `>=`: greater than or equal to
|
||||
* `<=`: less than or equal to
|
||||
|
||||
Hyphen Range Comparisons
|
||||
|
||||
There are multiple methods to handle ranges and the first is hyphens ranges.
|
||||
These look like:
|
||||
|
||||
* `1.2 - 1.4.5` which is equivalent to `>= 1.2, <= 1.4.5`
|
||||
* `2.3.4 - 4.5` which is equivalent to `>= 2.3.4 <= 4.5`
|
||||
|
||||
Wildcards In Comparisons
|
||||
|
||||
The `x`, `X`, and `*` characters can be used as a wildcard character. This works
|
||||
for all comparison operators. When used on the `=` operator it falls
|
||||
back to the tilde operation. For example,
|
||||
|
||||
* `1.2.x` is equivalent to `>= 1.2.0 < 1.3.0`
|
||||
* `>= 1.2.x` is equivalent to `>= 1.2.0`
|
||||
* `<= 2.x` is equivalent to `<= 3`
|
||||
* `*` is equivalent to `>= 0.0.0`
|
||||
|
||||
Tilde Range Comparisons (Patch)
|
||||
|
||||
The tilde (`~`) comparison operator is for patch level ranges when a minor
|
||||
version is specified and major level changes when the minor number is missing.
|
||||
For example,
|
||||
|
||||
* `~1.2.3` is equivalent to `>= 1.2.3 < 1.3.0`
|
||||
* `~1` is equivalent to `>= 1, < 2`
|
||||
* `~2.3` is equivalent to `>= 2.3 < 2.4`
|
||||
* `~1.2.x` is equivalent to `>= 1.2.0 < 1.3.0`
|
||||
* `~1.x` is equivalent to `>= 1 < 2`
|
||||
|
||||
Caret Range Comparisons (Major)
|
||||
|
||||
The caret (`^`) comparison operator is for major level changes once a stable
|
||||
(1.0.0) release has occurred. Prior to a 1.0.0 release the minor versions acts
|
||||
as the API stability level. This is useful when comparisons of API versions as a
|
||||
major change is API breaking. For example,
|
||||
|
||||
* `^1.2.3` is equivalent to `>= 1.2.3, < 2.0.0`
|
||||
* `^1.2.x` is equivalent to `>= 1.2.0, < 2.0.0`
|
||||
* `^2.3` is equivalent to `>= 2.3, < 3`
|
||||
* `^2.x` is equivalent to `>= 2.0.0, < 3`
|
||||
* `^0.2.3` is equivalent to `>=0.2.3 <0.3.0`
|
||||
* `^0.2` is equivalent to `>=0.2.0 <0.3.0`
|
||||
* `^0.0.3` is equivalent to `>=0.0.3 <0.0.4`
|
||||
* `^0.0` is equivalent to `>=0.0.0 <0.1.0`
|
||||
* `^0` is equivalent to `>=0.0.0 <1.0.0`
|
||||
|
||||
Validation
|
||||
|
||||
In addition to testing a version against a constraint, a version can be validated
|
||||
against a constraint. When validation fails a slice of errors containing why a
|
||||
version didn't meet the constraint is returned. For example,
|
||||
|
||||
c, err := semver.NewConstraint("<= 1.2.3, >= 1.4")
|
||||
if err != nil {
|
||||
// Handle constraint not being parseable.
|
||||
}
|
||||
|
||||
v, _ := semver.NewVersion("1.3")
|
||||
if err != nil {
|
||||
// Handle version not being parseable.
|
||||
}
|
||||
|
||||
// Validate a version against a constraint.
|
||||
a, msgs := c.Validate(v)
|
||||
// a is false
|
||||
for _, m := range msgs {
|
||||
fmt.Println(m)
|
||||
|
||||
// Loops over the errors which would read
|
||||
// "1.3 is greater than 1.2.3"
|
||||
// "1.3 is less than 1.4"
|
||||
}
|
||||
*/
|
||||
package semver
|
||||
22
vendor/github.com/Masterminds/semver/v3/fuzz.go
generated
vendored
22
vendor/github.com/Masterminds/semver/v3/fuzz.go
generated
vendored
|
|
@ -1,22 +0,0 @@
|
|||
// +build gofuzz
|
||||
|
||||
package semver
|
||||
|
||||
func Fuzz(data []byte) int {
|
||||
d := string(data)
|
||||
|
||||
// Test NewVersion
|
||||
_, _ = NewVersion(d)
|
||||
|
||||
// Test StrictNewVersion
|
||||
_, _ = StrictNewVersion(d)
|
||||
|
||||
// Test NewConstraint
|
||||
_, _ = NewConstraint(d)
|
||||
|
||||
// The return value should be 0 normally, 1 if the priority in future tests
|
||||
// should be increased, and -1 if future tests should skip passing in that
|
||||
// data. We do not have a reason to change priority so 0 is always returned.
|
||||
// There are example tests that do this.
|
||||
return 0
|
||||
}
|
||||
606
vendor/github.com/Masterminds/semver/v3/version.go
generated
vendored
606
vendor/github.com/Masterminds/semver/v3/version.go
generated
vendored
|
|
@ -1,606 +0,0 @@
|
|||
package semver
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"database/sql/driver"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// The compiled version of the regex created at init() is cached here so it
|
||||
// only needs to be created once.
|
||||
var versionRegex *regexp.Regexp
|
||||
|
||||
var (
|
||||
// ErrInvalidSemVer is returned a version is found to be invalid when
|
||||
// being parsed.
|
||||
ErrInvalidSemVer = errors.New("Invalid Semantic Version")
|
||||
|
||||
// ErrEmptyString is returned when an empty string is passed in for parsing.
|
||||
ErrEmptyString = errors.New("Version string empty")
|
||||
|
||||
// ErrInvalidCharacters is returned when invalid characters are found as
|
||||
// part of a version
|
||||
ErrInvalidCharacters = errors.New("Invalid characters in version")
|
||||
|
||||
// ErrSegmentStartsZero is returned when a version segment starts with 0.
|
||||
// This is invalid in SemVer.
|
||||
ErrSegmentStartsZero = errors.New("Version segment starts with 0")
|
||||
|
||||
// ErrInvalidMetadata is returned when the metadata is an invalid format
|
||||
ErrInvalidMetadata = errors.New("Invalid Metadata string")
|
||||
|
||||
// ErrInvalidPrerelease is returned when the pre-release is an invalid format
|
||||
ErrInvalidPrerelease = errors.New("Invalid Prerelease string")
|
||||
)
|
||||
|
||||
// semVerRegex is the regular expression used to parse a semantic version.
|
||||
const semVerRegex string = `v?([0-9]+)(\.[0-9]+)?(\.[0-9]+)?` +
|
||||
`(-([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?` +
|
||||
`(\+([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?`
|
||||
|
||||
// Version represents a single semantic version.
|
||||
type Version struct {
|
||||
major, minor, patch uint64
|
||||
pre string
|
||||
metadata string
|
||||
original string
|
||||
}
|
||||
|
||||
func init() {
|
||||
versionRegex = regexp.MustCompile("^" + semVerRegex + "$")
|
||||
}
|
||||
|
||||
const num string = "0123456789"
|
||||
const allowed string = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-" + num
|
||||
|
||||
// StrictNewVersion parses a given version and returns an instance of Version or
|
||||
// an error if unable to parse the version. Only parses valid semantic versions.
|
||||
// Performs checking that can find errors within the version.
|
||||
// If you want to coerce a version, such as 1 or 1.2, and perse that as the 1.x
|
||||
// releases of semver provided use the NewSemver() function.
|
||||
func StrictNewVersion(v string) (*Version, error) {
|
||||
// Parsing here does not use RegEx in order to increase performance and reduce
|
||||
// allocations.
|
||||
|
||||
if len(v) == 0 {
|
||||
return nil, ErrEmptyString
|
||||
}
|
||||
|
||||
// Split the parts into [0]major, [1]minor, and [2]patch,prerelease,build
|
||||
parts := strings.SplitN(v, ".", 3)
|
||||
if len(parts) != 3 {
|
||||
return nil, ErrInvalidSemVer
|
||||
}
|
||||
|
||||
sv := &Version{
|
||||
original: v,
|
||||
}
|
||||
|
||||
// check for prerelease or build metadata
|
||||
var extra []string
|
||||
if strings.ContainsAny(parts[2], "-+") {
|
||||
// Start with the build metadata first as it needs to be on the right
|
||||
extra = strings.SplitN(parts[2], "+", 2)
|
||||
if len(extra) > 1 {
|
||||
// build metadata found
|
||||
sv.metadata = extra[1]
|
||||
parts[2] = extra[0]
|
||||
}
|
||||
|
||||
extra = strings.SplitN(parts[2], "-", 2)
|
||||
if len(extra) > 1 {
|
||||
// prerelease found
|
||||
sv.pre = extra[1]
|
||||
parts[2] = extra[0]
|
||||
}
|
||||
}
|
||||
|
||||
// Validate the number segments are valid. This includes only having positive
|
||||
// numbers and no leading 0's.
|
||||
for _, p := range parts {
|
||||
if !containsOnly(p, num) {
|
||||
return nil, ErrInvalidCharacters
|
||||
}
|
||||
|
||||
if len(p) > 1 && p[0] == '0' {
|
||||
return nil, ErrSegmentStartsZero
|
||||
}
|
||||
}
|
||||
|
||||
// Extract the major, minor, and patch elements onto the returned Version
|
||||
var err error
|
||||
sv.major, err = strconv.ParseUint(parts[0], 10, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sv.minor, err = strconv.ParseUint(parts[1], 10, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sv.patch, err = strconv.ParseUint(parts[2], 10, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// No prerelease or build metadata found so returning now as a fastpath.
|
||||
if sv.pre == "" && sv.metadata == "" {
|
||||
return sv, nil
|
||||
}
|
||||
|
||||
if sv.pre != "" {
|
||||
if err = validatePrerelease(sv.pre); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if sv.metadata != "" {
|
||||
if err = validateMetadata(sv.metadata); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return sv, nil
|
||||
}
|
||||
|
||||
// NewVersion parses a given version and returns an instance of Version or
|
||||
// an error if unable to parse the version. If the version is SemVer-ish it
|
||||
// attempts to convert it to SemVer. If you want to validate it was a strict
|
||||
// semantic version at parse time see StrictNewVersion().
|
||||
func NewVersion(v string) (*Version, error) {
|
||||
m := versionRegex.FindStringSubmatch(v)
|
||||
if m == nil {
|
||||
return nil, ErrInvalidSemVer
|
||||
}
|
||||
|
||||
sv := &Version{
|
||||
metadata: m[8],
|
||||
pre: m[5],
|
||||
original: v,
|
||||
}
|
||||
|
||||
var err error
|
||||
sv.major, err = strconv.ParseUint(m[1], 10, 64)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error parsing version segment: %s", err)
|
||||
}
|
||||
|
||||
if m[2] != "" {
|
||||
sv.minor, err = strconv.ParseUint(strings.TrimPrefix(m[2], "."), 10, 64)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error parsing version segment: %s", err)
|
||||
}
|
||||
} else {
|
||||
sv.minor = 0
|
||||
}
|
||||
|
||||
if m[3] != "" {
|
||||
sv.patch, err = strconv.ParseUint(strings.TrimPrefix(m[3], "."), 10, 64)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error parsing version segment: %s", err)
|
||||
}
|
||||
} else {
|
||||
sv.patch = 0
|
||||
}
|
||||
|
||||
// Perform some basic due diligence on the extra parts to ensure they are
|
||||
// valid.
|
||||
|
||||
if sv.pre != "" {
|
||||
if err = validatePrerelease(sv.pre); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if sv.metadata != "" {
|
||||
if err = validateMetadata(sv.metadata); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return sv, nil
|
||||
}
|
||||
|
||||
// MustParse parses a given version and panics on error.
|
||||
func MustParse(v string) *Version {
|
||||
sv, err := NewVersion(v)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return sv
|
||||
}
|
||||
|
||||
// String converts a Version object to a string.
|
||||
// Note, if the original version contained a leading v this version will not.
|
||||
// See the Original() method to retrieve the original value. Semantic Versions
|
||||
// don't contain a leading v per the spec. Instead it's optional on
|
||||
// implementation.
|
||||
func (v Version) String() string {
|
||||
var buf bytes.Buffer
|
||||
|
||||
fmt.Fprintf(&buf, "%d.%d.%d", v.major, v.minor, v.patch)
|
||||
if v.pre != "" {
|
||||
fmt.Fprintf(&buf, "-%s", v.pre)
|
||||
}
|
||||
if v.metadata != "" {
|
||||
fmt.Fprintf(&buf, "+%s", v.metadata)
|
||||
}
|
||||
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
// Original returns the original value passed in to be parsed.
|
||||
func (v *Version) Original() string {
|
||||
return v.original
|
||||
}
|
||||
|
||||
// Major returns the major version.
|
||||
func (v Version) Major() uint64 {
|
||||
return v.major
|
||||
}
|
||||
|
||||
// Minor returns the minor version.
|
||||
func (v Version) Minor() uint64 {
|
||||
return v.minor
|
||||
}
|
||||
|
||||
// Patch returns the patch version.
|
||||
func (v Version) Patch() uint64 {
|
||||
return v.patch
|
||||
}
|
||||
|
||||
// Prerelease returns the pre-release version.
|
||||
func (v Version) Prerelease() string {
|
||||
return v.pre
|
||||
}
|
||||
|
||||
// Metadata returns the metadata on the version.
|
||||
func (v Version) Metadata() string {
|
||||
return v.metadata
|
||||
}
|
||||
|
||||
// originalVPrefix returns the original 'v' prefix if any.
|
||||
func (v Version) originalVPrefix() string {
|
||||
|
||||
// Note, only lowercase v is supported as a prefix by the parser.
|
||||
if v.original != "" && v.original[:1] == "v" {
|
||||
return v.original[:1]
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// IncPatch produces the next patch version.
|
||||
// If the current version does not have prerelease/metadata information,
|
||||
// it unsets metadata and prerelease values, increments patch number.
|
||||
// If the current version has any of prerelease or metadata information,
|
||||
// it unsets both values and keeps current patch value
|
||||
func (v Version) IncPatch() Version {
|
||||
vNext := v
|
||||
// according to http://semver.org/#spec-item-9
|
||||
// Pre-release versions have a lower precedence than the associated normal version.
|
||||
// according to http://semver.org/#spec-item-10
|
||||
// Build metadata SHOULD be ignored when determining version precedence.
|
||||
if v.pre != "" {
|
||||
vNext.metadata = ""
|
||||
vNext.pre = ""
|
||||
} else {
|
||||
vNext.metadata = ""
|
||||
vNext.pre = ""
|
||||
vNext.patch = v.patch + 1
|
||||
}
|
||||
vNext.original = v.originalVPrefix() + "" + vNext.String()
|
||||
return vNext
|
||||
}
|
||||
|
||||
// IncMinor produces the next minor version.
|
||||
// Sets patch to 0.
|
||||
// Increments minor number.
|
||||
// Unsets metadata.
|
||||
// Unsets prerelease status.
|
||||
func (v Version) IncMinor() Version {
|
||||
vNext := v
|
||||
vNext.metadata = ""
|
||||
vNext.pre = ""
|
||||
vNext.patch = 0
|
||||
vNext.minor = v.minor + 1
|
||||
vNext.original = v.originalVPrefix() + "" + vNext.String()
|
||||
return vNext
|
||||
}
|
||||
|
||||
// IncMajor produces the next major version.
|
||||
// Sets patch to 0.
|
||||
// Sets minor to 0.
|
||||
// Increments major number.
|
||||
// Unsets metadata.
|
||||
// Unsets prerelease status.
|
||||
func (v Version) IncMajor() Version {
|
||||
vNext := v
|
||||
vNext.metadata = ""
|
||||
vNext.pre = ""
|
||||
vNext.patch = 0
|
||||
vNext.minor = 0
|
||||
vNext.major = v.major + 1
|
||||
vNext.original = v.originalVPrefix() + "" + vNext.String()
|
||||
return vNext
|
||||
}
|
||||
|
||||
// SetPrerelease defines the prerelease value.
|
||||
// Value must not include the required 'hyphen' prefix.
|
||||
func (v Version) SetPrerelease(prerelease string) (Version, error) {
|
||||
vNext := v
|
||||
if len(prerelease) > 0 {
|
||||
if err := validatePrerelease(prerelease); err != nil {
|
||||
return vNext, err
|
||||
}
|
||||
}
|
||||
vNext.pre = prerelease
|
||||
vNext.original = v.originalVPrefix() + "" + vNext.String()
|
||||
return vNext, nil
|
||||
}
|
||||
|
||||
// SetMetadata defines metadata value.
|
||||
// Value must not include the required 'plus' prefix.
|
||||
func (v Version) SetMetadata(metadata string) (Version, error) {
|
||||
vNext := v
|
||||
if len(metadata) > 0 {
|
||||
if err := validateMetadata(metadata); err != nil {
|
||||
return vNext, err
|
||||
}
|
||||
}
|
||||
vNext.metadata = metadata
|
||||
vNext.original = v.originalVPrefix() + "" + vNext.String()
|
||||
return vNext, nil
|
||||
}
|
||||
|
||||
// LessThan tests if one version is less than another one.
|
||||
func (v *Version) LessThan(o *Version) bool {
|
||||
return v.Compare(o) < 0
|
||||
}
|
||||
|
||||
// GreaterThan tests if one version is greater than another one.
|
||||
func (v *Version) GreaterThan(o *Version) bool {
|
||||
return v.Compare(o) > 0
|
||||
}
|
||||
|
||||
// Equal tests if two versions are equal to each other.
|
||||
// Note, versions can be equal with different metadata since metadata
|
||||
// is not considered part of the comparable version.
|
||||
func (v *Version) Equal(o *Version) bool {
|
||||
return v.Compare(o) == 0
|
||||
}
|
||||
|
||||
// Compare compares this version to another one. It returns -1, 0, or 1 if
|
||||
// the version smaller, equal, or larger than the other version.
|
||||
//
|
||||
// Versions are compared by X.Y.Z. Build metadata is ignored. Prerelease is
|
||||
// lower than the version without a prerelease. Compare always takes into account
|
||||
// prereleases. If you want to work with ranges using typical range syntaxes that
|
||||
// skip prereleases if the range is not looking for them use constraints.
|
||||
func (v *Version) Compare(o *Version) int {
|
||||
// Compare the major, minor, and patch version for differences. If a
|
||||
// difference is found return the comparison.
|
||||
if d := compareSegment(v.Major(), o.Major()); d != 0 {
|
||||
return d
|
||||
}
|
||||
if d := compareSegment(v.Minor(), o.Minor()); d != 0 {
|
||||
return d
|
||||
}
|
||||
if d := compareSegment(v.Patch(), o.Patch()); d != 0 {
|
||||
return d
|
||||
}
|
||||
|
||||
// At this point the major, minor, and patch versions are the same.
|
||||
ps := v.pre
|
||||
po := o.Prerelease()
|
||||
|
||||
if ps == "" && po == "" {
|
||||
return 0
|
||||
}
|
||||
if ps == "" {
|
||||
return 1
|
||||
}
|
||||
if po == "" {
|
||||
return -1
|
||||
}
|
||||
|
||||
return comparePrerelease(ps, po)
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements JSON.Unmarshaler interface.
|
||||
func (v *Version) UnmarshalJSON(b []byte) error {
|
||||
var s string
|
||||
if err := json.Unmarshal(b, &s); err != nil {
|
||||
return err
|
||||
}
|
||||
temp, err := NewVersion(s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
v.major = temp.major
|
||||
v.minor = temp.minor
|
||||
v.patch = temp.patch
|
||||
v.pre = temp.pre
|
||||
v.metadata = temp.metadata
|
||||
v.original = temp.original
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalJSON implements JSON.Marshaler interface.
|
||||
func (v Version) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(v.String())
|
||||
}
|
||||
|
||||
// Scan implements the SQL.Scanner interface.
|
||||
func (v *Version) Scan(value interface{}) error {
|
||||
var s string
|
||||
s, _ = value.(string)
|
||||
temp, err := NewVersion(s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
v.major = temp.major
|
||||
v.minor = temp.minor
|
||||
v.patch = temp.patch
|
||||
v.pre = temp.pre
|
||||
v.metadata = temp.metadata
|
||||
v.original = temp.original
|
||||
return nil
|
||||
}
|
||||
|
||||
// Value implements the Driver.Valuer interface.
|
||||
func (v Version) Value() (driver.Value, error) {
|
||||
return v.String(), nil
|
||||
}
|
||||
|
||||
func compareSegment(v, o uint64) int {
|
||||
if v < o {
|
||||
return -1
|
||||
}
|
||||
if v > o {
|
||||
return 1
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
func comparePrerelease(v, o string) int {
|
||||
|
||||
// split the prelease versions by their part. The separator, per the spec,
|
||||
// is a .
|
||||
sparts := strings.Split(v, ".")
|
||||
oparts := strings.Split(o, ".")
|
||||
|
||||
// Find the longer length of the parts to know how many loop iterations to
|
||||
// go through.
|
||||
slen := len(sparts)
|
||||
olen := len(oparts)
|
||||
|
||||
l := slen
|
||||
if olen > slen {
|
||||
l = olen
|
||||
}
|
||||
|
||||
// Iterate over each part of the prereleases to compare the differences.
|
||||
for i := 0; i < l; i++ {
|
||||
// Since the lentgh of the parts can be different we need to create
|
||||
// a placeholder. This is to avoid out of bounds issues.
|
||||
stemp := ""
|
||||
if i < slen {
|
||||
stemp = sparts[i]
|
||||
}
|
||||
|
||||
otemp := ""
|
||||
if i < olen {
|
||||
otemp = oparts[i]
|
||||
}
|
||||
|
||||
d := comparePrePart(stemp, otemp)
|
||||
if d != 0 {
|
||||
return d
|
||||
}
|
||||
}
|
||||
|
||||
// Reaching here means two versions are of equal value but have different
|
||||
// metadata (the part following a +). They are not identical in string form
|
||||
// but the version comparison finds them to be equal.
|
||||
return 0
|
||||
}
|
||||
|
||||
func comparePrePart(s, o string) int {
|
||||
// Fastpath if they are equal
|
||||
if s == o {
|
||||
return 0
|
||||
}
|
||||
|
||||
// When s or o are empty we can use the other in an attempt to determine
|
||||
// the response.
|
||||
if s == "" {
|
||||
if o != "" {
|
||||
return -1
|
||||
}
|
||||
return 1
|
||||
}
|
||||
|
||||
if o == "" {
|
||||
if s != "" {
|
||||
return 1
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
// When comparing strings "99" is greater than "103". To handle
|
||||
// cases like this we need to detect numbers and compare them. According
|
||||
// to the semver spec, numbers are always positive. If there is a - at the
|
||||
// start like -99 this is to be evaluated as an alphanum. numbers always
|
||||
// have precedence over alphanum. Parsing as Uints because negative numbers
|
||||
// are ignored.
|
||||
|
||||
oi, n1 := strconv.ParseUint(o, 10, 64)
|
||||
si, n2 := strconv.ParseUint(s, 10, 64)
|
||||
|
||||
// The case where both are strings compare the strings
|
||||
if n1 != nil && n2 != nil {
|
||||
if s > o {
|
||||
return 1
|
||||
}
|
||||
return -1
|
||||
} else if n1 != nil {
|
||||
// o is a string and s is a number
|
||||
return -1
|
||||
} else if n2 != nil {
|
||||
// s is a string and o is a number
|
||||
return 1
|
||||
}
|
||||
// Both are numbers
|
||||
if si > oi {
|
||||
return 1
|
||||
}
|
||||
return -1
|
||||
|
||||
}
|
||||
|
||||
// Like strings.ContainsAny but does an only instead of any.
|
||||
func containsOnly(s string, comp string) bool {
|
||||
return strings.IndexFunc(s, func(r rune) bool {
|
||||
return !strings.ContainsRune(comp, r)
|
||||
}) == -1
|
||||
}
|
||||
|
||||
// From the spec, "Identifiers MUST comprise only
|
||||
// ASCII alphanumerics and hyphen [0-9A-Za-z-]. Identifiers MUST NOT be empty.
|
||||
// Numeric identifiers MUST NOT include leading zeroes.". These segments can
|
||||
// be dot separated.
|
||||
func validatePrerelease(p string) error {
|
||||
eparts := strings.Split(p, ".")
|
||||
for _, p := range eparts {
|
||||
if containsOnly(p, num) {
|
||||
if len(p) > 1 && p[0] == '0' {
|
||||
return ErrSegmentStartsZero
|
||||
}
|
||||
} else if !containsOnly(p, allowed) {
|
||||
return ErrInvalidPrerelease
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// From the spec, "Build metadata MAY be denoted by
|
||||
// appending a plus sign and a series of dot separated identifiers immediately
|
||||
// following the patch or pre-release version. Identifiers MUST comprise only
|
||||
// ASCII alphanumerics and hyphen [0-9A-Za-z-]. Identifiers MUST NOT be empty."
|
||||
func validateMetadata(m string) error {
|
||||
eparts := strings.Split(m, ".")
|
||||
for _, p := range eparts {
|
||||
if !containsOnly(p, allowed) {
|
||||
return ErrInvalidMetadata
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
1
vendor/github.com/Masterminds/squirrel/.gitignore
generated
vendored
1
vendor/github.com/Masterminds/squirrel/.gitignore
generated
vendored
|
|
@ -1 +0,0 @@
|
|||
squirrel.test
|
||||
30
vendor/github.com/Masterminds/squirrel/.travis.yml
generated
vendored
30
vendor/github.com/Masterminds/squirrel/.travis.yml
generated
vendored
|
|
@ -1,30 +0,0 @@
|
|||
language: go
|
||||
|
||||
go:
|
||||
- 1.11.x
|
||||
- 1.12.x
|
||||
- 1.13.x
|
||||
|
||||
services:
|
||||
- mysql
|
||||
- postgresql
|
||||
|
||||
# Setting sudo access to false will let Travis CI use containers rather than
|
||||
# VMs to run the tests. For more details see:
|
||||
# - http://docs.travis-ci.com/user/workers/container-based-infrastructure/
|
||||
# - http://docs.travis-ci.com/user/workers/standard-infrastructure/
|
||||
sudo: false
|
||||
|
||||
before_script:
|
||||
- mysql -e 'CREATE DATABASE squirrel;'
|
||||
- psql -c 'CREATE DATABASE squirrel;' -U postgres
|
||||
|
||||
script:
|
||||
- go test
|
||||
- cd integration
|
||||
- go test -args -driver sqlite3
|
||||
- go test -args -driver mysql -dataSource travis@/squirrel
|
||||
- go test -args -driver postgres -dataSource 'postgres://postgres@localhost/squirrel?sslmode=disable'
|
||||
|
||||
notifications:
|
||||
irc: "irc.freenode.net#masterminds"
|
||||
23
vendor/github.com/Masterminds/squirrel/LICENSE.txt
generated
vendored
23
vendor/github.com/Masterminds/squirrel/LICENSE.txt
generated
vendored
|
|
@ -1,23 +0,0 @@
|
|||
Squirrel
|
||||
The Masterminds
|
||||
Copyright (C) 2014-2015, Lann Martin
|
||||
Copyright (C) 2015-2016, Google
|
||||
Copyright (C) 2015, Matt Farina and Matt Butcher
|
||||
|
||||
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.
|
||||
142
vendor/github.com/Masterminds/squirrel/README.md
generated
vendored
142
vendor/github.com/Masterminds/squirrel/README.md
generated
vendored
|
|
@ -1,142 +0,0 @@
|
|||
[](https://masterminds.github.io/stability/maintenance.html)
|
||||
### Squirrel is "complete".
|
||||
Bug fixes will still be merged (slowly). Bug reports are welcome, but I will not necessarily respond to them. If another fork (or substantially similar project) actively improves on what Squirrel does, let me know and I may link to it here.
|
||||
|
||||
|
||||
# Squirrel - fluent SQL generator for Go
|
||||
|
||||
```go
|
||||
import "github.com/Masterminds/squirrel"
|
||||
```
|
||||
|
||||
|
||||
[](https://godoc.org/github.com/Masterminds/squirrel)
|
||||
[](https://travis-ci.org/Masterminds/squirrel)
|
||||
|
||||
**Squirrel is not an ORM.** For an application of Squirrel, check out
|
||||
[structable, a table-struct mapper](https://github.com/Masterminds/structable)
|
||||
|
||||
|
||||
Squirrel helps you build SQL queries from composable parts:
|
||||
|
||||
```go
|
||||
import sq "github.com/Masterminds/squirrel"
|
||||
|
||||
users := sq.Select("*").From("users").Join("emails USING (email_id)")
|
||||
|
||||
active := users.Where(sq.Eq{"deleted_at": nil})
|
||||
|
||||
sql, args, err := active.ToSql()
|
||||
|
||||
sql == "SELECT * FROM users JOIN emails USING (email_id) WHERE deleted_at IS NULL"
|
||||
```
|
||||
|
||||
```go
|
||||
sql, args, err := sq.
|
||||
Insert("users").Columns("name", "age").
|
||||
Values("moe", 13).Values("larry", sq.Expr("? + 5", 12)).
|
||||
ToSql()
|
||||
|
||||
sql == "INSERT INTO users (name,age) VALUES (?,?),(?,? + 5)"
|
||||
```
|
||||
|
||||
Squirrel can also execute queries directly:
|
||||
|
||||
```go
|
||||
stooges := users.Where(sq.Eq{"username": []string{"moe", "larry", "curly", "shemp"}})
|
||||
three_stooges := stooges.Limit(3)
|
||||
rows, err := three_stooges.RunWith(db).Query()
|
||||
|
||||
// Behaves like:
|
||||
rows, err := db.Query("SELECT * FROM users WHERE username IN (?,?,?,?) LIMIT 3",
|
||||
"moe", "larry", "curly", "shemp")
|
||||
```
|
||||
|
||||
Squirrel makes conditional query building a breeze:
|
||||
|
||||
```go
|
||||
if len(q) > 0 {
|
||||
users = users.Where("name LIKE ?", fmt.Sprint("%", q, "%"))
|
||||
}
|
||||
```
|
||||
|
||||
Squirrel wants to make your life easier:
|
||||
|
||||
```go
|
||||
// StmtCache caches Prepared Stmts for you
|
||||
dbCache := sq.NewStmtCache(db)
|
||||
|
||||
// StatementBuilder keeps your syntax neat
|
||||
mydb := sq.StatementBuilder.RunWith(dbCache)
|
||||
select_users := mydb.Select("*").From("users")
|
||||
```
|
||||
|
||||
Squirrel loves PostgreSQL:
|
||||
|
||||
```go
|
||||
psql := sq.StatementBuilder.PlaceholderFormat(sq.Dollar)
|
||||
|
||||
// You use question marks for placeholders...
|
||||
sql, _, _ := psql.Select("*").From("elephants").Where("name IN (?,?)", "Dumbo", "Verna").ToSql()
|
||||
|
||||
/// ...squirrel replaces them using PlaceholderFormat.
|
||||
sql == "SELECT * FROM elephants WHERE name IN ($1,$2)"
|
||||
|
||||
|
||||
/// You can retrieve id ...
|
||||
query := sq.Insert("nodes").
|
||||
Columns("uuid", "type", "data").
|
||||
Values(node.Uuid, node.Type, node.Data).
|
||||
Suffix("RETURNING \"id\"").
|
||||
RunWith(m.db).
|
||||
PlaceholderFormat(sq.Dollar)
|
||||
|
||||
query.QueryRow().Scan(&node.id)
|
||||
```
|
||||
|
||||
You can escape question marks by inserting two question marks:
|
||||
|
||||
```sql
|
||||
SELECT * FROM nodes WHERE meta->'format' ??| array[?,?]
|
||||
```
|
||||
|
||||
will generate with the Dollar Placeholder:
|
||||
|
||||
```sql
|
||||
SELECT * FROM nodes WHERE meta->'format' ?| array[$1,$2]
|
||||
```
|
||||
|
||||
## FAQ
|
||||
|
||||
* **How can I build an IN query on composite keys / tuples, e.g. `WHERE (col1, col2) IN ((1,2),(3,4))`? ([#104](https://github.com/Masterminds/squirrel/issues/104))**
|
||||
|
||||
Squirrel does not explicitly support tuples, but you can get the same effect with e.g.:
|
||||
|
||||
```go
|
||||
sq.Or{
|
||||
sq.Eq{"col1": 1, "col2": 2},
|
||||
sq.Eq{"col1": 3, "col2": 4}}
|
||||
```
|
||||
|
||||
```sql
|
||||
WHERE (col1 = 1 AND col2 = 2) OR (col1 = 3 AND col2 = 4)
|
||||
```
|
||||
|
||||
(which should produce the same query plan as the tuple version)
|
||||
|
||||
* **Why doesn't `Eq{"mynumber": []uint8{1,2,3}}` turn into an `IN` query? ([#114](https://github.com/Masterminds/squirrel/issues/114))**
|
||||
|
||||
Values of type `[]byte` are handled specially by `database/sql`. In Go, [`byte` is just an alias of `uint8`](https://golang.org/pkg/builtin/#byte), so there is no way to distinguish `[]uint8` from `[]byte`.
|
||||
|
||||
* **Some features are poorly documented!**
|
||||
|
||||
This isn't a frequent complaints section!
|
||||
|
||||
* **Some features are poorly documented?**
|
||||
|
||||
Yes. The tests should be considered a part of the documentation; take a look at those for ideas on how to express more complex queries.
|
||||
|
||||
## License
|
||||
|
||||
Squirrel is released under the
|
||||
[MIT License](http://www.opensource.org/licenses/MIT).
|
||||
128
vendor/github.com/Masterminds/squirrel/case.go
generated
vendored
128
vendor/github.com/Masterminds/squirrel/case.go
generated
vendored
|
|
@ -1,128 +0,0 @@
|
|||
package squirrel
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
|
||||
"github.com/lann/builder"
|
||||
)
|
||||
|
||||
func init() {
|
||||
builder.Register(CaseBuilder{}, caseData{})
|
||||
}
|
||||
|
||||
// sqlizerBuffer is a helper that allows to write many Sqlizers one by one
|
||||
// without constant checks for errors that may come from Sqlizer
|
||||
type sqlizerBuffer struct {
|
||||
bytes.Buffer
|
||||
args []interface{}
|
||||
err error
|
||||
}
|
||||
|
||||
// WriteSql converts Sqlizer to SQL strings and writes it to buffer
|
||||
func (b *sqlizerBuffer) WriteSql(item Sqlizer) {
|
||||
if b.err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var str string
|
||||
var args []interface{}
|
||||
str, args, b.err = nestedToSql(item)
|
||||
|
||||
if b.err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
b.WriteString(str)
|
||||
b.WriteByte(' ')
|
||||
b.args = append(b.args, args...)
|
||||
}
|
||||
|
||||
func (b *sqlizerBuffer) ToSql() (string, []interface{}, error) {
|
||||
return b.String(), b.args, b.err
|
||||
}
|
||||
|
||||
// whenPart is a helper structure to describe SQLs "WHEN ... THEN ..." expression
|
||||
type whenPart struct {
|
||||
when Sqlizer
|
||||
then Sqlizer
|
||||
}
|
||||
|
||||
func newWhenPart(when interface{}, then interface{}) whenPart {
|
||||
return whenPart{newPart(when), newPart(then)}
|
||||
}
|
||||
|
||||
// caseData holds all the data required to build a CASE SQL construct
|
||||
type caseData struct {
|
||||
What Sqlizer
|
||||
WhenParts []whenPart
|
||||
Else Sqlizer
|
||||
}
|
||||
|
||||
// ToSql implements Sqlizer
|
||||
func (d *caseData) ToSql() (sqlStr string, args []interface{}, err error) {
|
||||
if len(d.WhenParts) == 0 {
|
||||
err = errors.New("case expression must contain at lease one WHEN clause")
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
sql := sqlizerBuffer{}
|
||||
|
||||
sql.WriteString("CASE ")
|
||||
if d.What != nil {
|
||||
sql.WriteSql(d.What)
|
||||
}
|
||||
|
||||
for _, p := range d.WhenParts {
|
||||
sql.WriteString("WHEN ")
|
||||
sql.WriteSql(p.when)
|
||||
sql.WriteString("THEN ")
|
||||
sql.WriteSql(p.then)
|
||||
}
|
||||
|
||||
if d.Else != nil {
|
||||
sql.WriteString("ELSE ")
|
||||
sql.WriteSql(d.Else)
|
||||
}
|
||||
|
||||
sql.WriteString("END")
|
||||
|
||||
return sql.ToSql()
|
||||
}
|
||||
|
||||
// CaseBuilder builds SQL CASE construct which could be used as parts of queries.
|
||||
type CaseBuilder builder.Builder
|
||||
|
||||
// ToSql builds the query into a SQL string and bound args.
|
||||
func (b CaseBuilder) ToSql() (string, []interface{}, error) {
|
||||
data := builder.GetStruct(b).(caseData)
|
||||
return data.ToSql()
|
||||
}
|
||||
|
||||
// MustSql builds the query into a SQL string and bound args.
|
||||
// It panics if there are any errors.
|
||||
func (b CaseBuilder) MustSql() (string, []interface{}) {
|
||||
sql, args, err := b.ToSql()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return sql, args
|
||||
}
|
||||
|
||||
// what sets optional value for CASE construct "CASE [value] ..."
|
||||
func (b CaseBuilder) what(expr interface{}) CaseBuilder {
|
||||
return builder.Set(b, "What", newPart(expr)).(CaseBuilder)
|
||||
}
|
||||
|
||||
// When adds "WHEN ... THEN ..." part to CASE construct
|
||||
func (b CaseBuilder) When(when interface{}, then interface{}) CaseBuilder {
|
||||
// TODO: performance hint: replace slice of WhenPart with just slice of parts
|
||||
// where even indices of the slice belong to "when"s and odd indices belong to "then"s
|
||||
return builder.Append(b, "WhenParts", newWhenPart(when, then)).(CaseBuilder)
|
||||
}
|
||||
|
||||
// What sets optional "ELSE ..." part for CASE construct
|
||||
func (b CaseBuilder) Else(expr interface{}) CaseBuilder {
|
||||
return builder.Set(b, "Else", newPart(expr)).(CaseBuilder)
|
||||
}
|
||||
191
vendor/github.com/Masterminds/squirrel/delete.go
generated
vendored
191
vendor/github.com/Masterminds/squirrel/delete.go
generated
vendored
|
|
@ -1,191 +0,0 @@
|
|||
package squirrel
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/lann/builder"
|
||||
)
|
||||
|
||||
type deleteData struct {
|
||||
PlaceholderFormat PlaceholderFormat
|
||||
RunWith BaseRunner
|
||||
Prefixes []Sqlizer
|
||||
From string
|
||||
WhereParts []Sqlizer
|
||||
OrderBys []string
|
||||
Limit string
|
||||
Offset string
|
||||
Suffixes []Sqlizer
|
||||
}
|
||||
|
||||
func (d *deleteData) Exec() (sql.Result, error) {
|
||||
if d.RunWith == nil {
|
||||
return nil, RunnerNotSet
|
||||
}
|
||||
return ExecWith(d.RunWith, d)
|
||||
}
|
||||
|
||||
func (d *deleteData) ToSql() (sqlStr string, args []interface{}, err error) {
|
||||
if len(d.From) == 0 {
|
||||
err = fmt.Errorf("delete statements must specify a From table")
|
||||
return
|
||||
}
|
||||
|
||||
sql := &bytes.Buffer{}
|
||||
|
||||
if len(d.Prefixes) > 0 {
|
||||
args, err = appendToSql(d.Prefixes, sql, " ", args)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
sql.WriteString(" ")
|
||||
}
|
||||
|
||||
sql.WriteString("DELETE FROM ")
|
||||
sql.WriteString(d.From)
|
||||
|
||||
if len(d.WhereParts) > 0 {
|
||||
sql.WriteString(" WHERE ")
|
||||
args, err = appendToSql(d.WhereParts, sql, " AND ", args)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if len(d.OrderBys) > 0 {
|
||||
sql.WriteString(" ORDER BY ")
|
||||
sql.WriteString(strings.Join(d.OrderBys, ", "))
|
||||
}
|
||||
|
||||
if len(d.Limit) > 0 {
|
||||
sql.WriteString(" LIMIT ")
|
||||
sql.WriteString(d.Limit)
|
||||
}
|
||||
|
||||
if len(d.Offset) > 0 {
|
||||
sql.WriteString(" OFFSET ")
|
||||
sql.WriteString(d.Offset)
|
||||
}
|
||||
|
||||
if len(d.Suffixes) > 0 {
|
||||
sql.WriteString(" ")
|
||||
args, err = appendToSql(d.Suffixes, sql, " ", args)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
sqlStr, err = d.PlaceholderFormat.ReplacePlaceholders(sql.String())
|
||||
return
|
||||
}
|
||||
|
||||
// Builder
|
||||
|
||||
// DeleteBuilder builds SQL DELETE statements.
|
||||
type DeleteBuilder builder.Builder
|
||||
|
||||
func init() {
|
||||
builder.Register(DeleteBuilder{}, deleteData{})
|
||||
}
|
||||
|
||||
// Format methods
|
||||
|
||||
// PlaceholderFormat sets PlaceholderFormat (e.g. Question or Dollar) for the
|
||||
// query.
|
||||
func (b DeleteBuilder) PlaceholderFormat(f PlaceholderFormat) DeleteBuilder {
|
||||
return builder.Set(b, "PlaceholderFormat", f).(DeleteBuilder)
|
||||
}
|
||||
|
||||
// Runner methods
|
||||
|
||||
// RunWith sets a Runner (like database/sql.DB) to be used with e.g. Exec.
|
||||
func (b DeleteBuilder) RunWith(runner BaseRunner) DeleteBuilder {
|
||||
return setRunWith(b, runner).(DeleteBuilder)
|
||||
}
|
||||
|
||||
// Exec builds and Execs the query with the Runner set by RunWith.
|
||||
func (b DeleteBuilder) Exec() (sql.Result, error) {
|
||||
data := builder.GetStruct(b).(deleteData)
|
||||
return data.Exec()
|
||||
}
|
||||
|
||||
// SQL methods
|
||||
|
||||
// ToSql builds the query into a SQL string and bound args.
|
||||
func (b DeleteBuilder) ToSql() (string, []interface{}, error) {
|
||||
data := builder.GetStruct(b).(deleteData)
|
||||
return data.ToSql()
|
||||
}
|
||||
|
||||
// MustSql builds the query into a SQL string and bound args.
|
||||
// It panics if there are any errors.
|
||||
func (b DeleteBuilder) MustSql() (string, []interface{}) {
|
||||
sql, args, err := b.ToSql()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return sql, args
|
||||
}
|
||||
|
||||
// Prefix adds an expression to the beginning of the query
|
||||
func (b DeleteBuilder) Prefix(sql string, args ...interface{}) DeleteBuilder {
|
||||
return b.PrefixExpr(Expr(sql, args...))
|
||||
}
|
||||
|
||||
// PrefixExpr adds an expression to the very beginning of the query
|
||||
func (b DeleteBuilder) PrefixExpr(expr Sqlizer) DeleteBuilder {
|
||||
return builder.Append(b, "Prefixes", expr).(DeleteBuilder)
|
||||
}
|
||||
|
||||
// From sets the table to be deleted from.
|
||||
func (b DeleteBuilder) From(from string) DeleteBuilder {
|
||||
return builder.Set(b, "From", from).(DeleteBuilder)
|
||||
}
|
||||
|
||||
// Where adds WHERE expressions to the query.
|
||||
//
|
||||
// See SelectBuilder.Where for more information.
|
||||
func (b DeleteBuilder) Where(pred interface{}, args ...interface{}) DeleteBuilder {
|
||||
return builder.Append(b, "WhereParts", newWherePart(pred, args...)).(DeleteBuilder)
|
||||
}
|
||||
|
||||
// OrderBy adds ORDER BY expressions to the query.
|
||||
func (b DeleteBuilder) OrderBy(orderBys ...string) DeleteBuilder {
|
||||
return builder.Extend(b, "OrderBys", orderBys).(DeleteBuilder)
|
||||
}
|
||||
|
||||
// Limit sets a LIMIT clause on the query.
|
||||
func (b DeleteBuilder) Limit(limit uint64) DeleteBuilder {
|
||||
return builder.Set(b, "Limit", fmt.Sprintf("%d", limit)).(DeleteBuilder)
|
||||
}
|
||||
|
||||
// Offset sets a OFFSET clause on the query.
|
||||
func (b DeleteBuilder) Offset(offset uint64) DeleteBuilder {
|
||||
return builder.Set(b, "Offset", fmt.Sprintf("%d", offset)).(DeleteBuilder)
|
||||
}
|
||||
|
||||
// Suffix adds an expression to the end of the query
|
||||
func (b DeleteBuilder) Suffix(sql string, args ...interface{}) DeleteBuilder {
|
||||
return b.SuffixExpr(Expr(sql, args...))
|
||||
}
|
||||
|
||||
// SuffixExpr adds an expression to the end of the query
|
||||
func (b DeleteBuilder) SuffixExpr(expr Sqlizer) DeleteBuilder {
|
||||
return builder.Append(b, "Suffixes", expr).(DeleteBuilder)
|
||||
}
|
||||
|
||||
func (b DeleteBuilder) Query() (*sql.Rows, error) {
|
||||
data := builder.GetStruct(b).(deleteData)
|
||||
return data.Query()
|
||||
}
|
||||
|
||||
func (d *deleteData) Query() (*sql.Rows, error) {
|
||||
if d.RunWith == nil {
|
||||
return nil, RunnerNotSet
|
||||
}
|
||||
return QueryWith(d.RunWith, d)
|
||||
}
|
||||
69
vendor/github.com/Masterminds/squirrel/delete_ctx.go
generated
vendored
69
vendor/github.com/Masterminds/squirrel/delete_ctx.go
generated
vendored
|
|
@ -1,69 +0,0 @@
|
|||
// +build go1.8
|
||||
|
||||
package squirrel
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
|
||||
"github.com/lann/builder"
|
||||
)
|
||||
|
||||
func (d *deleteData) ExecContext(ctx context.Context) (sql.Result, error) {
|
||||
if d.RunWith == nil {
|
||||
return nil, RunnerNotSet
|
||||
}
|
||||
ctxRunner, ok := d.RunWith.(ExecerContext)
|
||||
if !ok {
|
||||
return nil, NoContextSupport
|
||||
}
|
||||
return ExecContextWith(ctx, ctxRunner, d)
|
||||
}
|
||||
|
||||
func (d *deleteData) QueryContext(ctx context.Context) (*sql.Rows, error) {
|
||||
if d.RunWith == nil {
|
||||
return nil, RunnerNotSet
|
||||
}
|
||||
ctxRunner, ok := d.RunWith.(QueryerContext)
|
||||
if !ok {
|
||||
return nil, NoContextSupport
|
||||
}
|
||||
return QueryContextWith(ctx, ctxRunner, d)
|
||||
}
|
||||
|
||||
func (d *deleteData) QueryRowContext(ctx context.Context) RowScanner {
|
||||
if d.RunWith == nil {
|
||||
return &Row{err: RunnerNotSet}
|
||||
}
|
||||
queryRower, ok := d.RunWith.(QueryRowerContext)
|
||||
if !ok {
|
||||
if _, ok := d.RunWith.(QueryerContext); !ok {
|
||||
return &Row{err: RunnerNotQueryRunner}
|
||||
}
|
||||
return &Row{err: NoContextSupport}
|
||||
}
|
||||
return QueryRowContextWith(ctx, queryRower, d)
|
||||
}
|
||||
|
||||
// ExecContext builds and ExecContexts the query with the Runner set by RunWith.
|
||||
func (b DeleteBuilder) ExecContext(ctx context.Context) (sql.Result, error) {
|
||||
data := builder.GetStruct(b).(deleteData)
|
||||
return data.ExecContext(ctx)
|
||||
}
|
||||
|
||||
// QueryContext builds and QueryContexts the query with the Runner set by RunWith.
|
||||
func (b DeleteBuilder) QueryContext(ctx context.Context) (*sql.Rows, error) {
|
||||
data := builder.GetStruct(b).(deleteData)
|
||||
return data.QueryContext(ctx)
|
||||
}
|
||||
|
||||
// QueryRowContext builds and QueryRowContexts the query with the Runner set by RunWith.
|
||||
func (b DeleteBuilder) QueryRowContext(ctx context.Context) RowScanner {
|
||||
data := builder.GetStruct(b).(deleteData)
|
||||
return data.QueryRowContext(ctx)
|
||||
}
|
||||
|
||||
// ScanContext is a shortcut for QueryRowContext().Scan.
|
||||
func (b DeleteBuilder) ScanContext(ctx context.Context, dest ...interface{}) error {
|
||||
return b.QueryRowContext(ctx).Scan(dest...)
|
||||
}
|
||||
419
vendor/github.com/Masterminds/squirrel/expr.go
generated
vendored
419
vendor/github.com/Masterminds/squirrel/expr.go
generated
vendored
|
|
@ -1,419 +0,0 @@
|
|||
package squirrel
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"database/sql/driver"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
// Portable true/false literals.
|
||||
sqlTrue = "(1=1)"
|
||||
sqlFalse = "(1=0)"
|
||||
)
|
||||
|
||||
type expr struct {
|
||||
sql string
|
||||
args []interface{}
|
||||
}
|
||||
|
||||
// Expr builds an expression from a SQL fragment and arguments.
|
||||
//
|
||||
// Ex:
|
||||
// Expr("FROM_UNIXTIME(?)", t)
|
||||
func Expr(sql string, args ...interface{}) Sqlizer {
|
||||
return expr{sql: sql, args: args}
|
||||
}
|
||||
|
||||
func (e expr) ToSql() (sql string, args []interface{}, err error) {
|
||||
simple := true
|
||||
for _, arg := range e.args {
|
||||
if _, ok := arg.(Sqlizer); ok {
|
||||
simple = false
|
||||
}
|
||||
}
|
||||
if simple {
|
||||
return e.sql, e.args, nil
|
||||
}
|
||||
|
||||
buf := &bytes.Buffer{}
|
||||
ap := e.args
|
||||
sp := e.sql
|
||||
|
||||
var isql string
|
||||
var iargs []interface{}
|
||||
|
||||
for err == nil && len(ap) > 0 && len(sp) > 0 {
|
||||
i := strings.Index(sp, "?")
|
||||
if i < 0 {
|
||||
// no more placeholders
|
||||
break
|
||||
}
|
||||
if len(sp) > i+1 && sp[i+1:i+2] == "?" {
|
||||
// escaped "??"; append it and step past
|
||||
buf.WriteString(sp[:i+2])
|
||||
sp = sp[i+2:]
|
||||
continue
|
||||
}
|
||||
|
||||
if as, ok := ap[0].(Sqlizer); ok {
|
||||
// sqlizer argument; expand it and append the result
|
||||
isql, iargs, err = as.ToSql()
|
||||
buf.WriteString(sp[:i])
|
||||
buf.WriteString(isql)
|
||||
args = append(args, iargs...)
|
||||
} else {
|
||||
// normal argument; append it and the placeholder
|
||||
buf.WriteString(sp[:i+1])
|
||||
args = append(args, ap[0])
|
||||
}
|
||||
|
||||
// step past the argument and placeholder
|
||||
ap = ap[1:]
|
||||
sp = sp[i+1:]
|
||||
}
|
||||
|
||||
// append the remaining sql and arguments
|
||||
buf.WriteString(sp)
|
||||
return buf.String(), append(args, ap...), err
|
||||
}
|
||||
|
||||
type concatExpr []interface{}
|
||||
|
||||
func (ce concatExpr) ToSql() (sql string, args []interface{}, err error) {
|
||||
for _, part := range ce {
|
||||
switch p := part.(type) {
|
||||
case string:
|
||||
sql += p
|
||||
case Sqlizer:
|
||||
pSql, pArgs, err := p.ToSql()
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
sql += pSql
|
||||
args = append(args, pArgs...)
|
||||
default:
|
||||
return "", nil, fmt.Errorf("%#v is not a string or Sqlizer", part)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// ConcatExpr builds an expression by concatenating strings and other expressions.
|
||||
//
|
||||
// Ex:
|
||||
// name_expr := Expr("CONCAT(?, ' ', ?)", firstName, lastName)
|
||||
// ConcatExpr("COALESCE(full_name,", name_expr, ")")
|
||||
func ConcatExpr(parts ...interface{}) concatExpr {
|
||||
return concatExpr(parts)
|
||||
}
|
||||
|
||||
// aliasExpr helps to alias part of SQL query generated with underlying "expr"
|
||||
type aliasExpr struct {
|
||||
expr Sqlizer
|
||||
alias string
|
||||
}
|
||||
|
||||
// Alias allows to define alias for column in SelectBuilder. Useful when column is
|
||||
// defined as complex expression like IF or CASE
|
||||
// Ex:
|
||||
// .Column(Alias(caseStmt, "case_column"))
|
||||
func Alias(expr Sqlizer, alias string) aliasExpr {
|
||||
return aliasExpr{expr, alias}
|
||||
}
|
||||
|
||||
func (e aliasExpr) ToSql() (sql string, args []interface{}, err error) {
|
||||
sql, args, err = e.expr.ToSql()
|
||||
if err == nil {
|
||||
sql = fmt.Sprintf("(%s) AS %s", sql, e.alias)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Eq is syntactic sugar for use with Where/Having/Set methods.
|
||||
type Eq map[string]interface{}
|
||||
|
||||
func (eq Eq) toSQL(useNotOpr bool) (sql string, args []interface{}, err error) {
|
||||
if len(eq) == 0 {
|
||||
// Empty Sql{} evaluates to true.
|
||||
sql = sqlTrue
|
||||
return
|
||||
}
|
||||
|
||||
var (
|
||||
exprs []string
|
||||
equalOpr = "="
|
||||
inOpr = "IN"
|
||||
nullOpr = "IS"
|
||||
inEmptyExpr = sqlFalse
|
||||
)
|
||||
|
||||
if useNotOpr {
|
||||
equalOpr = "<>"
|
||||
inOpr = "NOT IN"
|
||||
nullOpr = "IS NOT"
|
||||
inEmptyExpr = sqlTrue
|
||||
}
|
||||
|
||||
sortedKeys := getSortedKeys(eq)
|
||||
for _, key := range sortedKeys {
|
||||
var expr string
|
||||
val := eq[key]
|
||||
|
||||
switch v := val.(type) {
|
||||
case driver.Valuer:
|
||||
if val, err = v.Value(); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
r := reflect.ValueOf(val)
|
||||
if r.Kind() == reflect.Ptr {
|
||||
if r.IsNil() {
|
||||
val = nil
|
||||
} else {
|
||||
val = r.Elem().Interface()
|
||||
}
|
||||
}
|
||||
|
||||
if val == nil {
|
||||
expr = fmt.Sprintf("%s %s NULL", key, nullOpr)
|
||||
} else {
|
||||
if isListType(val) {
|
||||
valVal := reflect.ValueOf(val)
|
||||
if valVal.Len() == 0 {
|
||||
expr = inEmptyExpr
|
||||
if args == nil {
|
||||
args = []interface{}{}
|
||||
}
|
||||
} else {
|
||||
for i := 0; i < valVal.Len(); i++ {
|
||||
args = append(args, valVal.Index(i).Interface())
|
||||
}
|
||||
expr = fmt.Sprintf("%s %s (%s)", key, inOpr, Placeholders(valVal.Len()))
|
||||
}
|
||||
} else {
|
||||
expr = fmt.Sprintf("%s %s ?", key, equalOpr)
|
||||
args = append(args, val)
|
||||
}
|
||||
}
|
||||
exprs = append(exprs, expr)
|
||||
}
|
||||
sql = strings.Join(exprs, " AND ")
|
||||
return
|
||||
}
|
||||
|
||||
func (eq Eq) ToSql() (sql string, args []interface{}, err error) {
|
||||
return eq.toSQL(false)
|
||||
}
|
||||
|
||||
// NotEq is syntactic sugar for use with Where/Having/Set methods.
|
||||
// Ex:
|
||||
// .Where(NotEq{"id": 1}) == "id <> 1"
|
||||
type NotEq Eq
|
||||
|
||||
func (neq NotEq) ToSql() (sql string, args []interface{}, err error) {
|
||||
return Eq(neq).toSQL(true)
|
||||
}
|
||||
|
||||
// Like is syntactic sugar for use with LIKE conditions.
|
||||
// Ex:
|
||||
// .Where(Like{"name": "%irrel"})
|
||||
type Like map[string]interface{}
|
||||
|
||||
func (lk Like) toSql(opr string) (sql string, args []interface{}, err error) {
|
||||
var exprs []string
|
||||
for key, val := range lk {
|
||||
expr := ""
|
||||
|
||||
switch v := val.(type) {
|
||||
case driver.Valuer:
|
||||
if val, err = v.Value(); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if val == nil {
|
||||
err = fmt.Errorf("cannot use null with like operators")
|
||||
return
|
||||
} else {
|
||||
if isListType(val) {
|
||||
err = fmt.Errorf("cannot use array or slice with like operators")
|
||||
return
|
||||
} else {
|
||||
expr = fmt.Sprintf("%s %s ?", key, opr)
|
||||
args = append(args, val)
|
||||
}
|
||||
}
|
||||
exprs = append(exprs, expr)
|
||||
}
|
||||
sql = strings.Join(exprs, " AND ")
|
||||
return
|
||||
}
|
||||
|
||||
func (lk Like) ToSql() (sql string, args []interface{}, err error) {
|
||||
return lk.toSql("LIKE")
|
||||
}
|
||||
|
||||
// NotLike is syntactic sugar for use with LIKE conditions.
|
||||
// Ex:
|
||||
// .Where(NotLike{"name": "%irrel"})
|
||||
type NotLike Like
|
||||
|
||||
func (nlk NotLike) ToSql() (sql string, args []interface{}, err error) {
|
||||
return Like(nlk).toSql("NOT LIKE")
|
||||
}
|
||||
|
||||
// ILike is syntactic sugar for use with ILIKE conditions.
|
||||
// Ex:
|
||||
// .Where(ILike{"name": "sq%"})
|
||||
type ILike Like
|
||||
|
||||
func (ilk ILike) ToSql() (sql string, args []interface{}, err error) {
|
||||
return Like(ilk).toSql("ILIKE")
|
||||
}
|
||||
|
||||
// NotILike is syntactic sugar for use with ILIKE conditions.
|
||||
// Ex:
|
||||
// .Where(NotILike{"name": "sq%"})
|
||||
type NotILike Like
|
||||
|
||||
func (nilk NotILike) ToSql() (sql string, args []interface{}, err error) {
|
||||
return Like(nilk).toSql("NOT ILIKE")
|
||||
}
|
||||
|
||||
// Lt is syntactic sugar for use with Where/Having/Set methods.
|
||||
// Ex:
|
||||
// .Where(Lt{"id": 1})
|
||||
type Lt map[string]interface{}
|
||||
|
||||
func (lt Lt) toSql(opposite, orEq bool) (sql string, args []interface{}, err error) {
|
||||
var (
|
||||
exprs []string
|
||||
opr = "<"
|
||||
)
|
||||
|
||||
if opposite {
|
||||
opr = ">"
|
||||
}
|
||||
|
||||
if orEq {
|
||||
opr = fmt.Sprintf("%s%s", opr, "=")
|
||||
}
|
||||
|
||||
sortedKeys := getSortedKeys(lt)
|
||||
for _, key := range sortedKeys {
|
||||
var expr string
|
||||
val := lt[key]
|
||||
|
||||
switch v := val.(type) {
|
||||
case driver.Valuer:
|
||||
if val, err = v.Value(); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if val == nil {
|
||||
err = fmt.Errorf("cannot use null with less than or greater than operators")
|
||||
return
|
||||
}
|
||||
if isListType(val) {
|
||||
err = fmt.Errorf("cannot use array or slice with less than or greater than operators")
|
||||
return
|
||||
}
|
||||
expr = fmt.Sprintf("%s %s ?", key, opr)
|
||||
args = append(args, val)
|
||||
|
||||
exprs = append(exprs, expr)
|
||||
}
|
||||
sql = strings.Join(exprs, " AND ")
|
||||
return
|
||||
}
|
||||
|
||||
func (lt Lt) ToSql() (sql string, args []interface{}, err error) {
|
||||
return lt.toSql(false, false)
|
||||
}
|
||||
|
||||
// LtOrEq is syntactic sugar for use with Where/Having/Set methods.
|
||||
// Ex:
|
||||
// .Where(LtOrEq{"id": 1}) == "id <= 1"
|
||||
type LtOrEq Lt
|
||||
|
||||
func (ltOrEq LtOrEq) ToSql() (sql string, args []interface{}, err error) {
|
||||
return Lt(ltOrEq).toSql(false, true)
|
||||
}
|
||||
|
||||
// Gt is syntactic sugar for use with Where/Having/Set methods.
|
||||
// Ex:
|
||||
// .Where(Gt{"id": 1}) == "id > 1"
|
||||
type Gt Lt
|
||||
|
||||
func (gt Gt) ToSql() (sql string, args []interface{}, err error) {
|
||||
return Lt(gt).toSql(true, false)
|
||||
}
|
||||
|
||||
// GtOrEq is syntactic sugar for use with Where/Having/Set methods.
|
||||
// Ex:
|
||||
// .Where(GtOrEq{"id": 1}) == "id >= 1"
|
||||
type GtOrEq Lt
|
||||
|
||||
func (gtOrEq GtOrEq) ToSql() (sql string, args []interface{}, err error) {
|
||||
return Lt(gtOrEq).toSql(true, true)
|
||||
}
|
||||
|
||||
type conj []Sqlizer
|
||||
|
||||
func (c conj) join(sep, defaultExpr string) (sql string, args []interface{}, err error) {
|
||||
if len(c) == 0 {
|
||||
return defaultExpr, []interface{}{}, nil
|
||||
}
|
||||
var sqlParts []string
|
||||
for _, sqlizer := range c {
|
||||
partSQL, partArgs, err := nestedToSql(sqlizer)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
if partSQL != "" {
|
||||
sqlParts = append(sqlParts, partSQL)
|
||||
args = append(args, partArgs...)
|
||||
}
|
||||
}
|
||||
if len(sqlParts) > 0 {
|
||||
sql = fmt.Sprintf("(%s)", strings.Join(sqlParts, sep))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// And conjunction Sqlizers
|
||||
type And conj
|
||||
|
||||
func (a And) ToSql() (string, []interface{}, error) {
|
||||
return conj(a).join(" AND ", sqlTrue)
|
||||
}
|
||||
|
||||
// Or conjunction Sqlizers
|
||||
type Or conj
|
||||
|
||||
func (o Or) ToSql() (string, []interface{}, error) {
|
||||
return conj(o).join(" OR ", sqlFalse)
|
||||
}
|
||||
|
||||
func getSortedKeys(exp map[string]interface{}) []string {
|
||||
sortedKeys := make([]string, 0, len(exp))
|
||||
for k := range exp {
|
||||
sortedKeys = append(sortedKeys, k)
|
||||
}
|
||||
sort.Strings(sortedKeys)
|
||||
return sortedKeys
|
||||
}
|
||||
|
||||
func isListType(val interface{}) bool {
|
||||
if driver.IsValue(val) {
|
||||
return false
|
||||
}
|
||||
valVal := reflect.ValueOf(val)
|
||||
return valVal.Kind() == reflect.Array || valVal.Kind() == reflect.Slice
|
||||
}
|
||||
298
vendor/github.com/Masterminds/squirrel/insert.go
generated
vendored
298
vendor/github.com/Masterminds/squirrel/insert.go
generated
vendored
|
|
@ -1,298 +0,0 @@
|
|||
package squirrel
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/lann/builder"
|
||||
)
|
||||
|
||||
type insertData struct {
|
||||
PlaceholderFormat PlaceholderFormat
|
||||
RunWith BaseRunner
|
||||
Prefixes []Sqlizer
|
||||
StatementKeyword string
|
||||
Options []string
|
||||
Into string
|
||||
Columns []string
|
||||
Values [][]interface{}
|
||||
Suffixes []Sqlizer
|
||||
Select *SelectBuilder
|
||||
}
|
||||
|
||||
func (d *insertData) Exec() (sql.Result, error) {
|
||||
if d.RunWith == nil {
|
||||
return nil, RunnerNotSet
|
||||
}
|
||||
return ExecWith(d.RunWith, d)
|
||||
}
|
||||
|
||||
func (d *insertData) Query() (*sql.Rows, error) {
|
||||
if d.RunWith == nil {
|
||||
return nil, RunnerNotSet
|
||||
}
|
||||
return QueryWith(d.RunWith, d)
|
||||
}
|
||||
|
||||
func (d *insertData) QueryRow() RowScanner {
|
||||
if d.RunWith == nil {
|
||||
return &Row{err: RunnerNotSet}
|
||||
}
|
||||
queryRower, ok := d.RunWith.(QueryRower)
|
||||
if !ok {
|
||||
return &Row{err: RunnerNotQueryRunner}
|
||||
}
|
||||
return QueryRowWith(queryRower, d)
|
||||
}
|
||||
|
||||
func (d *insertData) ToSql() (sqlStr string, args []interface{}, err error) {
|
||||
if len(d.Into) == 0 {
|
||||
err = errors.New("insert statements must specify a table")
|
||||
return
|
||||
}
|
||||
if len(d.Values) == 0 && d.Select == nil {
|
||||
err = errors.New("insert statements must have at least one set of values or select clause")
|
||||
return
|
||||
}
|
||||
|
||||
sql := &bytes.Buffer{}
|
||||
|
||||
if len(d.Prefixes) > 0 {
|
||||
args, err = appendToSql(d.Prefixes, sql, " ", args)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
sql.WriteString(" ")
|
||||
}
|
||||
|
||||
if d.StatementKeyword == "" {
|
||||
sql.WriteString("INSERT ")
|
||||
} else {
|
||||
sql.WriteString(d.StatementKeyword)
|
||||
sql.WriteString(" ")
|
||||
}
|
||||
|
||||
if len(d.Options) > 0 {
|
||||
sql.WriteString(strings.Join(d.Options, " "))
|
||||
sql.WriteString(" ")
|
||||
}
|
||||
|
||||
sql.WriteString("INTO ")
|
||||
sql.WriteString(d.Into)
|
||||
sql.WriteString(" ")
|
||||
|
||||
if len(d.Columns) > 0 {
|
||||
sql.WriteString("(")
|
||||
sql.WriteString(strings.Join(d.Columns, ","))
|
||||
sql.WriteString(") ")
|
||||
}
|
||||
|
||||
if d.Select != nil {
|
||||
args, err = d.appendSelectToSQL(sql, args)
|
||||
} else {
|
||||
args, err = d.appendValuesToSQL(sql, args)
|
||||
}
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if len(d.Suffixes) > 0 {
|
||||
sql.WriteString(" ")
|
||||
args, err = appendToSql(d.Suffixes, sql, " ", args)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
sqlStr, err = d.PlaceholderFormat.ReplacePlaceholders(sql.String())
|
||||
return
|
||||
}
|
||||
|
||||
func (d *insertData) appendValuesToSQL(w io.Writer, args []interface{}) ([]interface{}, error) {
|
||||
if len(d.Values) == 0 {
|
||||
return args, errors.New("values for insert statements are not set")
|
||||
}
|
||||
|
||||
io.WriteString(w, "VALUES ")
|
||||
|
||||
valuesStrings := make([]string, len(d.Values))
|
||||
for r, row := range d.Values {
|
||||
valueStrings := make([]string, len(row))
|
||||
for v, val := range row {
|
||||
if vs, ok := val.(Sqlizer); ok {
|
||||
vsql, vargs, err := vs.ToSql()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
valueStrings[v] = vsql
|
||||
args = append(args, vargs...)
|
||||
} else {
|
||||
valueStrings[v] = "?"
|
||||
args = append(args, val)
|
||||
}
|
||||
}
|
||||
valuesStrings[r] = fmt.Sprintf("(%s)", strings.Join(valueStrings, ","))
|
||||
}
|
||||
|
||||
io.WriteString(w, strings.Join(valuesStrings, ","))
|
||||
|
||||
return args, nil
|
||||
}
|
||||
|
||||
func (d *insertData) appendSelectToSQL(w io.Writer, args []interface{}) ([]interface{}, error) {
|
||||
if d.Select == nil {
|
||||
return args, errors.New("select clause for insert statements are not set")
|
||||
}
|
||||
|
||||
selectClause, sArgs, err := d.Select.ToSql()
|
||||
if err != nil {
|
||||
return args, err
|
||||
}
|
||||
|
||||
io.WriteString(w, selectClause)
|
||||
args = append(args, sArgs...)
|
||||
|
||||
return args, nil
|
||||
}
|
||||
|
||||
// Builder
|
||||
|
||||
// InsertBuilder builds SQL INSERT statements.
|
||||
type InsertBuilder builder.Builder
|
||||
|
||||
func init() {
|
||||
builder.Register(InsertBuilder{}, insertData{})
|
||||
}
|
||||
|
||||
// Format methods
|
||||
|
||||
// PlaceholderFormat sets PlaceholderFormat (e.g. Question or Dollar) for the
|
||||
// query.
|
||||
func (b InsertBuilder) PlaceholderFormat(f PlaceholderFormat) InsertBuilder {
|
||||
return builder.Set(b, "PlaceholderFormat", f).(InsertBuilder)
|
||||
}
|
||||
|
||||
// Runner methods
|
||||
|
||||
// RunWith sets a Runner (like database/sql.DB) to be used with e.g. Exec.
|
||||
func (b InsertBuilder) RunWith(runner BaseRunner) InsertBuilder {
|
||||
return setRunWith(b, runner).(InsertBuilder)
|
||||
}
|
||||
|
||||
// Exec builds and Execs the query with the Runner set by RunWith.
|
||||
func (b InsertBuilder) Exec() (sql.Result, error) {
|
||||
data := builder.GetStruct(b).(insertData)
|
||||
return data.Exec()
|
||||
}
|
||||
|
||||
// Query builds and Querys the query with the Runner set by RunWith.
|
||||
func (b InsertBuilder) Query() (*sql.Rows, error) {
|
||||
data := builder.GetStruct(b).(insertData)
|
||||
return data.Query()
|
||||
}
|
||||
|
||||
// QueryRow builds and QueryRows the query with the Runner set by RunWith.
|
||||
func (b InsertBuilder) QueryRow() RowScanner {
|
||||
data := builder.GetStruct(b).(insertData)
|
||||
return data.QueryRow()
|
||||
}
|
||||
|
||||
// Scan is a shortcut for QueryRow().Scan.
|
||||
func (b InsertBuilder) Scan(dest ...interface{}) error {
|
||||
return b.QueryRow().Scan(dest...)
|
||||
}
|
||||
|
||||
// SQL methods
|
||||
|
||||
// ToSql builds the query into a SQL string and bound args.
|
||||
func (b InsertBuilder) ToSql() (string, []interface{}, error) {
|
||||
data := builder.GetStruct(b).(insertData)
|
||||
return data.ToSql()
|
||||
}
|
||||
|
||||
// MustSql builds the query into a SQL string and bound args.
|
||||
// It panics if there are any errors.
|
||||
func (b InsertBuilder) MustSql() (string, []interface{}) {
|
||||
sql, args, err := b.ToSql()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return sql, args
|
||||
}
|
||||
|
||||
// Prefix adds an expression to the beginning of the query
|
||||
func (b InsertBuilder) Prefix(sql string, args ...interface{}) InsertBuilder {
|
||||
return b.PrefixExpr(Expr(sql, args...))
|
||||
}
|
||||
|
||||
// PrefixExpr adds an expression to the very beginning of the query
|
||||
func (b InsertBuilder) PrefixExpr(expr Sqlizer) InsertBuilder {
|
||||
return builder.Append(b, "Prefixes", expr).(InsertBuilder)
|
||||
}
|
||||
|
||||
// Options adds keyword options before the INTO clause of the query.
|
||||
func (b InsertBuilder) Options(options ...string) InsertBuilder {
|
||||
return builder.Extend(b, "Options", options).(InsertBuilder)
|
||||
}
|
||||
|
||||
// Into sets the INTO clause of the query.
|
||||
func (b InsertBuilder) Into(from string) InsertBuilder {
|
||||
return builder.Set(b, "Into", from).(InsertBuilder)
|
||||
}
|
||||
|
||||
// Columns adds insert columns to the query.
|
||||
func (b InsertBuilder) Columns(columns ...string) InsertBuilder {
|
||||
return builder.Extend(b, "Columns", columns).(InsertBuilder)
|
||||
}
|
||||
|
||||
// Values adds a single row's values to the query.
|
||||
func (b InsertBuilder) Values(values ...interface{}) InsertBuilder {
|
||||
return builder.Append(b, "Values", values).(InsertBuilder)
|
||||
}
|
||||
|
||||
// Suffix adds an expression to the end of the query
|
||||
func (b InsertBuilder) Suffix(sql string, args ...interface{}) InsertBuilder {
|
||||
return b.SuffixExpr(Expr(sql, args...))
|
||||
}
|
||||
|
||||
// SuffixExpr adds an expression to the end of the query
|
||||
func (b InsertBuilder) SuffixExpr(expr Sqlizer) InsertBuilder {
|
||||
return builder.Append(b, "Suffixes", expr).(InsertBuilder)
|
||||
}
|
||||
|
||||
// SetMap set columns and values for insert builder from a map of column name and value
|
||||
// note that it will reset all previous columns and values was set if any
|
||||
func (b InsertBuilder) SetMap(clauses map[string]interface{}) InsertBuilder {
|
||||
// Keep the columns in a consistent order by sorting the column key string.
|
||||
cols := make([]string, 0, len(clauses))
|
||||
for col := range clauses {
|
||||
cols = append(cols, col)
|
||||
}
|
||||
sort.Strings(cols)
|
||||
|
||||
vals := make([]interface{}, 0, len(clauses))
|
||||
for _, col := range cols {
|
||||
vals = append(vals, clauses[col])
|
||||
}
|
||||
|
||||
b = builder.Set(b, "Columns", cols).(InsertBuilder)
|
||||
b = builder.Set(b, "Values", [][]interface{}{vals}).(InsertBuilder)
|
||||
|
||||
return b
|
||||
}
|
||||
|
||||
// Select set Select clause for insert query
|
||||
// If Values and Select are used, then Select has higher priority
|
||||
func (b InsertBuilder) Select(sb SelectBuilder) InsertBuilder {
|
||||
return builder.Set(b, "Select", &sb).(InsertBuilder)
|
||||
}
|
||||
|
||||
func (b InsertBuilder) statementKeyword(keyword string) InsertBuilder {
|
||||
return builder.Set(b, "StatementKeyword", keyword).(InsertBuilder)
|
||||
}
|
||||
69
vendor/github.com/Masterminds/squirrel/insert_ctx.go
generated
vendored
69
vendor/github.com/Masterminds/squirrel/insert_ctx.go
generated
vendored
|
|
@ -1,69 +0,0 @@
|
|||
// +build go1.8
|
||||
|
||||
package squirrel
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
|
||||
"github.com/lann/builder"
|
||||
)
|
||||
|
||||
func (d *insertData) ExecContext(ctx context.Context) (sql.Result, error) {
|
||||
if d.RunWith == nil {
|
||||
return nil, RunnerNotSet
|
||||
}
|
||||
ctxRunner, ok := d.RunWith.(ExecerContext)
|
||||
if !ok {
|
||||
return nil, NoContextSupport
|
||||
}
|
||||
return ExecContextWith(ctx, ctxRunner, d)
|
||||
}
|
||||
|
||||
func (d *insertData) QueryContext(ctx context.Context) (*sql.Rows, error) {
|
||||
if d.RunWith == nil {
|
||||
return nil, RunnerNotSet
|
||||
}
|
||||
ctxRunner, ok := d.RunWith.(QueryerContext)
|
||||
if !ok {
|
||||
return nil, NoContextSupport
|
||||
}
|
||||
return QueryContextWith(ctx, ctxRunner, d)
|
||||
}
|
||||
|
||||
func (d *insertData) QueryRowContext(ctx context.Context) RowScanner {
|
||||
if d.RunWith == nil {
|
||||
return &Row{err: RunnerNotSet}
|
||||
}
|
||||
queryRower, ok := d.RunWith.(QueryRowerContext)
|
||||
if !ok {
|
||||
if _, ok := d.RunWith.(QueryerContext); !ok {
|
||||
return &Row{err: RunnerNotQueryRunner}
|
||||
}
|
||||
return &Row{err: NoContextSupport}
|
||||
}
|
||||
return QueryRowContextWith(ctx, queryRower, d)
|
||||
}
|
||||
|
||||
// ExecContext builds and ExecContexts the query with the Runner set by RunWith.
|
||||
func (b InsertBuilder) ExecContext(ctx context.Context) (sql.Result, error) {
|
||||
data := builder.GetStruct(b).(insertData)
|
||||
return data.ExecContext(ctx)
|
||||
}
|
||||
|
||||
// QueryContext builds and QueryContexts the query with the Runner set by RunWith.
|
||||
func (b InsertBuilder) QueryContext(ctx context.Context) (*sql.Rows, error) {
|
||||
data := builder.GetStruct(b).(insertData)
|
||||
return data.QueryContext(ctx)
|
||||
}
|
||||
|
||||
// QueryRowContext builds and QueryRowContexts the query with the Runner set by RunWith.
|
||||
func (b InsertBuilder) QueryRowContext(ctx context.Context) RowScanner {
|
||||
data := builder.GetStruct(b).(insertData)
|
||||
return data.QueryRowContext(ctx)
|
||||
}
|
||||
|
||||
// ScanContext is a shortcut for QueryRowContext().Scan.
|
||||
func (b InsertBuilder) ScanContext(ctx context.Context, dest ...interface{}) error {
|
||||
return b.QueryRowContext(ctx).Scan(dest...)
|
||||
}
|
||||
63
vendor/github.com/Masterminds/squirrel/part.go
generated
vendored
63
vendor/github.com/Masterminds/squirrel/part.go
generated
vendored
|
|
@ -1,63 +0,0 @@
|
|||
package squirrel
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
type part struct {
|
||||
pred interface{}
|
||||
args []interface{}
|
||||
}
|
||||
|
||||
func newPart(pred interface{}, args ...interface{}) Sqlizer {
|
||||
return &part{pred, args}
|
||||
}
|
||||
|
||||
func (p part) ToSql() (sql string, args []interface{}, err error) {
|
||||
switch pred := p.pred.(type) {
|
||||
case nil:
|
||||
// no-op
|
||||
case Sqlizer:
|
||||
sql, args, err = pred.ToSql()
|
||||
case string:
|
||||
sql = pred
|
||||
args = p.args
|
||||
default:
|
||||
err = fmt.Errorf("expected string or Sqlizer, not %T", pred)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func nestedToSql(s Sqlizer) (string, []interface{}, error) {
|
||||
if raw, ok := s.(rawSqlizer); ok {
|
||||
return raw.toSqlRaw()
|
||||
} else {
|
||||
return s.ToSql()
|
||||
}
|
||||
}
|
||||
|
||||
func appendToSql(parts []Sqlizer, w io.Writer, sep string, args []interface{}) ([]interface{}, error) {
|
||||
for i, p := range parts {
|
||||
partSql, partArgs, err := nestedToSql(p)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if len(partSql) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
if i > 0 {
|
||||
_, err := io.WriteString(w, sep)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
_, err = io.WriteString(w, partSql)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
args = append(args, partArgs...)
|
||||
}
|
||||
return args, nil
|
||||
}
|
||||
114
vendor/github.com/Masterminds/squirrel/placeholder.go
generated
vendored
114
vendor/github.com/Masterminds/squirrel/placeholder.go
generated
vendored
|
|
@ -1,114 +0,0 @@
|
|||
package squirrel
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// PlaceholderFormat is the interface that wraps the ReplacePlaceholders method.
|
||||
//
|
||||
// ReplacePlaceholders takes a SQL statement and replaces each question mark
|
||||
// placeholder with a (possibly different) SQL placeholder.
|
||||
type PlaceholderFormat interface {
|
||||
ReplacePlaceholders(sql string) (string, error)
|
||||
}
|
||||
|
||||
type placeholderDebugger interface {
|
||||
debugPlaceholder() string
|
||||
}
|
||||
|
||||
var (
|
||||
// Question is a PlaceholderFormat instance that leaves placeholders as
|
||||
// question marks.
|
||||
Question = questionFormat{}
|
||||
|
||||
// Dollar is a PlaceholderFormat instance that replaces placeholders with
|
||||
// dollar-prefixed positional placeholders (e.g. $1, $2, $3).
|
||||
Dollar = dollarFormat{}
|
||||
|
||||
// Colon is a PlaceholderFormat instance that replaces placeholders with
|
||||
// colon-prefixed positional placeholders (e.g. :1, :2, :3).
|
||||
Colon = colonFormat{}
|
||||
|
||||
// AtP is a PlaceholderFormat instance that replaces placeholders with
|
||||
// "@p"-prefixed positional placeholders (e.g. @p1, @p2, @p3).
|
||||
AtP = atpFormat{}
|
||||
)
|
||||
|
||||
type questionFormat struct{}
|
||||
|
||||
func (questionFormat) ReplacePlaceholders(sql string) (string, error) {
|
||||
return sql, nil
|
||||
}
|
||||
|
||||
func (questionFormat) debugPlaceholder() string {
|
||||
return "?"
|
||||
}
|
||||
|
||||
type dollarFormat struct{}
|
||||
|
||||
func (dollarFormat) ReplacePlaceholders(sql string) (string, error) {
|
||||
return replacePositionalPlaceholders(sql, "$")
|
||||
}
|
||||
|
||||
func (dollarFormat) debugPlaceholder() string {
|
||||
return "$"
|
||||
}
|
||||
|
||||
type colonFormat struct{}
|
||||
|
||||
func (colonFormat) ReplacePlaceholders(sql string) (string, error) {
|
||||
return replacePositionalPlaceholders(sql, ":")
|
||||
}
|
||||
|
||||
func (colonFormat) debugPlaceholder() string {
|
||||
return ":"
|
||||
}
|
||||
|
||||
type atpFormat struct{}
|
||||
|
||||
func (atpFormat) ReplacePlaceholders(sql string) (string, error) {
|
||||
return replacePositionalPlaceholders(sql, "@p")
|
||||
}
|
||||
|
||||
func (atpFormat) debugPlaceholder() string {
|
||||
return "@p"
|
||||
}
|
||||
|
||||
// Placeholders returns a string with count ? placeholders joined with commas.
|
||||
func Placeholders(count int) string {
|
||||
if count < 1 {
|
||||
return ""
|
||||
}
|
||||
|
||||
return strings.Repeat(",?", count)[1:]
|
||||
}
|
||||
|
||||
func replacePositionalPlaceholders(sql, prefix string) (string, error) {
|
||||
buf := &bytes.Buffer{}
|
||||
i := 0
|
||||
for {
|
||||
p := strings.Index(sql, "?")
|
||||
if p == -1 {
|
||||
break
|
||||
}
|
||||
|
||||
if len(sql[p:]) > 1 && sql[p:p+2] == "??" { // escape ?? => ?
|
||||
buf.WriteString(sql[:p])
|
||||
buf.WriteString("?")
|
||||
if len(sql[p:]) == 1 {
|
||||
break
|
||||
}
|
||||
sql = sql[p+2:]
|
||||
} else {
|
||||
i++
|
||||
buf.WriteString(sql[:p])
|
||||
fmt.Fprintf(buf, "%s%d", prefix, i)
|
||||
sql = sql[p+1:]
|
||||
}
|
||||
}
|
||||
|
||||
buf.WriteString(sql)
|
||||
return buf.String(), nil
|
||||
}
|
||||
22
vendor/github.com/Masterminds/squirrel/row.go
generated
vendored
22
vendor/github.com/Masterminds/squirrel/row.go
generated
vendored
|
|
@ -1,22 +0,0 @@
|
|||
package squirrel
|
||||
|
||||
// RowScanner is the interface that wraps the Scan method.
|
||||
//
|
||||
// Scan behaves like database/sql.Row.Scan.
|
||||
type RowScanner interface {
|
||||
Scan(...interface{}) error
|
||||
}
|
||||
|
||||
// Row wraps database/sql.Row to let squirrel return new errors on Scan.
|
||||
type Row struct {
|
||||
RowScanner
|
||||
err error
|
||||
}
|
||||
|
||||
// Scan returns Row.err or calls RowScanner.Scan.
|
||||
func (r *Row) Scan(dest ...interface{}) error {
|
||||
if r.err != nil {
|
||||
return r.err
|
||||
}
|
||||
return r.RowScanner.Scan(dest...)
|
||||
}
|
||||
396
vendor/github.com/Masterminds/squirrel/select.go
generated
vendored
396
vendor/github.com/Masterminds/squirrel/select.go
generated
vendored
|
|
@ -1,396 +0,0 @@
|
|||
package squirrel
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/lann/builder"
|
||||
)
|
||||
|
||||
type selectData struct {
|
||||
PlaceholderFormat PlaceholderFormat
|
||||
RunWith BaseRunner
|
||||
Prefixes []Sqlizer
|
||||
Options []string
|
||||
Columns []Sqlizer
|
||||
From Sqlizer
|
||||
Joins []Sqlizer
|
||||
WhereParts []Sqlizer
|
||||
GroupBys []string
|
||||
HavingParts []Sqlizer
|
||||
OrderByParts []Sqlizer
|
||||
Limit string
|
||||
Offset string
|
||||
Suffixes []Sqlizer
|
||||
}
|
||||
|
||||
func (d *selectData) Exec() (sql.Result, error) {
|
||||
if d.RunWith == nil {
|
||||
return nil, RunnerNotSet
|
||||
}
|
||||
return ExecWith(d.RunWith, d)
|
||||
}
|
||||
|
||||
func (d *selectData) Query() (*sql.Rows, error) {
|
||||
if d.RunWith == nil {
|
||||
return nil, RunnerNotSet
|
||||
}
|
||||
return QueryWith(d.RunWith, d)
|
||||
}
|
||||
|
||||
func (d *selectData) QueryRow() RowScanner {
|
||||
if d.RunWith == nil {
|
||||
return &Row{err: RunnerNotSet}
|
||||
}
|
||||
queryRower, ok := d.RunWith.(QueryRower)
|
||||
if !ok {
|
||||
return &Row{err: RunnerNotQueryRunner}
|
||||
}
|
||||
return QueryRowWith(queryRower, d)
|
||||
}
|
||||
|
||||
func (d *selectData) ToSql() (sqlStr string, args []interface{}, err error) {
|
||||
sqlStr, args, err = d.toSqlRaw()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
sqlStr, err = d.PlaceholderFormat.ReplacePlaceholders(sqlStr)
|
||||
return
|
||||
}
|
||||
|
||||
func (d *selectData) toSqlRaw() (sqlStr string, args []interface{}, err error) {
|
||||
if len(d.Columns) == 0 {
|
||||
err = fmt.Errorf("select statements must have at least one result column")
|
||||
return
|
||||
}
|
||||
|
||||
sql := &bytes.Buffer{}
|
||||
|
||||
if len(d.Prefixes) > 0 {
|
||||
args, err = appendToSql(d.Prefixes, sql, " ", args)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
sql.WriteString(" ")
|
||||
}
|
||||
|
||||
sql.WriteString("SELECT ")
|
||||
|
||||
if len(d.Options) > 0 {
|
||||
sql.WriteString(strings.Join(d.Options, " "))
|
||||
sql.WriteString(" ")
|
||||
}
|
||||
|
||||
if len(d.Columns) > 0 {
|
||||
args, err = appendToSql(d.Columns, sql, ", ", args)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if d.From != nil {
|
||||
sql.WriteString(" FROM ")
|
||||
args, err = appendToSql([]Sqlizer{d.From}, sql, "", args)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if len(d.Joins) > 0 {
|
||||
sql.WriteString(" ")
|
||||
args, err = appendToSql(d.Joins, sql, " ", args)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if len(d.WhereParts) > 0 {
|
||||
sql.WriteString(" WHERE ")
|
||||
args, err = appendToSql(d.WhereParts, sql, " AND ", args)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if len(d.GroupBys) > 0 {
|
||||
sql.WriteString(" GROUP BY ")
|
||||
sql.WriteString(strings.Join(d.GroupBys, ", "))
|
||||
}
|
||||
|
||||
if len(d.HavingParts) > 0 {
|
||||
sql.WriteString(" HAVING ")
|
||||
args, err = appendToSql(d.HavingParts, sql, " AND ", args)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if len(d.OrderByParts) > 0 {
|
||||
sql.WriteString(" ORDER BY ")
|
||||
args, err = appendToSql(d.OrderByParts, sql, ", ", args)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if len(d.Limit) > 0 {
|
||||
sql.WriteString(" LIMIT ")
|
||||
sql.WriteString(d.Limit)
|
||||
}
|
||||
|
||||
if len(d.Offset) > 0 {
|
||||
sql.WriteString(" OFFSET ")
|
||||
sql.WriteString(d.Offset)
|
||||
}
|
||||
|
||||
if len(d.Suffixes) > 0 {
|
||||
sql.WriteString(" ")
|
||||
|
||||
args, err = appendToSql(d.Suffixes, sql, " ", args)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
sqlStr = sql.String()
|
||||
return
|
||||
}
|
||||
|
||||
// Builder
|
||||
|
||||
// SelectBuilder builds SQL SELECT statements.
|
||||
type SelectBuilder builder.Builder
|
||||
|
||||
func init() {
|
||||
builder.Register(SelectBuilder{}, selectData{})
|
||||
}
|
||||
|
||||
// Format methods
|
||||
|
||||
// PlaceholderFormat sets PlaceholderFormat (e.g. Question or Dollar) for the
|
||||
// query.
|
||||
func (b SelectBuilder) PlaceholderFormat(f PlaceholderFormat) SelectBuilder {
|
||||
return builder.Set(b, "PlaceholderFormat", f).(SelectBuilder)
|
||||
}
|
||||
|
||||
// Runner methods
|
||||
|
||||
// RunWith sets a Runner (like database/sql.DB) to be used with e.g. Exec.
|
||||
// For most cases runner will be a database connection.
|
||||
//
|
||||
// Internally we use this to mock out the database connection for testing.
|
||||
func (b SelectBuilder) RunWith(runner BaseRunner) SelectBuilder {
|
||||
return setRunWith(b, runner).(SelectBuilder)
|
||||
}
|
||||
|
||||
// Exec builds and Execs the query with the Runner set by RunWith.
|
||||
func (b SelectBuilder) Exec() (sql.Result, error) {
|
||||
data := builder.GetStruct(b).(selectData)
|
||||
return data.Exec()
|
||||
}
|
||||
|
||||
// Query builds and Querys the query with the Runner set by RunWith.
|
||||
func (b SelectBuilder) Query() (*sql.Rows, error) {
|
||||
data := builder.GetStruct(b).(selectData)
|
||||
return data.Query()
|
||||
}
|
||||
|
||||
// QueryRow builds and QueryRows the query with the Runner set by RunWith.
|
||||
func (b SelectBuilder) QueryRow() RowScanner {
|
||||
data := builder.GetStruct(b).(selectData)
|
||||
return data.QueryRow()
|
||||
}
|
||||
|
||||
// Scan is a shortcut for QueryRow().Scan.
|
||||
func (b SelectBuilder) Scan(dest ...interface{}) error {
|
||||
return b.QueryRow().Scan(dest...)
|
||||
}
|
||||
|
||||
// SQL methods
|
||||
|
||||
// ToSql builds the query into a SQL string and bound args.
|
||||
func (b SelectBuilder) ToSql() (string, []interface{}, error) {
|
||||
data := builder.GetStruct(b).(selectData)
|
||||
return data.ToSql()
|
||||
}
|
||||
|
||||
func (b SelectBuilder) toSqlRaw() (string, []interface{}, error) {
|
||||
data := builder.GetStruct(b).(selectData)
|
||||
return data.toSqlRaw()
|
||||
}
|
||||
|
||||
// MustSql builds the query into a SQL string and bound args.
|
||||
// It panics if there are any errors.
|
||||
func (b SelectBuilder) MustSql() (string, []interface{}) {
|
||||
sql, args, err := b.ToSql()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return sql, args
|
||||
}
|
||||
|
||||
// Prefix adds an expression to the beginning of the query
|
||||
func (b SelectBuilder) Prefix(sql string, args ...interface{}) SelectBuilder {
|
||||
return b.PrefixExpr(Expr(sql, args...))
|
||||
}
|
||||
|
||||
// PrefixExpr adds an expression to the very beginning of the query
|
||||
func (b SelectBuilder) PrefixExpr(expr Sqlizer) SelectBuilder {
|
||||
return builder.Append(b, "Prefixes", expr).(SelectBuilder)
|
||||
}
|
||||
|
||||
// Distinct adds a DISTINCT clause to the query.
|
||||
func (b SelectBuilder) Distinct() SelectBuilder {
|
||||
return b.Options("DISTINCT")
|
||||
}
|
||||
|
||||
// Options adds select option to the query
|
||||
func (b SelectBuilder) Options(options ...string) SelectBuilder {
|
||||
return builder.Extend(b, "Options", options).(SelectBuilder)
|
||||
}
|
||||
|
||||
// Columns adds result columns to the query.
|
||||
func (b SelectBuilder) Columns(columns ...string) SelectBuilder {
|
||||
parts := make([]interface{}, 0, len(columns))
|
||||
for _, str := range columns {
|
||||
parts = append(parts, newPart(str))
|
||||
}
|
||||
return builder.Extend(b, "Columns", parts).(SelectBuilder)
|
||||
}
|
||||
|
||||
// Column adds a result column to the query.
|
||||
// Unlike Columns, Column accepts args which will be bound to placeholders in
|
||||
// the columns string, for example:
|
||||
// Column("IF(col IN ("+squirrel.Placeholders(3)+"), 1, 0) as col", 1, 2, 3)
|
||||
func (b SelectBuilder) Column(column interface{}, args ...interface{}) SelectBuilder {
|
||||
return builder.Append(b, "Columns", newPart(column, args...)).(SelectBuilder)
|
||||
}
|
||||
|
||||
// From sets the FROM clause of the query.
|
||||
func (b SelectBuilder) From(from string) SelectBuilder {
|
||||
return builder.Set(b, "From", newPart(from)).(SelectBuilder)
|
||||
}
|
||||
|
||||
// FromSelect sets a subquery into the FROM clause of the query.
|
||||
func (b SelectBuilder) FromSelect(from SelectBuilder, alias string) SelectBuilder {
|
||||
// Prevent misnumbered parameters in nested selects (#183).
|
||||
from = from.PlaceholderFormat(Question)
|
||||
return builder.Set(b, "From", Alias(from, alias)).(SelectBuilder)
|
||||
}
|
||||
|
||||
// JoinClause adds a join clause to the query.
|
||||
func (b SelectBuilder) JoinClause(pred interface{}, args ...interface{}) SelectBuilder {
|
||||
return builder.Append(b, "Joins", newPart(pred, args...)).(SelectBuilder)
|
||||
}
|
||||
|
||||
// Join adds a JOIN clause to the query.
|
||||
func (b SelectBuilder) Join(join string, rest ...interface{}) SelectBuilder {
|
||||
return b.JoinClause("JOIN "+join, rest...)
|
||||
}
|
||||
|
||||
// LeftJoin adds a LEFT JOIN clause to the query.
|
||||
func (b SelectBuilder) LeftJoin(join string, rest ...interface{}) SelectBuilder {
|
||||
return b.JoinClause("LEFT JOIN "+join, rest...)
|
||||
}
|
||||
|
||||
// RightJoin adds a RIGHT JOIN clause to the query.
|
||||
func (b SelectBuilder) RightJoin(join string, rest ...interface{}) SelectBuilder {
|
||||
return b.JoinClause("RIGHT JOIN "+join, rest...)
|
||||
}
|
||||
|
||||
// InnerJoin adds a INNER JOIN clause to the query.
|
||||
func (b SelectBuilder) InnerJoin(join string, rest ...interface{}) SelectBuilder {
|
||||
return b.JoinClause("INNER JOIN "+join, rest...)
|
||||
}
|
||||
|
||||
// CrossJoin adds a CROSS JOIN clause to the query.
|
||||
func (b SelectBuilder) CrossJoin(join string, rest ...interface{}) SelectBuilder {
|
||||
return b.JoinClause("CROSS JOIN "+join, rest...)
|
||||
}
|
||||
|
||||
// Where adds an expression to the WHERE clause of the query.
|
||||
//
|
||||
// Expressions are ANDed together in the generated SQL.
|
||||
//
|
||||
// Where accepts several types for its pred argument:
|
||||
//
|
||||
// nil OR "" - ignored.
|
||||
//
|
||||
// string - SQL expression.
|
||||
// If the expression has SQL placeholders then a set of arguments must be passed
|
||||
// as well, one for each placeholder.
|
||||
//
|
||||
// map[string]interface{} OR Eq - map of SQL expressions to values. Each key is
|
||||
// transformed into an expression like "<key> = ?", with the corresponding value
|
||||
// bound to the placeholder. If the value is nil, the expression will be "<key>
|
||||
// IS NULL". If the value is an array or slice, the expression will be "<key> IN
|
||||
// (?,?,...)", with one placeholder for each item in the value. These expressions
|
||||
// are ANDed together.
|
||||
//
|
||||
// Where will panic if pred isn't any of the above types.
|
||||
func (b SelectBuilder) Where(pred interface{}, args ...interface{}) SelectBuilder {
|
||||
if pred == nil || pred == "" {
|
||||
return b
|
||||
}
|
||||
return builder.Append(b, "WhereParts", newWherePart(pred, args...)).(SelectBuilder)
|
||||
}
|
||||
|
||||
// GroupBy adds GROUP BY expressions to the query.
|
||||
func (b SelectBuilder) GroupBy(groupBys ...string) SelectBuilder {
|
||||
return builder.Extend(b, "GroupBys", groupBys).(SelectBuilder)
|
||||
}
|
||||
|
||||
// Having adds an expression to the HAVING clause of the query.
|
||||
//
|
||||
// See Where.
|
||||
func (b SelectBuilder) Having(pred interface{}, rest ...interface{}) SelectBuilder {
|
||||
return builder.Append(b, "HavingParts", newWherePart(pred, rest...)).(SelectBuilder)
|
||||
}
|
||||
|
||||
// OrderByClause adds ORDER BY clause to the query.
|
||||
func (b SelectBuilder) OrderByClause(pred interface{}, args ...interface{}) SelectBuilder {
|
||||
return builder.Append(b, "OrderByParts", newPart(pred, args...)).(SelectBuilder)
|
||||
}
|
||||
|
||||
// OrderBy adds ORDER BY expressions to the query.
|
||||
func (b SelectBuilder) OrderBy(orderBys ...string) SelectBuilder {
|
||||
for _, orderBy := range orderBys {
|
||||
b = b.OrderByClause(orderBy)
|
||||
}
|
||||
|
||||
return b
|
||||
}
|
||||
|
||||
// Limit sets a LIMIT clause on the query.
|
||||
func (b SelectBuilder) Limit(limit uint64) SelectBuilder {
|
||||
return builder.Set(b, "Limit", fmt.Sprintf("%d", limit)).(SelectBuilder)
|
||||
}
|
||||
|
||||
// Limit ALL allows to access all records with limit
|
||||
func (b SelectBuilder) RemoveLimit() SelectBuilder {
|
||||
return builder.Delete(b, "Limit").(SelectBuilder)
|
||||
}
|
||||
|
||||
// Offset sets a OFFSET clause on the query.
|
||||
func (b SelectBuilder) Offset(offset uint64) SelectBuilder {
|
||||
return builder.Set(b, "Offset", fmt.Sprintf("%d", offset)).(SelectBuilder)
|
||||
}
|
||||
|
||||
// RemoveOffset removes OFFSET clause.
|
||||
func (b SelectBuilder) RemoveOffset() SelectBuilder {
|
||||
return builder.Delete(b, "Offset").(SelectBuilder)
|
||||
}
|
||||
|
||||
// Suffix adds an expression to the end of the query
|
||||
func (b SelectBuilder) Suffix(sql string, args ...interface{}) SelectBuilder {
|
||||
return b.SuffixExpr(Expr(sql, args...))
|
||||
}
|
||||
|
||||
// SuffixExpr adds an expression to the end of the query
|
||||
func (b SelectBuilder) SuffixExpr(expr Sqlizer) SelectBuilder {
|
||||
return builder.Append(b, "Suffixes", expr).(SelectBuilder)
|
||||
}
|
||||
69
vendor/github.com/Masterminds/squirrel/select_ctx.go
generated
vendored
69
vendor/github.com/Masterminds/squirrel/select_ctx.go
generated
vendored
|
|
@ -1,69 +0,0 @@
|
|||
// +build go1.8
|
||||
|
||||
package squirrel
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
|
||||
"github.com/lann/builder"
|
||||
)
|
||||
|
||||
func (d *selectData) ExecContext(ctx context.Context) (sql.Result, error) {
|
||||
if d.RunWith == nil {
|
||||
return nil, RunnerNotSet
|
||||
}
|
||||
ctxRunner, ok := d.RunWith.(ExecerContext)
|
||||
if !ok {
|
||||
return nil, NoContextSupport
|
||||
}
|
||||
return ExecContextWith(ctx, ctxRunner, d)
|
||||
}
|
||||
|
||||
func (d *selectData) QueryContext(ctx context.Context) (*sql.Rows, error) {
|
||||
if d.RunWith == nil {
|
||||
return nil, RunnerNotSet
|
||||
}
|
||||
ctxRunner, ok := d.RunWith.(QueryerContext)
|
||||
if !ok {
|
||||
return nil, NoContextSupport
|
||||
}
|
||||
return QueryContextWith(ctx, ctxRunner, d)
|
||||
}
|
||||
|
||||
func (d *selectData) QueryRowContext(ctx context.Context) RowScanner {
|
||||
if d.RunWith == nil {
|
||||
return &Row{err: RunnerNotSet}
|
||||
}
|
||||
queryRower, ok := d.RunWith.(QueryRowerContext)
|
||||
if !ok {
|
||||
if _, ok := d.RunWith.(QueryerContext); !ok {
|
||||
return &Row{err: RunnerNotQueryRunner}
|
||||
}
|
||||
return &Row{err: NoContextSupport}
|
||||
}
|
||||
return QueryRowContextWith(ctx, queryRower, d)
|
||||
}
|
||||
|
||||
// ExecContext builds and ExecContexts the query with the Runner set by RunWith.
|
||||
func (b SelectBuilder) ExecContext(ctx context.Context) (sql.Result, error) {
|
||||
data := builder.GetStruct(b).(selectData)
|
||||
return data.ExecContext(ctx)
|
||||
}
|
||||
|
||||
// QueryContext builds and QueryContexts the query with the Runner set by RunWith.
|
||||
func (b SelectBuilder) QueryContext(ctx context.Context) (*sql.Rows, error) {
|
||||
data := builder.GetStruct(b).(selectData)
|
||||
return data.QueryContext(ctx)
|
||||
}
|
||||
|
||||
// QueryRowContext builds and QueryRowContexts the query with the Runner set by RunWith.
|
||||
func (b SelectBuilder) QueryRowContext(ctx context.Context) RowScanner {
|
||||
data := builder.GetStruct(b).(selectData)
|
||||
return data.QueryRowContext(ctx)
|
||||
}
|
||||
|
||||
// ScanContext is a shortcut for QueryRowContext().Scan.
|
||||
func (b SelectBuilder) ScanContext(ctx context.Context, dest ...interface{}) error {
|
||||
return b.QueryRowContext(ctx).Scan(dest...)
|
||||
}
|
||||
183
vendor/github.com/Masterminds/squirrel/squirrel.go
generated
vendored
183
vendor/github.com/Masterminds/squirrel/squirrel.go
generated
vendored
|
|
@ -1,183 +0,0 @@
|
|||
// Package squirrel provides a fluent SQL generator.
|
||||
//
|
||||
// See https://github.com/Masterminds/squirrel for examples.
|
||||
package squirrel
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/lann/builder"
|
||||
)
|
||||
|
||||
// Sqlizer is the interface that wraps the ToSql method.
|
||||
//
|
||||
// ToSql returns a SQL representation of the Sqlizer, along with a slice of args
|
||||
// as passed to e.g. database/sql.Exec. It can also return an error.
|
||||
type Sqlizer interface {
|
||||
ToSql() (string, []interface{}, error)
|
||||
}
|
||||
|
||||
// rawSqlizer is expected to do what Sqlizer does, but without finalizing placeholders.
|
||||
// This is useful for nested queries.
|
||||
type rawSqlizer interface {
|
||||
toSqlRaw() (string, []interface{}, error)
|
||||
}
|
||||
|
||||
// Execer is the interface that wraps the Exec method.
|
||||
//
|
||||
// Exec executes the given query as implemented by database/sql.Exec.
|
||||
type Execer interface {
|
||||
Exec(query string, args ...interface{}) (sql.Result, error)
|
||||
}
|
||||
|
||||
// Queryer is the interface that wraps the Query method.
|
||||
//
|
||||
// Query executes the given query as implemented by database/sql.Query.
|
||||
type Queryer interface {
|
||||
Query(query string, args ...interface{}) (*sql.Rows, error)
|
||||
}
|
||||
|
||||
// QueryRower is the interface that wraps the QueryRow method.
|
||||
//
|
||||
// QueryRow executes the given query as implemented by database/sql.QueryRow.
|
||||
type QueryRower interface {
|
||||
QueryRow(query string, args ...interface{}) RowScanner
|
||||
}
|
||||
|
||||
// BaseRunner groups the Execer and Queryer interfaces.
|
||||
type BaseRunner interface {
|
||||
Execer
|
||||
Queryer
|
||||
}
|
||||
|
||||
// Runner groups the Execer, Queryer, and QueryRower interfaces.
|
||||
type Runner interface {
|
||||
Execer
|
||||
Queryer
|
||||
QueryRower
|
||||
}
|
||||
|
||||
// WrapStdSql wraps a type implementing the standard SQL interface with methods that
|
||||
// squirrel expects.
|
||||
func WrapStdSql(stdSql StdSql) Runner {
|
||||
return &stdsqlRunner{stdSql}
|
||||
}
|
||||
|
||||
// StdSql encompasses the standard methods of the *sql.DB type, and other types that
|
||||
// wrap these methods.
|
||||
type StdSql interface {
|
||||
Query(string, ...interface{}) (*sql.Rows, error)
|
||||
QueryRow(string, ...interface{}) *sql.Row
|
||||
Exec(string, ...interface{}) (sql.Result, error)
|
||||
}
|
||||
|
||||
type stdsqlRunner struct {
|
||||
StdSql
|
||||
}
|
||||
|
||||
func (r *stdsqlRunner) QueryRow(query string, args ...interface{}) RowScanner {
|
||||
return r.StdSql.QueryRow(query, args...)
|
||||
}
|
||||
|
||||
func setRunWith(b interface{}, runner BaseRunner) interface{} {
|
||||
switch r := runner.(type) {
|
||||
case StdSqlCtx:
|
||||
runner = WrapStdSqlCtx(r)
|
||||
case StdSql:
|
||||
runner = WrapStdSql(r)
|
||||
}
|
||||
return builder.Set(b, "RunWith", runner)
|
||||
}
|
||||
|
||||
// RunnerNotSet is returned by methods that need a Runner if it isn't set.
|
||||
var RunnerNotSet = fmt.Errorf("cannot run; no Runner set (RunWith)")
|
||||
|
||||
// RunnerNotQueryRunner is returned by QueryRow if the RunWith value doesn't implement QueryRower.
|
||||
var RunnerNotQueryRunner = fmt.Errorf("cannot QueryRow; Runner is not a QueryRower")
|
||||
|
||||
// ExecWith Execs the SQL returned by s with db.
|
||||
func ExecWith(db Execer, s Sqlizer) (res sql.Result, err error) {
|
||||
query, args, err := s.ToSql()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return db.Exec(query, args...)
|
||||
}
|
||||
|
||||
// QueryWith Querys the SQL returned by s with db.
|
||||
func QueryWith(db Queryer, s Sqlizer) (rows *sql.Rows, err error) {
|
||||
query, args, err := s.ToSql()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return db.Query(query, args...)
|
||||
}
|
||||
|
||||
// QueryRowWith QueryRows the SQL returned by s with db.
|
||||
func QueryRowWith(db QueryRower, s Sqlizer) RowScanner {
|
||||
query, args, err := s.ToSql()
|
||||
return &Row{RowScanner: db.QueryRow(query, args...), err: err}
|
||||
}
|
||||
|
||||
// DebugSqlizer calls ToSql on s and shows the approximate SQL to be executed
|
||||
//
|
||||
// If ToSql returns an error, the result of this method will look like:
|
||||
// "[ToSql error: %s]" or "[DebugSqlizer error: %s]"
|
||||
//
|
||||
// IMPORTANT: As its name suggests, this function should only be used for
|
||||
// debugging. While the string result *might* be valid SQL, this function does
|
||||
// not try very hard to ensure it. Additionally, executing the output of this
|
||||
// function with any untrusted user input is certainly insecure.
|
||||
func DebugSqlizer(s Sqlizer) string {
|
||||
sql, args, err := s.ToSql()
|
||||
if err != nil {
|
||||
return fmt.Sprintf("[ToSql error: %s]", err)
|
||||
}
|
||||
|
||||
var placeholder string
|
||||
downCast, ok := s.(placeholderDebugger)
|
||||
if !ok {
|
||||
placeholder = "?"
|
||||
} else {
|
||||
placeholder = downCast.debugPlaceholder()
|
||||
}
|
||||
// TODO: dedupe this with placeholder.go
|
||||
buf := &bytes.Buffer{}
|
||||
i := 0
|
||||
for {
|
||||
p := strings.Index(sql, placeholder)
|
||||
if p == -1 {
|
||||
break
|
||||
}
|
||||
if len(sql[p:]) > 1 && sql[p:p+2] == "??" { // escape ?? => ?
|
||||
buf.WriteString(sql[:p])
|
||||
buf.WriteString("?")
|
||||
if len(sql[p:]) == 1 {
|
||||
break
|
||||
}
|
||||
sql = sql[p+2:]
|
||||
} else {
|
||||
if i+1 > len(args) {
|
||||
return fmt.Sprintf(
|
||||
"[DebugSqlizer error: too many placeholders in %#v for %d args]",
|
||||
sql, len(args))
|
||||
}
|
||||
buf.WriteString(sql[:p])
|
||||
fmt.Fprintf(buf, "'%v'", args[i])
|
||||
// advance our sql string "cursor" beyond the arg we placed
|
||||
sql = sql[p+1:]
|
||||
i++
|
||||
}
|
||||
}
|
||||
if i < len(args) {
|
||||
return fmt.Sprintf(
|
||||
"[DebugSqlizer error: not enough placeholders in %#v for %d args]",
|
||||
sql, len(args))
|
||||
}
|
||||
// "append" any remaning sql that won't need interpolating
|
||||
buf.WriteString(sql)
|
||||
return buf.String()
|
||||
}
|
||||
93
vendor/github.com/Masterminds/squirrel/squirrel_ctx.go
generated
vendored
93
vendor/github.com/Masterminds/squirrel/squirrel_ctx.go
generated
vendored
|
|
@ -1,93 +0,0 @@
|
|||
// +build go1.8
|
||||
|
||||
package squirrel
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"errors"
|
||||
)
|
||||
|
||||
// NoContextSupport is returned if a db doesn't support Context.
|
||||
var NoContextSupport = errors.New("DB does not support Context")
|
||||
|
||||
// ExecerContext is the interface that wraps the ExecContext method.
|
||||
//
|
||||
// Exec executes the given query as implemented by database/sql.ExecContext.
|
||||
type ExecerContext interface {
|
||||
ExecContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error)
|
||||
}
|
||||
|
||||
// QueryerContext is the interface that wraps the QueryContext method.
|
||||
//
|
||||
// QueryContext executes the given query as implemented by database/sql.QueryContext.
|
||||
type QueryerContext interface {
|
||||
QueryContext(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error)
|
||||
}
|
||||
|
||||
// QueryRowerContext is the interface that wraps the QueryRowContext method.
|
||||
//
|
||||
// QueryRowContext executes the given query as implemented by database/sql.QueryRowContext.
|
||||
type QueryRowerContext interface {
|
||||
QueryRowContext(ctx context.Context, query string, args ...interface{}) RowScanner
|
||||
}
|
||||
|
||||
// RunnerContext groups the Runner interface, along with the Context versions of each of
|
||||
// its methods
|
||||
type RunnerContext interface {
|
||||
Runner
|
||||
QueryerContext
|
||||
QueryRowerContext
|
||||
ExecerContext
|
||||
}
|
||||
|
||||
// WrapStdSqlCtx wraps a type implementing the standard SQL interface plus the context
|
||||
// versions of the methods with methods that squirrel expects.
|
||||
func WrapStdSqlCtx(stdSqlCtx StdSqlCtx) RunnerContext {
|
||||
return &stdsqlCtxRunner{stdSqlCtx}
|
||||
}
|
||||
|
||||
// StdSqlCtx encompasses the standard methods of the *sql.DB type, along with the Context
|
||||
// versions of those methods, and other types that wrap these methods.
|
||||
type StdSqlCtx interface {
|
||||
StdSql
|
||||
QueryContext(context.Context, string, ...interface{}) (*sql.Rows, error)
|
||||
QueryRowContext(context.Context, string, ...interface{}) *sql.Row
|
||||
ExecContext(context.Context, string, ...interface{}) (sql.Result, error)
|
||||
}
|
||||
|
||||
type stdsqlCtxRunner struct {
|
||||
StdSqlCtx
|
||||
}
|
||||
|
||||
func (r *stdsqlCtxRunner) QueryRow(query string, args ...interface{}) RowScanner {
|
||||
return r.StdSqlCtx.QueryRow(query, args...)
|
||||
}
|
||||
|
||||
func (r *stdsqlCtxRunner) QueryRowContext(ctx context.Context, query string, args ...interface{}) RowScanner {
|
||||
return r.StdSqlCtx.QueryRowContext(ctx, query, args...)
|
||||
}
|
||||
|
||||
// ExecContextWith ExecContexts the SQL returned by s with db.
|
||||
func ExecContextWith(ctx context.Context, db ExecerContext, s Sqlizer) (res sql.Result, err error) {
|
||||
query, args, err := s.ToSql()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return db.ExecContext(ctx, query, args...)
|
||||
}
|
||||
|
||||
// QueryContextWith QueryContexts the SQL returned by s with db.
|
||||
func QueryContextWith(ctx context.Context, db QueryerContext, s Sqlizer) (rows *sql.Rows, err error) {
|
||||
query, args, err := s.ToSql()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return db.QueryContext(ctx, query, args...)
|
||||
}
|
||||
|
||||
// QueryRowContextWith QueryRowContexts the SQL returned by s with db.
|
||||
func QueryRowContextWith(ctx context.Context, db QueryRowerContext, s Sqlizer) RowScanner {
|
||||
query, args, err := s.ToSql()
|
||||
return &Row{RowScanner: db.QueryRowContext(ctx, query, args...), err: err}
|
||||
}
|
||||
104
vendor/github.com/Masterminds/squirrel/statement.go
generated
vendored
104
vendor/github.com/Masterminds/squirrel/statement.go
generated
vendored
|
|
@ -1,104 +0,0 @@
|
|||
package squirrel
|
||||
|
||||
import "github.com/lann/builder"
|
||||
|
||||
// StatementBuilderType is the type of StatementBuilder.
|
||||
type StatementBuilderType builder.Builder
|
||||
|
||||
// Select returns a SelectBuilder for this StatementBuilderType.
|
||||
func (b StatementBuilderType) Select(columns ...string) SelectBuilder {
|
||||
return SelectBuilder(b).Columns(columns...)
|
||||
}
|
||||
|
||||
// Insert returns a InsertBuilder for this StatementBuilderType.
|
||||
func (b StatementBuilderType) Insert(into string) InsertBuilder {
|
||||
return InsertBuilder(b).Into(into)
|
||||
}
|
||||
|
||||
// Replace returns a InsertBuilder for this StatementBuilderType with the
|
||||
// statement keyword set to "REPLACE".
|
||||
func (b StatementBuilderType) Replace(into string) InsertBuilder {
|
||||
return InsertBuilder(b).statementKeyword("REPLACE").Into(into)
|
||||
}
|
||||
|
||||
// Update returns a UpdateBuilder for this StatementBuilderType.
|
||||
func (b StatementBuilderType) Update(tables ...string) UpdateBuilder {
|
||||
return UpdateBuilder(b).Table(tables...)
|
||||
}
|
||||
|
||||
// Delete returns a DeleteBuilder for this StatementBuilderType.
|
||||
func (b StatementBuilderType) Delete(from string) DeleteBuilder {
|
||||
return DeleteBuilder(b).From(from)
|
||||
}
|
||||
|
||||
// PlaceholderFormat sets the PlaceholderFormat field for any child builders.
|
||||
func (b StatementBuilderType) PlaceholderFormat(f PlaceholderFormat) StatementBuilderType {
|
||||
return builder.Set(b, "PlaceholderFormat", f).(StatementBuilderType)
|
||||
}
|
||||
|
||||
// RunWith sets the RunWith field for any child builders.
|
||||
func (b StatementBuilderType) RunWith(runner BaseRunner) StatementBuilderType {
|
||||
return setRunWith(b, runner).(StatementBuilderType)
|
||||
}
|
||||
|
||||
// Where adds WHERE expressions to the query.
|
||||
//
|
||||
// See SelectBuilder.Where for more information.
|
||||
func (b StatementBuilderType) Where(pred interface{}, args ...interface{}) StatementBuilderType {
|
||||
return builder.Append(b, "WhereParts", newWherePart(pred, args...)).(StatementBuilderType)
|
||||
}
|
||||
|
||||
// StatementBuilder is a parent builder for other builders, e.g. SelectBuilder.
|
||||
var StatementBuilder = StatementBuilderType(builder.EmptyBuilder).PlaceholderFormat(Question)
|
||||
|
||||
// Select returns a new SelectBuilder, optionally setting some result columns.
|
||||
//
|
||||
// See SelectBuilder.Columns.
|
||||
func Select(columns ...string) SelectBuilder {
|
||||
return StatementBuilder.Select(columns...)
|
||||
}
|
||||
|
||||
// Insert returns a new InsertBuilder with the given table name.
|
||||
//
|
||||
// See InsertBuilder.Into.
|
||||
func Insert(into string) InsertBuilder {
|
||||
return StatementBuilder.Insert(into)
|
||||
}
|
||||
|
||||
// Replace returns a new InsertBuilder with the statement keyword set to
|
||||
// "REPLACE" and with the given table name.
|
||||
//
|
||||
// See InsertBuilder.Into.
|
||||
func Replace(into string) InsertBuilder {
|
||||
return StatementBuilder.Replace(into)
|
||||
}
|
||||
|
||||
// Update returns a new UpdateBuilder with the given table name.
|
||||
//
|
||||
// See UpdateBuilder.Table.
|
||||
func Update(tables ...string) UpdateBuilder {
|
||||
return StatementBuilder.Update(tables...)
|
||||
}
|
||||
|
||||
// Delete returns a new DeleteBuilder with the given table name.
|
||||
//
|
||||
// See DeleteBuilder.Table.
|
||||
func Delete(from string) DeleteBuilder {
|
||||
return StatementBuilder.Delete(from)
|
||||
}
|
||||
|
||||
// Case returns a new CaseBuilder
|
||||
// "what" represents case value
|
||||
func Case(what ...interface{}) CaseBuilder {
|
||||
b := CaseBuilder(builder.EmptyBuilder)
|
||||
|
||||
switch len(what) {
|
||||
case 0:
|
||||
case 1:
|
||||
b = b.what(what[0])
|
||||
default:
|
||||
b = b.what(newPart(what[0], what[1:]...))
|
||||
|
||||
}
|
||||
return b
|
||||
}
|
||||
121
vendor/github.com/Masterminds/squirrel/stmtcacher.go
generated
vendored
121
vendor/github.com/Masterminds/squirrel/stmtcacher.go
generated
vendored
|
|
@ -1,121 +0,0 @@
|
|||
package squirrel
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// Prepareer is the interface that wraps the Prepare method.
|
||||
//
|
||||
// Prepare executes the given query as implemented by database/sql.Prepare.
|
||||
type Preparer interface {
|
||||
Prepare(query string) (*sql.Stmt, error)
|
||||
}
|
||||
|
||||
// DBProxy groups the Execer, Queryer, QueryRower, and Preparer interfaces.
|
||||
type DBProxy interface {
|
||||
Execer
|
||||
Queryer
|
||||
QueryRower
|
||||
Preparer
|
||||
}
|
||||
|
||||
// NOTE: NewStmtCache is defined in stmtcacher_ctx.go (Go >= 1.8) or stmtcacher_noctx.go (Go < 1.8).
|
||||
|
||||
// StmtCache wraps and delegates down to a Preparer type
|
||||
//
|
||||
// It also automatically prepares all statements sent to the underlying Preparer calls
|
||||
// for Exec, Query and QueryRow and caches the returns *sql.Stmt using the provided
|
||||
// query as the key. So that it can be automatically re-used.
|
||||
type StmtCache struct {
|
||||
prep Preparer
|
||||
cache map[string]*sql.Stmt
|
||||
mu sync.Mutex
|
||||
}
|
||||
|
||||
// Prepare delegates down to the underlying Preparer and caches the result
|
||||
// using the provided query as a key
|
||||
func (sc *StmtCache) Prepare(query string) (*sql.Stmt, error) {
|
||||
sc.mu.Lock()
|
||||
defer sc.mu.Unlock()
|
||||
|
||||
stmt, ok := sc.cache[query]
|
||||
if ok {
|
||||
return stmt, nil
|
||||
}
|
||||
stmt, err := sc.prep.Prepare(query)
|
||||
if err == nil {
|
||||
sc.cache[query] = stmt
|
||||
}
|
||||
return stmt, err
|
||||
}
|
||||
|
||||
// Exec delegates down to the underlying Preparer using a prepared statement
|
||||
func (sc *StmtCache) Exec(query string, args ...interface{}) (res sql.Result, err error) {
|
||||
stmt, err := sc.Prepare(query)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return stmt.Exec(args...)
|
||||
}
|
||||
|
||||
// Query delegates down to the underlying Preparer using a prepared statement
|
||||
func (sc *StmtCache) Query(query string, args ...interface{}) (rows *sql.Rows, err error) {
|
||||
stmt, err := sc.Prepare(query)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return stmt.Query(args...)
|
||||
}
|
||||
|
||||
// QueryRow delegates down to the underlying Preparer using a prepared statement
|
||||
func (sc *StmtCache) QueryRow(query string, args ...interface{}) RowScanner {
|
||||
stmt, err := sc.Prepare(query)
|
||||
if err != nil {
|
||||
return &Row{err: err}
|
||||
}
|
||||
return stmt.QueryRow(args...)
|
||||
}
|
||||
|
||||
// Clear removes and closes all the currently cached prepared statements
|
||||
func (sc *StmtCache) Clear() (err error) {
|
||||
sc.mu.Lock()
|
||||
defer sc.mu.Unlock()
|
||||
|
||||
for key, stmt := range sc.cache {
|
||||
delete(sc.cache, key)
|
||||
|
||||
if stmt == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if cerr := stmt.Close(); cerr != nil {
|
||||
err = cerr
|
||||
}
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("one or more Stmt.Close failed; last error: %v", err)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
type DBProxyBeginner interface {
|
||||
DBProxy
|
||||
Begin() (*sql.Tx, error)
|
||||
}
|
||||
|
||||
type stmtCacheProxy struct {
|
||||
DBProxy
|
||||
db *sql.DB
|
||||
}
|
||||
|
||||
func NewStmtCacheProxy(db *sql.DB) DBProxyBeginner {
|
||||
return &stmtCacheProxy{DBProxy: NewStmtCache(db), db: db}
|
||||
}
|
||||
|
||||
func (sp *stmtCacheProxy) Begin() (*sql.Tx, error) {
|
||||
return sp.db.Begin()
|
||||
}
|
||||
86
vendor/github.com/Masterminds/squirrel/stmtcacher_ctx.go
generated
vendored
86
vendor/github.com/Masterminds/squirrel/stmtcacher_ctx.go
generated
vendored
|
|
@ -1,86 +0,0 @@
|
|||
// +build go1.8
|
||||
|
||||
package squirrel
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
)
|
||||
|
||||
// PrepareerContext is the interface that wraps the Prepare and PrepareContext methods.
|
||||
//
|
||||
// Prepare executes the given query as implemented by database/sql.Prepare.
|
||||
// PrepareContext executes the given query as implemented by database/sql.PrepareContext.
|
||||
type PreparerContext interface {
|
||||
Preparer
|
||||
PrepareContext(ctx context.Context, query string) (*sql.Stmt, error)
|
||||
}
|
||||
|
||||
// DBProxyContext groups the Execer, Queryer, QueryRower and PreparerContext interfaces.
|
||||
type DBProxyContext interface {
|
||||
Execer
|
||||
Queryer
|
||||
QueryRower
|
||||
PreparerContext
|
||||
}
|
||||
|
||||
// NewStmtCache returns a *StmtCache wrapping a PreparerContext that caches Prepared Stmts.
|
||||
//
|
||||
// Stmts are cached based on the string value of their queries.
|
||||
func NewStmtCache(prep PreparerContext) *StmtCache {
|
||||
return &StmtCache{prep: prep, cache: make(map[string]*sql.Stmt)}
|
||||
}
|
||||
|
||||
// NewStmtCacher is deprecated
|
||||
//
|
||||
// Use NewStmtCache instead
|
||||
func NewStmtCacher(prep PreparerContext) DBProxyContext {
|
||||
return NewStmtCache(prep)
|
||||
}
|
||||
|
||||
// PrepareContext delegates down to the underlying PreparerContext and caches the result
|
||||
// using the provided query as a key
|
||||
func (sc *StmtCache) PrepareContext(ctx context.Context, query string) (*sql.Stmt, error) {
|
||||
ctxPrep, ok := sc.prep.(PreparerContext)
|
||||
if !ok {
|
||||
return nil, NoContextSupport
|
||||
}
|
||||
sc.mu.Lock()
|
||||
defer sc.mu.Unlock()
|
||||
stmt, ok := sc.cache[query]
|
||||
if ok {
|
||||
return stmt, nil
|
||||
}
|
||||
stmt, err := ctxPrep.PrepareContext(ctx, query)
|
||||
if err == nil {
|
||||
sc.cache[query] = stmt
|
||||
}
|
||||
return stmt, err
|
||||
}
|
||||
|
||||
// ExecContext delegates down to the underlying PreparerContext using a prepared statement
|
||||
func (sc *StmtCache) ExecContext(ctx context.Context, query string, args ...interface{}) (res sql.Result, err error) {
|
||||
stmt, err := sc.PrepareContext(ctx, query)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return stmt.ExecContext(ctx, args...)
|
||||
}
|
||||
|
||||
// QueryContext delegates down to the underlying PreparerContext using a prepared statement
|
||||
func (sc *StmtCache) QueryContext(ctx context.Context, query string, args ...interface{}) (rows *sql.Rows, err error) {
|
||||
stmt, err := sc.PrepareContext(ctx, query)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return stmt.QueryContext(ctx, args...)
|
||||
}
|
||||
|
||||
// QueryRowContext delegates down to the underlying PreparerContext using a prepared statement
|
||||
func (sc *StmtCache) QueryRowContext(ctx context.Context, query string, args ...interface{}) RowScanner {
|
||||
stmt, err := sc.PrepareContext(ctx, query)
|
||||
if err != nil {
|
||||
return &Row{err: err}
|
||||
}
|
||||
return stmt.QueryRowContext(ctx, args...)
|
||||
}
|
||||
21
vendor/github.com/Masterminds/squirrel/stmtcacher_noctx.go
generated
vendored
21
vendor/github.com/Masterminds/squirrel/stmtcacher_noctx.go
generated
vendored
|
|
@ -1,21 +0,0 @@
|
|||
// +build !go1.8
|
||||
|
||||
package squirrel
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
)
|
||||
|
||||
// NewStmtCacher returns a DBProxy wrapping prep that caches Prepared Stmts.
|
||||
//
|
||||
// Stmts are cached based on the string value of their queries.
|
||||
func NewStmtCache(prep Preparer) *StmtCache {
|
||||
return &StmtCacher{prep: prep, cache: make(map[string]*sql.Stmt)}
|
||||
}
|
||||
|
||||
// NewStmtCacher is deprecated
|
||||
//
|
||||
// Use NewStmtCache instead
|
||||
func NewStmtCacher(prep Preparer) DBProxy {
|
||||
return NewStmtCache(prep)
|
||||
}
|
||||
296
vendor/github.com/Masterminds/squirrel/update.go
generated
vendored
296
vendor/github.com/Masterminds/squirrel/update.go
generated
vendored
|
|
@ -1,296 +0,0 @@
|
|||
package squirrel
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/lann/builder"
|
||||
)
|
||||
|
||||
type updateData struct {
|
||||
PlaceholderFormat PlaceholderFormat
|
||||
RunWith BaseRunner
|
||||
Prefixes []Sqlizer
|
||||
Tables []string
|
||||
SetClauses []setClause
|
||||
From []Sqlizer
|
||||
WhereParts []Sqlizer
|
||||
OrderBys []string
|
||||
Limit string
|
||||
Offset string
|
||||
Suffixes []Sqlizer
|
||||
}
|
||||
|
||||
type setClause struct {
|
||||
column string
|
||||
value interface{}
|
||||
}
|
||||
|
||||
func (d *updateData) Exec() (sql.Result, error) {
|
||||
if d.RunWith == nil {
|
||||
return nil, RunnerNotSet
|
||||
}
|
||||
return ExecWith(d.RunWith, d)
|
||||
}
|
||||
|
||||
func (d *updateData) Query() (*sql.Rows, error) {
|
||||
if d.RunWith == nil {
|
||||
return nil, RunnerNotSet
|
||||
}
|
||||
return QueryWith(d.RunWith, d)
|
||||
}
|
||||
|
||||
func (d *updateData) QueryRow() RowScanner {
|
||||
if d.RunWith == nil {
|
||||
return &Row{err: RunnerNotSet}
|
||||
}
|
||||
queryRower, ok := d.RunWith.(QueryRower)
|
||||
if !ok {
|
||||
return &Row{err: RunnerNotQueryRunner}
|
||||
}
|
||||
return QueryRowWith(queryRower, d)
|
||||
}
|
||||
|
||||
func (d *updateData) ToSql() (sqlStr string, args []interface{}, err error) {
|
||||
if len(d.Tables) == 0 {
|
||||
err = fmt.Errorf("update statements must specify a table")
|
||||
return
|
||||
}
|
||||
if len(d.SetClauses) == 0 {
|
||||
err = fmt.Errorf("update statements must have at least one Set clause")
|
||||
return
|
||||
}
|
||||
|
||||
sql := &bytes.Buffer{}
|
||||
|
||||
if len(d.Prefixes) > 0 {
|
||||
args, err = appendToSql(d.Prefixes, sql, " ", args)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
sql.WriteString(" ")
|
||||
}
|
||||
|
||||
sql.WriteString("UPDATE ")
|
||||
sql.WriteString(strings.Join(d.Tables, ", "))
|
||||
|
||||
sql.WriteString(" SET ")
|
||||
setSqls := make([]string, len(d.SetClauses))
|
||||
for i, setClause := range d.SetClauses {
|
||||
var valSql string
|
||||
if vs, ok := setClause.value.(Sqlizer); ok {
|
||||
vsql, vargs, err := vs.ToSql()
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
if _, ok := vs.(SelectBuilder); ok {
|
||||
valSql = fmt.Sprintf("(%s)", vsql)
|
||||
} else {
|
||||
valSql = vsql
|
||||
}
|
||||
args = append(args, vargs...)
|
||||
} else {
|
||||
valSql = "?"
|
||||
args = append(args, setClause.value)
|
||||
}
|
||||
setSqls[i] = fmt.Sprintf("%s = %s", setClause.column, valSql)
|
||||
}
|
||||
sql.WriteString(strings.Join(setSqls, ", "))
|
||||
|
||||
if len(d.From) > 0 {
|
||||
sql.WriteString(" FROM ")
|
||||
args, err = appendToSql(d.From, sql, ", ", args)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if len(d.WhereParts) > 0 {
|
||||
sql.WriteString(" WHERE ")
|
||||
args, err = appendToSql(d.WhereParts, sql, " AND ", args)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if len(d.OrderBys) > 0 {
|
||||
sql.WriteString(" ORDER BY ")
|
||||
sql.WriteString(strings.Join(d.OrderBys, ", "))
|
||||
}
|
||||
|
||||
if len(d.Limit) > 0 {
|
||||
sql.WriteString(" LIMIT ")
|
||||
sql.WriteString(d.Limit)
|
||||
}
|
||||
|
||||
if len(d.Offset) > 0 {
|
||||
sql.WriteString(" OFFSET ")
|
||||
sql.WriteString(d.Offset)
|
||||
}
|
||||
|
||||
if len(d.Suffixes) > 0 {
|
||||
sql.WriteString(" ")
|
||||
args, err = appendToSql(d.Suffixes, sql, " ", args)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
sqlStr, err = d.PlaceholderFormat.ReplacePlaceholders(sql.String())
|
||||
return
|
||||
}
|
||||
|
||||
// Builder
|
||||
|
||||
// UpdateBuilder builds SQL UPDATE statements.
|
||||
type UpdateBuilder builder.Builder
|
||||
|
||||
func init() {
|
||||
builder.Register(UpdateBuilder{}, updateData{})
|
||||
}
|
||||
|
||||
// Format methods
|
||||
|
||||
// PlaceholderFormat sets PlaceholderFormat (e.g. Question or Dollar) for the
|
||||
// query.
|
||||
func (b UpdateBuilder) PlaceholderFormat(f PlaceholderFormat) UpdateBuilder {
|
||||
return builder.Set(b, "PlaceholderFormat", f).(UpdateBuilder)
|
||||
}
|
||||
|
||||
// Runner methods
|
||||
|
||||
// RunWith sets a Runner (like database/sql.DB) to be used with e.g. Exec.
|
||||
func (b UpdateBuilder) RunWith(runner BaseRunner) UpdateBuilder {
|
||||
return setRunWith(b, runner).(UpdateBuilder)
|
||||
}
|
||||
|
||||
// Exec builds and Execs the query with the Runner set by RunWith.
|
||||
func (b UpdateBuilder) Exec() (sql.Result, error) {
|
||||
data := builder.GetStruct(b).(updateData)
|
||||
return data.Exec()
|
||||
}
|
||||
|
||||
func (b UpdateBuilder) Query() (*sql.Rows, error) {
|
||||
data := builder.GetStruct(b).(updateData)
|
||||
return data.Query()
|
||||
}
|
||||
|
||||
func (b UpdateBuilder) QueryRow() RowScanner {
|
||||
data := builder.GetStruct(b).(updateData)
|
||||
return data.QueryRow()
|
||||
}
|
||||
|
||||
func (b UpdateBuilder) Scan(dest ...interface{}) error {
|
||||
return b.QueryRow().Scan(dest...)
|
||||
}
|
||||
|
||||
// SQL methods
|
||||
|
||||
// ToSql builds the query into a SQL string and bound args.
|
||||
func (b UpdateBuilder) ToSql() (string, []interface{}, error) {
|
||||
data := builder.GetStruct(b).(updateData)
|
||||
return data.ToSql()
|
||||
}
|
||||
|
||||
// MustSql builds the query into a SQL string and bound args.
|
||||
// It panics if there are any errors.
|
||||
func (b UpdateBuilder) MustSql() (string, []interface{}) {
|
||||
sql, args, err := b.ToSql()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return sql, args
|
||||
}
|
||||
|
||||
// Prefix adds an expression to the beginning of the query
|
||||
func (b UpdateBuilder) Prefix(sql string, args ...interface{}) UpdateBuilder {
|
||||
return b.PrefixExpr(Expr(sql, args...))
|
||||
}
|
||||
|
||||
// PrefixExpr adds an expression to the very beginning of the query
|
||||
func (b UpdateBuilder) PrefixExpr(expr Sqlizer) UpdateBuilder {
|
||||
return builder.Append(b, "Prefixes", expr).(UpdateBuilder)
|
||||
}
|
||||
|
||||
// Table sets the table to be updated.
|
||||
// Additional tables are used with supporting databases to implicitly join.
|
||||
func (b UpdateBuilder) Table(tables ...string) UpdateBuilder {
|
||||
nonEmptyTables := make([]string, 0, len(tables))
|
||||
for _, table := range tables {
|
||||
if table != "" {
|
||||
nonEmptyTables = append(nonEmptyTables, table)
|
||||
}
|
||||
}
|
||||
|
||||
return builder.Set(b, "Tables", nonEmptyTables).(UpdateBuilder)
|
||||
}
|
||||
|
||||
// Set adds SET clauses to the query.
|
||||
func (b UpdateBuilder) Set(column string, value interface{}) UpdateBuilder {
|
||||
return builder.Append(b, "SetClauses", setClause{column: column, value: value}).(UpdateBuilder)
|
||||
}
|
||||
|
||||
// SetMap is a convenience method which calls .Set for each key/value pair in clauses.
|
||||
func (b UpdateBuilder) SetMap(clauses map[string]interface{}) UpdateBuilder {
|
||||
keys := make([]string, len(clauses))
|
||||
i := 0
|
||||
for key := range clauses {
|
||||
keys[i] = key
|
||||
i++
|
||||
}
|
||||
sort.Strings(keys)
|
||||
for _, key := range keys {
|
||||
val, _ := clauses[key]
|
||||
b = b.Set(key, val)
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// From adds FROM clause to the query
|
||||
// FROM is valid construct in postgresql only.
|
||||
func (b UpdateBuilder) From(from string) UpdateBuilder {
|
||||
return builder.Append(b, "From", newPart(from)).(UpdateBuilder)
|
||||
}
|
||||
|
||||
// FromSelect sets a subquery into the FROM clause of the query.
|
||||
func (b UpdateBuilder) FromSelect(from SelectBuilder, alias string) UpdateBuilder {
|
||||
// Prevent misnumbered parameters in nested selects (#183).
|
||||
from = from.PlaceholderFormat(Question)
|
||||
return builder.Append(b, "From", Alias(from, alias)).(UpdateBuilder)
|
||||
}
|
||||
|
||||
// Where adds WHERE expressions to the query.
|
||||
//
|
||||
// See SelectBuilder.Where for more information.
|
||||
func (b UpdateBuilder) Where(pred interface{}, args ...interface{}) UpdateBuilder {
|
||||
return builder.Append(b, "WhereParts", newWherePart(pred, args...)).(UpdateBuilder)
|
||||
}
|
||||
|
||||
// OrderBy adds ORDER BY expressions to the query.
|
||||
func (b UpdateBuilder) OrderBy(orderBys ...string) UpdateBuilder {
|
||||
return builder.Extend(b, "OrderBys", orderBys).(UpdateBuilder)
|
||||
}
|
||||
|
||||
// Limit sets a LIMIT clause on the query.
|
||||
func (b UpdateBuilder) Limit(limit uint64) UpdateBuilder {
|
||||
return builder.Set(b, "Limit", fmt.Sprintf("%d", limit)).(UpdateBuilder)
|
||||
}
|
||||
|
||||
// Offset sets a OFFSET clause on the query.
|
||||
func (b UpdateBuilder) Offset(offset uint64) UpdateBuilder {
|
||||
return builder.Set(b, "Offset", fmt.Sprintf("%d", offset)).(UpdateBuilder)
|
||||
}
|
||||
|
||||
// Suffix adds an expression to the end of the query
|
||||
func (b UpdateBuilder) Suffix(sql string, args ...interface{}) UpdateBuilder {
|
||||
return b.SuffixExpr(Expr(sql, args...))
|
||||
}
|
||||
|
||||
// SuffixExpr adds an expression to the end of the query
|
||||
func (b UpdateBuilder) SuffixExpr(expr Sqlizer) UpdateBuilder {
|
||||
return builder.Append(b, "Suffixes", expr).(UpdateBuilder)
|
||||
}
|
||||
69
vendor/github.com/Masterminds/squirrel/update_ctx.go
generated
vendored
69
vendor/github.com/Masterminds/squirrel/update_ctx.go
generated
vendored
|
|
@ -1,69 +0,0 @@
|
|||
// +build go1.8
|
||||
|
||||
package squirrel
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
|
||||
"github.com/lann/builder"
|
||||
)
|
||||
|
||||
func (d *updateData) ExecContext(ctx context.Context) (sql.Result, error) {
|
||||
if d.RunWith == nil {
|
||||
return nil, RunnerNotSet
|
||||
}
|
||||
ctxRunner, ok := d.RunWith.(ExecerContext)
|
||||
if !ok {
|
||||
return nil, NoContextSupport
|
||||
}
|
||||
return ExecContextWith(ctx, ctxRunner, d)
|
||||
}
|
||||
|
||||
func (d *updateData) QueryContext(ctx context.Context) (*sql.Rows, error) {
|
||||
if d.RunWith == nil {
|
||||
return nil, RunnerNotSet
|
||||
}
|
||||
ctxRunner, ok := d.RunWith.(QueryerContext)
|
||||
if !ok {
|
||||
return nil, NoContextSupport
|
||||
}
|
||||
return QueryContextWith(ctx, ctxRunner, d)
|
||||
}
|
||||
|
||||
func (d *updateData) QueryRowContext(ctx context.Context) RowScanner {
|
||||
if d.RunWith == nil {
|
||||
return &Row{err: RunnerNotSet}
|
||||
}
|
||||
queryRower, ok := d.RunWith.(QueryRowerContext)
|
||||
if !ok {
|
||||
if _, ok := d.RunWith.(QueryerContext); !ok {
|
||||
return &Row{err: RunnerNotQueryRunner}
|
||||
}
|
||||
return &Row{err: NoContextSupport}
|
||||
}
|
||||
return QueryRowContextWith(ctx, queryRower, d)
|
||||
}
|
||||
|
||||
// ExecContext builds and ExecContexts the query with the Runner set by RunWith.
|
||||
func (b UpdateBuilder) ExecContext(ctx context.Context) (sql.Result, error) {
|
||||
data := builder.GetStruct(b).(updateData)
|
||||
return data.ExecContext(ctx)
|
||||
}
|
||||
|
||||
// QueryContext builds and QueryContexts the query with the Runner set by RunWith.
|
||||
func (b UpdateBuilder) QueryContext(ctx context.Context) (*sql.Rows, error) {
|
||||
data := builder.GetStruct(b).(updateData)
|
||||
return data.QueryContext(ctx)
|
||||
}
|
||||
|
||||
// QueryRowContext builds and QueryRowContexts the query with the Runner set by RunWith.
|
||||
func (b UpdateBuilder) QueryRowContext(ctx context.Context) RowScanner {
|
||||
data := builder.GetStruct(b).(updateData)
|
||||
return data.QueryRowContext(ctx)
|
||||
}
|
||||
|
||||
// ScanContext is a shortcut for QueryRowContext().Scan.
|
||||
func (b UpdateBuilder) ScanContext(ctx context.Context, dest ...interface{}) error {
|
||||
return b.QueryRowContext(ctx).Scan(dest...)
|
||||
}
|
||||
30
vendor/github.com/Masterminds/squirrel/where.go
generated
vendored
30
vendor/github.com/Masterminds/squirrel/where.go
generated
vendored
|
|
@ -1,30 +0,0 @@
|
|||
package squirrel
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type wherePart part
|
||||
|
||||
func newWherePart(pred interface{}, args ...interface{}) Sqlizer {
|
||||
return &wherePart{pred: pred, args: args}
|
||||
}
|
||||
|
||||
func (p wherePart) ToSql() (sql string, args []interface{}, err error) {
|
||||
switch pred := p.pred.(type) {
|
||||
case nil:
|
||||
// no-op
|
||||
case rawSqlizer:
|
||||
return pred.toSqlRaw()
|
||||
case Sqlizer:
|
||||
return pred.ToSql()
|
||||
case map[string]interface{}:
|
||||
return Eq(pred).ToSql()
|
||||
case string:
|
||||
sql = pred
|
||||
args = p.args
|
||||
default:
|
||||
err = fmt.Errorf("expected string-keyed map or string, not %T", pred)
|
||||
}
|
||||
return
|
||||
}
|
||||
1
vendor/github.com/PuerkitoBio/goquery/.gitattributes
generated
vendored
1
vendor/github.com/PuerkitoBio/goquery/.gitattributes
generated
vendored
|
|
@ -1 +0,0 @@
|
|||
testdata/* linguist-vendored
|
||||
16
vendor/github.com/PuerkitoBio/goquery/.gitignore
generated
vendored
16
vendor/github.com/PuerkitoBio/goquery/.gitignore
generated
vendored
|
|
@ -1,16 +0,0 @@
|
|||
# editor temporary files
|
||||
*.sublime-*
|
||||
.DS_Store
|
||||
*.swp
|
||||
#*.*#
|
||||
tags
|
||||
|
||||
# direnv config
|
||||
.env*
|
||||
|
||||
# test binaries
|
||||
*.test
|
||||
|
||||
# coverage and profilte outputs
|
||||
*.out
|
||||
|
||||
12
vendor/github.com/PuerkitoBio/goquery/LICENSE
generated
vendored
12
vendor/github.com/PuerkitoBio/goquery/LICENSE
generated
vendored
|
|
@ -1,12 +0,0 @@
|
|||
Copyright (c) 2012-2021, Martin Angers & Contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
195
vendor/github.com/PuerkitoBio/goquery/README.md
generated
vendored
195
vendor/github.com/PuerkitoBio/goquery/README.md
generated
vendored
|
|
@ -1,195 +0,0 @@
|
|||
# goquery - a little like that j-thing, only in Go
|
||||
|
||||
[](https://github.com/PuerkitoBio/goquery/actions)
|
||||
[](https://pkg.go.dev/github.com/PuerkitoBio/goquery)
|
||||
[](https://sourcegraph.com/github.com/PuerkitoBio/goquery?badge)
|
||||
|
||||
goquery brings a syntax and a set of features similar to [jQuery][] to the [Go language][go]. It is based on Go's [net/html package][html] and the CSS Selector library [cascadia][]. Since the net/html parser returns nodes, and not a full-featured DOM tree, jQuery's stateful manipulation functions (like height(), css(), detach()) have been left off.
|
||||
|
||||
Also, because the net/html parser requires UTF-8 encoding, so does goquery: it is the caller's responsibility to ensure that the source document provides UTF-8 encoded HTML. See the [wiki][] for various options to do this.
|
||||
|
||||
Syntax-wise, it is as close as possible to jQuery, with the same function names when possible, and that warm and fuzzy chainable interface. jQuery being the ultra-popular library that it is, I felt that writing a similar HTML-manipulating library was better to follow its API than to start anew (in the same spirit as Go's `fmt` package), even though some of its methods are less than intuitive (looking at you, [index()][index]...).
|
||||
|
||||
## Table of Contents
|
||||
|
||||
* [Installation](#installation)
|
||||
* [Changelog](#changelog)
|
||||
* [API](#api)
|
||||
* [Examples](#examples)
|
||||
* [Related Projects](#related-projects)
|
||||
* [Support](#support)
|
||||
* [License](#license)
|
||||
|
||||
## Installation
|
||||
|
||||
Please note that because of the net/html dependency, goquery requires Go1.1+ and is tested on Go1.7+.
|
||||
|
||||
$ go get github.com/PuerkitoBio/goquery
|
||||
|
||||
(optional) To run unit tests:
|
||||
|
||||
$ cd $GOPATH/src/github.com/PuerkitoBio/goquery
|
||||
$ go test
|
||||
|
||||
(optional) To run benchmarks (warning: it runs for a few minutes):
|
||||
|
||||
$ cd $GOPATH/src/github.com/PuerkitoBio/goquery
|
||||
$ go test -bench=".*"
|
||||
|
||||
## Changelog
|
||||
|
||||
**Note that goquery's API is now stable, and will not break.**
|
||||
|
||||
* **2021-10-25 (v1.8.0)** : Add `Render` function to render a `Selection` to an `io.Writer` (thanks [@anthonygedeon](https://github.com/anthonygedeon)).
|
||||
* **2021-07-11 (v1.7.1)** : Update go.mod dependencies and add dependabot config (thanks [@jauderho](https://github.com/jauderho)).
|
||||
* **2021-06-14 (v1.7.0)** : Add `Single` and `SingleMatcher` functions to optimize first-match selection (thanks [@gdollardollar](https://github.com/gdollardollar)).
|
||||
* **2021-01-11 (v1.6.1)** : Fix panic when calling `{Prepend,Append,Set}Html` on a `Selection` that contains non-Element nodes.
|
||||
* **2020-10-08 (v1.6.0)** : Parse html in context of the container node for all functions that deal with html strings (`AfterHtml`, `AppendHtml`, etc.). Thanks to [@thiemok][thiemok] and [@davidjwilkins][djw] for their work on this.
|
||||
* **2020-02-04 (v1.5.1)** : Update module dependencies.
|
||||
* **2018-11-15 (v1.5.0)** : Go module support (thanks @Zaba505).
|
||||
* **2018-06-07 (v1.4.1)** : Add `NewDocumentFromReader` examples.
|
||||
* **2018-03-24 (v1.4.0)** : Deprecate `NewDocument(url)` and `NewDocumentFromResponse(response)`.
|
||||
* **2018-01-28 (v1.3.0)** : Add `ToEnd` constant to `Slice` until the end of the selection (thanks to @davidjwilkins for raising the issue).
|
||||
* **2018-01-11 (v1.2.0)** : Add `AddBack*` and deprecate `AndSelf` (thanks to @davidjwilkins).
|
||||
* **2017-02-12 (v1.1.0)** : Add `SetHtml` and `SetText` (thanks to @glebtv).
|
||||
* **2016-12-29 (v1.0.2)** : Optimize allocations for `Selection.Text` (thanks to @radovskyb).
|
||||
* **2016-08-28 (v1.0.1)** : Optimize performance for large documents.
|
||||
* **2016-07-27 (v1.0.0)** : Tag version 1.0.0.
|
||||
* **2016-06-15** : Invalid selector strings internally compile to a `Matcher` implementation that never matches any node (instead of a panic). So for example, `doc.Find("~")` returns an empty `*Selection` object.
|
||||
* **2016-02-02** : Add `NodeName` utility function similar to the DOM's `nodeName` property. It returns the tag name of the first element in a selection, and other relevant values of non-element nodes (see [doc][] for details). Add `OuterHtml` utility function similar to the DOM's `outerHTML` property (named `OuterHtml` in small caps for consistency with the existing `Html` method on the `Selection`).
|
||||
* **2015-04-20** : Add `AttrOr` helper method to return the attribute's value or a default value if absent. Thanks to [piotrkowalczuk][piotr].
|
||||
* **2015-02-04** : Add more manipulation functions - Prepend* - thanks again to [Andrew Stone][thatguystone].
|
||||
* **2014-11-28** : Add more manipulation functions - ReplaceWith*, Wrap* and Unwrap - thanks again to [Andrew Stone][thatguystone].
|
||||
* **2014-11-07** : Add manipulation functions (thanks to [Andrew Stone][thatguystone]) and `*Matcher` functions, that receive compiled cascadia selectors instead of selector strings, thus avoiding potential panics thrown by goquery via `cascadia.MustCompile` calls. This results in better performance (selectors can be compiled once and reused) and more idiomatic error handling (you can handle cascadia's compilation errors, instead of recovering from panics, which had been bugging me for a long time). Note that the actual type expected is a `Matcher` interface, that `cascadia.Selector` implements. Other matcher implementations could be used.
|
||||
* **2014-11-06** : Change import paths of net/html to golang.org/x/net/html (see https://groups.google.com/forum/#!topic/golang-nuts/eD8dh3T9yyA). Make sure to update your code to use the new import path too when you call goquery with `html.Node`s.
|
||||
* **v0.3.2** : Add `NewDocumentFromReader()` (thanks jweir) which allows creating a goquery document from an io.Reader.
|
||||
* **v0.3.1** : Add `NewDocumentFromResponse()` (thanks assassingj) which allows creating a goquery document from an http response.
|
||||
* **v0.3.0** : Add `EachWithBreak()` which allows to break out of an `Each()` loop by returning false. This function was added instead of changing the existing `Each()` to avoid breaking compatibility.
|
||||
* **v0.2.1** : Make go-getable, now that [go.net/html is Go1.0-compatible][gonet] (thanks to @matrixik for pointing this out).
|
||||
* **v0.2.0** : Add support for negative indices in Slice(). **BREAKING CHANGE** `Document.Root` is removed, `Document` is now a `Selection` itself (a selection of one, the root element, just like `Document.Root` was before). Add jQuery's Closest() method.
|
||||
* **v0.1.1** : Add benchmarks to use as baseline for refactorings, refactor Next...() and Prev...() methods to use the new html package's linked list features (Next/PrevSibling, FirstChild). Good performance boost (40+% in some cases).
|
||||
* **v0.1.0** : Initial release.
|
||||
|
||||
## API
|
||||
|
||||
goquery exposes two structs, `Document` and `Selection`, and the `Matcher` interface. Unlike jQuery, which is loaded as part of a DOM document, and thus acts on its containing document, goquery doesn't know which HTML document to act upon. So it needs to be told, and that's what the `Document` type is for. It holds the root document node as the initial Selection value to manipulate.
|
||||
|
||||
jQuery often has many variants for the same function (no argument, a selector string argument, a jQuery object argument, a DOM element argument, ...). Instead of exposing the same features in goquery as a single method with variadic empty interface arguments, statically-typed signatures are used following this naming convention:
|
||||
|
||||
* When the jQuery equivalent can be called with no argument, it has the same name as jQuery for the no argument signature (e.g.: `Prev()`), and the version with a selector string argument is called `XxxFiltered()` (e.g.: `PrevFiltered()`)
|
||||
* When the jQuery equivalent **requires** one argument, the same name as jQuery is used for the selector string version (e.g.: `Is()`)
|
||||
* The signatures accepting a jQuery object as argument are defined in goquery as `XxxSelection()` and take a `*Selection` object as argument (e.g.: `FilterSelection()`)
|
||||
* The signatures accepting a DOM element as argument in jQuery are defined in goquery as `XxxNodes()` and take a variadic argument of type `*html.Node` (e.g.: `FilterNodes()`)
|
||||
* The signatures accepting a function as argument in jQuery are defined in goquery as `XxxFunction()` and take a function as argument (e.g.: `FilterFunction()`)
|
||||
* The goquery methods that can be called with a selector string have a corresponding version that take a `Matcher` interface and are defined as `XxxMatcher()` (e.g.: `IsMatcher()`)
|
||||
|
||||
Utility functions that are not in jQuery but are useful in Go are implemented as functions (that take a `*Selection` as parameter), to avoid a potential naming clash on the `*Selection`'s methods (reserved for jQuery-equivalent behaviour).
|
||||
|
||||
The complete [package reference documentation can be found here][doc].
|
||||
|
||||
Please note that Cascadia's selectors do not necessarily match all supported selectors of jQuery (Sizzle). See the [cascadia project][cascadia] for details. Invalid selector strings compile to a `Matcher` that fails to match any node. Behaviour of the various functions that take a selector string as argument follows from that fact, e.g. (where `~` is an invalid selector string):
|
||||
|
||||
* `Find("~")` returns an empty selection because the selector string doesn't match anything.
|
||||
* `Add("~")` returns a new selection that holds the same nodes as the original selection, because it didn't add any node (selector string didn't match anything).
|
||||
* `ParentsFiltered("~")` returns an empty selection because the selector string doesn't match anything.
|
||||
* `ParentsUntil("~")` returns all parents of the selection because the selector string didn't match any element to stop before the top element.
|
||||
|
||||
## Examples
|
||||
|
||||
See some tips and tricks in the [wiki][].
|
||||
|
||||
Adapted from example_test.go:
|
||||
|
||||
```Go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
|
||||
"github.com/PuerkitoBio/goquery"
|
||||
)
|
||||
|
||||
func ExampleScrape() {
|
||||
// Request the HTML page.
|
||||
res, err := http.Get("http://metalsucks.net")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer res.Body.Close()
|
||||
if res.StatusCode != 200 {
|
||||
log.Fatalf("status code error: %d %s", res.StatusCode, res.Status)
|
||||
}
|
||||
|
||||
// Load the HTML document
|
||||
doc, err := goquery.NewDocumentFromReader(res.Body)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// Find the review items
|
||||
doc.Find(".left-content article .post-title").Each(func(i int, s *goquery.Selection) {
|
||||
// For each item found, get the title
|
||||
title := s.Find("a").Text()
|
||||
fmt.Printf("Review %d: %s\n", i, title)
|
||||
})
|
||||
}
|
||||
|
||||
func main() {
|
||||
ExampleScrape()
|
||||
}
|
||||
```
|
||||
|
||||
## Related Projects
|
||||
|
||||
- [Goq][goq], an HTML deserialization and scraping library based on goquery and struct tags.
|
||||
- [andybalholm/cascadia][cascadia], the CSS selector library used by goquery.
|
||||
- [suntong/cascadia][cascadiacli], a command-line interface to the cascadia CSS selector library, useful to test selectors.
|
||||
- [gocolly/colly](https://github.com/gocolly/colly), a lightning fast and elegant Scraping Framework
|
||||
- [gnulnx/goperf](https://github.com/gnulnx/goperf), a website performance test tool that also fetches static assets.
|
||||
- [MontFerret/ferret](https://github.com/MontFerret/ferret), declarative web scraping.
|
||||
- [tacusci/berrycms](https://github.com/tacusci/berrycms), a modern simple to use CMS with easy to write plugins
|
||||
- [Dataflow kit](https://github.com/slotix/dataflowkit), Web Scraping framework for Gophers.
|
||||
- [Geziyor](https://github.com/geziyor/geziyor), a fast web crawling & scraping framework for Go. Supports JS rendering.
|
||||
- [Pagser](https://github.com/foolin/pagser), a simple, easy, extensible, configurable HTML parser to struct based on goquery and struct tags.
|
||||
- [stitcherd](https://github.com/vhodges/stitcherd), A server for doing server side includes using css selectors and DOM updates.
|
||||
|
||||
## Support
|
||||
|
||||
There are a number of ways you can support the project:
|
||||
|
||||
* Use it, star it, build something with it, spread the word!
|
||||
- If you do build something open-source or otherwise publicly-visible, let me know so I can add it to the [Related Projects](#related-projects) section!
|
||||
* Raise issues to improve the project (note: doc typos and clarifications are issues too!)
|
||||
- Please search existing issues before opening a new one - it may have already been adressed.
|
||||
* Pull requests: please discuss new code in an issue first, unless the fix is really trivial.
|
||||
- Make sure new code is tested.
|
||||
- Be mindful of existing code - PRs that break existing code have a high probability of being declined, unless it fixes a serious issue.
|
||||
* Sponsor the developer
|
||||
- See the Github Sponsor button at the top of the repo on github
|
||||
- or via BuyMeACoffee.com, below
|
||||
|
||||
<a href="https://www.buymeacoffee.com/mna" target="_blank"><img src="https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png" alt="Buy Me A Coffee" style="height: 41px !important;width: 174px !important;box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;-webkit-box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;" ></a>
|
||||
|
||||
## License
|
||||
|
||||
The [BSD 3-Clause license][bsd], the same as the [Go language][golic]. Cascadia's license is [here][caslic].
|
||||
|
||||
[jquery]: http://jquery.com/
|
||||
[go]: http://golang.org/
|
||||
[cascadia]: https://github.com/andybalholm/cascadia
|
||||
[cascadiacli]: https://github.com/suntong/cascadia
|
||||
[bsd]: http://opensource.org/licenses/BSD-3-Clause
|
||||
[golic]: http://golang.org/LICENSE
|
||||
[caslic]: https://github.com/andybalholm/cascadia/blob/master/LICENSE
|
||||
[doc]: https://pkg.go.dev/github.com/PuerkitoBio/goquery
|
||||
[index]: http://api.jquery.com/index/
|
||||
[gonet]: https://github.com/golang/net/
|
||||
[html]: https://pkg.go.dev/golang.org/x/net/html
|
||||
[wiki]: https://github.com/PuerkitoBio/goquery/wiki/Tips-and-tricks
|
||||
[thatguystone]: https://github.com/thatguystone
|
||||
[piotr]: https://github.com/piotrkowalczuk
|
||||
[goq]: https://github.com/andrewstuart/goq
|
||||
[thiemok]: https://github.com/thiemok
|
||||
[djw]: https://github.com/davidjwilkins
|
||||
124
vendor/github.com/PuerkitoBio/goquery/array.go
generated
vendored
124
vendor/github.com/PuerkitoBio/goquery/array.go
generated
vendored
|
|
@ -1,124 +0,0 @@
|
|||
package goquery
|
||||
|
||||
import (
|
||||
"golang.org/x/net/html"
|
||||
)
|
||||
|
||||
const (
|
||||
maxUint = ^uint(0)
|
||||
maxInt = int(maxUint >> 1)
|
||||
|
||||
// ToEnd is a special index value that can be used as end index in a call
|
||||
// to Slice so that all elements are selected until the end of the Selection.
|
||||
// It is equivalent to passing (*Selection).Length().
|
||||
ToEnd = maxInt
|
||||
)
|
||||
|
||||
// First reduces the set of matched elements to the first in the set.
|
||||
// It returns a new Selection object, and an empty Selection object if the
|
||||
// the selection is empty.
|
||||
func (s *Selection) First() *Selection {
|
||||
return s.Eq(0)
|
||||
}
|
||||
|
||||
// Last reduces the set of matched elements to the last in the set.
|
||||
// It returns a new Selection object, and an empty Selection object if
|
||||
// the selection is empty.
|
||||
func (s *Selection) Last() *Selection {
|
||||
return s.Eq(-1)
|
||||
}
|
||||
|
||||
// Eq reduces the set of matched elements to the one at the specified index.
|
||||
// If a negative index is given, it counts backwards starting at the end of the
|
||||
// set. It returns a new Selection object, and an empty Selection object if the
|
||||
// index is invalid.
|
||||
func (s *Selection) Eq(index int) *Selection {
|
||||
if index < 0 {
|
||||
index += len(s.Nodes)
|
||||
}
|
||||
|
||||
if index >= len(s.Nodes) || index < 0 {
|
||||
return newEmptySelection(s.document)
|
||||
}
|
||||
|
||||
return s.Slice(index, index+1)
|
||||
}
|
||||
|
||||
// Slice reduces the set of matched elements to a subset specified by a range
|
||||
// of indices. The start index is 0-based and indicates the index of the first
|
||||
// element to select. The end index is 0-based and indicates the index at which
|
||||
// the elements stop being selected (the end index is not selected).
|
||||
//
|
||||
// The indices may be negative, in which case they represent an offset from the
|
||||
// end of the selection.
|
||||
//
|
||||
// The special value ToEnd may be specified as end index, in which case all elements
|
||||
// until the end are selected. This works both for a positive and negative start
|
||||
// index.
|
||||
func (s *Selection) Slice(start, end int) *Selection {
|
||||
if start < 0 {
|
||||
start += len(s.Nodes)
|
||||
}
|
||||
if end == ToEnd {
|
||||
end = len(s.Nodes)
|
||||
} else if end < 0 {
|
||||
end += len(s.Nodes)
|
||||
}
|
||||
return pushStack(s, s.Nodes[start:end])
|
||||
}
|
||||
|
||||
// Get retrieves the underlying node at the specified index.
|
||||
// Get without parameter is not implemented, since the node array is available
|
||||
// on the Selection object.
|
||||
func (s *Selection) Get(index int) *html.Node {
|
||||
if index < 0 {
|
||||
index += len(s.Nodes) // Negative index gets from the end
|
||||
}
|
||||
return s.Nodes[index]
|
||||
}
|
||||
|
||||
// Index returns the position of the first element within the Selection object
|
||||
// relative to its sibling elements.
|
||||
func (s *Selection) Index() int {
|
||||
if len(s.Nodes) > 0 {
|
||||
return newSingleSelection(s.Nodes[0], s.document).PrevAll().Length()
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
// IndexSelector returns the position of the first element within the
|
||||
// Selection object relative to the elements matched by the selector, or -1 if
|
||||
// not found.
|
||||
func (s *Selection) IndexSelector(selector string) int {
|
||||
if len(s.Nodes) > 0 {
|
||||
sel := s.document.Find(selector)
|
||||
return indexInSlice(sel.Nodes, s.Nodes[0])
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
// IndexMatcher returns the position of the first element within the
|
||||
// Selection object relative to the elements matched by the matcher, or -1 if
|
||||
// not found.
|
||||
func (s *Selection) IndexMatcher(m Matcher) int {
|
||||
if len(s.Nodes) > 0 {
|
||||
sel := s.document.FindMatcher(m)
|
||||
return indexInSlice(sel.Nodes, s.Nodes[0])
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
// IndexOfNode returns the position of the specified node within the Selection
|
||||
// object, or -1 if not found.
|
||||
func (s *Selection) IndexOfNode(node *html.Node) int {
|
||||
return indexInSlice(s.Nodes, node)
|
||||
}
|
||||
|
||||
// IndexOfSelection returns the position of the first node in the specified
|
||||
// Selection object within this Selection object, or -1 if not found.
|
||||
func (s *Selection) IndexOfSelection(sel *Selection) int {
|
||||
if sel != nil && len(sel.Nodes) > 0 {
|
||||
return indexInSlice(s.Nodes, sel.Nodes[0])
|
||||
}
|
||||
return -1
|
||||
}
|
||||
123
vendor/github.com/PuerkitoBio/goquery/doc.go
generated
vendored
123
vendor/github.com/PuerkitoBio/goquery/doc.go
generated
vendored
|
|
@ -1,123 +0,0 @@
|
|||
// Copyright (c) 2012-2016, Martin Angers & Contributors
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation and/or
|
||||
// other materials provided with the distribution.
|
||||
// * Neither the name of the author nor the names of its contributors may be used to
|
||||
// endorse or promote products derived from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
|
||||
// OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
// AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
|
||||
// WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
/*
|
||||
Package goquery implements features similar to jQuery, including the chainable
|
||||
syntax, to manipulate and query an HTML document.
|
||||
|
||||
It brings a syntax and a set of features similar to jQuery to the Go language.
|
||||
It is based on Go's net/html package and the CSS Selector library cascadia.
|
||||
Since the net/html parser returns nodes, and not a full-featured DOM
|
||||
tree, jQuery's stateful manipulation functions (like height(), css(), detach())
|
||||
have been left off.
|
||||
|
||||
Also, because the net/html parser requires UTF-8 encoding, so does goquery: it is
|
||||
the caller's responsibility to ensure that the source document provides UTF-8 encoded HTML.
|
||||
See the repository's wiki for various options on how to do this.
|
||||
|
||||
Syntax-wise, it is as close as possible to jQuery, with the same method names when
|
||||
possible, and that warm and fuzzy chainable interface. jQuery being the
|
||||
ultra-popular library that it is, writing a similar HTML-manipulating
|
||||
library was better to follow its API than to start anew (in the same spirit as
|
||||
Go's fmt package), even though some of its methods are less than intuitive (looking
|
||||
at you, index()...).
|
||||
|
||||
It is hosted on GitHub, along with additional documentation in the README.md
|
||||
file: https://github.com/puerkitobio/goquery
|
||||
|
||||
Please note that because of the net/html dependency, goquery requires Go1.1+.
|
||||
|
||||
The various methods are split into files based on the category of behavior.
|
||||
The three dots (...) indicate that various "overloads" are available.
|
||||
|
||||
* array.go : array-like positional manipulation of the selection.
|
||||
- Eq()
|
||||
- First()
|
||||
- Get()
|
||||
- Index...()
|
||||
- Last()
|
||||
- Slice()
|
||||
|
||||
* expand.go : methods that expand or augment the selection's set.
|
||||
- Add...()
|
||||
- AndSelf()
|
||||
- Union(), which is an alias for AddSelection()
|
||||
|
||||
* filter.go : filtering methods, that reduce the selection's set.
|
||||
- End()
|
||||
- Filter...()
|
||||
- Has...()
|
||||
- Intersection(), which is an alias of FilterSelection()
|
||||
- Not...()
|
||||
|
||||
* iteration.go : methods to loop over the selection's nodes.
|
||||
- Each()
|
||||
- EachWithBreak()
|
||||
- Map()
|
||||
|
||||
* manipulation.go : methods for modifying the document
|
||||
- After...()
|
||||
- Append...()
|
||||
- Before...()
|
||||
- Clone()
|
||||
- Empty()
|
||||
- Prepend...()
|
||||
- Remove...()
|
||||
- ReplaceWith...()
|
||||
- Unwrap()
|
||||
- Wrap...()
|
||||
- WrapAll...()
|
||||
- WrapInner...()
|
||||
|
||||
* property.go : methods that inspect and get the node's properties values.
|
||||
- Attr*(), RemoveAttr(), SetAttr()
|
||||
- AddClass(), HasClass(), RemoveClass(), ToggleClass()
|
||||
- Html()
|
||||
- Length()
|
||||
- Size(), which is an alias for Length()
|
||||
- Text()
|
||||
|
||||
* query.go : methods that query, or reflect, a node's identity.
|
||||
- Contains()
|
||||
- Is...()
|
||||
|
||||
* traversal.go : methods to traverse the HTML document tree.
|
||||
- Children...()
|
||||
- Contents()
|
||||
- Find...()
|
||||
- Next...()
|
||||
- Parent[s]...()
|
||||
- Prev...()
|
||||
- Siblings...()
|
||||
|
||||
* type.go : definition of the types exposed by goquery.
|
||||
- Document
|
||||
- Selection
|
||||
- Matcher
|
||||
|
||||
* utilities.go : definition of helper functions (and not methods on a *Selection)
|
||||
that are not part of jQuery, but are useful to goquery.
|
||||
- NodeName
|
||||
- OuterHtml
|
||||
*/
|
||||
package goquery
|
||||
70
vendor/github.com/PuerkitoBio/goquery/expand.go
generated
vendored
70
vendor/github.com/PuerkitoBio/goquery/expand.go
generated
vendored
|
|
@ -1,70 +0,0 @@
|
|||
package goquery
|
||||
|
||||
import "golang.org/x/net/html"
|
||||
|
||||
// Add adds the selector string's matching nodes to those in the current
|
||||
// selection and returns a new Selection object.
|
||||
// The selector string is run in the context of the document of the current
|
||||
// Selection object.
|
||||
func (s *Selection) Add(selector string) *Selection {
|
||||
return s.AddNodes(findWithMatcher([]*html.Node{s.document.rootNode}, compileMatcher(selector))...)
|
||||
}
|
||||
|
||||
// AddMatcher adds the matcher's matching nodes to those in the current
|
||||
// selection and returns a new Selection object.
|
||||
// The matcher is run in the context of the document of the current
|
||||
// Selection object.
|
||||
func (s *Selection) AddMatcher(m Matcher) *Selection {
|
||||
return s.AddNodes(findWithMatcher([]*html.Node{s.document.rootNode}, m)...)
|
||||
}
|
||||
|
||||
// AddSelection adds the specified Selection object's nodes to those in the
|
||||
// current selection and returns a new Selection object.
|
||||
func (s *Selection) AddSelection(sel *Selection) *Selection {
|
||||
if sel == nil {
|
||||
return s.AddNodes()
|
||||
}
|
||||
return s.AddNodes(sel.Nodes...)
|
||||
}
|
||||
|
||||
// Union is an alias for AddSelection.
|
||||
func (s *Selection) Union(sel *Selection) *Selection {
|
||||
return s.AddSelection(sel)
|
||||
}
|
||||
|
||||
// AddNodes adds the specified nodes to those in the
|
||||
// current selection and returns a new Selection object.
|
||||
func (s *Selection) AddNodes(nodes ...*html.Node) *Selection {
|
||||
return pushStack(s, appendWithoutDuplicates(s.Nodes, nodes, nil))
|
||||
}
|
||||
|
||||
// AndSelf adds the previous set of elements on the stack to the current set.
|
||||
// It returns a new Selection object containing the current Selection combined
|
||||
// with the previous one.
|
||||
// Deprecated: This function has been deprecated and is now an alias for AddBack().
|
||||
func (s *Selection) AndSelf() *Selection {
|
||||
return s.AddBack()
|
||||
}
|
||||
|
||||
// AddBack adds the previous set of elements on the stack to the current set.
|
||||
// It returns a new Selection object containing the current Selection combined
|
||||
// with the previous one.
|
||||
func (s *Selection) AddBack() *Selection {
|
||||
return s.AddSelection(s.prevSel)
|
||||
}
|
||||
|
||||
// AddBackFiltered reduces the previous set of elements on the stack to those that
|
||||
// match the selector string, and adds them to the current set.
|
||||
// It returns a new Selection object containing the current Selection combined
|
||||
// with the filtered previous one
|
||||
func (s *Selection) AddBackFiltered(selector string) *Selection {
|
||||
return s.AddSelection(s.prevSel.Filter(selector))
|
||||
}
|
||||
|
||||
// AddBackMatcher reduces the previous set of elements on the stack to those that match
|
||||
// the mateher, and adds them to the curernt set.
|
||||
// It returns a new Selection object containing the current Selection combined
|
||||
// with the filtered previous one
|
||||
func (s *Selection) AddBackMatcher(m Matcher) *Selection {
|
||||
return s.AddSelection(s.prevSel.FilterMatcher(m))
|
||||
}
|
||||
163
vendor/github.com/PuerkitoBio/goquery/filter.go
generated
vendored
163
vendor/github.com/PuerkitoBio/goquery/filter.go
generated
vendored
|
|
@ -1,163 +0,0 @@
|
|||
package goquery
|
||||
|
||||
import "golang.org/x/net/html"
|
||||
|
||||
// Filter reduces the set of matched elements to those that match the selector string.
|
||||
// It returns a new Selection object for this subset of matching elements.
|
||||
func (s *Selection) Filter(selector string) *Selection {
|
||||
return s.FilterMatcher(compileMatcher(selector))
|
||||
}
|
||||
|
||||
// FilterMatcher reduces the set of matched elements to those that match
|
||||
// the given matcher. It returns a new Selection object for this subset
|
||||
// of matching elements.
|
||||
func (s *Selection) FilterMatcher(m Matcher) *Selection {
|
||||
return pushStack(s, winnow(s, m, true))
|
||||
}
|
||||
|
||||
// Not removes elements from the Selection that match the selector string.
|
||||
// It returns a new Selection object with the matching elements removed.
|
||||
func (s *Selection) Not(selector string) *Selection {
|
||||
return s.NotMatcher(compileMatcher(selector))
|
||||
}
|
||||
|
||||
// NotMatcher removes elements from the Selection that match the given matcher.
|
||||
// It returns a new Selection object with the matching elements removed.
|
||||
func (s *Selection) NotMatcher(m Matcher) *Selection {
|
||||
return pushStack(s, winnow(s, m, false))
|
||||
}
|
||||
|
||||
// FilterFunction reduces the set of matched elements to those that pass the function's test.
|
||||
// It returns a new Selection object for this subset of elements.
|
||||
func (s *Selection) FilterFunction(f func(int, *Selection) bool) *Selection {
|
||||
return pushStack(s, winnowFunction(s, f, true))
|
||||
}
|
||||
|
||||
// NotFunction removes elements from the Selection that pass the function's test.
|
||||
// It returns a new Selection object with the matching elements removed.
|
||||
func (s *Selection) NotFunction(f func(int, *Selection) bool) *Selection {
|
||||
return pushStack(s, winnowFunction(s, f, false))
|
||||
}
|
||||
|
||||
// FilterNodes reduces the set of matched elements to those that match the specified nodes.
|
||||
// It returns a new Selection object for this subset of elements.
|
||||
func (s *Selection) FilterNodes(nodes ...*html.Node) *Selection {
|
||||
return pushStack(s, winnowNodes(s, nodes, true))
|
||||
}
|
||||
|
||||
// NotNodes removes elements from the Selection that match the specified nodes.
|
||||
// It returns a new Selection object with the matching elements removed.
|
||||
func (s *Selection) NotNodes(nodes ...*html.Node) *Selection {
|
||||
return pushStack(s, winnowNodes(s, nodes, false))
|
||||
}
|
||||
|
||||
// FilterSelection reduces the set of matched elements to those that match a
|
||||
// node in the specified Selection object.
|
||||
// It returns a new Selection object for this subset of elements.
|
||||
func (s *Selection) FilterSelection(sel *Selection) *Selection {
|
||||
if sel == nil {
|
||||
return pushStack(s, winnowNodes(s, nil, true))
|
||||
}
|
||||
return pushStack(s, winnowNodes(s, sel.Nodes, true))
|
||||
}
|
||||
|
||||
// NotSelection removes elements from the Selection that match a node in the specified
|
||||
// Selection object. It returns a new Selection object with the matching elements removed.
|
||||
func (s *Selection) NotSelection(sel *Selection) *Selection {
|
||||
if sel == nil {
|
||||
return pushStack(s, winnowNodes(s, nil, false))
|
||||
}
|
||||
return pushStack(s, winnowNodes(s, sel.Nodes, false))
|
||||
}
|
||||
|
||||
// Intersection is an alias for FilterSelection.
|
||||
func (s *Selection) Intersection(sel *Selection) *Selection {
|
||||
return s.FilterSelection(sel)
|
||||
}
|
||||
|
||||
// Has reduces the set of matched elements to those that have a descendant
|
||||
// that matches the selector.
|
||||
// It returns a new Selection object with the matching elements.
|
||||
func (s *Selection) Has(selector string) *Selection {
|
||||
return s.HasSelection(s.document.Find(selector))
|
||||
}
|
||||
|
||||
// HasMatcher reduces the set of matched elements to those that have a descendant
|
||||
// that matches the matcher.
|
||||
// It returns a new Selection object with the matching elements.
|
||||
func (s *Selection) HasMatcher(m Matcher) *Selection {
|
||||
return s.HasSelection(s.document.FindMatcher(m))
|
||||
}
|
||||
|
||||
// HasNodes reduces the set of matched elements to those that have a
|
||||
// descendant that matches one of the nodes.
|
||||
// It returns a new Selection object with the matching elements.
|
||||
func (s *Selection) HasNodes(nodes ...*html.Node) *Selection {
|
||||
return s.FilterFunction(func(_ int, sel *Selection) bool {
|
||||
// Add all nodes that contain one of the specified nodes
|
||||
for _, n := range nodes {
|
||||
if sel.Contains(n) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
})
|
||||
}
|
||||
|
||||
// HasSelection reduces the set of matched elements to those that have a
|
||||
// descendant that matches one of the nodes of the specified Selection object.
|
||||
// It returns a new Selection object with the matching elements.
|
||||
func (s *Selection) HasSelection(sel *Selection) *Selection {
|
||||
if sel == nil {
|
||||
return s.HasNodes()
|
||||
}
|
||||
return s.HasNodes(sel.Nodes...)
|
||||
}
|
||||
|
||||
// End ends the most recent filtering operation in the current chain and
|
||||
// returns the set of matched elements to its previous state.
|
||||
func (s *Selection) End() *Selection {
|
||||
if s.prevSel != nil {
|
||||
return s.prevSel
|
||||
}
|
||||
return newEmptySelection(s.document)
|
||||
}
|
||||
|
||||
// Filter based on the matcher, and the indicator to keep (Filter) or
|
||||
// to get rid of (Not) the matching elements.
|
||||
func winnow(sel *Selection, m Matcher, keep bool) []*html.Node {
|
||||
// Optimize if keep is requested
|
||||
if keep {
|
||||
return m.Filter(sel.Nodes)
|
||||
}
|
||||
// Use grep
|
||||
return grep(sel, func(i int, s *Selection) bool {
|
||||
return !m.Match(s.Get(0))
|
||||
})
|
||||
}
|
||||
|
||||
// Filter based on an array of nodes, and the indicator to keep (Filter) or
|
||||
// to get rid of (Not) the matching elements.
|
||||
func winnowNodes(sel *Selection, nodes []*html.Node, keep bool) []*html.Node {
|
||||
if len(nodes)+len(sel.Nodes) < minNodesForSet {
|
||||
return grep(sel, func(i int, s *Selection) bool {
|
||||
return isInSlice(nodes, s.Get(0)) == keep
|
||||
})
|
||||
}
|
||||
|
||||
set := make(map[*html.Node]bool)
|
||||
for _, n := range nodes {
|
||||
set[n] = true
|
||||
}
|
||||
return grep(sel, func(i int, s *Selection) bool {
|
||||
return set[s.Get(0)] == keep
|
||||
})
|
||||
}
|
||||
|
||||
// Filter based on a function test, and the indicator to keep (Filter) or
|
||||
// to get rid of (Not) the matching elements.
|
||||
func winnowFunction(sel *Selection, f func(int, *Selection) bool, keep bool) []*html.Node {
|
||||
return grep(sel, func(i int, s *Selection) bool {
|
||||
return f(i, s) == keep
|
||||
})
|
||||
}
|
||||
39
vendor/github.com/PuerkitoBio/goquery/iteration.go
generated
vendored
39
vendor/github.com/PuerkitoBio/goquery/iteration.go
generated
vendored
|
|
@ -1,39 +0,0 @@
|
|||
package goquery
|
||||
|
||||
// Each iterates over a Selection object, executing a function for each
|
||||
// matched element. It returns the current Selection object. The function
|
||||
// f is called for each element in the selection with the index of the
|
||||
// element in that selection starting at 0, and a *Selection that contains
|
||||
// only that element.
|
||||
func (s *Selection) Each(f func(int, *Selection)) *Selection {
|
||||
for i, n := range s.Nodes {
|
||||
f(i, newSingleSelection(n, s.document))
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// EachWithBreak iterates over a Selection object, executing a function for each
|
||||
// matched element. It is identical to Each except that it is possible to break
|
||||
// out of the loop by returning false in the callback function. It returns the
|
||||
// current Selection object.
|
||||
func (s *Selection) EachWithBreak(f func(int, *Selection) bool) *Selection {
|
||||
for i, n := range s.Nodes {
|
||||
if !f(i, newSingleSelection(n, s.document)) {
|
||||
return s
|
||||
}
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// Map passes each element in the current matched set through a function,
|
||||
// producing a slice of string holding the returned values. The function
|
||||
// f is called for each element in the selection with the index of the
|
||||
// element in that selection starting at 0, and a *Selection that contains
|
||||
// only that element.
|
||||
func (s *Selection) Map(f func(int, *Selection) string) (result []string) {
|
||||
for i, n := range s.Nodes {
|
||||
result = append(result, f(i, newSingleSelection(n, s.document)))
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue