Skip to content

Add support for i18n in the cli #676

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 49 commits into from
Jun 1, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
ea0fa07
add po message catalog implementation
hdiniz Apr 24, 2020
818c40d
add po parser for i18n cmd
hdiniz Apr 24, 2020
d1103c2
add po merge function
hdiniz Apr 24, 2020
d9f989e
add command to generate en po file from source
hdiniz Apr 24, 2020
4fe2df2
add command to update local po files with en catalog change
hdiniz Apr 24, 2020
6b6d237
add task to generate po files
hdiniz Apr 24, 2020
fcd0082
add locale option for i18n
hdiniz Apr 24, 2020
602cd54
add dependencies for i18n
hdiniz Apr 24, 2020
46cacf2
add unit test for i18n
hdiniz Apr 24, 2020
a203de5
add godoc to exported fields
hdiniz Apr 24, 2020
0c7be38
add rice box for i18n messages
hdiniz Apr 24, 2020
19dc9ef
add readme for i18n module
hdiniz Apr 24, 2020
484ae8a
update README to add instruction to install go-rice
hdiniz Apr 24, 2020
c9ac6b1
remove warning log in case locale is not found
hdiniz Apr 24, 2020
d3b957c
add command to pull and push translation files from/to transifex
hdiniz May 6, 2020
ceb1e03
remove unused import
hdiniz May 6, 2020
dd4f3fb
dont generate new rice file if there are no translation changes
hdiniz May 13, 2020
fa054dd
add copyright headers
hdiniz May 13, 2020
74a7971
use 'tr' function call as indicator for translations
hdiniz May 13, 2020
5879928
adding documentation to pull,push translations and adding new languages
hdiniz May 13, 2020
7628634
push only the reference translation catalog
hdiniz May 14, 2020
e09185a
add check on PR for updated catalog not commited
hdiniz May 14, 2020
4560261
push message catalog to transifex
hdiniz May 14, 2020
b29dd93
pull translations fro transifex weekly
hdiniz May 14, 2020
94c6afd
get locale identifier from diferent OSes
hdiniz May 14, 2020
4d076f9
get locale identifier from diferent OSes
hdiniz May 14, 2020
ed9b523
match locale algo
hdiniz May 18, 2020
38b78aa
add locale match test
hdiniz May 18, 2020
c977f8c
preserve LF in translation string unchanged
hdiniz May 18, 2020
2d4b288
init config before executing command
hdiniz May 18, 2020
749192d
create arduino cmd dynamically
hdiniz May 18, 2020
968931d
make all command init dynamically
hdiniz May 18, 2020
e4d201d
save all message occurrences in catalog
hdiniz May 18, 2020
cba0cf6
add translatable cli usage template
hdiniz May 18, 2020
56a0642
add messages for cli usage template
hdiniz May 18, 2020
46af5e0
remove standalone i18n message check
hdiniz May 18, 2020
ba1af89
add more i18n tests
hdiniz May 19, 2020
6c8aa1e
fix po parsing correctness and implement tests
hdiniz May 19, 2020
eec5609
fix configuration path search tests
hdiniz May 19, 2020
9007746
update catalog command to find go files
hdiniz May 22, 2020
2d3cf92
update catalog with new path
hdiniz May 22, 2020
4d6e353
fix docsgen command
hdiniz May 25, 2020
2da2907
remove dependency on shell script for windows compat
hdiniz May 25, 2020
450aa60
fix test workflow
hdiniz May 25, 2020
98b8e16
update setup-go to v2
hdiniz May 25, 2020
672fc5e
fail i18n:check task if catalog was not updated
hdiniz May 26, 2020
9ffa200
replace windows separator with forward slash
hdiniz May 26, 2020
0d66bec
use filepath function to translate windows paths
hdiniz May 26, 2020
8e64833
only update en catalog
hdiniz May 26, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions .github/workflows/i18n-nightly-push.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: i18n-nightly-push

on:
schedule:
# run every day at 1AM
- cron: '0 1 * * *'

jobs:
push-to-transifex:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@master

- name: Install Go
uses: actions/setup-go@v2
with:
go-version: '1.14'

- name: Install Taskfile
uses: Arduino/actions/setup-taskfile@master
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}

- name: Run task i18n:push
run: task i18n:push
env:
TRANSIFEX_PROJECT: ${{ secrets.TRANSIFEX_PROJECT }}
TRANSIFEX_RESOURCE: ${{ secrets.TRANSIFEX_RESOURCE }}
TRANSIFEX_API_KEY: ${{ secrets.TRANSIFEX_API_KEY }}
41 changes: 41 additions & 0 deletions .github/workflows/i18n-weekly-pull.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: i18n-weekly-pull

on:
schedule:
# run every monday at 2AM
- cron: '0 2 * * 1'

jobs:
pull-from-transifex:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@master

- name: Install Go
uses: actions/setup-go@v2
with:
go-version: '1.14'

- name: Install Go deps
run: |
go get github.com/GeertJohan/go.rice/rice
- name: Install Taskfile
uses: Arduino/actions/setup-taskfile@master
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}

- name: Run task i18n:pull
run: task i18n:pull
env:
TRANSIFEX_PROJECT: ${{ secrets.TRANSIFEX_PROJECT }}
TRANSIFEX_RESOURCE: ${{ secrets.TRANSIFEX_RESOURCE }}
TRANSIFEX_API_KEY: ${{ secrets.TRANSIFEX_API_KEY }}

- name: Create Pull Request
uses: peter-evans/create-pull-request@v2
with:
commit-message: Updated translation files
title: Updated translation files
branch: i18n/translations-update
3 changes: 2 additions & 1 deletion .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
uses: actions/checkout@master

- name: Install Go
uses: actions/setup-go@v1
uses: actions/setup-go@v2
with:
go-version: '1.14'

Expand All @@ -35,6 +35,7 @@ jobs:
go get github.com/golangci/govet
go get golang.org/x/lint/golint
go get github.com/golang/protobuf/protoc-gen-go
go get github.com/GeertJohan/go.rice/rice
shell: bash

- name: Install Taskfile
Expand Down
32 changes: 32 additions & 0 deletions Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ tasks:
- test -z $(go fmt {{ default .DEFAULT_TARGETS .TARGETS }})
- go vet {{ default .DEFAULT_TARGETS .TARGETS }}
- "'{{.GOLINTBIN}}' {{.GOLINTFLAGS}} {{ default .DEFAULT_TARGETS .TARGETS }}"
- task: i18n:check

check-legacy:
desc: Check fmt and lint for the `legacy` package
Expand All @@ -114,6 +115,36 @@ tasks:
cmds:
- go test -run TestWithClientE2E ./commands/daemon

i18n:update:
desc: Updates i18n files
cmds:
- go run ./i18n/cmd/main.go catalog generate . > ./i18n/data/en.po
- task: i18n:generate

i18n:pull:
desc: Pull i18n files from transifex
cmds:
- go run ./i18n/cmd/main.go transifex pull -l {{.I18N_LANGS}} ./i18n/data
- task: i18n:generate

i18n:push:
desc: Push i18n files to transifex
cmds:
- go run ./i18n/cmd/main.go transifex push ./i18n/data

i18n:check:
desc: Check if the i18n message catalog was updated
cmds:
- task: i18n:update
- git add -N ./i18n/data
- git diff --exit-code ./i18n/data

i18n:generate:
desc: Generate embedded i18n catalog files
cmds:
- git add -N ./i18n/data
- git diff --exit-code ./i18n/data &> /dev/null || (cd ./i18n && rice embed-go)

vars:
# all modules of this project except for "legacy/..." module
DEFAULT_TARGETS:
Expand All @@ -138,3 +169,4 @@ vars:
DOCS_VERSION: dev
DOCS_ALIAS: ""
DOCS_REMOTE: "origin"
I18N_LANGS: "pt_BR"
2 changes: 1 addition & 1 deletion cli/board/board.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func NewCommand() *cobra.Command {
boardCommand.AddCommand(initAttachCommand())
boardCommand.AddCommand(initDetailsCommand())
boardCommand.AddCommand(initListCommand())
boardCommand.AddCommand(listAllCommand)
boardCommand.AddCommand(initListAllCommand())

return boardCommand
}
3 changes: 2 additions & 1 deletion cli/board/details.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ package board
import (
"context"
"fmt"
"os"

"github.com/arduino/arduino-cli/cli/errorcodes"
"github.com/arduino/arduino-cli/cli/feedback"
"github.com/arduino/arduino-cli/cli/instance"
Expand All @@ -26,7 +28,6 @@ import (
"github.com/arduino/arduino-cli/table"
"github.com/fatih/color"
"github.com/spf13/cobra"
"os"
)

var showFullDetails bool
Expand Down
25 changes: 14 additions & 11 deletions cli/board/listall.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,20 @@ import (
"github.com/spf13/cobra"
)

var listAllCommand = &cobra.Command{
Use: "listall [boardname]",
Short: "List all known boards and their corresponding FQBN.",
Long: "" +
"List all boards that have the support platform installed. You can search\n" +
"for a specific board if you specify the board name",
Example: "" +
" " + os.Args[0] + " board listall\n" +
" " + os.Args[0] + " board listall zero",
Args: cobra.ArbitraryArgs,
Run: runListAllCommand,
func initListAllCommand() *cobra.Command {
var listAllCommand = &cobra.Command{
Use: "listall [boardname]",
Short: "List all known boards and their corresponding FQBN.",
Long: "" +
"List all boards that have the support platform installed. You can search\n" +
"for a specific board if you specify the board name",
Example: "" +
" " + os.Args[0] + " board listall\n" +
" " + os.Args[0] + " board listall zero",
Args: cobra.ArbitraryArgs,
Run: runListAllCommand,
}
return listAllCommand
}

// runListAllCommand list all installed boards
Expand Down
70 changes: 15 additions & 55 deletions cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strings"

"github.com/arduino/arduino-cli/cli/board"
Expand All @@ -38,7 +37,7 @@ import (
"github.com/arduino/arduino-cli/cli/sketch"
"github.com/arduino/arduino-cli/cli/upload"
"github.com/arduino/arduino-cli/cli/version"
"github.com/arduino/arduino-cli/configuration"
"github.com/arduino/arduino-cli/i18n"
"github.com/arduino/arduino-cli/inventory"
"github.com/mattn/go-colorable"
"github.com/rifflock/lfshook"
Expand All @@ -48,23 +47,29 @@ import (
)

var (
verbose bool
outputFormat string
configFile string
)

// NewCommand creates a new ArduinoCli command root
func NewCommand() *cobra.Command {
cobra.AddTemplateFunc("tr", i18n.Tr)

// ArduinoCli is the root command
ArduinoCli = &cobra.Command{
arduinoCli := &cobra.Command{
Use: "arduino-cli",
Short: "Arduino CLI.",
Long: "Arduino Command Line Interface (arduino-cli).",
Example: " " + os.Args[0] + " <command> [flags...]",
PersistentPreRun: preRun,
}

verbose bool
outputFormat string
configFile string
)
arduinoCli.SetUsageTemplate(usageTemplate)

// Init the cobra root command
func init() {
createCliCommandTree(ArduinoCli)
createCliCommandTree(arduinoCli)

return arduinoCli
}

// this is here only for testing
Expand Down Expand Up @@ -120,52 +125,7 @@ func parseFormatString(arg string) (feedback.OutputFormat, bool) {
return f, found
}

// This function is here to replicate the old logic looking for a config
// file in the parent tree of the CWD, aka "project config".
// Please
func searchConfigTree(cwd string) string {
// go back up to root and search for the config file
for {
if _, err := os.Stat(filepath.Join(cwd, "arduino-cli.yaml")); err == nil {
// config file found
return cwd
} else if os.IsNotExist(err) {
// no config file found
next := filepath.Dir(cwd)
if next == cwd {
return ""
}
cwd = next
} else {
// some error we can't handle happened
return ""
}
}
}

func preRun(cmd *cobra.Command, args []string) {
//
// Prepare the configuration system
//
configPath := ""

// get cwd, if something is wrong don't do anything and let
// configuration init proceed
if cwd, err := os.Getwd(); err == nil {
configPath = searchConfigTree(cwd)
}

// override the config path if --config-file was passed
if fi, err := os.Stat(configFile); err == nil {
if fi.IsDir() {
configPath = configFile
} else {
configPath = filepath.Dir(configFile)
}
}

// initialize the config system
configuration.Init(configPath)
configFile := viper.ConfigFileUsed()

// initialize inventory
Expand Down
2 changes: 1 addition & 1 deletion cli/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func NewCommand() *cobra.Command {
Example: " " + os.Args[0] + " config init",
}

configCommand.AddCommand(dumpCmd)
configCommand.AddCommand(initDumpCmd())
configCommand.AddCommand(initInitCommand())

return configCommand
Expand Down
17 changes: 10 additions & 7 deletions cli/config/dump.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,16 @@ import (
"gopkg.in/yaml.v2"
)

var dumpCmd = &cobra.Command{
Use: "dump",
Short: "Prints the current configuration",
Long: "Prints the current configuration.",
Example: " " + os.Args[0] + " config dump",
Args: cobra.NoArgs,
Run: runDumpCommand,
func initDumpCmd() *cobra.Command {
var dumpCmd = &cobra.Command{
Use: "dump",
Short: "Prints the current configuration",
Long: "Prints the current configuration.",
Example: " " + os.Args[0] + " config dump",
Args: cobra.NoArgs,
Run: runDumpCommand,
}
return dumpCmd
}

// output from this command requires special formatting, let's create a dedicated
Expand Down
58 changes: 58 additions & 0 deletions cli/usage.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// This file is part of arduino-cli.
//
// Copyright 2020 ARDUINO SA (http://www.arduino.cc/)
//
// This software is released under the GNU General Public License version 3,
// which covers the main part of arduino-cli.
// The terms of this license can be found at:
// https://www.gnu.org/licenses/gpl-3.0.en.html
//
// You can be released from the requirements of the above licenses by purchasing
// a commercial license. Buying such a license is mandatory if you want to
// modify or otherwise use the software for commercial activities involving the
// Arduino software without disclosing the source code of your own applications.
// To purchase a commercial license, send an email to [email protected].

package cli

import (
"github.com/arduino/arduino-cli/i18n"
)

// Declare ids used in usage
var (
tr = i18n.Tr
_ = tr("Usage:")
_ = tr("Aliases:")
_ = tr("Examples:")
_ = tr("Available Commands:")
_ = tr("Flags:")
_ = tr("Global Flags:")
_ = tr("Additional help topics:")
_ = tr("Use %s for more information about a command.")
)

const usageTemplate = `{{tr "Usage:"}}{{if .Runnable}}
{{.UseLine}}{{end}}{{if .HasAvailableSubCommands}}
{{.CommandPath}} [command]{{end}}{{if gt (len .Aliases) 0}}
{{tr "Aliases:"}}
{{.NameAndAliases}}{{end}}{{if .HasExample}}
{{tr "Examples:"}}
{{.Example}}{{end}}{{if .HasAvailableSubCommands}}
{{tr "Available Commands:"}}{{range .Commands}}{{if (or .IsAvailableCommand (eq .Name "help"))}}
{{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{end}}{{if .HasAvailableLocalFlags}}
{{tr "Flags:"}}
{{.LocalFlags.FlagUsages | trimTrailingWhitespaces}}{{end}}{{if .HasAvailableInheritedFlags}}
{{tr "Global Flags:"}}
{{.InheritedFlags.FlagUsages | trimTrailingWhitespaces}}{{end}}{{if .HasHelpSubCommands}}
{{tr "Additional help topics:"}}{{range .Commands}}{{if .IsAdditionalHelpTopicCommand}}
{{rpad .CommandPath .CommandPathPadding}} {{.Short}}{{end}}{{end}}{{end}}{{if .HasAvailableSubCommands}}
{{tr "Use %s for more information about a command." (printf "%s %s" .CommandPath "[command] --help" | printf "%q")}}{{end}}
`
Loading