-
Notifications
You must be signed in to change notification settings - Fork 20
/
library.go
106 lines (89 loc) · 2.31 KB
/
library.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
package po
import (
"errors"
"os"
"os/exec"
"path"
"strings"
)
// Library is a collection of PO files providing translations in different languages
type Library struct {
path string
srcLanguage string
}
// NewLibrary creates new library from directory structure in path
func NewLibrary(path, srcLanguage string) *Library {
return &Library{path: path, srcLanguage: srcLanguage}
}
// Path returns the root path of this library
func (l *Library) Path() string {
return l.path
}
// SrcLanguage returns the source language of this library
func (l *Library) SrcLanguage() string {
return l.srcLanguage
}
// Update updates the message IDs in the default language from the given PO,
// and merges those changes into the other PO files
func (l *Library) Update(domain string, pot *PO) error {
// update the PO file for the source language (i.e. our POT)
f, err := os.Create(l.poPath(l.srcLanguage, domain))
if err != nil {
return err
}
defer f.Close()
pot.Write(f)
// merge the ID changes into the PO files for the translation languages
for _, lc := range l.locales(false) {
args := []string{
"-q",
"--previous",
l.poPath(lc, domain),
l.poPath(l.srcLanguage, domain),
"-o",
l.poPath(lc, domain),
"--no-wrap",
"--sort-output",
}
b := &strings.Builder{}
cmd := exec.Command("msgmerge", args...)
cmd.Stderr = b
if err := cmd.Run(); err != nil {
return errors.New(b.String())
}
}
return nil
}
// Load loads the PO for the given language and domain
func (l *Library) Load(language, domain string) (*PO, error) {
f, err := os.Open(l.poPath(language, domain))
if err != nil {
return nil, err
}
defer f.Close()
return ReadPO(f)
}
// Locales returns the names of the locales included in this library
func (l *Library) Locales() []string {
return l.locales(true)
}
func (l *Library) locales(includeSrc bool) []string {
directory, err := os.ReadDir(l.path)
if err != nil {
panic(err)
}
var languages []string
for _, file := range directory {
if file.IsDir() {
lang := file.Name()
if includeSrc || lang != l.srcLanguage {
languages = append(languages, lang)
}
}
}
return languages
}
// returns the path of the PO file for the given language and domain
func (l *Library) poPath(language, domain string) string {
return path.Join(l.Path(), language, domain+".po")
}