Skip to content
This repository was archived by the owner on Jan 11, 2023. It is now read-only.

First round of i18n in acs-engine based on gettext. Subsequent change… #627

Merged
merged 22 commits into from
Jul 31, 2017
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
ecdd9b9
First round of i18n in acs-engine based on gettext. Subsequent change…
JiangtianLi May 13, 2017
78be458
Update acs-engine go source to use translation functions. Generate tr…
JiangtianLi May 18, 2017
261ffdf
Merge branch 'master' of https://github.com/Azure/acs-engine into jia…
JiangtianLi May 18, 2017
1867b0c
Vendor github.com/leonelquinteros/gotext package using glide
JiangtianLi May 18, 2017
638031b
Rebase and update translation for update and deploy command
JiangtianLi May 18, 2017
201c149
Merge branch 'master' of https://github.com/Azure/acs-engine into jia…
JiangtianLi May 18, 2017
f9e7193
Move test translation files so that translations directory is used fo…
JiangtianLi May 18, 2017
150b711
Use go-bindata to add resource strings to acs-engine binary
JiangtianLi May 19, 2017
db742c9
Fix reading bindata and unit test
JiangtianLi May 19, 2017
1a54a26
Merge branch 'master' of https://github.com/Azure/acs-engine into jia…
JiangtianLi May 19, 2017
bcbcac0
Merge branch 'master' of https://github.com/Azure/acs-engine into jia…
JiangtianLi Jun 1, 2017
f16bb48
Update translation files
JiangtianLi Jun 1, 2017
3847870
Merge branch 'master' of https://github.com/Azure/acs-engine into jia…
JiangtianLi Jul 7, 2017
9ea4527
Merge branch 'master' of https://github.com/Azure/acs-engine into jia…
JiangtianLi Jul 20, 2017
67642cb
More fix/refactor after rebase and add README
JiangtianLi Jul 21, 2017
8337029
Merge branch 'master' of https://github.com/Azure/acs-engine into jia…
JiangtianLi Jul 25, 2017
39fbb34
Update resource files
JiangtianLi Jul 25, 2017
7816133
Add LCG files converted from PO files.
JiangtianLi Jul 25, 2017
91ad8cd
Update translation bindata
JiangtianLi Jul 25, 2017
e7dc96a
Merge branch 'master' of https://github.com/Azure/acs-engine into jia…
JiangtianLi Jul 28, 2017
4aa260e
Merge branch 'master' of https://github.com/Azure/acs-engine into jia…
JiangtianLi Jul 31, 2017
68e8ddb
Remove go generated translation bindata
JiangtianLi Jul 31, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
6 changes: 5 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ FROM buildpack-deps:xenial

RUN apt-get update \
&& apt-get -y upgrade \
&& apt-get -y install python-pip make build-essential curl openssl vim jq \
&& apt-get -y install python-pip make build-essential curl openssl vim jq gettext \
&& rm -rf /var/lib/apt/lists/*

ENV GO_VERSION 1.8
Expand Down Expand Up @@ -34,6 +34,10 @@ RUN git clone https://github.com/akesterson/cmdarg.git /tmp/cmdarg \
RUN git clone https://github.com/akesterson/shunit.git /tmp/shunit \
&& cd /tmp/shunit && make install && rm -rf /tmp/shunit

# Go tool for internationalization and localization
RUN go get github.com/JiangtianLi/gettext/... \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should ACS Engine be getting stuff from private repos?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried not to but I spent some time and didn't find a tool. That package is basically used for extract strings out of source file for translation so it will only run every time we update translation strings. I forked https://github.com/gosexy/gettext to address the parsing we need. I can try to merge into upstream.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I submitted a PR to that tool: gosexy/gettext#16

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just echoing others and calling out we can't include this change as is, the repo has to be publically accessible.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like https://github.com/JiangtianLi/gettext is public now (might have been from the beginning), so we're OK to use the fork, as long as we've registered it at https://ossmsft.visualstudio.com/_oss.

&& go install github.com/JiangtianLi/gettext/...

# Used by some CI jobs
ADD ./test/bootstrap/checkout-pr.sh /tmp/checkout-pr.sh

Expand Down
30 changes: 27 additions & 3 deletions cmd/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@ import (
"time"

log "github.com/Sirupsen/logrus"
"github.com/leonelquinteros/gotext"
"github.com/spf13/cobra"

"encoding/json"

"github.com/Azure/acs-engine/pkg/acsengine"
"github.com/Azure/acs-engine/pkg/api"
"github.com/Azure/acs-engine/pkg/armhelpers"
"github.com/Azure/acs-engine/pkg/i18n"
)

const (
Expand All @@ -37,6 +39,7 @@ type deployCmd struct {
// derived
containerService *api.ContainerService
apiVersion string
locale *gotext.Locale

// experimental
client armhelpers.ACSEngineClient
Expand Down Expand Up @@ -78,6 +81,11 @@ func (dc *deployCmd) validate(cmd *cobra.Command, args []string) {
var caKeyBytes []byte
var err error

dc.locale, err = i18n.LoadTranslations()
if err != nil {
log.Fatalf("error loading translation files: %s", err.Error())
}

if dc.apimodelPath == "" {
if len(args) > 0 {
dc.apimodelPath = args[0]
Expand All @@ -94,7 +102,12 @@ func (dc *deployCmd) validate(cmd *cobra.Command, args []string) {
log.Fatalf("specified api model does not exist (%s)", dc.apimodelPath)
}

dc.containerService, dc.apiVersion, err = api.LoadContainerServiceFromFile(dc.apimodelPath)
apiloader := &api.Apiloader{
Translator: &i18n.Translator{
Locale: dc.locale,
},
}
dc.containerService, dc.apiVersion, err = apiloader.LoadContainerServiceFromFile(dc.apimodelPath)
if err != nil {
log.Fatalf("error parsing the api model: %s", err.Error())
}
Expand Down Expand Up @@ -129,7 +142,13 @@ func (dc *deployCmd) validate(cmd *cobra.Command, args []string) {
}

func (dc *deployCmd) run() error {
templateGenerator, err := acsengine.InitializeTemplateGenerator(dc.classicMode)
ctx := acsengine.Context{
Translator: &i18n.Translator{
Locale: dc.locale,
},
}

templateGenerator, err := acsengine.InitializeTemplateGenerator(ctx, dc.classicMode)
if err != nil {
log.Fatalln("failed to initialize template generator: %s", err.Error())
}
Expand All @@ -149,7 +168,12 @@ func (dc *deployCmd) run() error {
log.Fatalf("error pretty printing template parameters: %s \n", err.Error())
}

if err = acsengine.WriteArtifacts(dc.containerService, dc.apiVersion, template, parametersFile, dc.outputDirectory, certsgenerated, dc.parametersOnly); err != nil {
writer := &acsengine.ArtifactWriter{
Translator: &i18n.Translator{
Locale: dc.locale,
},
}
if err = writer.WriteArtifacts(dc.containerService, dc.apiVersion, template, parametersFile, dc.outputDirectory, certsgenerated, dc.parametersOnly); err != nil {
log.Fatalf("error writing artifacts: %s \n", err.Error())
}

Expand Down
33 changes: 29 additions & 4 deletions cmd/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,12 @@ import (
log "github.com/Sirupsen/logrus"
"github.com/spf13/cobra"

"io/ioutil"

"github.com/Azure/acs-engine/pkg/acsengine"
"github.com/Azure/acs-engine/pkg/api"
"io/ioutil"
"github.com/Azure/acs-engine/pkg/i18n"
"github.com/leonelquinteros/gotext"
)

const (
Expand All @@ -30,6 +33,7 @@ type generateCmd struct {
// derived
containerService *api.ContainerService
apiVersion string
locale *gotext.Locale
}

func newGenerateCmd() *cobra.Command {
Expand Down Expand Up @@ -62,6 +66,11 @@ func (gc *generateCmd) validate(cmd *cobra.Command, args []string) {
var caKeyBytes []byte
var err error

gc.locale, err = i18n.LoadTranslations()
if err != nil {
log.Fatalf("error loading translation files: %s", err.Error())
}

if gc.apimodelPath == "" {
if len(args) > 0 {
gc.apimodelPath = args[0]
Expand All @@ -78,7 +87,13 @@ func (gc *generateCmd) validate(cmd *cobra.Command, args []string) {
log.Fatalf("specified api model does not exist (%s)", gc.apimodelPath)
}

gc.containerService, gc.apiVersion, err = api.LoadContainerServiceFromFile(gc.apimodelPath)
apiloader := &api.Apiloader{
Translator: &i18n.Translator{
Locale: gc.locale,
},
}
gc.containerService, gc.apiVersion, err = apiloader.LoadContainerServiceFromFile(gc.apimodelPath)

if err != nil {
log.Fatalf("error parsing the api model: %s", err.Error())
}
Expand Down Expand Up @@ -112,7 +127,12 @@ func (gc *generateCmd) validate(cmd *cobra.Command, args []string) {
func (gc *generateCmd) run() error {
log.Infoln("Generating assets...")

templateGenerator, err := acsengine.InitializeTemplateGenerator(gc.classicMode)
ctx := acsengine.Context{
Translator: &i18n.Translator{
Locale: gc.locale,
},
}
templateGenerator, err := acsengine.InitializeTemplateGenerator(ctx, gc.classicMode)
if err != nil {
log.Fatalln("failed to initialize template generator: %s", err.Error())
}
Expand All @@ -133,7 +153,12 @@ func (gc *generateCmd) run() error {
}
}

if err = acsengine.WriteArtifacts(gc.containerService, gc.apiVersion, template, parameters, gc.outputDirectory, certsGenerated, gc.parametersOnly); err != nil {
writer := &acsengine.ArtifactWriter{
Translator: &i18n.Translator{
Locale: gc.locale,
},
}
if err = writer.WriteArtifacts(gc.containerService, gc.apiVersion, template, parameters, gc.outputDirectory, certsGenerated, gc.parametersOnly); err != nil {
log.Fatalf("error writing artifacts: %s \n", err.Error())
}

Expand Down
25 changes: 23 additions & 2 deletions cmd/upgrade.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ import (

"github.com/Azure/acs-engine/pkg/api"
"github.com/Azure/acs-engine/pkg/armhelpers"
"github.com/Azure/acs-engine/pkg/i18n"
"github.com/Azure/acs-engine/pkg/operations/kubernetesupgrade"
"github.com/leonelquinteros/gotext"

log "github.com/Sirupsen/logrus"
"github.com/spf13/cobra"
Expand All @@ -35,6 +37,7 @@ type upgradeCmd struct {
upgradeContainerService *api.UpgradeContainerService
upgradeAPIVersion string
client armhelpers.ACSEngineClient
locale *gotext.Locale
nameSuffix string
}

Expand Down Expand Up @@ -65,6 +68,11 @@ func (uc *upgradeCmd) validate(cmd *cobra.Command, args []string) {

var err error

uc.locale, err = i18n.LoadTranslations()
if err != nil {
log.Fatalf("error loading translation files: %s", err.Error())
}

if uc.resourceGroupName == "" {
cmd.Usage()
log.Fatal("--resource-group must be specified")
Expand Down Expand Up @@ -92,7 +100,12 @@ func (uc *upgradeCmd) validate(cmd *cobra.Command, args []string) {
log.Fatalf("specified api model does not exist (%s)", apiModelPath)
}

uc.containerService, uc.apiVersion, err = api.LoadContainerServiceFromFile(apiModelPath)
apiloader := &api.Apiloader{
Translator: &i18n.Translator{
Locale: uc.locale,
},
}
uc.containerService, uc.apiVersion, err = apiloader.LoadContainerServiceFromFile(apiModelPath)
if err != nil {
log.Fatalf("error parsing the api model: %s", err.Error())
}
Expand All @@ -101,7 +114,12 @@ func (uc *upgradeCmd) validate(cmd *cobra.Command, args []string) {
log.Fatalf("specified upgrade model file does not exist (%s)", uc.upgradeModelFile)
}

uc.upgradeContainerService, uc.upgradeAPIVersion, err = api.LoadUpgradeContainerServiceFromFile(uc.upgradeModelFile)
upgradeapiloader := &api.UpgradeApiloader{
Translator: &i18n.Translator{
Locale: uc.locale,
},
}
uc.upgradeContainerService, uc.upgradeAPIVersion, err = upgradeapiloader.LoadUpgradeContainerServiceFromFile(uc.upgradeModelFile)
if err != nil {
log.Fatalf("error parsing the upgrade api model: %s", err.Error())
}
Expand Down Expand Up @@ -134,6 +152,9 @@ func (uc *upgradeCmd) run(cmd *cobra.Command, args []string) error {
uc.validate(cmd, args)

upgradeCluster := kubernetesupgrade.UpgradeCluster{
Translator: &i18n.Translator{
Locale: uc.locale,
},
Client: uc.client,
}

Expand Down
8 changes: 8 additions & 0 deletions glide.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions glide.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ import:
- package: github.com/spf13/cobra
version: 4cdb38c072b86bf795d2c81de50784d9fdd6eb77
- package: github.com/spf13/pflag
- package: github.com/leonelquinteros/gotext
version: v1.1.1
version: e57e3eeb33f795204c1ca35f56c44f83227c6e66
- package: gopkg.in/go-playground/validator.v9
version: v9.4.0
Expand Down
21 changes: 12 additions & 9 deletions pkg/acsengine/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"text/template"

"github.com/Azure/acs-engine/pkg/api"
"github.com/Azure/acs-engine/pkg/i18n"
"github.com/ghodss/yaml"
)

Expand Down Expand Up @@ -181,7 +182,7 @@ func (t *TemplateGenerator) verifyFiles() error {
allFiles = append(allFiles, swarmTemplateFiles...)
for _, file := range allFiles {
if _, err := Asset(file); err != nil {
return fmt.Errorf("template file %s does not exist", file)
return t.Translator.Errorf("template file %s does not exist", file)
}
}
return nil
Expand All @@ -190,12 +191,14 @@ func (t *TemplateGenerator) verifyFiles() error {
// TemplateGenerator represents the object that performs the template generation.
type TemplateGenerator struct {
ClassicMode bool
Translator *i18n.Translator
}

// InitializeTemplateGenerator creates a new template generator object
func InitializeTemplateGenerator(classicMode bool) (*TemplateGenerator, error) {
func InitializeTemplateGenerator(ctx Context, classicMode bool) (*TemplateGenerator, error) {
t := &TemplateGenerator{
ClassicMode: classicMode,
Translator: ctx.Translator,
}

if err := t.verifyFiles(); err != nil {
Expand Down Expand Up @@ -223,15 +226,15 @@ func (t *TemplateGenerator) GenerateTemplate(containerService *api.ContainerServ

templ = template.New("acs template").Funcs(t.getTemplateFuncMap(containerService))

files, baseFile, e := prepareTemplateFiles(properties)
files, baseFile, e := t.prepareTemplateFiles(properties)
if e != nil {
return "", "", false, e
}

for _, file := range files {
bytes, e := Asset(file)
if e != nil {
err = fmt.Errorf("Error reading file %s, Error: %s", file, e.Error())
err = t.Translator.Errorf("Error reading file %s, Error: %s", file, e.Error())
return templateRaw, parametersRaw, certsGenerated, err
}
if _, err = templ.New(file).Parse(string(bytes)); err != nil {
Expand Down Expand Up @@ -296,7 +299,7 @@ func GenerateKubeConfig(properties *api.Properties, location string) (string, er
return kubeconfig, nil
}

func prepareTemplateFiles(properties *api.Properties) ([]string, string, error) {
func (t *TemplateGenerator) prepareTemplateFiles(properties *api.Properties) ([]string, string, error) {
var files []string
var baseFile string
if properties.OrchestratorProfile.OrchestratorType == api.DCOS {
Expand All @@ -312,7 +315,7 @@ func prepareTemplateFiles(properties *api.Properties) ([]string, string, error)
files = append(commonTemplateFiles, swarmModeTemplateFiles...)
baseFile = swarmBaseFile
} else {
return nil, "", fmt.Errorf("orchestrator '%s' is unsupported", properties.OrchestratorProfile.OrchestratorType)
return nil, "", t.Translator.Errorf("orchestrator '%s' is unsupported", properties.OrchestratorProfile.OrchestratorType)
}

return files, baseFile, nil
Expand Down Expand Up @@ -1150,18 +1153,18 @@ func getSecurityRules(ports []int) string {
func (t *TemplateGenerator) getSingleLineForTemplate(textFilename string, cs *api.ContainerService, profile interface{}) (string, error) {
b, err := Asset(textFilename)
if err != nil {
return "", fmt.Errorf("yaml file %s does not exist", textFilename)
return "", t.Translator.Errorf("yaml file %s does not exist", textFilename)
}

// use go templates to process the text filename
templ := template.New("customdata template").Funcs(t.getTemplateFuncMap(cs))
if _, err = templ.New(textFilename).Parse(string(b)); err != nil {
return "", fmt.Errorf("error parsing file %s: %v", textFilename, err)
return "", t.Translator.Errorf("error parsing file %s: %v", textFilename, err)
}

var buffer bytes.Buffer
if err = templ.ExecuteTemplate(&buffer, textFilename, profile); err != nil {
return "", fmt.Errorf("error executing template for file %s: %v", textFilename, err)
return "", t.Translator.Errorf("error executing template for file %s: %v", textFilename, err)
}
expandedTemplate := buffer.String()

Expand Down
Loading