lfshttp: make strings translatable

Move several top-level variables into functions so that they can be
translated properly.  Top-level variables can't be translated because
the locale is not set until after startup.
This commit is contained in:
brian m. carlson 2021-12-14 16:06:21 +00:00
parent a97307b631
commit cda9c3ce6c
No known key found for this signature in database
GPG Key ID: 2D0C9BC12F82B3A1
5 changed files with 47 additions and 48 deletions

@ -21,6 +21,7 @@ import (
"github.com/git-lfs/git-lfs/v3/creds"
"github.com/git-lfs/git-lfs/v3/errors"
"github.com/git-lfs/git-lfs/v3/tools"
"github.com/git-lfs/git-lfs/v3/tr"
"github.com/rubyist/tracerx"
"golang.org/x/net/http2"
)
@ -32,12 +33,6 @@ var (
httpRE = regexp.MustCompile(`\Ahttps?://`)
)
var hintFileUrl = strings.TrimSpace(`
hint: The remote resolves to a file:// URL, which can only work with a
hint: standalone transfer agent. See section "Using a Custom Transfer Type
hint: without the API server" in custom-transfers.md for details.
`)
type hostData struct {
host string
mode creds.AccessMode
@ -118,7 +113,9 @@ func (c *Client) URLConfig() *config.URLConfig {
func (c *Client) NewRequest(method string, e Endpoint, suffix string, body interface{}) (*http.Request, error) {
if strings.HasPrefix(e.Url, "file://") {
// Initial `\n` to avoid overprinting `Downloading LFS...`.
fmt.Fprintf(os.Stderr, "\n%s\n", hintFileUrl)
fmt.Fprintf(os.Stderr, "\n%s\n", tr.Tr.Get(`hint: The remote resolves to a file:// URL, which can only work with a
hint: standalone transfer agent. See section "Using a Custom Transfer Type
hint: without the API server" in custom-transfers.md for details.`))
}
sshRes, err := c.sshResolveWithRetries(e, method)
@ -133,7 +130,7 @@ func (c *Client) NewRequest(method string, e Endpoint, suffix string, body inter
if !httpRE.MatchString(prefix) {
urlfragment := strings.SplitN(prefix, "?", 2)[0]
return nil, fmt.Errorf("missing protocol: %q", urlfragment)
return nil, errors.New(tr.Tr.Get("missing protocol: %q", urlfragment))
}
req, err := http.NewRequest(method, joinURL(prefix, suffix), nil)
@ -339,7 +336,7 @@ func (c *Client) DoWithRedirect(cli *http.Client, req *http.Request, remote stri
via = append(via, req)
if len(via) >= 3 {
return nil, res, errors.New("too many redirects")
return nil, res, errors.New(tr.Tr.Get("too many redirects"))
}
redirectedReq, err := newRequestForRetry(req, redirectTo)
@ -359,28 +356,28 @@ func (c *Client) doWithRedirects(cli *http.Client, req *http.Request, remote str
}
if redirectedReq == nil {
return nil, errors.New("failed to redirect request")
return nil, errors.New(tr.Tr.Get("failed to redirect request"))
}
return c.doWithRedirects(cli, redirectedReq, remote, via)
}
func (c *Client) configureProtocols(u *url.URL, tr *http.Transport) error {
func (c *Client) configureProtocols(u *url.URL, transport *http.Transport) error {
version, _ := c.uc.Get("http", u.String(), "version")
switch version {
case "HTTP/1.1":
// This disables HTTP/2, according to the documentation.
tr.TLSNextProto = make(map[string]func(authority string, c *tls.Conn) http.RoundTripper)
transport.TLSNextProto = make(map[string]func(authority string, c *tls.Conn) http.RoundTripper)
case "HTTP/2":
if u.Scheme != "https" {
return fmt.Errorf("HTTP/2 cannot be used except with TLS")
return errors.New(tr.Tr.Get("HTTP/2 cannot be used except with TLS"))
}
http2.ConfigureTransport(tr)
delete(tr.TLSNextProto, "http/1.1")
http2.ConfigureTransport(transport)
delete(transport.TLSNextProto, "http/1.1")
case "":
http2.ConfigureTransport(tr)
http2.ConfigureTransport(transport)
default:
return fmt.Errorf("Unknown HTTP version %q", version)
return errors.New(tr.Tr.Get("Unknown HTTP version %q", version))
}
return nil
}
@ -542,7 +539,7 @@ func newRequestForRetry(req *http.Request, location string) (*http.Request, erro
}
if req.URL.Scheme == "https" && newReq.URL.Scheme == "http" {
return nil, errors.New("lfsapi/client: refusing insecure redirect, https->http")
return nil, errors.New(tr.Tr.Get("lfsapi/client: refusing insecure redirect, https->http"))
}
sameHost := req.URL.Host == newReq.URL.Host

@ -6,6 +6,7 @@ import (
"strings"
"github.com/git-lfs/git-lfs/v3/errors"
"github.com/git-lfs/git-lfs/v3/tr"
)
type httpError interface {
@ -99,31 +100,28 @@ func (e *statusCodeError) HTTPResponse() *http.Response {
return e.response
}
var (
defaultErrors = map[int]string{
400: "Client error: %s",
401: "Authorization error: %s\nCheck that you have proper access to the repository",
403: "Authorization error: %s\nCheck that you have proper access to the repository",
404: "Repository or object not found: %s\nCheck that it exists and that you have proper access to it",
422: "Unprocessable entity: %s",
429: "Rate limit exceeded: %s",
500: "Server error: %s",
501: "Not Implemented: %s",
507: "Insufficient server storage: %s",
509: "Bandwidth limit exceeded: %s",
}
)
func defaultError(res *http.Response) error {
var msgFmt string
defaultErrors := map[int]string{
400: tr.Tr.Get("Client error: %%s"),
401: tr.Tr.Get("Authorization error: %%s\nCheck that you have proper access to the repository"),
403: tr.Tr.Get("Authorization error: %%s\nCheck that you have proper access to the repository"),
404: tr.Tr.Get("Repository or object not found: %%s\nCheck that it exists and that you have proper access to it"),
422: tr.Tr.Get("Unprocessable entity: %%s"),
429: tr.Tr.Get("Rate limit exceeded: %%s"),
500: tr.Tr.Get("Server error: %%s"),
501: tr.Tr.Get("Not Implemented: %%s"),
507: tr.Tr.Get("Insufficient server storage: %%s"),
509: tr.Tr.Get("Bandwidth limit exceeded: %%s"),
}
if f, ok := defaultErrors[res.StatusCode]; ok {
msgFmt = f
} else if res.StatusCode < 500 {
msgFmt = defaultErrors[400] + fmt.Sprintf(" from HTTP %d", res.StatusCode)
msgFmt = fmt.Sprintf("Client error %%s from HTTP %d", res.StatusCode)
} else {
msgFmt = defaultErrors[500] + fmt.Sprintf(" from HTTP %d", res.StatusCode)
msgFmt = fmt.Sprintf("Server error %%s from HTTP %d", res.StatusCode)
}
return errors.Errorf(msgFmt, res.Request.URL)
return errors.Errorf(fmt.Sprintf(msgFmt), res.Request.URL)
}

@ -9,6 +9,7 @@ import (
"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 (
@ -71,7 +72,7 @@ type decodeTypeError struct {
func (e *decodeTypeError) TypeError() {}
func (e *decodeTypeError) Error() string {
return fmt.Sprintf("Expected json type, got: %q", e.Type)
return fmt.Sprintf(tr.Tr.Get("Expected json type, got: %q", e.Type))
}
func DecodeJSON(res *http.Response, obj interface{}) error {
@ -84,7 +85,7 @@ func DecodeJSON(res *http.Response, obj interface{}) error {
res.Body.Close()
if err != nil {
return errors.Wrapf(err, "Unable to parse HTTP response for %s %s", res.Request.Method, res.Request.URL)
return errors.Wrapf(err, tr.Tr.Get("Unable to parse HTTP response for %s %s", res.Request.Method, res.Request.URL))
}
return nil

@ -18,6 +18,7 @@ import (
"github.com/git-lfs/git-lfs/v3/lfsapi"
"github.com/git-lfs/git-lfs/v3/subprocess"
"github.com/git-lfs/git-lfs/v3/tools"
"github.com/git-lfs/git-lfs/v3/tr"
"github.com/rubyist/tracerx"
)
@ -122,17 +123,17 @@ func gitDirAtPath(path string) (string, error) {
cmd.Cmd.Env = env
out, err := cmd.Output()
if err != nil {
return "", errors.Wrap(err, "failed to call git rev-parse --git-dir")
return "", errors.Wrap(err, tr.Tr.Get("failed to call git rev-parse --git-dir"))
}
gitdir, err := tools.TranslateCygwinPath(strings.TrimRight(string(out), "\n"))
if err != nil {
return "", errors.Wrap(err, "unable to translate path")
return "", errors.Wrap(err, tr.Tr.Get("unable to translate path"))
}
gitdir, err = filepath.Abs(gitdir)
if err != nil {
return "", errors.Wrap(err, "unable to canonicalize path")
return "", errors.Wrap(err, tr.Tr.Get("unable to canonicalize path"))
}
err = os.Chdir(curdir)
@ -165,7 +166,7 @@ func newHandler(cfg *config.Configuration, output *os.File, msg *inputMessage) (
return nil, err
}
if url == nil {
return nil, errors.New("no valid file:// URLs found")
return nil, errors.New(tr.Tr.Get("no valid file:// URLs found"))
}
path, err := tools.TranslateCygwinPath(fixUrlPath(url.Path))
@ -206,7 +207,7 @@ func (h *fileHandler) dispatch(msg *inputMessage) bool {
case "terminate":
return false
default:
standaloneFailure(fmt.Sprintf("unknown event %q", msg.Event), nil)
standaloneFailure(tr.Tr.Get("unknown event %q", msg.Event), nil)
}
return true
}
@ -244,7 +245,7 @@ func (h *fileHandler) upload(oid string, size int64, path string) (string, strin
func (h *fileHandler) download(oid string, size int64) (string, string, error) {
if !h.remoteConfig.LFSObjectExists(oid, size) {
tracerx.Printf("missing object in %q (%s)", h.remotePath, oid)
return oid, "", errors.Errorf("remote missing object %s", oid)
return oid, "", errors.Errorf(tr.Tr.Get("remote missing object %s", oid))
}
src, err := h.remoteConfig.Filesystem().ObjectPath(oid)
@ -278,13 +279,13 @@ func ProcessStandaloneData(cfg *config.Configuration, input *os.File, output *os
for scanner.Scan() {
var msg inputMessage
if err := json.NewDecoder(strings.NewReader(scanner.Text())).Decode(&msg); err != nil {
return errors.Wrapf(err, "error decoding json")
return errors.Wrapf(err, tr.Tr.Get("error decoding JSON"))
}
if handler == nil {
var err error
handler, err = newHandler(cfg, output, &msg)
if err != nil {
return errors.Wrapf(err, "error creating handler")
return errors.Wrapf(err, tr.Tr.Get("error creating handler"))
}
}
if !handler.dispatch(&msg) {
@ -295,7 +296,7 @@ func ProcessStandaloneData(cfg *config.Configuration, input *os.File, output *os
os.RemoveAll(handler.tempdir)
}
if err := scanner.Err(); err != nil {
return errors.Wrapf(err, "error reading input")
return errors.Wrapf(err, tr.Tr.Get("error reading input"))
}
return nil
}

@ -9,6 +9,8 @@ import (
"net/http/httputil"
"strings"
"github.com/git-lfs/git-lfs/v3/errors"
"github.com/git-lfs/git-lfs/v3/tr"
"github.com/rubyist/tracerx"
)
@ -23,7 +25,7 @@ func (c *Client) traceRequest(req *http.Request) (*tracedRequest, error) {
body, ok := req.Body.(ReadSeekCloser)
if body != nil && !ok {
return nil, fmt.Errorf("Request body must implement io.ReadCloser and io.Seeker. Got: %T", body)
return nil, errors.New(tr.Tr.Get("Request body must implement io.ReadCloser and io.Seeker. Got: %T", body))
}
if body != nil && ok {