arm64 support and build update (#190)

This commit is contained in:
Atanas Koralski 2021-09-28 12:07:25 -07:00 коммит произвёл GitHub
Родитель e99c79aa4d
Коммит 6ff686b62f
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
41 изменённых файлов: 1421 добавлений и 895 удалений

121
Godeps/Godeps.json сгенерированный
Просмотреть файл

@ -1,121 +0,0 @@
{
"ImportPath": "github.com/Azure/custom-script-extension-linux",
"GoVersion": "go1.6",
"GodepVersion": "v74",
"Packages": [
"./..."
],
"Deps": [
{
"ImportPath": "github.com/Azure/azure-docker-extension/pkg/vmextension",
"Comment": "1.1.1606092330-20-g0dd2f19",
"Rev": "0dd2f199467db78e91d28c30d8595d1bcaf776de"
},
{
"ImportPath": "github.com/Azure/azure-docker-extension/pkg/vmextension/status",
"Comment": "1.1.1606092330-20-g0dd2f19",
"Rev": "0dd2f199467db78e91d28c30d8595d1bcaf776de"
},
{
"ImportPath": "github.com/Azure/azure-sdk-for-go/storage",
"Comment": "v3.1.0-beta-18-g87de771",
"Rev": "87de771fcdf5ec4341f3842f74b5bb98652b10f7"
},
{
"ImportPath": "github.com/ahmetalpbalkan/go-httpbin",
"Rev": "8817b883dae18c2cf82e5af7b4d4f4674de24b09"
},
{
"ImportPath": "github.com/davecgh/go-spew/spew",
"Rev": "5215b55f46b2b919f50a1df0eaa5886afe4e3b3d"
},
{
"ImportPath": "github.com/go-kit/kit/log",
"Comment": "v0.1.0-64-gb076b44",
"Rev": "b076b44dbec2aa943b52c9efaa5e8b46fd52b061"
},
{
"ImportPath": "github.com/go-logfmt/logfmt",
"Comment": "v0.2.0-9-gd432719",
"Rev": "d4327190ff838312623b09bfeb50d7c93c8d9c1d"
},
{
"ImportPath": "github.com/go-stack/stack",
"Comment": "v1.5.2",
"Rev": "100eb0c0a9c5b306ca2fb4f165df21d80ada4b82"
},
{
"ImportPath": "github.com/gorilla/context",
"Comment": "v1.1-4-gaed02d1",
"Rev": "aed02d124ae4a0e94fea4541c8effd05bf0c8296"
},
{
"ImportPath": "github.com/gorilla/mux",
"Comment": "v1.1-13-g9fa818a",
"Rev": "9fa818a44c2bf1396a17f9d5a3c0f6dd39d2ff8e"
},
{
"ImportPath": "github.com/kr/logfmt",
"Rev": "b84e30acd515aadc4b783ad4ff83aff3299bdfe0"
},
{
"ImportPath": "github.com/pkg/errors",
"Comment": "v0.7.0-5-ga2d6902",
"Rev": "a2d6902c6d2a2f194eb3fb474981ab7867c81505"
},
{
"ImportPath": "github.com/pmezard/go-difflib/difflib",
"Rev": "792786c7400a136282c1664665ae0a8db921c6c2"
},
{
"ImportPath": "github.com/stretchr/testify/assert",
"Comment": "v1.1.3-19-gd77da35",
"Rev": "d77da356e56a7428ad25149ca77381849a6a5232"
},
{
"ImportPath": "github.com/stretchr/testify/require",
"Comment": "v1.1.3-19-gd77da35",
"Rev": "d77da356e56a7428ad25149ca77381849a6a5232"
},
{
"ImportPath": "github.com/xeipuuv/gojsonpointer",
"Rev": "e0fe6f68307607d540ed8eac07a342c33fa1b54a"
},
{
"ImportPath": "github.com/xeipuuv/gojsonreference",
"Rev": "e02fc20de94c78484cd5ffb007f8af96be030a45"
},
{
"ImportPath": "github.com/xeipuuv/gojsonschema",
"Rev": "c539bca196be50ccdd1f0bcd9076de95f9081831"
},
{
"ImportPath": "golang.org/x/text/encoding",
"Rev": "ce78b075c2fbd48520f4995b173eb9fe18b56ef3"
},
{
"ImportPath": "golang.org/x/text/encoding/internal",
"Rev": "ce78b075c2fbd48520f4995b173eb9fe18b56ef3"
},
{
"ImportPath": "golang.org/x/text/encoding/internal/identifier",
"Rev": "ce78b075c2fbd48520f4995b173eb9fe18b56ef3"
},
{
"ImportPath": "golang.org/x/text/encoding/unicode",
"Rev": "ce78b075c2fbd48520f4995b173eb9fe18b56ef3"
},
{
"ImportPath": "golang.org/x/text/internal/utf8internal",
"Rev": "ce78b075c2fbd48520f4995b173eb9fe18b56ef3"
},
{
"ImportPath": "golang.org/x/text/runes",
"Rev": "ce78b075c2fbd48520f4995b173eb9fe18b56ef3"
},
{
"ImportPath": "golang.org/x/text/transform",
"Rev": "ce78b075c2fbd48520f4995b173eb9fe18b56ef3"
}
]
}

5
Godeps/Readme сгенерированный
Просмотреть файл

@ -1,5 +0,0 @@
This directory tree is generated automatically by godep.
Please do not edit.
See https://github.com/tools/godep for more information.

Просмотреть файл

@ -1,12 +1,12 @@
BINDIR=bin
BIN=custom-script-extension
BIN_ARM64=custom-script-extension-arm64
BUNDLEDIR=bundle
BUNDLE=custom-script-extension.zip
bundle: clean binary
@mkdir -p $(BUNDLEDIR)
zip ./$(BUNDLEDIR)/$(BUNDLE) ./$(BINDIR)/$(BIN)
zip ./$(BUNDLEDIR)/$(BUNDLE) ./$(BINDIR)/custom-script-shim
zip -r ./$(BUNDLEDIR)/$(BUNDLE) ./$(BINDIR)
zip -j ./$(BUNDLEDIR)/$(BUNDLE) ./misc/HandlerManifest.json
zip -j ./$(BUNDLEDIR)/$(BUNDLE) ./misc/manifest.xml
@ -15,10 +15,12 @@ binary: clean
echo "GOPATH is not set"; \
exit 1; \
fi
go get -d -u -f github.com/Azure/azure-extension-foundation/...
GOOS=linux GOARCH=amd64 govvv build -v \
-ldflags "-X main.Version=`grep -E -m 1 -o '<Version>(.*)</Version>' misc/manifest.xml | awk -F">" '{print $$2}' | awk -F"<" '{print $$1}'`" \
-o $(BINDIR)/$(BIN) ./main
GOOS=linux GOARCH=arm64 govvv build -v \
-ldflags "-X main.Version=`grep -E -m 1 -o '<Version>(.*)</Version>' misc/manifest.xml | awk -F">" '{print $$2}' | awk -F"<" '{print $$1}'`" \
-o $(BINDIR)/$(BIN_ARM64) ./main
cp ./misc/custom-script-shim ./$(BINDIR)
clean:
rm -rf "$(BINDIR)" "$(BUNDLEDIR)"

24
go.mod Normal file
Просмотреть файл

@ -0,0 +1,24 @@
module github.com/Azure/custom-script-extension-linux
go 1.16
require (
github.com/Azure/azure-extension-foundation v0.0.0-20190726000431-02f4f599e64a
github.com/Azure/azure-sdk-for-go v3.1.0-beta.0.20160802173609-87de771fcdf5+incompatible
github.com/ahmetalpbalkan/go-httpbin v0.0.0-20160706084156-8817b883dae1
github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2 // indirect
github.com/go-kit/kit v0.1.1-0.20160721083846-b076b44dbec2
github.com/go-logfmt/logfmt v0.2.1-0.20160601130801-d4327190ff83 // indirect
github.com/go-stack/stack v1.5.2 // indirect
github.com/gorilla/context v0.0.0-20160525203319-aed02d124ae4 // indirect
github.com/gorilla/mux v0.0.0-20160605233521-9fa818a44c2b // indirect
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 // indirect
github.com/pkg/errors v0.9.1
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/stretchr/testify v1.1.4-0.20160615092844-d77da356e56a
github.com/xeipuuv/gojsonpointer v0.0.0-20151027082146-e0fe6f683076 // indirect
github.com/xeipuuv/gojsonreference v0.0.0-20150808065054-e02fc20de94c // indirect
github.com/xeipuuv/gojsonschema v0.0.0-20160623135812-c539bca196be
golang.org/x/text v0.3.7
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
)

42
go.sum Normal file
Просмотреть файл

@ -0,0 +1,42 @@
github.com/Azure/azure-extension-foundation v0.0.0-20190726000431-02f4f599e64a h1:dU4O2MKIUGQ9JeJf6yyBLXwA1wso5zu1wLcz0pQggbc=
github.com/Azure/azure-extension-foundation v0.0.0-20190726000431-02f4f599e64a/go.mod h1:a0BFq9UoWBHvBS7iagvjFqBjYfxtBsmqvCLWIHRq9b0=
github.com/Azure/azure-sdk-for-go v3.1.0-beta.0.20160802173609-87de771fcdf5+incompatible h1:7CctKV2SGUVFq3a+WNHypGRKQzaPCNVEAMMAlEJXrWc=
github.com/Azure/azure-sdk-for-go v3.1.0-beta.0.20160802173609-87de771fcdf5+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
github.com/ahmetalpbalkan/go-httpbin v0.0.0-20160706084156-8817b883dae1 h1:/sPElPBMLSi6+bV0o0fPN4U24qQCNHs1i/BjnO+GqLc=
github.com/ahmetalpbalkan/go-httpbin v0.0.0-20160706084156-8817b883dae1/go.mod h1:Rg55S63lgqSBCawY/oTm7jdFSySp6jwIqgHMB2IeHK8=
github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2 h1:5zdDAMuB3gvbHB1m2BZT9+t9w+xaBmK3ehb7skDXcwM=
github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-kit/kit v0.1.1-0.20160721083846-b076b44dbec2 h1:awXynDTA1TiAp1SA/o/xoU6oRHE3xKCokck9l4/poMc=
github.com/go-kit/kit v0.1.1-0.20160721083846-b076b44dbec2/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-logfmt/logfmt v0.2.1-0.20160601130801-d4327190ff83 h1:WEFlTYvIQSd2ofUwgM9nOR+KTzdG/pLZzdUlDp6mciM=
github.com/go-logfmt/logfmt v0.2.1-0.20160601130801-d4327190ff83/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-stack/stack v1.5.2 h1:5sTB/0oZM2O31k/N1IRwxxVXzLIt5NF2Aqx/2gWI9OY=
github.com/go-stack/stack v1.5.2/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/gorilla/context v0.0.0-20160525203319-aed02d124ae4 h1:3nOfQt8sRPYbXORD5tJ8YyQ3HlL2Jt3LJ2U17CbNh6I=
github.com/gorilla/context v0.0.0-20160525203319-aed02d124ae4/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
github.com/gorilla/mux v0.0.0-20160605233521-9fa818a44c2b h1:OFvZV3a+25cGJH9dETHw0nk0wV6hLZI7IJijOkXEFS0=
github.com/gorilla/mux v0.0.0-20160605233521-9fa818a44c2b/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.1.4-0.20160615092844-d77da356e56a h1:UWu0XgfW9PCuyeZYNe2eGGkDZjooQKjVQqY/+d/jYmc=
github.com/stretchr/testify v1.1.4-0.20160615092844-d77da356e56a/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/xeipuuv/gojsonpointer v0.0.0-20151027082146-e0fe6f683076 h1:KM4T3G70MiR+JtqplcYkNVoNz7pDwYaBxWBXQK804So=
github.com/xeipuuv/gojsonpointer v0.0.0-20151027082146-e0fe6f683076/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
github.com/xeipuuv/gojsonreference v0.0.0-20150808065054-e02fc20de94c h1:XZWnr3bsDQWAZg4Ne+cPoXRPILrNlPNQfxBuwLl43is=
github.com/xeipuuv/gojsonreference v0.0.0-20150808065054-e02fc20de94c/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
github.com/xeipuuv/gojsonschema v0.0.0-20160623135812-c539bca196be h1:sRGd3e18izj1hQgF1hSvDOA8RPPnA2t4p8YeLZ/GdBU=
github.com/xeipuuv/gojsonschema v0.0.0-20160623135812-c539bca196be/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs=
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=

Просмотреть файл

@ -11,7 +11,6 @@ import (
"path/filepath"
"time"
"github.com/Azure/azure-docker-extension/pkg/vmextension"
"github.com/Azure/custom-script-extension-linux/pkg/seqnum"
"github.com/go-kit/kit/log"
"github.com/pkg/errors"
@ -21,7 +20,7 @@ const (
maxScriptSize = 256 * 1024
)
type cmdFunc func(ctx *log.Context, hEnv vmextension.HandlerEnvironment, seqNum int) (msg string, err error)
type cmdFunc func(ctx *log.Context, hEnv HandlerEnvironment, seqNum int) (msg string, err error)
type preFunc func(ctx *log.Context, seqNum int) error
type cmd struct {
@ -54,12 +53,12 @@ var (
}
)
func noop(ctx *log.Context, h vmextension.HandlerEnvironment, seqNum int) (string, error) {
func noop(ctx *log.Context, h HandlerEnvironment, seqNum int) (string, error) {
ctx.Log("event", "noop")
return "", nil
}
func install(ctx *log.Context, h vmextension.HandlerEnvironment, seqNum int) (string, error) {
func install(ctx *log.Context, h HandlerEnvironment, seqNum int) (string, error) {
if err := os.MkdirAll(dataDir, 0755); err != nil {
return "", errors.Wrap(err, "failed to create data dir")
}
@ -79,7 +78,7 @@ func install(ctx *log.Context, h vmextension.HandlerEnvironment, seqNum int) (st
return "", nil
}
func migrateToMostRecentSequence(ctx *log.Context, h vmextension.HandlerEnvironment, seqNum int) {
func migrateToMostRecentSequence(ctx *log.Context, h HandlerEnvironment, seqNum int) {
// The status folder is used instead of the settings because the settings file is written
// by the agent before install is called. As a result, the extension cannot determine if this
// is a new install or an upgrade.
@ -93,7 +92,7 @@ func migrateToMostRecentSequence(ctx *log.Context, h vmextension.HandlerEnvironm
// do not have invent another method. The CustomScript extension should have been using this
// from the beginning, but it was not.
//
computedSeqNum, err := vmextension.FindSeqNumStatus(h.HandlerEnvironment.StatusFolder)
computedSeqNum, err := FindSeqNumStatus(h.HandlerEnvironment.StatusFolder)
if err != nil {
// If there was an error, the sequence number is zero.
ctx.Log("event", "migrate to mrseq", "error", err)
@ -111,7 +110,7 @@ func migrateToMostRecentSequence(ctx *log.Context, h vmextension.HandlerEnvironm
fout.WriteString(fmt.Sprintf("%v", computedSeqNum))
}
func uninstall(ctx *log.Context, h vmextension.HandlerEnvironment, seqNum int) (string, error) {
func uninstall(ctx *log.Context, h HandlerEnvironment, seqNum int) (string, error) {
{ // a new context scope with path
ctx = ctx.With("path", dataDir)
ctx.Log("event", "removing data dir", "path", dataDir)
@ -143,9 +142,9 @@ func min(a, b int) int {
return b
}
func enable(ctx *log.Context, h vmextension.HandlerEnvironment, seqNum int) (string, error) {
func enable(ctx *log.Context, h HandlerEnvironment, seqNum int) (string, error) {
// parse the extension handler settings (not available prior to 'enable')
cfg, err := parseAndValidateSettings(ctx, h.HandlerEnvironment.ConfigFolder)
cfg, err := parseAndValidateSettings(ctx, h.HandlerEnvironment.ConfigFolder, seqNum)
if err != nil {
return "", errors.Wrap(err, "failed to get configuration")
}

Просмотреть файл

@ -7,13 +7,14 @@ import (
"path/filepath"
"strings"
"os"
"github.com/Azure/custom-script-extension-linux/pkg/blobutil"
"github.com/Azure/custom-script-extension-linux/pkg/download"
"github.com/Azure/custom-script-extension-linux/pkg/preprocess"
"github.com/Azure/custom-script-extension-linux/pkg/urlutil"
"github.com/go-kit/kit/log"
"github.com/pkg/errors"
"os"
)
// downloadAndProcessURL downloads using the specified downloader and saves it to the

Просмотреть файл

@ -1,4 +1,4 @@
package vmextension
package main
import (
"encoding/json"

Просмотреть файл

@ -2,8 +2,9 @@ package main
import (
"encoding/json"
"fmt"
"path/filepath"
"github.com/Azure/azure-docker-extension/pkg/vmextension"
"github.com/go-kit/kit/log"
"github.com/pkg/errors"
)
@ -20,8 +21,8 @@ var (
// handlerSettings holds the configuration of the extension handler.
type handlerSettings struct {
publicSettings
protectedSettings
publicSettings `json:"publicSettings"`
protectedSettings `json:"protectedSettings"`
}
func (s *handlerSettings) commandToExecute() string {
@ -112,9 +113,9 @@ func (self *clientOrObjectId) isEmpty() bool {
// parseAndValidateSettings reads configuration from configFolder, decrypts it,
// runs JSON-schema and logical validation on it and returns it back.
func parseAndValidateSettings(ctx *log.Context, configFolder string) (h handlerSettings, _ error) {
func parseAndValidateSettings(ctx *log.Context, configFolder string, seqNum int) (h handlerSettings, _ error) {
ctx.Log("event", "reading configuration")
pubJSON, protJSON, err := readSettings(configFolder)
pubJSON, protJSON, err := readSettings(configFolder, seqNum)
if err != nil {
return h, err
}
@ -127,7 +128,7 @@ func parseAndValidateSettings(ctx *log.Context, configFolder string) (h handlerS
ctx.Log("event", "json schema valid")
ctx.Log("event", "parsing configuration json")
if err := vmextension.UnmarshalHandlerSettings(pubJSON, protJSON, &h.publicSettings, &h.protectedSettings); err != nil {
if err := UnmarshalHandlerSettings(pubJSON, protJSON, &h.publicSettings, &h.protectedSettings); err != nil {
return h, errors.Wrap(err, "json parsing error")
}
ctx.Log("event", "parsed configuration json")
@ -143,8 +144,9 @@ func parseAndValidateSettings(ctx *log.Context, configFolder string) (h handlerS
// readSettings uses specified configFolder (comes from HandlerEnvironment) to
// decrypt and parse the public/protected settings of the extension handler into
// JSON objects.
func readSettings(configFolder string) (pubSettingsJSON, protSettingsJSON map[string]interface{}, err error) {
pubSettingsJSON, protSettingsJSON, err = vmextension.ReadSettings(configFolder)
func readSettings(configFolder string, seqNum int) (pubSettingsJSON, protSettingsJSON map[string]interface{}, err error) {
cf := filepath.Join(configFolder, fmt.Sprintf("%d%s", seqNum, ".settings"))
pubSettingsJSON, protSettingsJSON, err = ReadSettings(cf)
err = errors.Wrapf(err, "error reading extension configuration")
return
}

Просмотреть файл

@ -1,4 +1,4 @@
package vmextension
package main
import (
"bytes"
@ -7,9 +7,8 @@ import (
"errors"
"fmt"
"io/ioutil"
"path/filepath"
"os/exec"
"path/filepath"
)
const (
@ -18,11 +17,11 @@ const (
type handlerSettingsFile struct {
RuntimeSettings []struct {
HandlerSettings handlerSettings `json:"handlerSettings"`
HandlerSettings handlerSettingsCommon `json:"handlerSettings"`
} `json:"runtimeSettings"`
}
type handlerSettings struct {
type handlerSettingsCommon struct {
PublicSettings map[string]interface{} `json:"publicSettings"`
ProtectedSettingsBase64 string `json:"protectedSettings"`
SettingsCertThumbprint string `json:"protectedSettingsCertThumbprint"`
@ -41,17 +40,14 @@ func settingsPath(configFolder string) (string, error) {
// ReadSettings locates the .settings file and returns public settings
// JSON, and protected settings JSON (by decrypting it with the keys in
// configFolder).
func ReadSettings(configFolder string) (public, protected map[string]interface{}, _ error) {
cf, err := settingsPath(configFolder)
if err != nil {
return nil, nil, fmt.Errorf("canot locate settings file: %v", err)
}
hs, err := parseHandlerSettingsFile(cf)
func ReadSettings(configFilePath string) (public, protected map[string]interface{}, _ error) {
hs, err := parseHandlerSettingsFile(configFilePath)
if err != nil {
return nil, nil, fmt.Errorf("error parsing settings file: %v", err)
}
public = hs.PublicSettings
configFolder := filepath.Dir(configFilePath)
if err := unmarshalProtectedSettings(configFolder, hs, &protected); err != nil {
return nil, nil, fmt.Errorf("failed to parse protected settings: %v", err)
}
@ -86,7 +82,7 @@ func unmarshalSettings(in interface{}, v interface{}) error {
// parseHandlerSettings parses a handler settings file (e.g. 0.settings) and
// returns it as a structured object.
func parseHandlerSettingsFile(path string) (h handlerSettings, _ error) {
func parseHandlerSettingsFile(path string) (h handlerSettingsCommon, _ error) {
b, err := ioutil.ReadFile(path)
if err != nil {
return h, fmt.Errorf("Error reading %s: %v", path, err)
@ -108,7 +104,7 @@ func parseHandlerSettingsFile(path string) (h handlerSettings, _ error) {
// unmarshalProtectedSettings decodes the protected settings from handler
// runtime settings JSON file, decrypts it using the certificates and unmarshals
// into the given struct v.
func unmarshalProtectedSettings(configFolder string, hs handlerSettings, v interface{}) error {
func unmarshalProtectedSettings(configFolder string, hs handlerSettingsCommon, v interface{}) error {
if hs.ProtectedSettingsBase64 == "" {
return nil
}

Просмотреть файл

@ -3,10 +3,9 @@ package main
import (
"fmt"
"os"
"strconv"
"strings"
"github.com/Azure/azure-docker-extension/pkg/vmextension"
"github.com/Azure/azure-docker-extension/pkg/vmextension/status"
"github.com/go-kit/kit/log"
)
@ -27,6 +26,9 @@ var (
// downloadDir is where we store the downloaded files in the "{downloadDir}/{seqnum}/file"
// format and the logs as "{downloadDir}/{seqnum}/std(out|err)". Stored under dataDir
downloadDir = "download"
// configSequenceNumber environment variable should be set by VMAgent to sequence number
configSequenceNumber = "ConfigSequenceNumber"
)
func main() {
@ -38,14 +40,30 @@ func main() {
ctx = ctx.With("operation", strings.ToLower(cmd.name))
// parse extension environment
hEnv, err := vmextension.GetHandlerEnv()
hEnv, err := GetHandlerEnv()
if err != nil {
ctx.Log("message", "failed to parse handlerenv", "error", err)
os.Exit(cmd.failExitCode)
}
seqNum, err := vmextension.FindSeqNumConfig(hEnv.HandlerEnvironment.ConfigFolder)
if err != nil {
ctx.Log("messsage", "failed to find sequence number", "error", err)
seqNum := -1
// Agent should set env variable sequence number
seqNumVariable := os.Getenv(configSequenceNumber)
if seqNumVariable != "" {
seqNum, err = strconv.Atoi(seqNumVariable)
if err != nil {
ctx.Log("message", "failed to parse env variable ConfigSequenceNumber:"+seqNumVariable, "error", err)
os.Exit(cmd.failExitCode)
}
}
// Read the seqNum from latest config file in case VMAgent did not set it as env variable (old agent versions)
if seqNum == -1 {
seqNum, err = FindSeqNumConfig(hEnv.HandlerEnvironment.ConfigFolder)
if err != nil {
ctx.Log("messsage", "failed to find sequence number", "error", err)
os.Exit(cmd.failExitCode)
}
}
ctx = ctx.With("seq", seqNum)
@ -59,14 +77,14 @@ func main() {
}
}
// execute the subcommand
reportStatus(ctx, hEnv, seqNum, status.StatusTransitioning, cmd, "")
reportStatus(ctx, hEnv, seqNum, StatusTransitioning, cmd, "")
msg, err := cmd.f(ctx, hEnv, seqNum)
if err != nil {
ctx.Log("event", "failed to handle", "error", err)
reportStatus(ctx, hEnv, seqNum, status.StatusError, cmd, err.Error()+msg)
reportStatus(ctx, hEnv, seqNum, StatusError, cmd, err.Error()+msg)
os.Exit(cmd.failExitCode)
}
reportStatus(ctx, hEnv, seqNum, status.StatusSuccess, cmd, msg)
reportStatus(ctx, hEnv, seqNum, StatusSuccess, cmd, msg)
ctx.Log("event", "end")
}

Просмотреть файл

@ -1,22 +1,30 @@
package vmextension
package main
import (
"fmt"
"os"
"path/filepath"
"sort"
"strconv"
"strings"
)
const (
// chmod is used to set the mode bits for new seqnum files.
chmod = os.FileMode(0600)
)
// FindSeqNumConfig gets the laster seq no from config files
func FindSeqNumConfig(path string) (int, error) {
return FindSeqNum(path, ".settings")
}
// FindSeqNumStatus gets the laster seq no from status files
func FindSeqNumStatus(path string) (int, error) {
return FindSeqNum(path, ".status")
}
// FindSeqnum finds the file with the highest number under configFolder
// FindSeqNum finds the file with the highest number under configFolder
// named like 0.settings, 1.settings so on.
func FindSeqNum(path, ext string) (int, error) {
g, err := filepath.Glob(filepath.Join(path, fmt.Sprintf("*%s", ext)))
@ -33,9 +41,8 @@ func FindSeqNum(path, ext string) (int, error) {
seqs = append(seqs, i)
}
if len(seqs) == 0 {
return 0, fmt.Errorf("Can't find out seqnum from %s, not enough files.", path)
return 0, fmt.Errorf("Can't find out seqnum from %s, not enough files", path)
}
sort.Sort(sort.Reverse(sort.IntSlice(seqs)))
return seqs[0], nil
}

Просмотреть файл

@ -1,23 +1,100 @@
package main
import (
"github.com/Azure/azure-docker-extension/pkg/vmextension"
"github.com/Azure/azure-docker-extension/pkg/vmextension/status"
"encoding/json"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"time"
"github.com/go-kit/kit/log"
"github.com/pkg/errors"
)
type StatusReport []StatusItem
type StatusItem struct {
Version float64 `json:"version"`
TimestampUTC string `json:"timestampUTC"`
Status Status `json:"status"`
}
type Type string
const (
StatusTransitioning Type = "transitioning"
StatusError Type = "error"
StatusSuccess Type = "success"
)
type Status struct {
Operation string `json:"operation"`
Status Type `json:"status"`
FormattedMessage FormattedMessage `json:"formattedMessage"`
}
type FormattedMessage struct {
Lang string `json:"lang"`
Message string `json:"message"`
}
func NewStatus(t Type, operation, message string) StatusReport {
return []StatusItem{
{
Version: 1.0,
TimestampUTC: time.Now().UTC().Format(time.RFC3339),
Status: Status{
Operation: operation,
Status: t,
FormattedMessage: FormattedMessage{
Lang: "en",
Message: message},
},
},
}
}
func (r StatusReport) marshal() ([]byte, error) {
return json.MarshalIndent(r, "", "\t")
}
// Save persists the status message to the specified status folder using the
// sequence number. The operation consists of writing to a temporary file in the
// same folder and moving it to the final destination for atomicity.
func (r StatusReport) Save(statusFolder string, seqNum int) error {
fn := fmt.Sprintf("%d.status", seqNum)
path := filepath.Join(statusFolder, fn)
tmpFile, err := ioutil.TempFile(statusFolder, fn)
if err != nil {
return fmt.Errorf("status: failed to create temporary file: %v", err)
}
tmpFile.Close()
b, err := r.marshal()
if err != nil {
return fmt.Errorf("status: failed to marshal into json: %v", err)
}
if err := ioutil.WriteFile(tmpFile.Name(), b, 0644); err != nil {
return fmt.Errorf("status: failed to path=%s error=%v", tmpFile.Name(), err)
}
if err := os.Rename(tmpFile.Name(), path); err != nil {
return fmt.Errorf("status: failed to move to path=%s error=%v", path, err)
}
return nil
}
// reportStatus saves operation status to the status file for the extension
// handler with the optional given message, if the given cmd requires reporting
// status.
//
// If an error occurs reporting the status, it will be logged and returned.
func reportStatus(ctx *log.Context, hEnv vmextension.HandlerEnvironment, seqNum int, t status.Type, c cmd, msg string) error {
func reportStatus(ctx *log.Context, hEnv HandlerEnvironment, seqNum int, t Type, c cmd, msg string) error {
if !c.shouldReportStatus {
ctx.Log("status", "not reported for operation (by design)")
return nil
}
s := status.NewStatus(t, c.name, statusMsg(c, t, msg))
s := NewStatus(t, c.name, statusMsg(c, t, msg))
if err := s.Save(hEnv.HandlerEnvironment.StatusFolder, seqNum); err != nil {
ctx.Log("event", "failed to save handler status", "error", err)
return errors.Wrap(err, "failed to save handler status")
@ -25,19 +102,39 @@ func reportStatus(ctx *log.Context, hEnv vmextension.HandlerEnvironment, seqNum
return nil
}
// readStatus loads current status file in StatusReport
func readStatus(ctx *log.Context, hEnv HandlerEnvironment, seqNum int) (Type, error) {
fileName := fmt.Sprintf("%d.status", seqNum)
path := filepath.Join(hEnv.HandlerEnvironment.StatusFolder, fileName)
buffer, err := ioutil.ReadFile(path)
if err != nil {
return "", fmt.Errorf("Error reading status file %s: %v", path, err)
}
var statusReport StatusReport
if err := json.Unmarshal(buffer, &statusReport); err != nil {
return "", fmt.Errorf("error parsing json: %v", err)
}
if len(statusReport) != 1 {
return "", fmt.Errorf("wrong statusReport count. expected:1, got:%d", len(statusReport))
}
return statusReport[0].Status.Status, nil
}
// statusMsg creates the reported status message based on the provided operation
// type and the given message string.
//
// A message will be generated for empty string. For error status, pass the
// error message.
func statusMsg(c cmd, t status.Type, msg string) string {
func statusMsg(c cmd, t Type, msg string) string {
s := c.name
switch t {
case status.StatusSuccess:
case StatusSuccess:
s += " succeeded"
case status.StatusTransitioning:
case StatusTransitioning:
s += " in progress"
case status.StatusError:
case StatusError:
s += " failed"
}

Просмотреть файл

@ -6,28 +6,26 @@ import (
"path/filepath"
"testing"
"github.com/Azure/azure-docker-extension/pkg/vmextension"
"github.com/Azure/azure-docker-extension/pkg/vmextension/status"
"github.com/go-kit/kit/log"
"github.com/stretchr/testify/require"
)
func Test_statusMsg(t *testing.T) {
require.Equal(t, "Enable succeeded", statusMsg(cmdEnable, status.StatusSuccess, ""))
require.Equal(t, "Enable succeeded: msg", statusMsg(cmdEnable, status.StatusSuccess, "msg"))
require.Equal(t, "Enable succeeded", statusMsg(cmdEnable, StatusSuccess, ""))
require.Equal(t, "Enable succeeded: msg", statusMsg(cmdEnable, StatusSuccess, "msg"))
require.Equal(t, "Enable failed", statusMsg(cmdEnable, status.StatusError, ""))
require.Equal(t, "Enable failed: msg", statusMsg(cmdEnable, status.StatusError, "msg"))
require.Equal(t, "Enable failed", statusMsg(cmdEnable, StatusError, ""))
require.Equal(t, "Enable failed: msg", statusMsg(cmdEnable, StatusError, "msg"))
require.Equal(t, "Enable in progress", statusMsg(cmdEnable, status.StatusTransitioning, ""))
require.Equal(t, "Enable in progress: msg", statusMsg(cmdEnable, status.StatusTransitioning, "msg"))
require.Equal(t, "Enable in progress", statusMsg(cmdEnable, StatusTransitioning, ""))
require.Equal(t, "Enable in progress: msg", statusMsg(cmdEnable, StatusTransitioning, "msg"))
}
func Test_reportStatus_fails(t *testing.T) {
fakeEnv := vmextension.HandlerEnvironment{}
fakeEnv := HandlerEnvironment{}
fakeEnv.HandlerEnvironment.StatusFolder = "/non-existing/dir/"
err := reportStatus(log.NewContext(log.NewNopLogger()), fakeEnv, 1, status.StatusSuccess, cmdEnable, "")
err := reportStatus(log.NewContext(log.NewNopLogger()), fakeEnv, 1, StatusSuccess, cmdEnable, "")
require.NotNil(t, err)
require.Contains(t, err.Error(), "failed to save handler status")
}
@ -37,10 +35,10 @@ func Test_reportStatus_fileExists(t *testing.T) {
require.Nil(t, err)
defer os.RemoveAll(tmpDir)
fakeEnv := vmextension.HandlerEnvironment{}
fakeEnv := HandlerEnvironment{}
fakeEnv.HandlerEnvironment.StatusFolder = tmpDir
require.Nil(t, reportStatus(log.NewContext(log.NewNopLogger()), fakeEnv, 1, status.StatusError, cmdEnable, "FOO ERROR"))
require.Nil(t, reportStatus(log.NewContext(log.NewNopLogger()), fakeEnv, 1, StatusError, cmdEnable, "FOO ERROR"))
path := filepath.Join(tmpDir, "1.status")
b, err := ioutil.ReadFile(path)
@ -54,9 +52,9 @@ func Test_reportStatus_checksIfShouldBeReported(t *testing.T) {
require.Nil(t, err)
defer os.RemoveAll(tmpDir)
fakeEnv := vmextension.HandlerEnvironment{}
fakeEnv := HandlerEnvironment{}
fakeEnv.HandlerEnvironment.StatusFolder = tmpDir
require.Nil(t, reportStatus(log.NewContext(log.NewNopLogger()), fakeEnv, 2, status.StatusSuccess, c, ""))
require.Nil(t, reportStatus(log.NewContext(log.NewNopLogger()), fakeEnv, 2, StatusSuccess, c, ""))
fp := filepath.Join(tmpDir, "2.status")
_, err = os.Stat(fp) // check if the .status file is there

Просмотреть файл

@ -4,8 +4,11 @@ set -euo pipefail
readonly SCRIPT_DIR=$(dirname "$0")
readonly LOG_DIR="/var/log/azure/custom-script"
readonly LOG_FILE=handler.log
readonly HANDLER_BIN="custom-script-extension"
readonly ARCHITECTURE=$(uname -p)
HANDLER_BIN="custom-script-extension"
if [ $ARCHITECTURE == "arm64" ] || [ $ARCHITECTURE == "aarch64" ]; then
HANDLER_BIN="custom-script-extension-arm64";
fi
# status_file returns the .status file path we are supposed to write
# by determining the highest sequence number from ./config/*.settings files.

Просмотреть файл

@ -2,7 +2,7 @@
<ExtensionImage xmlns="http://schemas.microsoft.com/windowsazure">
<ProviderNameSpace>Microsoft.Azure.Extensions</ProviderNameSpace>
<Type>CustomScript</Type>
<Version>2.1.5</Version>
<Version>2.1.6</Version>
<Label>Microsoft Azure Custom Script Extension for Linux Virtual Machines</Label>
<HostingResources>VmRole</HostingResources>
<MediaLink></MediaLink>

Просмотреть файл

@ -8,11 +8,11 @@ import (
"path/filepath"
"fmt"
"github.com/stretchr/testify/require"
)
import "fmt"
const testDataDir = "testdata"
// BOM test files and their checksums in case of loss of BOM bytes

202
vendor/github.com/Azure/azure-docker-extension/LICENSE сгенерированный поставляемый
Просмотреть файл

@ -1,202 +0,0 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2016 Microsoft Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

82
vendor/github.com/Azure/azure-docker-extension/pkg/vmextension/status/status.go сгенерированный поставляемый
Просмотреть файл

@ -1,82 +0,0 @@
package status
import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"time"
)
type StatusReport []StatusItem
type StatusItem struct {
Version float64 `json:"version"`
TimestampUTC string `json:"timestampUTC"`
Status Status `json:"status"`
}
type Type string
const (
StatusTransitioning Type = "transitioning"
StatusError Type = "error"
StatusSuccess Type = "success"
)
type Status struct {
Operation string `json:"operation"`
Status Type `json:"status"`
FormattedMessage FormattedMessage `json:"formattedMessage"`
}
type FormattedMessage struct {
Lang string `json:"lang"`
Message string `json:"message"`
}
func NewStatus(t Type, operation, message string) StatusReport {
return []StatusItem{
{
Version: 1.0,
TimestampUTC: time.Now().UTC().Format(time.RFC3339),
Status: Status{
Operation: operation,
Status: t,
FormattedMessage: FormattedMessage{
Lang: "en",
Message: message},
},
},
}
}
func (r StatusReport) marshal() ([]byte, error) {
return json.MarshalIndent(r, "", "\t")
}
// Save persists the status message to the specified status folder using the
// sequence number. The operation consists of writing to a temporary file in the
// same folder and moving it to the final destination for atomicity.
func (r StatusReport) Save(statusFolder string, seqNum int) error {
fn := fmt.Sprintf("%d.status", seqNum)
path := filepath.Join(statusFolder, fn)
tmpFile, err := ioutil.TempFile(statusFolder, fn)
if err != nil {
return fmt.Errorf("status: failed to create temporary file: %v", err)
}
tmpFile.Close()
b, err := r.marshal()
if err != nil {
return fmt.Errorf("status: failed to marshal into json: %v", err)
}
if err := ioutil.WriteFile(tmpFile.Name(), b, 0644); err != nil {
return fmt.Errorf("status: failed to path=%s error=%v", tmpFile.Name(), err)
}
if err := os.Rename(tmpFile.Name(), path); err != nil {
return fmt.Errorf("status: failed to move to path=%s error=%v", path, err)
}
return nil
}

21
vendor/github.com/Azure/azure-extension-foundation/LICENSE сгенерированный поставляемый Normal file
Просмотреть файл

@ -0,0 +1,21 @@
MIT License
Copyright (c) Microsoft Corporation. All rights reserved.
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

19
vendor/github.com/Azure/azure-extension-foundation/errorhelper/errorhelper.go сгенерированный поставляемый Normal file
Просмотреть файл

@ -0,0 +1,19 @@
package errorhelper
import (
"fmt"
"runtime/debug"
)
func AddStackToError(err error) error {
if err == nil {
return nil
}
stackString := string(debug.Stack())
return fmt.Errorf("%+v\nCallStack: %s", err, stackString)
}
func NewErrorWithStack(errString string) error {
stackString := string(debug.Stack())
return fmt.Errorf("%s\nCallStack: %s", errString, stackString)
}

214
vendor/github.com/Azure/azure-extension-foundation/httputil/httputil.go сгенерированный поставляемый Normal file
Просмотреть файл

@ -0,0 +1,214 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
package httputil
import (
"bytes"
"crypto/tls"
"github.com/Azure/azure-extension-foundation/errorhelper"
"io/ioutil"
"log"
"net/http"
"time"
)
const (
OperationGet = "GET"
OperationPost = "POST"
OperationDelete = "DELETE"
OperationPut = "PUT"
)
type HttpClient interface {
Get(url string, headers map[string]string) (responseCode int, body []byte, err error)
Post(url string, headers map[string]string, payload []byte) (responseCode int, body []byte, err error)
Put(url string, headers map[string]string, payload []byte) (responseCode int, body []byte, err error)
Delete(url string, headers map[string]string, payload []byte) (responseCode int, body []byte, err error)
}
// for testing
type httpClientInterface interface {
Do(req *http.Request) (*http.Response, error)
}
type Client struct {
httpClient httpClientInterface
retryBehavior RetryBehavior
}
type RetryBehavior = func(statusCode int, i int) bool
// return false to end retries
// i starts from 1 keeps getting incremented while function returns true
var NoRetry RetryBehavior = func(statusCode int, i int) bool {
return false
}
var LinearRetryThrice RetryBehavior = func(statusCode int, i int) bool {
if !isTransientHttpStatusCode(statusCode) {
return false
}
time.Sleep(time.Second * 3)
if i < 3 {
return true // retry if count < 3
}
return false
}
// The default retry behavior is 5 retries with exponential back-off with a maximum wait time of 60 seconds
var DefaultRetryBehavior RetryBehavior = func(statusCode int, i int) bool {
if !isTransientHttpStatusCode(statusCode) {
return false
}
delay := time.Second * time.Duration(2^(i))
const maxDelay time.Duration = 60 * time.Second
if delay > maxDelay {
delay = maxDelay
}
time.Sleep(delay)
if i < 5 {
return true
}
return false
}
func isTransientHttpStatusCode(statusCode int) bool {
switch statusCode {
case
http.StatusRequestTimeout, // 408
http.StatusTooManyRequests, // 429
http.StatusInternalServerError, // 500
http.StatusBadGateway, // 502
http.StatusServiceUnavailable, // 503
http.StatusGatewayTimeout: // 504
return true // timeout and too many requests
default:
return false
}
}
func IsSuccessStatusCode(statusCode int) bool {
switch statusCode {
case 200, 201:
return true
default:
return false
}
}
func NewSecureHttpClient(retryBehavior RetryBehavior) HttpClient {
if retryBehavior == nil {
panic("Retry policy must be specified")
}
tlsConfig := &tls.Config{
Renegotiation: tls.RenegotiateFreelyAsClient,
}
transport := &http.Transport{TLSClientConfig: tlsConfig}
httpClient := &http.Client{Transport: transport}
return &Client{httpClient, retryBehavior}
}
func NewSecureHttpClientWithCertificates(certificate string, key string, retryBehavior RetryBehavior) HttpClient {
if retryBehavior == nil {
panic("Retry policy must be specified")
}
cert, err := tls.LoadX509KeyPair(certificate, key)
if err != nil {
log.Fatal(err)
}
tlsConfig := &tls.Config{
Certificates: []tls.Certificate{cert},
Renegotiation: tls.RenegotiateFreelyAsClient,
}
transport := &http.Transport{TLSClientConfig: tlsConfig}
httpClient := &http.Client{Transport: transport}
return &Client{httpClient, retryBehavior}
}
func NewInsecureHttpClientWithCertificates(certificate string, key string, retryBehavior RetryBehavior) HttpClient {
if retryBehavior == nil {
panic("Retry policy must be specified")
}
cert, err := tls.LoadX509KeyPair(certificate, key)
if err != nil {
log.Fatal(err)
}
tlsConfig := &tls.Config{
Certificates: []tls.Certificate{cert},
InsecureSkipVerify: true,
Renegotiation: tls.RenegotiateFreelyAsClient,
}
transport := &http.Transport{TLSClientConfig: tlsConfig}
httpClient := &http.Client{Transport: transport}
return &Client{httpClient, retryBehavior}
}
// Get issues a get request
func (client *Client) Get(url string, headers map[string]string) (responseCode int, body []byte, err error) {
return client.issueRequest(OperationGet, url, headers, nil)
}
// Post issues a post request
func (client *Client) Post(url string, headers map[string]string, payload []byte) (responseCode int, body []byte, err error) {
return client.issueRequest(OperationPost, url, headers, bytes.NewBuffer(payload))
}
// Put issues a put request
func (client *Client) Put(url string, headers map[string]string, payload []byte) (responseCode int, body []byte, err error) {
return client.issueRequest(OperationPut, url, headers, bytes.NewBuffer(payload))
}
// Delete issues a delete request
func (client *Client) Delete(url string, headers map[string]string, payload []byte) (responseCode int, body []byte, err error) {
return client.issueRequest(OperationDelete, url, headers, bytes.NewBuffer(payload))
}
func (client *Client) issueRequest(operation string, url string, headers map[string]string, payload *bytes.Buffer) (int, []byte, error) {
request, err := http.NewRequest(operation, url, nil)
if payload != nil && payload.Len() != 0 {
request, err = http.NewRequest(operation, url, payload)
}
for key, value := range headers {
request.Header.Add(key, value)
}
res, err := client.httpClient.Do(request)
if err == nil && IsSuccessStatusCode(res.StatusCode) {
// no need to retry
} else if err == nil && res != nil {
// there was no error, so look at the status code to retry
for i := 1; client.retryBehavior(res.StatusCode, i); i++ {
res, err = client.httpClient.Do(request)
if err != nil {
break
}
}
}
if err != nil {
return -1, nil, errorhelper.AddStackToError(err)
}
body, err := ioutil.ReadAll(res.Body)
res.Body.Close()
code := res.StatusCode
if err != nil {
return -1, nil, errorhelper.AddStackToError(err)
}
return code, body, nil
}

26
vendor/github.com/Azure/azure-extension-foundation/httputil/mockclient.go сгенерированный поставляемый Normal file
Просмотреть файл

@ -0,0 +1,26 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
package httputil
type MockHttpClient struct {
// overwrite these methods to get the desired output
Getfunc func(url string, headers map[string]string) (responseCode int, body []byte, err error)
Postfunc func(url string, headers map[string]string, payload []byte) (responseCode int, body []byte, err error)
Putfunc func(url string, headers map[string]string, payload []byte) (responseCode int, body []byte, err error)
Deletefunc func(url string, headers map[string]string, payload []byte) (responseCode int, body []byte, err error)
}
func (client *MockHttpClient) Get(url string, headers map[string]string) (responseCode int, body []byte, err error) {
return client.Getfunc(url, headers)
}
func (client *MockHttpClient) Post(url string, headers map[string]string, payload []byte) (responseCode int, body []byte, err error) {
return client.Postfunc(url, headers, payload)
}
func (client *MockHttpClient) Put(url string, headers map[string]string, payload []byte) (responseCode int, body []byte, err error) {
return client.Putfunc(url, headers, payload)
}
func (client *MockHttpClient) Delete(url string, headers map[string]string, payload []byte) (responseCode int, body []byte, err error) {
return client.Deletefunc(url, headers, payload)
}

129
vendor/github.com/Azure/azure-extension-foundation/msi/msi.go сгенерированный поставляемый Normal file
Просмотреть файл

@ -0,0 +1,129 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
package msi
import (
"encoding/json"
"fmt"
"github.com/Azure/azure-extension-foundation/errorhelper"
"github.com/Azure/azure-extension-foundation/httputil"
"net/url"
"strconv"
"time"
)
const (
metadataIdentityURL = "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01"
clientIdQueryParam = "client_id"
objectIdQueryParam = "object_id"
resourceQueryParam = "resource"
armResourceUri = "https://management.core.windows.net/"
)
type Msi struct {
AccessToken string `json:"access_token"`
ClientID string `json:"client_id"`
ExpiresIn string `json:"expires_in"`
ExpiresOn string `json:"expires_on"` // expressed in seconds from epoch
ExtExpiresIn string `json:"ext_expires_in"`
NotBefore string `json:"not_before"`
Resource string `json:"resource"`
TokenType string `json:"token_type"`
}
type MsiProvider interface {
GetMsi() (Msi, error)
GetMsiForResource(targetResource string) (Msi, error)
GetMsiUsingClientId(clientId string, targetResource string) (Msi, error)
GetMsiUsingObjectId(objectId string, targetResource string) (Msi, error)
}
type provider struct {
httpClient httputil.HttpClient
}
func NewMsiProvider(client httputil.HttpClient) provider {
return provider{httpClient: client}
}
func (p *provider) getMsiHelper(queryParams map[string]string) (*Msi, error) {
var msi = Msi{}
requestUrl, err := url.Parse(metadataIdentityURL)
if err != nil {
return &msi, err
}
urlQuery := requestUrl.Query()
for key, value := range queryParams {
urlQuery.Add(key, value)
}
requestUrl.RawQuery = urlQuery.Encode()
code, body, err := p.httpClient.Get(requestUrl.String(), map[string]string{"Metadata": "true"})
if err != nil {
return &msi, err
}
if code != 200 {
return &msi, errorhelper.AddStackToError(fmt.Errorf("unable to get msi, metadata service response code %v", code))
}
err = json.Unmarshal(body, &msi)
if err != nil {
return &msi, errorhelper.AddStackToError(fmt.Errorf("unable to deserialize metadata service response"))
}
return &msi, nil
}
func (p *provider) GetMsi() (Msi, error) {
msi, err := p.getMsiHelper(map[string]string{resourceQueryParam: armResourceUri})
return *msi, err
}
func (p *provider) GetMsiForResource(targetResource string) (Msi, error) {
msi, err := p.getMsiHelper(map[string]string{resourceQueryParam: targetResource})
return *msi, err
}
func (p *provider) GetMsiUsingClientId(clientId string, targetResource string) (Msi, error) {
msi, err := p.getMsiHelper(map[string]string{clientIdQueryParam: clientId, resourceQueryParam: targetResource})
return *msi, err
}
func (p *provider) GetMsiUsingObjectId(objectId string, targetResource string) (Msi, error) {
msi, err := p.getMsiHelper(map[string]string{objectIdQueryParam: objectId, resourceQueryParam: targetResource})
return *msi, err
}
// check expiry of MSI token based on time
func (msi *Msi) IsMsiTokenExpired() (bool, error) {
expiryTime, err := msi.GetExpiryTime()
if err != nil {
return false, err
}
// Consider token expired 2 minutes before expiry time
expiryTime = expiryTime.Add(-2 * time.Minute)
if time.Now().After(expiryTime) {
return true, nil
} else {
return false, nil
}
}
func (msi *Msi) GetExpiryTime() (time.Time, error) {
expiryTimeInSeconds, err := strconv.ParseInt(msi.ExpiresOn, 10, 64)
if err != nil {
return time.Unix(0, 0), err
}
expiryTime := time.Unix(expiryTimeInSeconds, 0)
return expiryTime, nil
}
func (msi *Msi) GetJson() (string, error) {
jsonBytes, err := json.Marshal(msi)
return string(jsonBytes[:]), err
}

8
vendor/github.com/ahmetalpbalkan/go-httpbin/handlers.go сгенерированный поставляемый
Просмотреть файл

@ -7,11 +7,12 @@ import (
"fmt"
"io"
"math/rand"
"net"
"net/http"
"strconv"
"time"
"net"
"github.com/gorilla/mux"
"github.com/pkg/errors"
)
@ -42,7 +43,6 @@ func GetMux() *mux.Router {
r.HandleFunc(`/bytes/{n:[\d]+}`, BytesHandler).Methods("GET")
r.HandleFunc(`/delay/{n:\d+(\.\d+)?}`, DelayHandler).Methods("GET")
r.HandleFunc(`/stream/{n:[\d]+}`, StreamHandler).Methods("GET")
r.HandleFunc(`/dos2unix`, Dos2UnixHandler).Methods("GET")
r.HandleFunc(`/drip`, DripHandler).Methods("GET").Queries(
"numbytes", `{numbytes:\d+}`,
"duration", `{duration:\d+(\.\d+)?}`)
@ -62,10 +62,6 @@ func IPHandler(w http.ResponseWriter, r *http.Request) {
}
}
func Dos2UnixHandler(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("#!/bin/sh\r\necho 'Hello, world!'\r\n"))
}
// UserAgentHandler returns user agent.
func UserAgentHandler(w http.ResponseWriter, r *http.Request) {
if err := writeJSON(w, userAgentResponse{r.UserAgent()}); err != nil {

8
vendor/github.com/pkg/errors/.travis.yml сгенерированный поставляемый
Просмотреть файл

@ -1,10 +1,10 @@
language: go
go_import_path: github.com/pkg/errors
go:
- 1.4.3
- 1.5.4
- 1.6.2
- 1.11.x
- 1.12.x
- 1.13.x
- tip
script:
- go test -v ./...
- make check

44
vendor/github.com/pkg/errors/Makefile сгенерированный поставляемый Normal file
Просмотреть файл

@ -0,0 +1,44 @@
PKGS := github.com/pkg/errors
SRCDIRS := $(shell go list -f '{{.Dir}}' $(PKGS))
GO := go
check: test vet gofmt misspell unconvert staticcheck ineffassign unparam
test:
$(GO) test $(PKGS)
vet: | test
$(GO) vet $(PKGS)
staticcheck:
$(GO) get honnef.co/go/tools/cmd/staticcheck
staticcheck -checks all $(PKGS)
misspell:
$(GO) get github.com/client9/misspell/cmd/misspell
misspell \
-locale GB \
-error \
*.md *.go
unconvert:
$(GO) get github.com/mdempsky/unconvert
unconvert -v $(PKGS)
ineffassign:
$(GO) get github.com/gordonklaus/ineffassign
find $(SRCDIRS) -name '*.go' | xargs ineffassign
pedantic: check errcheck
unparam:
$(GO) get mvdan.cc/unparam
unparam ./...
errcheck:
$(GO) get github.com/kisielk/errcheck
errcheck $(PKGS)
gofmt:
@echo Checking code is gofmted
@test -z "$(shell gofmt -s -l -d -e $(SRCDIRS) | tee /dev/stderr)"

17
vendor/github.com/pkg/errors/README.md сгенерированный поставляемый
Просмотреть файл

@ -1,7 +1,9 @@
# errors [![Travis-CI](https://travis-ci.org/pkg/errors.svg)](https://travis-ci.org/pkg/errors) [![AppVeyor](https://ci.appveyor.com/api/projects/status/b98mptawhudj53ep/branch/master?svg=true)](https://ci.appveyor.com/project/davecheney/errors/branch/master) [![GoDoc](https://godoc.org/github.com/pkg/errors?status.svg)](http://godoc.org/github.com/pkg/errors) [![Report card](https://goreportcard.com/badge/github.com/pkg/errors)](https://goreportcard.com/report/github.com/pkg/errors)
# errors [![Travis-CI](https://travis-ci.org/pkg/errors.svg)](https://travis-ci.org/pkg/errors) [![AppVeyor](https://ci.appveyor.com/api/projects/status/b98mptawhudj53ep/branch/master?svg=true)](https://ci.appveyor.com/project/davecheney/errors/branch/master) [![GoDoc](https://godoc.org/github.com/pkg/errors?status.svg)](http://godoc.org/github.com/pkg/errors) [![Report card](https://goreportcard.com/badge/github.com/pkg/errors)](https://goreportcard.com/report/github.com/pkg/errors) [![Sourcegraph](https://sourcegraph.com/github.com/pkg/errors/-/badge.svg)](https://sourcegraph.com/github.com/pkg/errors?badge)
Package errors provides simple error handling primitives.
`go get github.com/pkg/errors`
The traditional error handling idiom in Go is roughly akin to
```go
if err != nil {
@ -39,12 +41,19 @@ default:
[Read the package documentation for more information](https://godoc.org/github.com/pkg/errors).
## Roadmap
With the upcoming [Go2 error proposals](https://go.googlesource.com/proposal/+/master/design/go2draft.md) this package is moving into maintenance mode. The roadmap for a 1.0 release is as follows:
- 0.9. Remove pre Go 1.9 and Go 1.10 support, address outstanding pull requests (if possible)
- 1.0. Final release.
## Contributing
We welcome pull requests, bug fixes and issue reports. With that said, the bar for adding new symbols to this package is intentionally set high.
Because of the Go2 errors changes, this package is not accepting proposals for new functionality. With that said, we welcome pull requests, bug fixes and issue reports.
Before proposing a change, please discuss your change by raising an issue.
Before sending a PR, please discuss your change by raising an issue.
## Licence
## License
BSD-2-Clause

210
vendor/github.com/pkg/errors/errors.go сгенерированный поставляемый
Просмотреть файл

@ -6,7 +6,7 @@
// return err
// }
//
// which applied recursively up the call stack results in error reports
// which when applied recursively up the call stack results in error reports
// without context or debugging information. The errors package allows
// programmers to add context to the failure path in their code in a way
// that does not destroy the original value of the error.
@ -14,13 +14,19 @@
// Adding context to an error
//
// The errors.Wrap function returns a new error that adds context to the
// original error. For example
// original error by recording a stack trace at the point Wrap is called,
// together with the supplied message. For example
//
// _, err := ioutil.ReadAll(r)
// if err != nil {
// return errors.Wrap(err, "read failed")
// }
//
// If additional control is required, the errors.WithStack and
// errors.WithMessage functions destructure errors.Wrap into its component
// operations: annotating an error with a stack trace and with a message,
// respectively.
//
// Retrieving the cause of an error
//
// Using errors.Wrap constructs a stack of errors, adding context to the
@ -28,12 +34,12 @@
// to reverse the operation of errors.Wrap to retrieve the original error
// for inspection. Any error value which implements this interface
//
// type Causer interface {
// type causer interface {
// Cause() error
// }
//
// can be inspected by errors.Cause. errors.Cause will recursively retrieve
// the topmost error which does not implement causer, which is assumed to be
// the topmost error that does not implement causer, which is assumed to be
// the original cause. For example:
//
// switch err := errors.Cause(err).(type) {
@ -43,13 +49,16 @@
// // unknown error
// }
//
// Although the causer interface is not exported by this package, it is
// considered a part of its stable public interface.
//
// Formatted printing of errors
//
// All error values returned from this package implement fmt.Formatter and can
// be formatted by the fmt package. The following verbs are supported
// be formatted by the fmt package. The following verbs are supported:
//
// %s print the error. If the error has a Cause it will be
// printed recursively
// printed recursively.
// %v see %s
// %+v extended format. Each Frame of the error's StackTrace will
// be printed in detail.
@ -57,13 +66,13 @@
// Retrieving the stack trace of an error or wrapper
//
// New, Errorf, Wrap, and Wrapf record a stack trace at the point they are
// invoked. This information can be retrieved with the following interface.
// invoked. This information can be retrieved with the following interface:
//
// type stackTracer interface {
// StackTrace() errors.StackTrace
// }
//
// Where errors.StackTrace is defined as
// The returned errors.StackTrace type is defined as
//
// type StackTrace []Frame
//
@ -73,10 +82,13 @@
//
// if err, ok := err.(stackTracer); ok {
// for _, f := range err.StackTrace() {
// fmt.Printf("%+s:%d", f)
// fmt.Printf("%+s:%d\n", f, f)
// }
// }
//
// Although the stackTracer interface is not exported by this package, it is
// considered a part of its stable public interface.
//
// See the documentation for Frame.Format for more details.
package errors
@ -85,68 +97,77 @@ import (
"io"
)
// _error is an error implementation returned by New and Errorf
// that implements its own fmt.Formatter.
type _error struct {
msg string
*stack
}
func (e _error) Error() string { return e.msg }
func (e _error) Format(s fmt.State, verb rune) {
switch verb {
case 'v':
if s.Flag('+') {
io.WriteString(s, e.msg)
fmt.Fprintf(s, "%+v", e.StackTrace())
return
}
fallthrough
case 's':
io.WriteString(s, e.msg)
}
}
// New returns an error with the supplied message.
// New also records the stack trace at the point it was called.
func New(message string) error {
return _error{
message,
callers(),
return &fundamental{
msg: message,
stack: callers(),
}
}
// Errorf formats according to a format specifier and returns the string
// as a value that satisfies error.
// Errorf also records the stack trace at the point it was called.
func Errorf(format string, args ...interface{}) error {
return _error{
fmt.Sprintf(format, args...),
return &fundamental{
msg: fmt.Sprintf(format, args...),
stack: callers(),
}
}
// fundamental is an error that has a message and a stack, but no caller.
type fundamental struct {
msg string
*stack
}
func (f *fundamental) Error() string { return f.msg }
func (f *fundamental) Format(s fmt.State, verb rune) {
switch verb {
case 'v':
if s.Flag('+') {
io.WriteString(s, f.msg)
f.stack.Format(s, verb)
return
}
fallthrough
case 's':
io.WriteString(s, f.msg)
case 'q':
fmt.Fprintf(s, "%q", f.msg)
}
}
// WithStack annotates err with a stack trace at the point WithStack was called.
// If err is nil, WithStack returns nil.
func WithStack(err error) error {
if err == nil {
return nil
}
return &withStack{
err,
callers(),
}
}
type cause struct {
cause error
msg string
}
func (c cause) Error() string { return fmt.Sprintf("%s: %v", c.msg, c.Cause()) }
func (c cause) Cause() error { return c.cause }
// wrapper is an error implementation returned by Wrap and Wrapf
// that implements its own fmt.Formatter.
type wrapper struct {
cause
type withStack struct {
error
*stack
}
func (w wrapper) Format(s fmt.State, verb rune) {
func (w *withStack) Cause() error { return w.error }
// Unwrap provides compatibility for Go 1.13 error chains.
func (w *withStack) Unwrap() error { return w.error }
func (w *withStack) Format(s fmt.State, verb rune) {
switch verb {
case 'v':
if s.Flag('+') {
fmt.Fprintf(s, "%+v\n", w.Cause())
io.WriteString(s, w.msg)
fmt.Fprintf(s, "%+v", w.StackTrace())
fmt.Fprintf(s, "%+v", w.Cause())
w.stack.Format(s, verb)
return
}
fallthrough
@ -157,33 +178,86 @@ func (w wrapper) Format(s fmt.State, verb rune) {
}
}
// Wrap returns an error annotating err with message.
// Wrap returns an error annotating err with a stack trace
// at the point Wrap is called, and the supplied message.
// If err is nil, Wrap returns nil.
func Wrap(err error, message string) error {
if err == nil {
return nil
}
return wrapper{
cause: cause{
cause: err,
msg: message,
},
stack: callers(),
err = &withMessage{
cause: err,
msg: message,
}
return &withStack{
err,
callers(),
}
}
// Wrapf returns an error annotating err with the format specifier.
// Wrapf returns an error annotating err with a stack trace
// at the point Wrapf is called, and the format specifier.
// If err is nil, Wrapf returns nil.
func Wrapf(err error, format string, args ...interface{}) error {
if err == nil {
return nil
}
return wrapper{
cause: cause{
cause: err,
msg: fmt.Sprintf(format, args...),
},
stack: callers(),
err = &withMessage{
cause: err,
msg: fmt.Sprintf(format, args...),
}
return &withStack{
err,
callers(),
}
}
// WithMessage annotates err with a new message.
// If err is nil, WithMessage returns nil.
func WithMessage(err error, message string) error {
if err == nil {
return nil
}
return &withMessage{
cause: err,
msg: message,
}
}
// WithMessagef annotates err with the format specifier.
// If err is nil, WithMessagef returns nil.
func WithMessagef(err error, format string, args ...interface{}) error {
if err == nil {
return nil
}
return &withMessage{
cause: err,
msg: fmt.Sprintf(format, args...),
}
}
type withMessage struct {
cause error
msg string
}
func (w *withMessage) Error() string { return w.msg + ": " + w.cause.Error() }
func (w *withMessage) Cause() error { return w.cause }
// Unwrap provides compatibility for Go 1.13 error chains.
func (w *withMessage) Unwrap() error { return w.cause }
func (w *withMessage) Format(s fmt.State, verb rune) {
switch verb {
case 'v':
if s.Flag('+') {
fmt.Fprintf(s, "%+v\n", w.Cause())
io.WriteString(s, w.msg)
return
}
fallthrough
case 's', 'q':
io.WriteString(s, w.Error())
}
}
@ -191,7 +265,7 @@ func Wrapf(err error, format string, args ...interface{}) error {
// An error value has a cause if it implements the following
// interface:
//
// type Causer interface {
// type causer interface {
// Cause() error
// }
//

38
vendor/github.com/pkg/errors/go113.go сгенерированный поставляемый Normal file
Просмотреть файл

@ -0,0 +1,38 @@
// +build go1.13
package errors
import (
stderrors "errors"
)
// Is reports whether any error in err's chain matches target.
//
// The chain consists of err itself followed by the sequence of errors obtained by
// repeatedly calling Unwrap.
//
// An error is considered to match a target if it is equal to that target or if
// it implements a method Is(error) bool such that Is(target) returns true.
func Is(err, target error) bool { return stderrors.Is(err, target) }
// As finds the first error in err's chain that matches target, and if so, sets
// target to that error value and returns true.
//
// The chain consists of err itself followed by the sequence of errors obtained by
// repeatedly calling Unwrap.
//
// An error matches target if the error's concrete value is assignable to the value
// pointed to by target, or if the error has a method As(interface{}) bool such that
// As(target) returns true. In the latter case, the As method is responsible for
// setting target.
//
// As will panic if target is not a non-nil pointer to either a type that implements
// error, or to any interface type. As returns false if err is nil.
func As(err error, target interface{}) bool { return stderrors.As(err, target) }
// Unwrap returns the result of calling the Unwrap method on err, if err's
// type contains an Unwrap method returning error.
// Otherwise, Unwrap returns nil.
func Unwrap(err error) error {
return stderrors.Unwrap(err)
}

122
vendor/github.com/pkg/errors/stack.go сгенерированный поставляемый
Просмотреть файл

@ -5,10 +5,13 @@ import (
"io"
"path"
"runtime"
"strconv"
"strings"
)
// Frame represents a program counter inside a stack frame.
// For historical reasons if Frame is interpreted as a uintptr
// its value represents the program counter + 1.
type Frame uintptr
// pc returns the program counter for this frame;
@ -37,6 +40,15 @@ func (f Frame) line() int {
return line
}
// name returns the name of this function, if known.
func (f Frame) name() string {
fn := runtime.FuncForPC(f.pc())
if fn == nil {
return "unknown"
}
return fn.Name()
}
// Format formats the frame according to the fmt.Formatter interface.
//
// %s source file
@ -46,29 +58,24 @@ func (f Frame) line() int {
//
// Format accepts flags that alter the printing of some verbs, as follows:
//
// %+s path of source file relative to the compile time GOPATH
// %+s function name and path of source file relative to the compile time
// GOPATH separated by \n\t (<funcname>\n\t<path>)
// %+v equivalent to %+s:%d
func (f Frame) Format(s fmt.State, verb rune) {
switch verb {
case 's':
switch {
case s.Flag('+'):
pc := f.pc()
fn := runtime.FuncForPC(pc)
if fn == nil {
io.WriteString(s, "unknown")
} else {
file, _ := fn.FileLine(pc)
fmt.Fprintf(s, "%s\n\t%s", fn.Name(), file)
}
io.WriteString(s, f.name())
io.WriteString(s, "\n\t")
io.WriteString(s, f.file())
default:
io.WriteString(s, path.Base(f.file()))
}
case 'd':
fmt.Fprintf(s, "%d", f.line())
io.WriteString(s, strconv.Itoa(f.line()))
case 'n':
name := runtime.FuncForPC(f.pc()).Name()
io.WriteString(s, funcname(name))
io.WriteString(s, funcname(f.name()))
case 'v':
f.Format(s, 's')
io.WriteString(s, ":")
@ -76,30 +83,75 @@ func (f Frame) Format(s fmt.State, verb rune) {
}
}
// MarshalText formats a stacktrace Frame as a text string. The output is the
// same as that of fmt.Sprintf("%+v", f), but without newlines or tabs.
func (f Frame) MarshalText() ([]byte, error) {
name := f.name()
if name == "unknown" {
return []byte(name), nil
}
return []byte(fmt.Sprintf("%s %s:%d", name, f.file(), f.line())), nil
}
// StackTrace is stack of Frames from innermost (newest) to outermost (oldest).
type StackTrace []Frame
// Format formats the stack of Frames according to the fmt.Formatter interface.
//
// %s lists source files for each Frame in the stack
// %v lists the source file and line number for each Frame in the stack
//
// Format accepts flags that alter the printing of some verbs, as follows:
//
// %+v Prints filename, function, and line number for each Frame in the stack.
func (st StackTrace) Format(s fmt.State, verb rune) {
switch verb {
case 'v':
switch {
case s.Flag('+'):
for _, f := range st {
fmt.Fprintf(s, "\n%+v", f)
io.WriteString(s, "\n")
f.Format(s, verb)
}
case s.Flag('#'):
fmt.Fprintf(s, "%#v", []Frame(st))
default:
fmt.Fprintf(s, "%v", []Frame(st))
st.formatSlice(s, verb)
}
case 's':
fmt.Fprintf(s, "%s", []Frame(st))
st.formatSlice(s, verb)
}
}
// formatSlice will format this StackTrace into the given buffer as a slice of
// Frame, only valid when called with '%s' or '%v'.
func (st StackTrace) formatSlice(s fmt.State, verb rune) {
io.WriteString(s, "[")
for i, f := range st {
if i > 0 {
io.WriteString(s, " ")
}
f.Format(s, verb)
}
io.WriteString(s, "]")
}
// stack represents a stack of program counters.
type stack []uintptr
func (s *stack) Format(st fmt.State, verb rune) {
switch verb {
case 'v':
switch {
case st.Flag('+'):
for _, pc := range *s {
f := Frame(pc)
fmt.Fprintf(st, "\n%+v", f)
}
}
}
}
func (s *stack) StackTrace() StackTrace {
f := make([]Frame, len(*s))
for i := 0; i < len(f); i++ {
@ -123,43 +175,3 @@ func funcname(name string) string {
i = strings.Index(name, ".")
return name[i+1:]
}
func trimGOPATH(name, file string) string {
// Here we want to get the source file path relative to the compile time
// GOPATH. As of Go 1.6.x there is no direct way to know the compiled
// GOPATH at runtime, but we can infer the number of path segments in the
// GOPATH. We note that fn.Name() returns the function name qualified by
// the import path, which does not include the GOPATH. Thus we can trim
// segments from the beginning of the file path until the number of path
// separators remaining is one more than the number of path separators in
// the function name. For example, given:
//
// GOPATH /home/user
// file /home/user/src/pkg/sub/file.go
// fn.Name() pkg/sub.Type.Method
//
// We want to produce:
//
// pkg/sub/file.go
//
// From this we can easily see that fn.Name() has one less path separator
// than our desired output. We count separators from the end of the file
// path until it finds two more than in the function name and then move
// one character forward to preserve the initial path segment without a
// leading separator.
const sep = "/"
goal := strings.Count(name, sep) + 2
i := len(file)
for n := 0; n < goal; n++ {
i = strings.LastIndex(file[:i], sep)
if i == -1 {
// not enough separators found, set i so that the slice expression
// below leaves file unmodified
i = -len(sep)
break
}
}
// get back to 0 or trim the leading separator
file = file[i+len(sep):]
return file
}

22
vendor/github.com/stretchr/testify/LICENCE.txt сгенерированный поставляемый
Просмотреть файл

@ -1,22 +0,0 @@
Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell
Please consider promoting this project if you find it useful.
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.

12
vendor/golang.org/x/text/encoding/encoding.go сгенерированный поставляемый
Просмотреть файл

@ -8,7 +8,7 @@
// Encoding implementations are provided in other packages, such as
// golang.org/x/text/encoding/charmap and
// golang.org/x/text/encoding/japanese.
package encoding
package encoding // import "golang.org/x/text/encoding"
import (
"errors"
@ -52,7 +52,7 @@ type Decoder struct {
}
// Bytes converts the given encoded bytes to UTF-8. It returns the converted
// bytes or 0, err if any error occurred.
// bytes or nil, err if any error occurred.
func (d *Decoder) Bytes(b []byte) ([]byte, error) {
b, _, err := transform.Bytes(d, b)
if err != nil {
@ -62,7 +62,7 @@ func (d *Decoder) Bytes(b []byte) ([]byte, error) {
}
// String converts the given encoded string to UTF-8. It returns the converted
// string or 0, err if any error occurred.
// string or "", err if any error occurred.
func (d *Decoder) String(s string) (string, error) {
s, _, err := transform.String(d, s)
if err != nil {
@ -95,7 +95,7 @@ type Encoder struct {
_ struct{}
}
// Bytes converts bytes from UTF-8. It returns the converted bytes or 0, err if
// Bytes converts bytes from UTF-8. It returns the converted bytes or nil, err if
// any error occurred.
func (e *Encoder) Bytes(b []byte) ([]byte, error) {
b, _, err := transform.Bytes(e, b)
@ -106,7 +106,7 @@ func (e *Encoder) Bytes(b []byte) ([]byte, error) {
}
// String converts a string from UTF-8. It returns the converted string or
// 0, err if any error occurred.
// "", err if any error occurred.
func (e *Encoder) String(s string) (string, error) {
s, _, err := transform.String(e, s)
if err != nil {
@ -124,7 +124,7 @@ func (e *Encoder) Writer(w io.Writer) io.Writer {
}
// ASCIISub is the ASCII substitute character, as recommended by
// http://unicode.org/reports/tr36/#Text_Comparison
// https://unicode.org/reports/tr36/#Text_Comparison
const ASCIISub = '\x1a'
// Nop is the nop encoding. Its transformed bytes are the same as the source

137
vendor/golang.org/x/text/encoding/internal/identifier/gen.go сгенерированный поставляемый
Просмотреть файл

@ -1,137 +0,0 @@
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build ignore
package main
import (
"bytes"
"encoding/xml"
"fmt"
"io"
"log"
"strings"
"golang.org/x/text/internal/gen"
)
type registry struct {
XMLName xml.Name `xml:"registry"`
Updated string `xml:"updated"`
Registry []struct {
ID string `xml:"id,attr"`
Record []struct {
Name string `xml:"name"`
Xref []struct {
Type string `xml:"type,attr"`
Data string `xml:"data,attr"`
} `xml:"xref"`
Desc struct {
Data string `xml:",innerxml"`
// Any []struct {
// Data string `xml:",chardata"`
// } `xml:",any"`
// Data string `xml:",chardata"`
} `xml:"description,"`
MIB string `xml:"value"`
Alias []string `xml:"alias"`
MIME string `xml:"preferred_alias"`
} `xml:"record"`
} `xml:"registry"`
}
func main() {
r := gen.OpenIANAFile("assignments/character-sets/character-sets.xml")
reg := &registry{}
if err := xml.NewDecoder(r).Decode(&reg); err != nil && err != io.EOF {
log.Fatalf("Error decoding charset registry: %v", err)
}
if len(reg.Registry) == 0 || reg.Registry[0].ID != "character-sets-1" {
log.Fatalf("Unexpected ID %s", reg.Registry[0].ID)
}
w := &bytes.Buffer{}
fmt.Fprintf(w, "const (\n")
for _, rec := range reg.Registry[0].Record {
constName := ""
for _, a := range rec.Alias {
if strings.HasPrefix(a, "cs") && strings.IndexByte(a, '-') == -1 {
// Some of the constant definitions have comments in them. Strip those.
constName = strings.Title(strings.SplitN(a[2:], "\n", 2)[0])
}
}
if constName == "" {
switch rec.MIB {
case "2085":
constName = "HZGB2312" // Not listed as alias for some reason.
default:
log.Fatalf("No cs alias defined for %s.", rec.MIB)
}
}
if rec.MIME != "" {
rec.MIME = fmt.Sprintf(" (MIME: %s)", rec.MIME)
}
fmt.Fprintf(w, "// %s is the MIB identifier with IANA name %s%s.\n//\n", constName, rec.Name, rec.MIME)
if len(rec.Desc.Data) > 0 {
fmt.Fprint(w, "// ")
d := xml.NewDecoder(strings.NewReader(rec.Desc.Data))
inElem := true
attr := ""
for {
t, err := d.Token()
if err != nil {
if err != io.EOF {
log.Fatal(err)
}
break
}
switch x := t.(type) {
case xml.CharData:
attr = "" // Don't need attribute info.
a := bytes.Split([]byte(x), []byte("\n"))
for i, b := range a {
if b = bytes.TrimSpace(b); len(b) != 0 {
if !inElem && i > 0 {
fmt.Fprint(w, "\n// ")
}
inElem = false
fmt.Fprintf(w, "%s ", string(b))
}
}
case xml.StartElement:
if x.Name.Local == "xref" {
inElem = true
use := false
for _, a := range x.Attr {
if a.Name.Local == "type" {
use = use || a.Value != "person"
}
if a.Name.Local == "data" && use {
attr = a.Value + " "
}
}
}
case xml.EndElement:
inElem = false
fmt.Fprint(w, attr)
}
}
fmt.Fprint(w, "\n")
}
for _, x := range rec.Xref {
switch x.Type {
case "rfc":
fmt.Fprintf(w, "// Reference: %s\n", strings.ToUpper(x.Data))
case "uri":
fmt.Fprintf(w, "// Reference: %s\n", x.Data)
}
}
fmt.Fprintf(w, "%s MIB = %s\n", constName, rec.MIB)
fmt.Fprintln(w)
}
fmt.Fprintln(w, ")")
gen.WriteGoFile("mib.go", "identifier", w.Bytes())
}

4
vendor/golang.org/x/text/encoding/internal/identifier/identifier.go сгенерированный поставляемый
Просмотреть файл

@ -34,10 +34,10 @@ package identifier
// - http://www.iana.org/assignments/character-sets/character-sets.xhtml
// - http://www.iana.org/assignments/ianacharset-mib/ianacharset-mib
// - http://www.ietf.org/rfc/rfc2978.txt
// - http://www.unicode.org/reports/tr22/
// - https://www.unicode.org/reports/tr22/
// - http://www.w3.org/TR/encoding/
// - http://www.w3.org/TR/encoding/indexes/encodings.json
// - https://encoding.spec.whatwg.org/
// - https://encoding.spec.whatwg.org/encodings.json
// - https://tools.ietf.org/html/rfc6657#section-5
// Interface can be implemented by Encodings to define the CCS or CES for which

98
vendor/golang.org/x/text/encoding/internal/identifier/mib.go сгенерированный поставляемый
Просмотреть файл

@ -1,4 +1,4 @@
// This file was generated by go generate; DO NOT EDIT
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
package identifier
@ -538,8 +538,6 @@ const (
// ISO111ECMACyrillic is the MIB identifier with IANA name ECMA-cyrillic.
//
// ISO registry
// (formerly ECMA
// registry )
ISO111ECMACyrillic MIB = 77
// ISO121Canadian1 is the MIB identifier with IANA name CSA_Z243.4-1985-1.
@ -732,18 +730,18 @@ const (
// ISO885913 is the MIB identifier with IANA name ISO-8859-13.
//
// ISO See http://www.iana.org/assignments/charset-reg/ISO-8859-13 http://www.iana.org/assignments/charset-reg/ISO-8859-13
// ISO See https://www.iana.org/assignments/charset-reg/ISO-8859-13 https://www.iana.org/assignments/charset-reg/ISO-8859-13
ISO885913 MIB = 109
// ISO885914 is the MIB identifier with IANA name ISO-8859-14.
//
// ISO See http://www.iana.org/assignments/charset-reg/ISO-8859-14
// ISO See https://www.iana.org/assignments/charset-reg/ISO-8859-14
ISO885914 MIB = 110
// ISO885915 is the MIB identifier with IANA name ISO-8859-15.
//
// ISO
// Please see: http://www.iana.org/assignments/charset-reg/ISO-8859-15
// Please see: https://www.iana.org/assignments/charset-reg/ISO-8859-15
ISO885915 MIB = 111
// ISO885916 is the MIB identifier with IANA name ISO-8859-16.
@ -754,41 +752,41 @@ const (
// GBK is the MIB identifier with IANA name GBK.
//
// Chinese IT Standardization Technical Committee
// Please see: http://www.iana.org/assignments/charset-reg/GBK
// Please see: https://www.iana.org/assignments/charset-reg/GBK
GBK MIB = 113
// GB18030 is the MIB identifier with IANA name GB18030.
//
// Chinese IT Standardization Technical Committee
// Please see: http://www.iana.org/assignments/charset-reg/GB18030
// Please see: https://www.iana.org/assignments/charset-reg/GB18030
GB18030 MIB = 114
// OSDEBCDICDF0415 is the MIB identifier with IANA name OSD_EBCDIC_DF04_15.
//
// Fujitsu-Siemens standard mainframe EBCDIC encoding
// Please see: http://www.iana.org/assignments/charset-reg/OSD-EBCDIC-DF04-15
// Please see: https://www.iana.org/assignments/charset-reg/OSD-EBCDIC-DF04-15
OSDEBCDICDF0415 MIB = 115
// OSDEBCDICDF03IRV is the MIB identifier with IANA name OSD_EBCDIC_DF03_IRV.
//
// Fujitsu-Siemens standard mainframe EBCDIC encoding
// Please see: http://www.iana.org/assignments/charset-reg/OSD-EBCDIC-DF03-IRV
// Please see: https://www.iana.org/assignments/charset-reg/OSD-EBCDIC-DF03-IRV
OSDEBCDICDF03IRV MIB = 116
// OSDEBCDICDF041 is the MIB identifier with IANA name OSD_EBCDIC_DF04_1.
//
// Fujitsu-Siemens standard mainframe EBCDIC encoding
// Please see: http://www.iana.org/assignments/charset-reg/OSD-EBCDIC-DF04-1
// Please see: https://www.iana.org/assignments/charset-reg/OSD-EBCDIC-DF04-1
OSDEBCDICDF041 MIB = 117
// ISO115481 is the MIB identifier with IANA name ISO-11548-1.
//
// See http://www.iana.org/assignments/charset-reg/ISO-11548-1
// See https://www.iana.org/assignments/charset-reg/ISO-11548-1
ISO115481 MIB = 118
// KZ1048 is the MIB identifier with IANA name KZ-1048.
//
// See http://www.iana.org/assignments/charset-reg/KZ-1048
// See https://www.iana.org/assignments/charset-reg/KZ-1048
KZ1048 MIB = 119
// Unicode is the MIB identifier with IANA name ISO-10646-UCS-2.
@ -855,7 +853,7 @@ const (
// SCSU is the MIB identifier with IANA name SCSU.
//
// SCSU See http://www.iana.org/assignments/charset-reg/SCSU
// SCSU See https://www.iana.org/assignments/charset-reg/SCSU
SCSU MIB = 1011
// UTF7 is the MIB identifier with IANA name UTF-7.
@ -884,27 +882,27 @@ const (
// CESU8 is the MIB identifier with IANA name CESU-8.
//
// http://www.unicode.org/unicode/reports/tr26
// https://www.unicode.org/reports/tr26
CESU8 MIB = 1016
// UTF32 is the MIB identifier with IANA name UTF-32.
//
// http://www.unicode.org/unicode/reports/tr19/
// https://www.unicode.org/reports/tr19/
UTF32 MIB = 1017
// UTF32BE is the MIB identifier with IANA name UTF-32BE.
//
// http://www.unicode.org/unicode/reports/tr19/
// https://www.unicode.org/reports/tr19/
UTF32BE MIB = 1018
// UTF32LE is the MIB identifier with IANA name UTF-32LE.
//
// http://www.unicode.org/unicode/reports/tr19/
// https://www.unicode.org/reports/tr19/
UTF32LE MIB = 1019
// BOCU1 is the MIB identifier with IANA name BOCU-1.
//
// http://www.unicode.org/notes/tn6/
// https://www.unicode.org/notes/tn6/
BOCU1 MIB = 1020
// Windows30Latin1 is the MIB identifier with IANA name ISO-8859-1-Windows-3.0-Latin-1.
@ -1461,152 +1459,152 @@ const (
// IBM00858 is the MIB identifier with IANA name IBM00858.
//
// IBM See http://www.iana.org/assignments/charset-reg/IBM00858
// IBM See https://www.iana.org/assignments/charset-reg/IBM00858
IBM00858 MIB = 2089
// IBM00924 is the MIB identifier with IANA name IBM00924.
//
// IBM See http://www.iana.org/assignments/charset-reg/IBM00924
// IBM See https://www.iana.org/assignments/charset-reg/IBM00924
IBM00924 MIB = 2090
// IBM01140 is the MIB identifier with IANA name IBM01140.
//
// IBM See http://www.iana.org/assignments/charset-reg/IBM01140
// IBM See https://www.iana.org/assignments/charset-reg/IBM01140
IBM01140 MIB = 2091
// IBM01141 is the MIB identifier with IANA name IBM01141.
//
// IBM See http://www.iana.org/assignments/charset-reg/IBM01141
// IBM See https://www.iana.org/assignments/charset-reg/IBM01141
IBM01141 MIB = 2092
// IBM01142 is the MIB identifier with IANA name IBM01142.
//
// IBM See http://www.iana.org/assignments/charset-reg/IBM01142
// IBM See https://www.iana.org/assignments/charset-reg/IBM01142
IBM01142 MIB = 2093
// IBM01143 is the MIB identifier with IANA name IBM01143.
//
// IBM See http://www.iana.org/assignments/charset-reg/IBM01143
// IBM See https://www.iana.org/assignments/charset-reg/IBM01143
IBM01143 MIB = 2094
// IBM01144 is the MIB identifier with IANA name IBM01144.
//
// IBM See http://www.iana.org/assignments/charset-reg/IBM01144
// IBM See https://www.iana.org/assignments/charset-reg/IBM01144
IBM01144 MIB = 2095
// IBM01145 is the MIB identifier with IANA name IBM01145.
//
// IBM See http://www.iana.org/assignments/charset-reg/IBM01145
// IBM See https://www.iana.org/assignments/charset-reg/IBM01145
IBM01145 MIB = 2096
// IBM01146 is the MIB identifier with IANA name IBM01146.
//
// IBM See http://www.iana.org/assignments/charset-reg/IBM01146
// IBM See https://www.iana.org/assignments/charset-reg/IBM01146
IBM01146 MIB = 2097
// IBM01147 is the MIB identifier with IANA name IBM01147.
//
// IBM See http://www.iana.org/assignments/charset-reg/IBM01147
// IBM See https://www.iana.org/assignments/charset-reg/IBM01147
IBM01147 MIB = 2098
// IBM01148 is the MIB identifier with IANA name IBM01148.
//
// IBM See http://www.iana.org/assignments/charset-reg/IBM01148
// IBM See https://www.iana.org/assignments/charset-reg/IBM01148
IBM01148 MIB = 2099
// IBM01149 is the MIB identifier with IANA name IBM01149.
//
// IBM See http://www.iana.org/assignments/charset-reg/IBM01149
// IBM See https://www.iana.org/assignments/charset-reg/IBM01149
IBM01149 MIB = 2100
// Big5HKSCS is the MIB identifier with IANA name Big5-HKSCS.
//
// See http://www.iana.org/assignments/charset-reg/Big5-HKSCS
// See https://www.iana.org/assignments/charset-reg/Big5-HKSCS
Big5HKSCS MIB = 2101
// IBM1047 is the MIB identifier with IANA name IBM1047.
//
// IBM1047 (EBCDIC Latin 1/Open Systems) http://www-1.ibm.com/servers/eserver/iseries/software/globalization/pdf/cp01047z.pdf
// IBM1047 (EBCDIC Latin 1/Open Systems) https://www-1.ibm.com/servers/eserver/iseries/software/globalization/pdf/cp01047z.pdf
IBM1047 MIB = 2102
// PTCP154 is the MIB identifier with IANA name PTCP154.
//
// See http://www.iana.org/assignments/charset-reg/PTCP154
// See https://www.iana.org/assignments/charset-reg/PTCP154
PTCP154 MIB = 2103
// Amiga1251 is the MIB identifier with IANA name Amiga-1251.
//
// See http://www.amiga.ultranet.ru/Amiga-1251.html
// See https://www.amiga.ultranet.ru/Amiga-1251.html
Amiga1251 MIB = 2104
// KOI7switched is the MIB identifier with IANA name KOI7-switched.
//
// See http://www.iana.org/assignments/charset-reg/KOI7-switched
// See https://www.iana.org/assignments/charset-reg/KOI7-switched
KOI7switched MIB = 2105
// BRF is the MIB identifier with IANA name BRF.
//
// See http://www.iana.org/assignments/charset-reg/BRF
// See https://www.iana.org/assignments/charset-reg/BRF
BRF MIB = 2106
// TSCII is the MIB identifier with IANA name TSCII.
//
// See http://www.iana.org/assignments/charset-reg/TSCII
// See https://www.iana.org/assignments/charset-reg/TSCII
TSCII MIB = 2107
// CP51932 is the MIB identifier with IANA name CP51932.
//
// See http://www.iana.org/assignments/charset-reg/CP51932
// See https://www.iana.org/assignments/charset-reg/CP51932
CP51932 MIB = 2108
// Windows874 is the MIB identifier with IANA name windows-874.
//
// See http://www.iana.org/assignments/charset-reg/windows-874
// See https://www.iana.org/assignments/charset-reg/windows-874
Windows874 MIB = 2109
// Windows1250 is the MIB identifier with IANA name windows-1250.
//
// Microsoft http://www.iana.org/assignments/charset-reg/windows-1250
// Microsoft https://www.iana.org/assignments/charset-reg/windows-1250
Windows1250 MIB = 2250
// Windows1251 is the MIB identifier with IANA name windows-1251.
//
// Microsoft http://www.iana.org/assignments/charset-reg/windows-1251
// Microsoft https://www.iana.org/assignments/charset-reg/windows-1251
Windows1251 MIB = 2251
// Windows1252 is the MIB identifier with IANA name windows-1252.
//
// Microsoft http://www.iana.org/assignments/charset-reg/windows-1252
// Microsoft https://www.iana.org/assignments/charset-reg/windows-1252
Windows1252 MIB = 2252
// Windows1253 is the MIB identifier with IANA name windows-1253.
//
// Microsoft http://www.iana.org/assignments/charset-reg/windows-1253
// Microsoft https://www.iana.org/assignments/charset-reg/windows-1253
Windows1253 MIB = 2253
// Windows1254 is the MIB identifier with IANA name windows-1254.
//
// Microsoft http://www.iana.org/assignments/charset-reg/windows-1254
// Microsoft https://www.iana.org/assignments/charset-reg/windows-1254
Windows1254 MIB = 2254
// Windows1255 is the MIB identifier with IANA name windows-1255.
//
// Microsoft http://www.iana.org/assignments/charset-reg/windows-1255
// Microsoft https://www.iana.org/assignments/charset-reg/windows-1255
Windows1255 MIB = 2255
// Windows1256 is the MIB identifier with IANA name windows-1256.
//
// Microsoft http://www.iana.org/assignments/charset-reg/windows-1256
// Microsoft https://www.iana.org/assignments/charset-reg/windows-1256
Windows1256 MIB = 2256
// Windows1257 is the MIB identifier with IANA name windows-1257.
//
// Microsoft http://www.iana.org/assignments/charset-reg/windows-1257
// Microsoft https://www.iana.org/assignments/charset-reg/windows-1257
Windows1257 MIB = 2257
// Windows1258 is the MIB identifier with IANA name windows-1258.
//
// Microsoft http://www.iana.org/assignments/charset-reg/windows-1258
// Microsoft https://www.iana.org/assignments/charset-reg/windows-1258
Windows1258 MIB = 2258
// TIS620 is the MIB identifier with IANA name TIS-620.
@ -1616,6 +1614,6 @@ const (
// CP50220 is the MIB identifier with IANA name CP50220.
//
// See http://www.iana.org/assignments/charset-reg/CP50220
// See https://www.iana.org/assignments/charset-reg/CP50220
CP50220 MIB = 2260
)

98
vendor/golang.org/x/text/encoding/unicode/unicode.go сгенерированный поставляемый
Просмотреть файл

@ -3,9 +3,10 @@
// license that can be found in the LICENSE file.
// Package unicode provides Unicode encodings such as UTF-16.
package unicode
package unicode // import "golang.org/x/text/encoding/unicode"
import (
"bytes"
"errors"
"unicode/utf16"
"unicode/utf8"
@ -25,15 +26,95 @@ import (
// the introduction of some kind of error type for conveying the erroneous code
// point.
// UTF8 is the UTF-8 encoding.
// UTF8 is the UTF-8 encoding. It neither removes nor adds byte order marks.
var UTF8 encoding.Encoding = utf8enc
// UTF8BOM is an UTF-8 encoding where the decoder strips a leading byte order
// mark while the encoder adds one.
//
// Some editors add a byte order mark as a signature to UTF-8 files. Although
// the byte order mark is not useful for detecting byte order in UTF-8, it is
// sometimes used as a convention to mark UTF-8-encoded files. This relies on
// the observation that the UTF-8 byte order mark is either an illegal or at
// least very unlikely sequence in any other character encoding.
var UTF8BOM encoding.Encoding = utf8bomEncoding{}
type utf8bomEncoding struct{}
func (utf8bomEncoding) String() string {
return "UTF-8-BOM"
}
func (utf8bomEncoding) ID() (identifier.MIB, string) {
return identifier.Unofficial, "x-utf8bom"
}
func (utf8bomEncoding) NewEncoder() *encoding.Encoder {
return &encoding.Encoder{
Transformer: &utf8bomEncoder{t: runes.ReplaceIllFormed()},
}
}
func (utf8bomEncoding) NewDecoder() *encoding.Decoder {
return &encoding.Decoder{Transformer: &utf8bomDecoder{}}
}
var utf8enc = &internal.Encoding{
&internal.SimpleEncoding{utf8Decoder{}, runes.ReplaceIllFormed()},
"UTF-8",
identifier.UTF8,
}
type utf8bomDecoder struct {
checked bool
}
func (t *utf8bomDecoder) Reset() {
t.checked = false
}
func (t *utf8bomDecoder) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
if !t.checked {
if !atEOF && len(src) < len(utf8BOM) {
if len(src) == 0 {
return 0, 0, nil
}
return 0, 0, transform.ErrShortSrc
}
if bytes.HasPrefix(src, []byte(utf8BOM)) {
nSrc += len(utf8BOM)
src = src[len(utf8BOM):]
}
t.checked = true
}
nDst, n, err := utf8Decoder.Transform(utf8Decoder{}, dst[nDst:], src, atEOF)
nSrc += n
return nDst, nSrc, err
}
type utf8bomEncoder struct {
written bool
t transform.Transformer
}
func (t *utf8bomEncoder) Reset() {
t.written = false
t.t.Reset()
}
func (t *utf8bomEncoder) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
if !t.written {
if len(dst) < len(utf8BOM) {
return nDst, 0, transform.ErrShortDst
}
nDst = copy(dst, utf8BOM)
t.written = true
}
n, nSrc, err := utf8Decoder.Transform(utf8Decoder{}, dst[nDst:], src, atEOF)
nDst += n
return nDst, nSrc, err
}
type utf8Decoder struct{ transform.NopResetter }
func (utf8Decoder) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
@ -145,7 +226,7 @@ func (utf8Decoder) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err e
// and consumed in a greater context that implies a certain endianness, use
// IgnoreBOM. Otherwise, use ExpectBOM and always produce and consume a BOM.
//
// In the language of http://www.unicode.org/faq/utf_bom.html#bom10, IgnoreBOM
// In the language of https://www.unicode.org/faq/utf_bom.html#bom10, IgnoreBOM
// corresponds to "Where the precise type of the data stream is known... the
// BOM should not be used" and ExpectBOM corresponds to "A particular
// protocol... may require use of the BOM".
@ -287,16 +368,13 @@ func (u *utf16Decoder) Reset() {
}
func (u *utf16Decoder) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
if len(src) < 2 && atEOF && u.current.bomPolicy&requireBOM != 0 {
return 0, 0, ErrMissingBOM
}
if len(src) == 0 {
if atEOF && u.current.bomPolicy&requireBOM != 0 {
return 0, 0, ErrMissingBOM
}
return 0, 0, nil
}
if u.current.bomPolicy&acceptBOM != 0 {
if len(src) < 2 {
return 0, 0, transform.ErrShortSrc
}
if len(src) >= 2 && u.current.bomPolicy&acceptBOM != 0 {
switch {
case src[0] == 0xfe && src[1] == 0xff:
u.current.endianness = BigEndian

77
vendor/golang.org/x/text/runes/cond.go сгенерированный поставляемый
Просмотреть файл

@ -41,20 +41,35 @@ func If(s Set, tIn, tNotIn transform.Transformer) Transformer {
if tNotIn == nil {
tNotIn = transform.Nop
}
sIn, ok := tIn.(transform.SpanningTransformer)
if !ok {
sIn = dummySpan{tIn}
}
sNotIn, ok := tNotIn.(transform.SpanningTransformer)
if !ok {
sNotIn = dummySpan{tNotIn}
}
a := &cond{
tIn: tIn,
tNotIn: tNotIn,
tIn: sIn,
tNotIn: sNotIn,
f: s.Contains,
}
a.Reset()
return Transformer{a}
}
type dummySpan struct{ transform.Transformer }
func (d dummySpan) Span(src []byte, atEOF bool) (n int, err error) {
return 0, transform.ErrEndOfSpan
}
type cond struct {
tIn, tNotIn transform.Transformer
tIn, tNotIn transform.SpanningTransformer
f func(rune) bool
check func(rune) bool // current check to perform
t transform.Transformer // current transformer to use
check func(rune) bool // current check to perform
t transform.SpanningTransformer // current transformer to use
}
// Reset implements transform.Transformer.
@ -84,6 +99,51 @@ func (t *cond) isNot(r rune) bool {
return false
}
// This implementation of Span doesn't help all too much, but it needs to be
// there to satisfy this package's Transformer interface.
// TODO: there are certainly room for improvements, though. For example, if
// t.t == transform.Nop (which will a common occurrence) it will save a bundle
// to special-case that loop.
func (t *cond) Span(src []byte, atEOF bool) (n int, err error) {
p := 0
for n < len(src) && err == nil {
// Don't process too much at a time as the Spanner that will be
// called on this block may terminate early.
const maxChunk = 4096
max := len(src)
if v := n + maxChunk; v < max {
max = v
}
atEnd := false
size := 0
current := t.t
for ; p < max; p += size {
r := rune(src[p])
if r < utf8.RuneSelf {
size = 1
} else if r, size = utf8.DecodeRune(src[p:]); size == 1 {
if !atEOF && !utf8.FullRune(src[p:]) {
err = transform.ErrShortSrc
break
}
}
if !t.check(r) {
// The next rune will be the start of a new run.
atEnd = true
break
}
}
n2, err2 := current.Span(src[n:p], atEnd || (atEOF && p == len(src)))
n += n2
if err2 != nil {
return n, err2
}
// At this point either err != nil or t.check will pass for the rune at p.
p = n + size
}
return n, err
}
func (t *cond) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
p := 0
for nSrc < len(src) && err == nil {
@ -99,9 +159,10 @@ func (t *cond) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error
size := 0
current := t.t
for ; p < max; p += size {
var r rune
r, size = utf8.DecodeRune(src[p:])
if r == utf8.RuneError && size == 1 {
r := rune(src[p])
if r < utf8.RuneSelf {
size = 1
} else if r, size = utf8.DecodeRune(src[p:]); size == 1 {
if !atEOF && !utf8.FullRune(src[p:]) {
err = transform.ErrShortSrc
break

141
vendor/golang.org/x/text/runes/runes.go сгенерированный поставляемый
Просмотреть файл

@ -3,7 +3,7 @@
// license that can be found in the LICENSE file.
// Package runes provide transforms for UTF-8 encoded text.
package runes
package runes // import "golang.org/x/text/runes"
import (
"unicode"
@ -46,9 +46,19 @@ func Predicate(f func(rune) bool) Set {
// Transformer implements the transform.Transformer interface.
type Transformer struct {
transform.Transformer
t transform.SpanningTransformer
}
func (t Transformer) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
return t.t.Transform(dst, src, atEOF)
}
func (t Transformer) Span(b []byte, atEOF bool) (n int, err error) {
return t.t.Span(b, atEOF)
}
func (t Transformer) Reset() { t.t.Reset() }
// Bytes returns a new byte slice with the result of converting b using t. It
// calls Reset on t. It returns nil if any error was found. This can only happen
// if an error-producing Transformer is passed to If.
@ -96,39 +106,57 @@ type remove func(r rune) bool
func (remove) Reset() {}
// Span implements transform.Spanner.
func (t remove) Span(src []byte, atEOF bool) (n int, err error) {
for r, size := rune(0), 0; n < len(src); {
if r = rune(src[n]); r < utf8.RuneSelf {
size = 1
} else if r, size = utf8.DecodeRune(src[n:]); size == 1 {
// Invalid rune.
if !atEOF && !utf8.FullRune(src[n:]) {
err = transform.ErrShortSrc
} else {
err = transform.ErrEndOfSpan
}
break
}
if t(r) {
err = transform.ErrEndOfSpan
break
}
n += size
}
return
}
// Transform implements transform.Transformer.
func (t remove) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
for r, size := rune(0), 0; nSrc < len(src); {
if r = rune(src[nSrc]); r < utf8.RuneSelf {
size = 1
} else {
r, size = utf8.DecodeRune(src[nSrc:])
if size == 1 {
// Invalid rune.
if !atEOF && !utf8.FullRune(src[nSrc:]) {
err = transform.ErrShortSrc
} else if r, size = utf8.DecodeRune(src[nSrc:]); size == 1 {
// Invalid rune.
if !atEOF && !utf8.FullRune(src[nSrc:]) {
err = transform.ErrShortSrc
break
}
// We replace illegal bytes with RuneError. Not doing so might
// otherwise turn a sequence of invalid UTF-8 into valid UTF-8.
// The resulting byte sequence may subsequently contain runes
// for which t(r) is true that were passed unnoticed.
if !t(utf8.RuneError) {
if nDst+3 > len(dst) {
err = transform.ErrShortDst
break
}
// We replace illegal bytes with RuneError. Not doing so might
// otherwise turn a sequence of invalid UTF-8 into valid UTF-8.
// The resulting byte sequence may subsequently contain runes
// for which t(r) is true that were passed unnoticed.
if !t(utf8.RuneError) {
if nDst+3 > len(dst) {
err = transform.ErrShortDst
break
}
dst[nDst+0] = runeErrorString[0]
dst[nDst+1] = runeErrorString[1]
dst[nDst+2] = runeErrorString[2]
nDst += 3
}
nSrc++
continue
dst[nDst+0] = runeErrorString[0]
dst[nDst+1] = runeErrorString[1]
dst[nDst+2] = runeErrorString[2]
nDst += 3
}
nSrc++
continue
}
if t(r) {
nSrc += size
continue
@ -157,6 +185,28 @@ type mapper func(rune) rune
func (mapper) Reset() {}
// Span implements transform.Spanner.
func (t mapper) Span(src []byte, atEOF bool) (n int, err error) {
for r, size := rune(0), 0; n < len(src); n += size {
if r = rune(src[n]); r < utf8.RuneSelf {
size = 1
} else if r, size = utf8.DecodeRune(src[n:]); size == 1 {
// Invalid rune.
if !atEOF && !utf8.FullRune(src[n:]) {
err = transform.ErrShortSrc
} else {
err = transform.ErrEndOfSpan
}
break
}
if t(r) != r {
err = transform.ErrEndOfSpan
break
}
}
return n, err
}
// Transform implements transform.Transformer.
func (t mapper) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
var replacement rune
@ -230,24 +280,51 @@ func ReplaceIllFormed() Transformer {
type replaceIllFormed struct{ transform.NopResetter }
func (t replaceIllFormed) Span(src []byte, atEOF bool) (n int, err error) {
for n < len(src) {
// ASCII fast path.
if src[n] < utf8.RuneSelf {
n++
continue
}
r, size := utf8.DecodeRune(src[n:])
// Look for a valid non-ASCII rune.
if r != utf8.RuneError || size != 1 {
n += size
continue
}
// Look for short source data.
if !atEOF && !utf8.FullRune(src[n:]) {
err = transform.ErrShortSrc
break
}
// We have an invalid rune.
err = transform.ErrEndOfSpan
break
}
return n, err
}
func (t replaceIllFormed) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
for nSrc < len(src) {
r, size := utf8.DecodeRune(src[nSrc:])
// Look for an ASCII rune.
if r < utf8.RuneSelf {
// ASCII fast path.
if r := src[nSrc]; r < utf8.RuneSelf {
if nDst == len(dst) {
err = transform.ErrShortDst
break
}
dst[nDst] = byte(r)
dst[nDst] = r
nDst++
nSrc++
continue
}
// Look for a valid non-ASCII rune.
if r != utf8.RuneError || size != 1 {
if _, size := utf8.DecodeRune(src[nSrc:]); size != 1 {
if size != copy(dst[nDst:], src[nSrc:nSrc+size]) {
err = transform.ErrShortDst
break

60
vendor/golang.org/x/text/transform/transform.go сгенерированный поставляемый
Просмотреть файл

@ -6,7 +6,7 @@
// bytes passing through as well as various transformations. Example
// transformations provided by other packages include normalization and
// conversion between character sets.
package transform
package transform // import "golang.org/x/text/transform"
import (
"bytes"
@ -24,6 +24,10 @@ var (
// complete the transformation.
ErrShortSrc = errors.New("transform: short source buffer")
// ErrEndOfSpan means that the input and output (the transformed input)
// are not identical.
ErrEndOfSpan = errors.New("transform: input and output are not identical")
// errInconsistentByteCount means that Transform returned success (nil
// error) but also returned nSrc inconsistent with the src argument.
errInconsistentByteCount = errors.New("transform: inconsistent byte count returned")
@ -60,6 +64,41 @@ type Transformer interface {
Reset()
}
// SpanningTransformer extends the Transformer interface with a Span method
// that determines how much of the input already conforms to the Transformer.
type SpanningTransformer interface {
Transformer
// Span returns a position in src such that transforming src[:n] results in
// identical output src[:n] for these bytes. It does not necessarily return
// the largest such n. The atEOF argument tells whether src represents the
// last bytes of the input.
//
// Callers should always account for the n bytes consumed before
// considering the error err.
//
// A nil error means that all input bytes are known to be identical to the
// output produced by the Transformer. A nil error can be returned
// regardless of whether atEOF is true. If err is nil, then n must
// equal len(src); the converse is not necessarily true.
//
// ErrEndOfSpan means that the Transformer output may differ from the
// input after n bytes. Note that n may be len(src), meaning that the output
// would contain additional bytes after otherwise identical output.
// ErrShortSrc means that src had insufficient data to determine whether the
// remaining bytes would change. Other than the error conditions listed
// here, implementations are free to report other errors that arise.
//
// Calling Span can modify the Transformer state as a side effect. In
// effect, it does the transformation just as calling Transform would, only
// without copying to a destination buffer and only up to a point it can
// determine the input and output bytes are the same. This is obviously more
// limited than calling Transform, but can be more efficient in terms of
// copying and allocating buffers. Calls to Span and Transform may be
// interleaved.
Span(src []byte, atEOF bool) (n int, err error)
}
// NopResetter can be embedded by implementations of Transformer to add a nop
// Reset method.
type NopResetter struct{}
@ -278,6 +317,10 @@ func (nop) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
return n, n, err
}
func (nop) Span(src []byte, atEOF bool) (n int, err error) {
return len(src), nil
}
type discard struct{ NopResetter }
func (discard) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
@ -289,8 +332,8 @@ var (
// by consuming all bytes and writing nothing.
Discard Transformer = discard{}
// Nop is a Transformer that copies src to dst.
Nop Transformer = nop{}
// Nop is a SpanningTransformer that copies src to dst.
Nop SpanningTransformer = nop{}
)
// chain is a sequence of links. A chain with N Transformers has N+1 links and
@ -358,6 +401,8 @@ func (c *chain) Reset() {
}
}
// TODO: make chain use Span (is going to be fun to implement!)
// Transform applies the transformers of c in sequence.
func (c *chain) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
// Set up src and dst in the chain.
@ -448,8 +493,7 @@ func (c *chain) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err erro
return dstL.n, srcL.p, err
}
// RemoveFunc returns a Transformer that removes from the input all runes r for
// which f(r) is true. Illegal bytes in the input are replaced by RuneError.
// Deprecated: Use runes.Remove instead.
func RemoveFunc(f func(r rune) bool) Transformer {
return removeF(f)
}
@ -604,7 +648,8 @@ func String(t Transformer, s string) (result string, n int, err error) {
// Transform the remaining input, growing dst and src buffers as necessary.
for {
n := copy(src, s[pSrc:])
nDst, nSrc, err := t.Transform(dst[pDst:], src[:n], pSrc+n == len(s))
atEOF := pSrc+n == len(s)
nDst, nSrc, err := t.Transform(dst[pDst:], src[:n], atEOF)
pDst += nDst
pSrc += nSrc
@ -615,6 +660,9 @@ func String(t Transformer, s string) (result string, n int, err error) {
dst = grow(dst, pDst)
}
} else if err == ErrShortSrc {
if atEOF {
return string(dst[:pDst]), pSrc, err
}
if nSrc == 0 {
src = grow(src, 0)
}

62
vendor/modules.txt поставляемый Normal file
Просмотреть файл

@ -0,0 +1,62 @@
# github.com/Azure/azure-extension-foundation v0.0.0-20190726000431-02f4f599e64a
## explicit
github.com/Azure/azure-extension-foundation/errorhelper
github.com/Azure/azure-extension-foundation/httputil
github.com/Azure/azure-extension-foundation/msi
# github.com/Azure/azure-sdk-for-go v3.1.0-beta.0.20160802173609-87de771fcdf5+incompatible
## explicit
github.com/Azure/azure-sdk-for-go/storage
# github.com/ahmetalpbalkan/go-httpbin v0.0.0-20160706084156-8817b883dae1
## explicit
github.com/ahmetalpbalkan/go-httpbin
# github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2
## explicit
github.com/davecgh/go-spew/spew
# github.com/go-kit/kit v0.1.1-0.20160721083846-b076b44dbec2
## explicit
github.com/go-kit/kit/log
# github.com/go-logfmt/logfmt v0.2.1-0.20160601130801-d4327190ff83
## explicit
github.com/go-logfmt/logfmt
# github.com/go-stack/stack v1.5.2
## explicit
github.com/go-stack/stack
# github.com/gorilla/context v0.0.0-20160525203319-aed02d124ae4
## explicit
github.com/gorilla/context
# github.com/gorilla/mux v0.0.0-20160605233521-9fa818a44c2b
## explicit
github.com/gorilla/mux
# github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515
## explicit
github.com/kr/logfmt
# github.com/pkg/errors v0.9.1
## explicit
github.com/pkg/errors
# github.com/pmezard/go-difflib v1.0.0
## explicit
github.com/pmezard/go-difflib/difflib
# github.com/stretchr/testify v1.1.4-0.20160615092844-d77da356e56a
## explicit
github.com/stretchr/testify/assert
github.com/stretchr/testify/require
# github.com/xeipuuv/gojsonpointer v0.0.0-20151027082146-e0fe6f683076
## explicit
github.com/xeipuuv/gojsonpointer
# github.com/xeipuuv/gojsonreference v0.0.0-20150808065054-e02fc20de94c
## explicit
github.com/xeipuuv/gojsonreference
# github.com/xeipuuv/gojsonschema v0.0.0-20160623135812-c539bca196be
## explicit
github.com/xeipuuv/gojsonschema
# golang.org/x/text v0.3.7
## explicit
golang.org/x/text/encoding
golang.org/x/text/encoding/internal
golang.org/x/text/encoding/internal/identifier
golang.org/x/text/encoding/unicode
golang.org/x/text/internal/utf8internal
golang.org/x/text/runes
golang.org/x/text/transform
# gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c
## explicit