2830d39ef4
Because the tr.Tr.Get() family of methods insert arguments into printf(3)-style format strings after translating the format string, we can in a few cases drop a surrounding call to fmt.Sprintf() or a similar method, as those now take no arguments and so are redundant. Moreover, this will help us avoid situations where either the translated string or the argument values interpolated by tr.Tr.Get() produce an output string which itself happens to contain character sequences that resemble Go format specifiers (e.g., "%s", "%d", etc.) In such cases passing the string at runtime to a method such as fmt.Fprintf() will result in the output containing a warning such as "%!s(MISSING)", which is not ideal. Note that in one case, in lfs/attribute.go, we can now also simplify the format string to use standard format specifiers instead of double-escaped ones (e.g., "%%q") since we can just allow tr.Tr.Get() to do the interpolation. We also take the opportunity to remove explicit leading or trailing newlines from translation messages wherever it is possible to convert the surrounding call to fmt.Print(), fmt.Fprint(), fmt.Println(), or fmt.Fprintln(). Finally, in the commands/run.go file, we can replace two calls to fmt.Fprintf() with fmt.Println() because they are just printing output to os.Stdout, not os.Stderr, and in the lfs/extension.go file, we can make better use of fmt.Errorf(). Note that at least one of these messages is not yet actually passed as a translation string, but we will address that issue in a subsequent commit.
92 lines
1.9 KiB
Go
92 lines
1.9 KiB
Go
package lfshttp
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/http"
|
|
"regexp"
|
|
|
|
"github.com/git-lfs/git-lfs/v3/config"
|
|
"github.com/git-lfs/git-lfs/v3/errors"
|
|
"github.com/git-lfs/git-lfs/v3/git"
|
|
"github.com/git-lfs/git-lfs/v3/tr"
|
|
)
|
|
|
|
var (
|
|
lfsMediaTypeRE = regexp.MustCompile(`\Aapplication/vnd\.git\-lfs\+json(;|\z)`)
|
|
jsonMediaTypeRE = regexp.MustCompile(`\Aapplication/json(;|\z)`)
|
|
)
|
|
|
|
type Context interface {
|
|
GitConfig() *git.Configuration
|
|
OSEnv() config.Environment
|
|
GitEnv() config.Environment
|
|
}
|
|
|
|
func NewContext(gitConf *git.Configuration, osEnv, gitEnv map[string]string) Context {
|
|
c := &testContext{gitConfig: gitConf}
|
|
if c.gitConfig == nil {
|
|
c.gitConfig = git.NewConfig("", "")
|
|
}
|
|
if osEnv != nil {
|
|
c.osEnv = testEnv(osEnv)
|
|
} else {
|
|
c.osEnv = make(testEnv)
|
|
}
|
|
|
|
if gitEnv != nil {
|
|
c.gitEnv = testEnv(gitEnv)
|
|
} else {
|
|
c.gitEnv = make(testEnv)
|
|
}
|
|
return c
|
|
}
|
|
|
|
type testContext struct {
|
|
gitConfig *git.Configuration
|
|
osEnv config.Environment
|
|
gitEnv config.Environment
|
|
}
|
|
|
|
func (c *testContext) GitConfig() *git.Configuration {
|
|
return c.gitConfig
|
|
}
|
|
|
|
func (c *testContext) OSEnv() config.Environment {
|
|
return c.osEnv
|
|
}
|
|
|
|
func (c *testContext) GitEnv() config.Environment {
|
|
return c.gitEnv
|
|
}
|
|
|
|
func IsDecodeTypeError(err error) bool {
|
|
_, ok := err.(*decodeTypeError)
|
|
return ok
|
|
}
|
|
|
|
type decodeTypeError struct {
|
|
Type string
|
|
}
|
|
|
|
func (e *decodeTypeError) TypeError() {}
|
|
|
|
func (e *decodeTypeError) Error() string {
|
|
return tr.Tr.Get("Expected JSON type, got: %q", e.Type)
|
|
}
|
|
|
|
func DecodeJSON(res *http.Response, obj interface{}) error {
|
|
ctype := res.Header.Get("Content-Type")
|
|
if !(lfsMediaTypeRE.MatchString(ctype) || jsonMediaTypeRE.MatchString(ctype)) {
|
|
return &decodeTypeError{Type: ctype}
|
|
}
|
|
|
|
err := json.NewDecoder(res.Body).Decode(obj)
|
|
res.Body.Close()
|
|
|
|
if err != nil {
|
|
return errors.Wrapf(err, tr.Tr.Get("Unable to parse HTTP response for %s %s", res.Request.Method, res.Request.URL))
|
|
}
|
|
|
|
return nil
|
|
}
|