git-lfs/tr/trgen/trgen.go
brian m. carlson 182ed28852
tr: add a tool to build locales into the binary
Currently, Git LFS has the benefit of being a single, relocatable
binary.  While it is customary to store locales in /usr/share/locales on
Unix systems, this isn't necessarily the case on Windows, and we'd like
to preserve the ability of users to move the binary where they like.

As a result, let's add a program which can be run by go generate that
embeds these translations into the binary.  They are Base64-encoded to
make handling them a little easier and avoiding need to write giant
strings of backslashed escape sequences.  The reader will note that this
is based off the related command to embed the manual pages.
2021-11-10 14:30:29 +00:00

85 lines
2.0 KiB
Go

package main
import (
"encoding/base64"
"flag"
"fmt"
"io"
"io/ioutil"
"os"
"path/filepath"
"regexp"
)
func infof(w io.Writer, format string, a ...interface{}) {
if !*verbose {
return
}
fmt.Fprintf(w, format, a...)
}
func warnf(w io.Writer, format string, a ...interface{}) {
fmt.Fprintf(w, format, a...)
}
func readPoDir() (string, []os.FileInfo) {
rootDirs := []string{
".",
"..",
"../..",
}
var err error
for _, rootDir := range rootDirs {
fs, err := ioutil.ReadDir(filepath.Join(rootDir, "po", "build"))
if err == nil {
return rootDir, fs
}
}
// In this case, we don't care about the fact that the build dir doesn't
// exist since that just means there are no translations built. That's
// fine for us, so just exit successfully.
infof(os.Stderr, "Failed to open po dir: %v\n", err)
os.Exit(0)
return "", nil
}
var (
verbose = flag.Bool("verbose", false, "Show verbose output.")
)
func main() {
flag.Parse()
infof(os.Stderr, "Converting po files into translations...\n")
rootDir, fs := readPoDir()
poDir := filepath.Join(rootDir, "po", "build")
out, err := os.Create(filepath.Join(rootDir, "tr", "tr_gen.go"))
if err != nil {
warnf(os.Stderr, "Failed to create go file: %v\n", err)
os.Exit(2)
}
out.WriteString("package tr\n\nfunc init() {\n")
out.WriteString("\t// THIS FILE IS GENERATED, DO NOT EDIT\n")
out.WriteString("\t// Use 'go generate ./tr/trgen' to update\n")
fileregex := regexp.MustCompile(`([A-Za-z\-_]+).mo`)
count := 0
for _, f := range fs {
if match := fileregex.FindStringSubmatch(f.Name()); match != nil {
infof(os.Stderr, "%v\n", f.Name())
cmd := match[1]
content, err := ioutil.ReadFile(filepath.Join(poDir, f.Name()))
if err != nil {
warnf(os.Stderr, "Failed to open %v: %v\n", f.Name(), err)
os.Exit(2)
}
fmt.Fprintf(out, "\tlocales[\"%s\"] = \"%s\"\n", cmd, base64.StdEncoding.EncodeToString(content))
count++
}
}
out.WriteString("}\n")
infof(os.Stderr, "Successfully processed %d translations.\n", count)
}