diff --git a/cmd/translations.go b/cmd/translations.go index 3d52b12..6c3b593 100644 --- a/cmd/translations.go +++ b/cmd/translations.go @@ -105,8 +105,9 @@ translations.swift: cmd.Flags().StringVarP(&flags.Kind, "type", "t", "", "The type of output to generate, valid options are 'ios' or 'android' (Required)") cmd.Flags().IntVarP(&flags.KeyIndex, "index", "k", 0, "The index of the key row, defaults to 0") cmd.Flags().StringArrayVarP(&configurations, "configuration", "c", make([]string, 0), "A configuration string consisting of space separated row index and output path. Multiple configurations can be added, but one is required") - cmd.Flags().IntVarP(&flags.DefaultValueIndex, "main-index", "m", 0, "Required for ios. The index of the main/default language row, defaults to 0") + cmd.Flags().IntVarP(&flags.DefaultValueIndex, "main-index", "m", 0, "Required for ios or when using fill-in. The index of the main/default language row, defaults to 0") cmd.Flags().StringVarP(&flags.Output, "output", "o", "", "Required for ios. A path for the generated output") + cmd.Flags().BoolVarP(&flags.FillIn, "fill-in", "l", false, "Fill in the value from the main/default language if a value is missing for the current language") cmd.MarkFlagRequired("input") cmd.MarkFlagRequired("kind") cmd.MarkFlagRequired("configuration") diff --git a/docs/generated/lane_translations_generate.md b/docs/generated/lane_translations_generate.md index d1b85f5..91c1958 100644 --- a/docs/generated/lane_translations_generate.md +++ b/docs/generated/lane_translations_generate.md @@ -55,10 +55,11 @@ lane translations generate [flags] ``` -c, --configuration stringArray A configuration string consisting of space separated row index and output path. Multiple configurations can be added, but one is required + -l, --fill-in Fill in the value from the main/default language if a value is missing for the current language -h, --help help for generate -k, --index int The index of the key row, defaults to 0 -i, --input string Path to a CSV file containing a key row and a row for each language (Required) - -m, --main-index int Required for ios. The index of the main/default language row, defaults to 0 + -m, --main-index int Required for ios or when using fill-in. The index of the main/default language row, defaults to 0 -o, --output string Required for ios. A path for the generated output -t, --type string The type of output to generate, valid options are 'ios' or 'android' (Required) ``` diff --git a/internal/translations/flags.go b/internal/translations/flags.go index 1b5c40d..c18d4b1 100644 --- a/internal/translations/flags.go +++ b/internal/translations/flags.go @@ -13,6 +13,7 @@ type Flags struct { KeyIndex int DefaultValueIndex int Output string + FillIn bool } func (f *Flags) validate() error { diff --git a/internal/translations/generator_test.go b/internal/translations/generator_test.go index d0591c7..e360a42 100644 --- a/internal/translations/generator_test.go +++ b/internal/translations/generator_test.go @@ -53,3 +53,56 @@ func TestIos(t *testing.T) { equalFiles(t, "testdata/ios-da.expected", "../../build/da.strings") equalFiles(t, "testdata/ios-swift.expected", "../../build/Translations.swift") } + +func TestAndroidWithFillIn(t *testing.T) { + flags := Flags{ + Input: "testdata/fill-in/input.csv", + Kind: "android", + KeyIndex: 1, + DefaultValueIndex: 2, + FillIn: true, + } + configurations := []string{"2 ../../build/en.xml", "3 ../../build/da.xml"} + + err := Generate(context.Background(), &flags, configurations) + + assert.Nil(t, err) + equalFiles(t, "testdata/fill-in/android-en.expected", "../../build/en.xml") + equalFiles(t, "testdata/fill-in/android-da.expected", "../../build/da.xml") +} + +func TestJsonWithFillIn(t *testing.T) { + flags := Flags{ + Input: "testdata/fill-in/input.csv", + Kind: "json", + KeyIndex: 1, + DefaultValueIndex: 2, + FillIn: true, + } + configurations := []string{"2 ../../build/en.json", "3 ../../build/da.json"} + + err := Generate(context.Background(), &flags, configurations) + + assert.Nil(t, err) + equalFiles(t, "testdata/fill-in/json-en.expected", "../../build/en.json") + equalFiles(t, "testdata/fill-in/json-da.expected", "../../build/da.json") +} + +func TestIosWithFillIn(t *testing.T) { + flags := Flags{ + Input: "testdata/fill-in/input.csv", + Kind: "ios", + KeyIndex: 1, + DefaultValueIndex: 2, + Output: "../../build/Translations.swift", + FillIn: true, + } + configurations := []string{"2 ../../build/en.strings", "3 ../../build/da.strings"} + + err := Generate(context.Background(), &flags, configurations) + + assert.Nil(t, err) + equalFiles(t, "testdata/fill-in/ios-en.expected", "../../build/en.strings") + equalFiles(t, "testdata/fill-in/ios-da.expected", "../../build/da.strings") + equalFiles(t, "testdata/fill-in/ios-swift.expected", "../../build/Translations.swift") +} diff --git a/internal/translations/language_file.go b/internal/translations/language_file.go index 7785856..92f5944 100644 --- a/internal/translations/language_file.go +++ b/internal/translations/language_file.go @@ -10,9 +10,11 @@ import ( ) type languageFile struct { - path string - keyIndex int - valueIndex int + path string + keyIndex int + valueIndex int + useFallback bool + fallbackIndex int } type languageFileWriter interface { @@ -21,7 +23,7 @@ type languageFileWriter interface { } func (f *languageFile) write(writer languageFileWriter, translations *translationData) error { - translation := translations.translation(f.keyIndex, f.valueIndex) + translation := translations.translation(f.keyIndex, f.valueIndex, f.useFallback, f.fallbackIndex) tempPath := f.path + ".tmp" defer os.Remove(tempPath) @@ -65,15 +67,16 @@ func newLanguageFiles(flags *Flags, configurations []string) ([]languageFileWrit arguments[path] = index } - once := true list := make([]languageFileWriter, 0) for path, index := range arguments { var writer languageFileWriter file := &languageFile{ - path: path, - keyIndex: flags.KeyIndex, - valueIndex: index, + path: path, + keyIndex: flags.KeyIndex, + valueIndex: index, + useFallback: flags.FillIn, + fallbackIndex: flags.DefaultValueIndex, } switch flags.Kind { @@ -81,15 +84,6 @@ func newLanguageFiles(flags *Flags, configurations []string) ([]languageFileWrit writer = &androidLanguageFile{file: file} case iosKind: writer = &iosLanguageFile{file: file} - if once { - once = false - supporter := &iosSupportLanguageFile{file: &languageFile{ - path: flags.Output, - keyIndex: flags.KeyIndex, - valueIndex: flags.DefaultValueIndex, - }} - list = append(list, supporter) - } case jsonKind: writer = &jsonLanguageFile{file: file} default: @@ -99,5 +93,16 @@ func newLanguageFiles(flags *Flags, configurations []string) ([]languageFileWrit list = append(list, writer) } + switch flags.Kind { + case iosKind: + supporter := &iosSupportLanguageFile{file: &languageFile{ + path: flags.Output, + keyIndex: flags.KeyIndex, + valueIndex: flags.DefaultValueIndex, + useFallback: false, + }} + list = append(list, supporter) + } + return list, nil } diff --git a/internal/translations/language_file_test.go b/internal/translations/language_file_test.go index 05182c4..8c1a1ff 100644 --- a/internal/translations/language_file_test.go +++ b/internal/translations/language_file_test.go @@ -112,7 +112,7 @@ func TestLanguageFileWriteInputFile(t *testing.T) { } for _, x := range inputWriters { - tr := translations.translation(1, x.index) + tr := translations.translation(1, x.index, false, 0) var b bytes.Buffer err := x.writer.write(tr, &b) diff --git a/internal/translations/testdata/fill-in/android-da.expected b/internal/translations/testdata/fill-in/android-da.expected new file mode 100644 index 0000000..a19768f --- /dev/null +++ b/internal/translations/testdata/fill-in/android-da.expected @@ -0,0 +1,4 @@ + + Noget + Something only in English + diff --git a/internal/translations/testdata/fill-in/android-en.expected b/internal/translations/testdata/fill-in/android-en.expected new file mode 100644 index 0000000..4369c54 --- /dev/null +++ b/internal/translations/testdata/fill-in/android-en.expected @@ -0,0 +1,4 @@ + + Something + Something only in English + diff --git a/internal/translations/testdata/fill-in/input.csv b/internal/translations/testdata/fill-in/input.csv new file mode 100644 index 0000000..d0b2700 --- /dev/null +++ b/internal/translations/testdata/fill-in/input.csv @@ -0,0 +1,3 @@ +KEY,EN,DA +SOMETHING,Something,Noget +SOMETHING_ONLY_IN_EN,"Something only in English", diff --git a/internal/translations/testdata/fill-in/ios-da.expected b/internal/translations/testdata/fill-in/ios-da.expected new file mode 100644 index 0000000..e4861ef --- /dev/null +++ b/internal/translations/testdata/fill-in/ios-da.expected @@ -0,0 +1,2 @@ +"SOMETHING" = "Noget"; +"SOMETHING_ONLY_IN_EN" = "Something only in English"; diff --git a/internal/translations/testdata/fill-in/ios-en.expected b/internal/translations/testdata/fill-in/ios-en.expected new file mode 100644 index 0000000..fccad1d --- /dev/null +++ b/internal/translations/testdata/fill-in/ios-en.expected @@ -0,0 +1,2 @@ +"SOMETHING" = "Something"; +"SOMETHING_ONLY_IN_EN" = "Something only in English"; diff --git a/internal/translations/testdata/fill-in/ios-swift.expected b/internal/translations/testdata/fill-in/ios-swift.expected new file mode 100644 index 0000000..56ade64 --- /dev/null +++ b/internal/translations/testdata/fill-in/ios-swift.expected @@ -0,0 +1,6 @@ +// swiftlint:disable all +import Foundation +struct Translations { + static let SOMETHING = NSLocalizedString("SOMETHING", comment: "") + static let SOMETHING_ONLY_IN_EN = NSLocalizedString("SOMETHING_ONLY_IN_EN", comment: "") +} diff --git a/internal/translations/testdata/fill-in/json-da.expected b/internal/translations/testdata/fill-in/json-da.expected new file mode 100644 index 0000000..8174b23 --- /dev/null +++ b/internal/translations/testdata/fill-in/json-da.expected @@ -0,0 +1,4 @@ +{ + "something": "Noget", + "something_only_in_en": "Something only in English" +} \ No newline at end of file diff --git a/internal/translations/testdata/fill-in/json-en.expected b/internal/translations/testdata/fill-in/json-en.expected new file mode 100644 index 0000000..59972c3 --- /dev/null +++ b/internal/translations/testdata/fill-in/json-en.expected @@ -0,0 +1,4 @@ +{ + "something": "Something", + "something_only_in_en": "Something only in English" +} \ No newline at end of file diff --git a/internal/translations/translations.go b/internal/translations/translations.go index 25dd578..0d89206 100644 --- a/internal/translations/translations.go +++ b/internal/translations/translations.go @@ -30,10 +30,14 @@ func newTranslations(path string) (*translationData, error) { return &translationData{data: records}, nil } -func (t *translationData) translation(keyIndex int, valueIndex int) *translation { +func (t *translationData) translation(keyIndex int, valueIndex int, useFallback bool, fallbackIndex int) *translation { items := map[string]string{} for _, r := range t.data { - items[strings.ToLower(r[keyIndex-1])] = r[valueIndex-1] + s := r[valueIndex-1] + if useFallback && s == "" { + s = r[fallbackIndex-1] + } + items[strings.ToLower(r[keyIndex-1])] = s } return newTranslation(items) } diff --git a/internal/translations/translations_test.go b/internal/translations/translations_test.go index 5f5a2aa..bb7cab0 100644 --- a/internal/translations/translations_test.go +++ b/internal/translations/translations_test.go @@ -27,7 +27,7 @@ func TestTranslationsTranslation(t *testing.T) { if !assert.NoError(t, err) { return } - translation := translations.translation(1, 3) + translation := translations.translation(1, 3, false, 0) assert.NotNil(t, translation) }