git-lfs/git/ls_files.go
Chris Darroch 04abbd8436 make additional message strings translatable
Following on from the changes in PR #4781, we can make
additional message strings translatable using the
tr.Tr.Get() method.

Because this method performs printf(3)-style format string
parsing and interpolation, we can simplify some of the
surrounding calls, e.g., from fmt.Errorf() to errors.New(),
and from fmt.Fprintf() to fmt.Fprintln().  This ensures
that if either the translated text or any interpolated
arguments happen to contain character sequences that would
be interpreted as Go format specifiers (e.g., "%s" or "%d"),
these will not result in warnings such as "%!s(MISSING)"
in the output text.

Note also that we try to remove newlines from the message
strings were possible and change the surrounding calls to
append them instead, e.g., with fmt.Fprintln().
2022-01-29 22:36:19 -08:00

94 lines
2.0 KiB
Go

package git
import (
"bufio"
"io/ioutil"
"path"
"strings"
"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"
)
type lsFileInfo struct {
BaseName string
FullPath string
}
type LsFiles struct {
Files map[string]*lsFileInfo
FilesByName map[string][]*lsFileInfo
}
func NewLsFiles(workingDir string, standardExclude bool, untracked bool) (*LsFiles, error) {
args := []string{
"ls-files",
"-z", // Use a NUL separator. This also disables the escaping of special characters.
"--cached",
}
if standardExclude {
args = append(args, "--exclude-standard")
}
if untracked {
args = append(args, "--others")
}
cmd := gitNoLFS(args...)
cmd.Dir = workingDir
tracerx.Printf("NewLsFiles: running in %s git %s",
workingDir, strings.Join(args, " "))
// Capture stdout and stderr
stdout, err := cmd.StdoutPipe()
if err != nil {
return nil, err
}
stderr, err := cmd.StderrPipe()
if err != nil {
return nil, err
}
scanner := bufio.NewScanner(stdout)
scanner.Split(tools.SplitOnNul)
if err := cmd.Start(); err != nil {
return nil, err
}
rv := &LsFiles{
Files: make(map[string]*lsFileInfo),
FilesByName: make(map[string][]*lsFileInfo),
}
// Setup a goroutine to drain stderr as large amounts of error output may cause
// the subprocess to block.
errorMessages := make(chan []byte)
go func() {
msg, _ := ioutil.ReadAll(stderr)
errorMessages <- msg
}()
// Read all files
for scanner.Scan() {
base := path.Base(scanner.Text())
finfo := &lsFileInfo{
BaseName: base,
FullPath: scanner.Text(),
}
rv.Files[scanner.Text()] = finfo
rv.FilesByName[base] = append(rv.FilesByName[base], finfo)
}
// Check the output of the subprocess, output stderr if the command failed.
msg := <-errorMessages
if err := cmd.Wait(); err != nil {
return nil, errors.New(tr.Tr.Get("Error in `git %s`: %v %s",
strings.Join(args, " "), err, msg))
}
return rv, nil
}