diff --git a/bluemix/configuration/config_helpers/helpers_test.go b/bluemix/configuration/config_helpers/helpers_test.go index c691937e..c82b6575 100644 --- a/bluemix/configuration/config_helpers/helpers_test.go +++ b/bluemix/configuration/config_helpers/helpers_test.go @@ -10,16 +10,6 @@ import ( "github.com/stretchr/testify/assert" ) -// import ( -// "io/ioutil" -// "os" -// "path/filepath" -// "testing" - -// "github.com/stretchr/testify/assert" -// "github.ibm.com/bluemix-cli-release/build/src/github.ibm.com/Bluemix/bluemix-cli-common/file_helpers" -// ) - func captureAndPrepareEnv(a *assert.Assertions) ([]string, string) { env := os.Environ() @@ -30,7 +20,11 @@ func captureAndPrepareEnv(a *assert.Assertions) ([]string, string) { os.Unsetenv("IBMCLOUD_HOME") os.Unsetenv("BLUEMIX_HOME") os.Setenv("HOME", userHome) - + // UserHomeDir() uses HOMEDRIVE + HOMEPATH for windows + if os.Getenv("OS") == "Windows_NT" { + // ioutil.TempDir has the drive letter in the path, so we need to remove it when we set HOMEDRIVE + os.Setenv("HOMEPATH", strings.Replace(userHome, os.Getenv("HOMEDRIVE"), "", -1)) + } a.NoError(os.RemoveAll(userHome)) return env, userHome diff --git a/bluemix/env_test.go b/bluemix/env_test.go index b326cfba..a6a16c80 100644 --- a/bluemix/env_test.go +++ b/bluemix/env_test.go @@ -9,8 +9,6 @@ import ( ) func TestGet(t *testing.T) { - assert.Empty(t, EnvTrace.Get()) - os.Setenv("IBMCLOUD_TRACE", "true") assert.Equal(t, "true", EnvTrace.Get()) diff --git a/bluemix/terminal/table.go b/bluemix/terminal/table.go index f99fc869..3235e9ee 100644 --- a/bluemix/terminal/table.go +++ b/bluemix/terminal/table.go @@ -1,10 +1,12 @@ package terminal import ( + "encoding/csv" "fmt" "io" "strings" + . "github.com/IBM-Cloud/ibm-cloud-cli-sdk/i18n" "github.com/mattn/go-runewidth" ) @@ -18,6 +20,7 @@ type Table interface { Add(row ...string) Print() PrintJson() + PrintCsv() error } type PrintableTable struct { @@ -157,3 +160,16 @@ func (t *PrintableTable) PrintJson() { // mimic behavior of Print() t.rows = [][]string{} } + +func (t *PrintableTable) PrintCsv() error { + csvwriter := csv.NewWriter(t.writer) + err := csvwriter.Write(t.headers) + if err != nil { + return fmt.Errorf(T("Failed, header could not convert to csv format"), err.Error()) + } + err = csvwriter.WriteAll(t.rows) + if err != nil { + return fmt.Errorf(T("Failed, rows could not convert to csv format"), err.Error()) + } + return nil +} diff --git a/bluemix/terminal/table_test.go b/bluemix/terminal/table_test.go index e62bde1e..230529c0 100644 --- a/bluemix/terminal/table_test.go +++ b/bluemix/terminal/table_test.go @@ -2,6 +2,7 @@ package terminal_test import ( "bytes" + "strings" "testing" "github.com/stretchr/testify/assert" @@ -92,3 +93,47 @@ func TestNotEnoughRowEntiresJson(t *testing.T) { assert.Contains(t, buf.String(), "\"column_1\": \"row1\"") assert.Contains(t, buf.String(), "\"column_1\": \"\"") } + +func TestPrintCsvSimple(t *testing.T) { + buf := bytes.Buffer{} + testTable := NewTable(&buf, []string{"col1", "col2"}) + testTable.Add("row1-col1", "row1-col2") + testTable.Add("row2-col1", "row2-col2") + err := testTable.PrintCsv() + assert.Equal(t, err, nil) + assert.Contains(t, buf.String(), "col1,col2") + assert.Contains(t, buf.String(), "row1-col1,row1-col2") + assert.Contains(t, buf.String(), "row2-col1,row2-col2") +} + +func TestNotEnoughColPrintCsv(t *testing.T) { + buf := bytes.Buffer{} + testTable := NewTable(&buf, []string{"", "col2"}) + testTable.Add("row1-col1", "row1-col2") + testTable.Add("row2-col1", "row2-col2") + err := testTable.PrintCsv() + assert.Equal(t, err, nil) + assert.Contains(t, buf.String(), ",col2") + assert.Contains(t, buf.String(), "row1-col1,row1-col2") + assert.Contains(t, buf.String(), "row2-col1,row2-col2") +} + +func TestNotEnoughRowPrintCsv(t *testing.T) { + buf := bytes.Buffer{} + testTable := NewTable(&buf, []string{"col1", "col2"}) + testTable.Add("row1-col1", "row1-col2") + testTable.Add("row2-col1", "") + err := testTable.PrintCsv() + assert.Equal(t, err, nil) + assert.Contains(t, buf.String(), "col1,col2") + assert.Contains(t, buf.String(), "row1-col1,row1-col2") + assert.Contains(t, buf.String(), "row2-col1,") +} + +func TestEmptyTable(t *testing.T) { + buf := bytes.Buffer{} + testTable := NewTable(&buf, []string{}) + err := testTable.PrintCsv() + assert.Equal(t, err, nil) + assert.Equal(t, len(strings.TrimSpace(buf.String())), 0) +} diff --git a/bluemix/version.go b/bluemix/version.go index a3c1ccda..16f68770 100644 --- a/bluemix/version.go +++ b/bluemix/version.go @@ -3,7 +3,7 @@ package bluemix import "fmt" // Version is the SDK version -var Version = VersionType{Major: 1, Minor: 0, Build: 3} +var Version = VersionType{Major: 1, Minor: 1, Build: 0} // VersionType describe version info type VersionType struct { diff --git a/common/rest/client.go b/common/rest/client.go index c132e836..d32dddeb 100644 --- a/common/rest/client.go +++ b/common/rest/client.go @@ -63,6 +63,7 @@ func (c *Client) DoWithContext(ctx context.Context, r *Request, respV interface{ client = http.DefaultClient } + req.Close = true resp, err := client.Do(req) if err != nil { return resp, err diff --git a/go.mod b/go.mod index 9e14beb2..61b67852 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.17 require ( github.com/fatih/color v1.7.1-0.20180516100307-2d684516a886 github.com/fatih/structs v1.0.1-0.20171020064819-f5faa72e7309 + github.com/gofrs/flock v0.8.1 github.com/mattn/go-colorable v0.0.0-20160210001857-9fdad7c47650 github.com/mattn/go-runewidth v0.0.0-20151118072159-d96d1bd051f2 github.com/nicksnyder/go-i18n/v2 v2.2.0 @@ -22,10 +23,10 @@ require ( require ( github.com/BurntSushi/toml v1.1.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/gofrs/flock v0.8.1 // indirect github.com/golang/protobuf v1.5.2 // indirect github.com/hpcloud/tail v1.0.0 // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect + github.com/jteeuwen/go-bindata v3.0.7+incompatible // indirect github.com/mattn/go-isatty v0.0.5-0.20180830101745-3fb116b82035 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect golang.org/x/net v0.7.0 // indirect diff --git a/go.sum b/go.sum index c4c55ebb..1700f130 100644 --- a/go.sum +++ b/go.sum @@ -58,6 +58,8 @@ github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpO github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/jteeuwen/go-bindata v3.0.7+incompatible h1:91Uy4d9SYVr1kyTJ15wJsog+esAZZl7JmEfTkwmhJts= +github.com/jteeuwen/go-bindata v3.0.7+incompatible/go.mod h1:JVvhzYOiGBnFSYRyV00iY8q7/0PThjIYav1p9h5dmKs= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= diff --git a/i18n/resources/all.de_DE.json b/i18n/resources/all.de_DE.json index 85d505c3..9b999c83 100644 --- a/i18n/resources/all.de_DE.json +++ b/i18n/resources/all.de_DE.json @@ -31,6 +31,14 @@ "id": "FAILED", "translation": "FEHLGESCHLAGEN" }, + { + "id": "Failed, header could not convert to csv format", + "translation": "Failed, header could not convert to csv format" + }, + { + "id": "Failed, rows could not convert to csv format", + "translation": "Failed, rows could not convert to csv format" + }, { "id": "Invalid grant type: ", "translation": "Invalid grant type: " diff --git a/i18n/resources/all.en_US.json b/i18n/resources/all.en_US.json index 74dc1759..fb7320d3 100644 --- a/i18n/resources/all.en_US.json +++ b/i18n/resources/all.en_US.json @@ -31,6 +31,14 @@ "id": "FAILED", "translation": "FAILED" }, + { + "id": "Failed, header could not convert to csv format", + "translation": "Failed, header could not convert to csv format" + }, + { + "id": "Failed, rows could not convert to csv format", + "translation": "Failed, rows could not convert to csv format" + }, { "id": "Invalid grant type: ", "translation": "Invalid grant type: " diff --git a/i18n/resources/all.es_ES.json b/i18n/resources/all.es_ES.json index 9cb11056..7d5fc0c2 100644 --- a/i18n/resources/all.es_ES.json +++ b/i18n/resources/all.es_ES.json @@ -30,6 +30,14 @@ "id": "FAILED", "translation": "ERROR" }, + { + "id": "Failed, header could not convert to csv format", + "translation": "Failed, header could not convert to csv format" + }, + { + "id": "Failed, rows could not convert to csv format", + "translation": "Failed, rows could not convert to csv format" + }, { "id": "Invalid grant type: ", "translation": "Invalid grant type: " diff --git a/i18n/resources/all.fr_FR.json b/i18n/resources/all.fr_FR.json index 7446648d..64cf63aa 100644 --- a/i18n/resources/all.fr_FR.json +++ b/i18n/resources/all.fr_FR.json @@ -31,6 +31,14 @@ "id": "FAILED", "translation": "ECHEC" }, + { + "id": "Failed, header could not convert to csv format", + "translation": "Failed, header could not convert to csv format" + }, + { + "id": "Failed, rows could not convert to csv format", + "translation": "Failed, rows could not convert to csv format" + }, { "id": "Invalid grant type: ", "translation": "Invalid grant type: " diff --git a/i18n/resources/all.it_IT.json b/i18n/resources/all.it_IT.json index 4b476cba..f521b7b7 100644 --- a/i18n/resources/all.it_IT.json +++ b/i18n/resources/all.it_IT.json @@ -31,6 +31,14 @@ "id": "FAILED", "translation": "NON RIUSCITO" }, + { + "id": "Failed, header could not convert to csv format", + "translation": "Failed, header could not convert to csv format" + }, + { + "id": "Failed, rows could not convert to csv format", + "translation": "Failed, rows could not convert to csv format" + }, { "id": "Invalid grant type: ", "translation": "Invalid grant type: " diff --git a/i18n/resources/all.ja_JP.json b/i18n/resources/all.ja_JP.json index a1dfd9ce..1bb7f065 100644 --- a/i18n/resources/all.ja_JP.json +++ b/i18n/resources/all.ja_JP.json @@ -31,6 +31,14 @@ "id": "FAILED", "translation": "失敗" }, + { + "id": "Failed, header could not convert to csv format", + "translation": "Failed, header could not convert to csv format" + }, + { + "id": "Failed, rows could not convert to csv format", + "translation": "Failed, rows could not convert to csv format" + }, { "id": "Invalid grant type: ", "translation": "Invalid grant type: " diff --git a/i18n/resources/all.ko_KR.json b/i18n/resources/all.ko_KR.json index 5aad64c5..3f53cdbe 100644 --- a/i18n/resources/all.ko_KR.json +++ b/i18n/resources/all.ko_KR.json @@ -31,6 +31,14 @@ "id": "FAILED", "translation": "실패" }, + { + "id": "Failed, header could not convert to csv format", + "translation": "Failed, header could not convert to csv format" + }, + { + "id": "Failed, rows could not convert to csv format", + "translation": "Failed, rows could not convert to csv format" + }, { "id": "Invalid grant type: ", "translation": "Invalid grant type: " diff --git a/i18n/resources/all.pt_BR.json b/i18n/resources/all.pt_BR.json index c5312fea..6ee7e66c 100644 --- a/i18n/resources/all.pt_BR.json +++ b/i18n/resources/all.pt_BR.json @@ -31,6 +31,14 @@ "id": "FAILED", "translation": "COM FALHA" }, + { + "id": "Failed, header could not convert to csv format", + "translation": "Failed, header could not convert to csv format" + }, + { + "id": "Failed, rows could not convert to csv format", + "translation": "Failed, rows could not convert to csv format" + }, { "id": "Invalid grant type: ", "translation": "Invalid grant type: " diff --git a/i18n/resources/all.zh_Hans.json b/i18n/resources/all.zh_Hans.json index c024a67a..6b1ffeb6 100644 --- a/i18n/resources/all.zh_Hans.json +++ b/i18n/resources/all.zh_Hans.json @@ -31,6 +31,14 @@ "id": "FAILED", "translation": "失败" }, + { + "id": "Failed, header could not convert to csv format", + "translation": "Failed, header could not convert to csv format" + }, + { + "id": "Failed, rows could not convert to csv format", + "translation": "Failed, rows could not convert to csv format" + }, { "id": "Invalid grant type: ", "translation": "Invalid grant type: " diff --git a/i18n/resources/all.zh_Hant.json b/i18n/resources/all.zh_Hant.json index 472791d9..128c81bd 100644 --- a/i18n/resources/all.zh_Hant.json +++ b/i18n/resources/all.zh_Hant.json @@ -31,6 +31,14 @@ "id": "FAILED", "translation": "失敗" }, + { + "id": "Failed, header could not convert to csv format", + "translation": "Failed, header could not convert to csv format" + }, + { + "id": "Failed, rows could not convert to csv format", + "translation": "Failed, rows could not convert to csv format" + }, { "id": "Invalid grant type: ", "translation": "Invalid grant type: " diff --git a/resources/i18n_resources.go b/resources/i18n_resources.go index 7c3397f2..881bc1f9 100644 --- a/resources/i18n_resources.go +++ b/resources/i18n_resources.go @@ -1,20 +1,20 @@ -// Code generated by go-bindata. (@generated) DO NOT EDIT. - -// Package resources generated by go-bindata. +// Code generated by go-bindata. DO NOT EDIT. // sources: -// i18n/resources/all.de_DE.json -// i18n/resources/all.en_US.json -// i18n/resources/all.es_ES.json -// i18n/resources/all.fr_FR.json -// i18n/resources/all.it_IT.json -// i18n/resources/all.ja_JP.json -// i18n/resources/all.ko_KR.json -// i18n/resources/all.pt_BR.json -// i18n/resources/all.zh_Hans.json -// i18n/resources/all.zh_Hant.json +// i18n/resources/all.de_DE.json (2.787kB) +// i18n/resources/all.en_US.json (2.588kB) +// i18n/resources/all.es_ES.json (2.683kB) +// i18n/resources/all.fr_FR.json (2.627kB) +// i18n/resources/all.it_IT.json (2.684kB) +// i18n/resources/all.ja_JP.json (2.849kB) +// i18n/resources/all.ko_KR.json (2.764kB) +// i18n/resources/all.pt_BR.json (2.634kB) +// i18n/resources/all.zh_Hans.json (2.591kB) +// i18n/resources/all.zh_Hant.json (2.572kB) + package resources import ( + "crypto/sha256" "fmt" "io/ioutil" "os" @@ -24,8 +24,9 @@ import ( ) type asset struct { - bytes []byte - info os.FileInfo + bytes []byte + info os.FileInfo + digest [sha256.Size]byte } type bindataFileInfo struct { @@ -35,32 +36,21 @@ type bindataFileInfo struct { modTime time.Time } -// Name return file name func (fi bindataFileInfo) Name() string { return fi.name } - -// Size return file size func (fi bindataFileInfo) Size() int64 { return fi.size } - -// Mode return file mode func (fi bindataFileInfo) Mode() os.FileMode { return fi.mode } - -// ModTime return file modify time func (fi bindataFileInfo) ModTime() time.Time { return fi.modTime } - -// IsDir return file whether a directory func (fi bindataFileInfo) IsDir() bool { - return fi.mode&os.ModeDir != 0 + return false } - -// Sys return file is sys mode func (fi bindataFileInfo) Sys() interface{} { return nil } @@ -98,6 +88,14 @@ var _i18nResourcesAllDe_deJson = []byte(`[ "id": "FAILED", "translation": "FEHLGESCHLAGEN" }, + { + "id": "Failed, header could not convert to csv format", + "translation": "Failed, header could not convert to csv format" + }, + { + "id": "Failed, rows could not convert to csv format", + "translation": "Failed, rows could not convert to csv format" + }, { "id": "Invalid grant type: ", "translation": "Invalid grant type: " @@ -164,7 +162,7 @@ func i18nResourcesAllDe_deJson() (*asset, error) { } info := bindataFileInfo{name: "i18n/resources/all.de_DE.json", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} - a := &asset{bytes: bytes, info: info} + a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xda, 0xf1, 0x1f, 0x67, 0x68, 0x69, 0xc7, 0xf7, 0xc3, 0xa4, 0xe1, 0xc1, 0xb4, 0x7e, 0x4f, 0x90, 0xba, 0x9c, 0x2d, 0xf5, 0x86, 0x94, 0x1f, 0xec, 0xf2, 0xf3, 0x50, 0x6d, 0xa, 0x5e, 0xba, 0xf8}} return a, nil } @@ -201,6 +199,14 @@ var _i18nResourcesAllEn_usJson = []byte(`[ "id": "FAILED", "translation": "FAILED" }, + { + "id": "Failed, header could not convert to csv format", + "translation": "Failed, header could not convert to csv format" + }, + { + "id": "Failed, rows could not convert to csv format", + "translation": "Failed, rows could not convert to csv format" + }, { "id": "Invalid grant type: ", "translation": "Invalid grant type: " @@ -267,7 +273,7 @@ func i18nResourcesAllEn_usJson() (*asset, error) { } info := bindataFileInfo{name: "i18n/resources/all.en_US.json", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} - a := &asset{bytes: bytes, info: info} + a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xe9, 0x57, 0x32, 0xa, 0x51, 0xba, 0xa9, 0xe, 0x7c, 0x73, 0x3e, 0x7b, 0x98, 0xb6, 0x61, 0xab, 0x71, 0x9, 0x48, 0xcc, 0x5, 0x34, 0x6f, 0x9e, 0x6d, 0x3f, 0x55, 0x32, 0x18, 0x3c, 0xcb, 0x4b}} return a, nil } @@ -303,6 +309,14 @@ var _i18nResourcesAllEs_esJson = []byte(`[ { "id": "FAILED", "translation": "ERROR" }, + { + "id": "Failed, header could not convert to csv format", + "translation": "Failed, header could not convert to csv format" + }, + { + "id": "Failed, rows could not convert to csv format", + "translation": "Failed, rows could not convert to csv format" + }, { "id": "Invalid grant type: ", "translation": "Invalid grant type: " @@ -369,7 +383,7 @@ func i18nResourcesAllEs_esJson() (*asset, error) { } info := bindataFileInfo{name: "i18n/resources/all.es_ES.json", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} - a := &asset{bytes: bytes, info: info} + a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xa1, 0xea, 0xc8, 0x71, 0xda, 0xa, 0x98, 0xe1, 0x1a, 0x54, 0xa8, 0x8, 0xf0, 0xab, 0xaa, 0x2, 0x69, 0xfd, 0x66, 0x95, 0x6, 0xf8, 0x9, 0xf1, 0xf4, 0x21, 0xe4, 0x5, 0xf8, 0xc, 0x2b, 0x2e}} return a, nil } @@ -406,6 +420,14 @@ var _i18nResourcesAllFr_frJson = []byte(`[ "id": "FAILED", "translation": "ECHEC" }, + { + "id": "Failed, header could not convert to csv format", + "translation": "Failed, header could not convert to csv format" + }, + { + "id": "Failed, rows could not convert to csv format", + "translation": "Failed, rows could not convert to csv format" + }, { "id": "Invalid grant type: ", "translation": "Invalid grant type: " @@ -472,7 +494,7 @@ func i18nResourcesAllFr_frJson() (*asset, error) { } info := bindataFileInfo{name: "i18n/resources/all.fr_FR.json", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} - a := &asset{bytes: bytes, info: info} + a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xa6, 0x25, 0x4a, 0x4f, 0xcd, 0x23, 0x22, 0xee, 0xb8, 0x5, 0xdf, 0xfc, 0xd1, 0x91, 0x1d, 0xc1, 0x32, 0xe1, 0x81, 0x9a, 0x59, 0x1e, 0x3d, 0xc0, 0xf9, 0xe8, 0x37, 0x97, 0xcb, 0x9f, 0xed, 0x2d}} return a, nil } @@ -509,6 +531,14 @@ var _i18nResourcesAllIt_itJson = []byte(`[ "id": "FAILED", "translation": "NON RIUSCITO" }, + { + "id": "Failed, header could not convert to csv format", + "translation": "Failed, header could not convert to csv format" + }, + { + "id": "Failed, rows could not convert to csv format", + "translation": "Failed, rows could not convert to csv format" + }, { "id": "Invalid grant type: ", "translation": "Invalid grant type: " @@ -575,7 +605,7 @@ func i18nResourcesAllIt_itJson() (*asset, error) { } info := bindataFileInfo{name: "i18n/resources/all.it_IT.json", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} - a := &asset{bytes: bytes, info: info} + a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x88, 0xfd, 0x20, 0xd5, 0x84, 0x7b, 0x16, 0xce, 0x73, 0x4b, 0x14, 0x14, 0x4e, 0x2b, 0x80, 0x71, 0x14, 0xd0, 0x1d, 0xab, 0x10, 0x34, 0xc8, 0x74, 0xa, 0xf2, 0xe, 0x59, 0xf3, 0xdb, 0x9, 0x2e}} return a, nil } @@ -612,6 +642,14 @@ var _i18nResourcesAllJa_jpJson = []byte(`[ "id": "FAILED", "translation": "失敗" }, + { + "id": "Failed, header could not convert to csv format", + "translation": "Failed, header could not convert to csv format" + }, + { + "id": "Failed, rows could not convert to csv format", + "translation": "Failed, rows could not convert to csv format" + }, { "id": "Invalid grant type: ", "translation": "Invalid grant type: " @@ -678,7 +716,7 @@ func i18nResourcesAllJa_jpJson() (*asset, error) { } info := bindataFileInfo{name: "i18n/resources/all.ja_JP.json", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} - a := &asset{bytes: bytes, info: info} + a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xca, 0x81, 0x11, 0x3f, 0xc4, 0xeb, 0x49, 0x74, 0x94, 0xcd, 0xf2, 0x44, 0x20, 0x46, 0xfa, 0x5a, 0x86, 0x7d, 0xbd, 0xff, 0x6e, 0x6b, 0x0, 0x4f, 0x7a, 0xf3, 0xd0, 0x2d, 0xcc, 0xd6, 0xe6, 0xac}} return a, nil } @@ -715,6 +753,14 @@ var _i18nResourcesAllKo_krJson = []byte(`[ "id": "FAILED", "translation": "실패" }, + { + "id": "Failed, header could not convert to csv format", + "translation": "Failed, header could not convert to csv format" + }, + { + "id": "Failed, rows could not convert to csv format", + "translation": "Failed, rows could not convert to csv format" + }, { "id": "Invalid grant type: ", "translation": "Invalid grant type: " @@ -781,7 +827,7 @@ func i18nResourcesAllKo_krJson() (*asset, error) { } info := bindataFileInfo{name: "i18n/resources/all.ko_KR.json", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} - a := &asset{bytes: bytes, info: info} + a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xc0, 0xe0, 0x9c, 0xd2, 0x39, 0xfc, 0xe1, 0xba, 0x2, 0x57, 0xde, 0x91, 0x9, 0x72, 0x9, 0xc8, 0x60, 0x10, 0x3c, 0x8b, 0xdf, 0x9f, 0x71, 0xe9, 0xda, 0x70, 0xe6, 0x4, 0xc7, 0xc, 0x8, 0xbf}} return a, nil } @@ -818,6 +864,14 @@ var _i18nResourcesAllPt_brJson = []byte(`[ "id": "FAILED", "translation": "COM FALHA" }, + { + "id": "Failed, header could not convert to csv format", + "translation": "Failed, header could not convert to csv format" + }, + { + "id": "Failed, rows could not convert to csv format", + "translation": "Failed, rows could not convert to csv format" + }, { "id": "Invalid grant type: ", "translation": "Invalid grant type: " @@ -884,7 +938,7 @@ func i18nResourcesAllPt_brJson() (*asset, error) { } info := bindataFileInfo{name: "i18n/resources/all.pt_BR.json", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} - a := &asset{bytes: bytes, info: info} + a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xf8, 0x9b, 0x43, 0x5b, 0x29, 0x81, 0x4d, 0x76, 0x96, 0xce, 0x2, 0xda, 0xe8, 0x66, 0xc5, 0xb5, 0xf6, 0x54, 0xf1, 0x9b, 0xca, 0xd6, 0x28, 0x81, 0x45, 0x72, 0x93, 0x37, 0x78, 0x99, 0x59, 0x57}} return a, nil } @@ -921,6 +975,14 @@ var _i18nResourcesAllZh_hansJson = []byte(`[ "id": "FAILED", "translation": "失败" }, + { + "id": "Failed, header could not convert to csv format", + "translation": "Failed, header could not convert to csv format" + }, + { + "id": "Failed, rows could not convert to csv format", + "translation": "Failed, rows could not convert to csv format" + }, { "id": "Invalid grant type: ", "translation": "Invalid grant type: " @@ -987,7 +1049,7 @@ func i18nResourcesAllZh_hansJson() (*asset, error) { } info := bindataFileInfo{name: "i18n/resources/all.zh_Hans.json", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} - a := &asset{bytes: bytes, info: info} + a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x37, 0x4b, 0x89, 0x23, 0x86, 0x1, 0x83, 0xa8, 0xc8, 0x83, 0xc7, 0x55, 0x80, 0xb0, 0xfb, 0x41, 0x2f, 0x48, 0xc1, 0x19, 0x88, 0x66, 0x3b, 0xd0, 0x6f, 0x84, 0x91, 0x8c, 0x70, 0xb, 0x12, 0x87}} return a, nil } @@ -1024,6 +1086,14 @@ var _i18nResourcesAllZh_hantJson = []byte(`[ "id": "FAILED", "translation": "失敗" }, + { + "id": "Failed, header could not convert to csv format", + "translation": "Failed, header could not convert to csv format" + }, + { + "id": "Failed, rows could not convert to csv format", + "translation": "Failed, rows could not convert to csv format" + }, { "id": "Invalid grant type: ", "translation": "Invalid grant type: " @@ -1090,7 +1160,7 @@ func i18nResourcesAllZh_hantJson() (*asset, error) { } info := bindataFileInfo{name: "i18n/resources/all.zh_Hant.json", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} - a := &asset{bytes: bytes, info: info} + a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x62, 0xa8, 0x1, 0xf0, 0x6a, 0xd5, 0x31, 0xaf, 0x2b, 0x40, 0xf0, 0xc0, 0x39, 0x8, 0xda, 0x1d, 0x66, 0xd0, 0x11, 0xcc, 0xaa, 0x7, 0xbd, 0x45, 0x3f, 0x9b, 0x8d, 0xc5, 0x50, 0x5f, 0xf0, 0xfa}} return a, nil } @@ -1109,6 +1179,12 @@ func Asset(name string) ([]byte, error) { return nil, fmt.Errorf("Asset %s not found", name) } +// AssetString returns the asset contents as a string (instead of a []byte). +func AssetString(name string) (string, error) { + data, err := Asset(name) + return string(data), err +} + // MustAsset is like Asset but panics when Asset would return an error. // It simplifies safe initialization of global variables. func MustAsset(name string) []byte { @@ -1120,6 +1196,12 @@ func MustAsset(name string) []byte { return a } +// MustAssetString is like AssetString but panics when Asset would return an +// error. It simplifies safe initialization of global variables. +func MustAssetString(name string) string { + return string(MustAsset(name)) +} + // AssetInfo loads and returns the asset info for the given name. // It returns an error if the asset could not be found or // could not be loaded. @@ -1135,6 +1217,33 @@ func AssetInfo(name string) (os.FileInfo, error) { return nil, fmt.Errorf("AssetInfo %s not found", name) } +// AssetDigest returns the digest of the file with the given name. It returns an +// error if the asset could not be found or the digest could not be loaded. +func AssetDigest(name string) ([sha256.Size]byte, error) { + canonicalName := strings.Replace(name, "\\", "/", -1) + if f, ok := _bindata[canonicalName]; ok { + a, err := f() + if err != nil { + return [sha256.Size]byte{}, fmt.Errorf("AssetDigest %s can't read by error: %v", name, err) + } + return a.digest, nil + } + return [sha256.Size]byte{}, fmt.Errorf("AssetDigest %s not found", name) +} + +// Digests returns a map of all known files and their checksums. +func Digests() (map[string][sha256.Size]byte, error) { + mp := make(map[string][sha256.Size]byte, len(_bindata)) + for name := range _bindata { + a, err := _bindata[name]() + if err != nil { + return nil, err + } + mp[name] = a.digest + } + return mp, nil +} + // AssetNames returns the names of the assets. func AssetNames() []string { names := make([]string, 0, len(_bindata)) @@ -1158,6 +1267,9 @@ var _bindata = map[string]func() (*asset, error){ "i18n/resources/all.zh_Hant.json": i18nResourcesAllZh_hantJson, } +// AssetDebug is true if the assets were built with the debug flag enabled. +const AssetDebug = false + // AssetDir returns the file names below a certain // directory embedded in the file by go-bindata. // For example if you run go-bindata on data/... and data contains the @@ -1169,9 +1281,9 @@ var _bindata = map[string]func() (*asset, error){ // a.png // b.png // -// then AssetDir("data") would return []string{"foo.txt", "img"} -// AssetDir("data/img") would return []string{"a.png", "b.png"} -// AssetDir("foo.txt") and AssetDir("nonexistent") would return an error +// then AssetDir("data") would return []string{"foo.txt", "img"}, +// AssetDir("data/img") would return []string{"a.png", "b.png"}, +// AssetDir("foo.txt") and AssetDir("notexist") would return an error, and // AssetDir("") will return []string{"data"}. func AssetDir(name string) ([]string, error) { node := _bintree @@ -1201,23 +1313,23 @@ type bintree struct { } var _bintree = &bintree{nil, map[string]*bintree{ - "i18n": &bintree{nil, map[string]*bintree{ - "resources": &bintree{nil, map[string]*bintree{ - "all.de_DE.json": &bintree{i18nResourcesAllDe_deJson, map[string]*bintree{}}, - "all.en_US.json": &bintree{i18nResourcesAllEn_usJson, map[string]*bintree{}}, - "all.es_ES.json": &bintree{i18nResourcesAllEs_esJson, map[string]*bintree{}}, - "all.fr_FR.json": &bintree{i18nResourcesAllFr_frJson, map[string]*bintree{}}, - "all.it_IT.json": &bintree{i18nResourcesAllIt_itJson, map[string]*bintree{}}, - "all.ja_JP.json": &bintree{i18nResourcesAllJa_jpJson, map[string]*bintree{}}, - "all.ko_KR.json": &bintree{i18nResourcesAllKo_krJson, map[string]*bintree{}}, - "all.pt_BR.json": &bintree{i18nResourcesAllPt_brJson, map[string]*bintree{}}, - "all.zh_Hans.json": &bintree{i18nResourcesAllZh_hansJson, map[string]*bintree{}}, - "all.zh_Hant.json": &bintree{i18nResourcesAllZh_hantJson, map[string]*bintree{}}, + "i18n": {nil, map[string]*bintree{ + "resources": {nil, map[string]*bintree{ + "all.de_DE.json": {i18nResourcesAllDe_deJson, map[string]*bintree{}}, + "all.en_US.json": {i18nResourcesAllEn_usJson, map[string]*bintree{}}, + "all.es_ES.json": {i18nResourcesAllEs_esJson, map[string]*bintree{}}, + "all.fr_FR.json": {i18nResourcesAllFr_frJson, map[string]*bintree{}}, + "all.it_IT.json": {i18nResourcesAllIt_itJson, map[string]*bintree{}}, + "all.ja_JP.json": {i18nResourcesAllJa_jpJson, map[string]*bintree{}}, + "all.ko_KR.json": {i18nResourcesAllKo_krJson, map[string]*bintree{}}, + "all.pt_BR.json": {i18nResourcesAllPt_brJson, map[string]*bintree{}}, + "all.zh_Hans.json": {i18nResourcesAllZh_hansJson, map[string]*bintree{}}, + "all.zh_Hant.json": {i18nResourcesAllZh_hantJson, map[string]*bintree{}}, }}, }}, }} -// RestoreAsset restores an asset under the given directory +// RestoreAsset restores an asset under the given directory. func RestoreAsset(dir, name string) error { data, err := Asset(name) if err != nil { @@ -1235,14 +1347,10 @@ func RestoreAsset(dir, name string) error { if err != nil { return err } - err = os.Chtimes(_filePath(dir, name), info.ModTime(), info.ModTime()) - if err != nil { - return err - } - return nil + return os.Chtimes(_filePath(dir, name), info.ModTime(), info.ModTime()) } -// RestoreAssets restores an asset under the given directory recursively +// RestoreAssets restores an asset under the given directory recursively. func RestoreAssets(dir, name string) error { children, err := AssetDir(name) // File