<commit_before># i18n-tasks [![Build Status][badge-travis]][travis] [![Coverage Status][badge-coveralls]][coveralls] [![Code Climate][badge-code-climate]][code-climate] [![Gemnasium][badge-gemnasium]][gemnasium]

i18n-tasks helps you find and manage missing and unused translations.

The default approach to locale data management with gems such as [i18n][i18n-gem] is flawed.
If you use a key that does not exist, this will only blow up at runtime. Keys left over from removed code accumulate
in the resource files and introduce unnecessary overhead on the translators. Translation files can quickly turn to disarray.

i18n-tasks improves this by analysing code statically, without running it. It scans calls such as `I18n.t('some.key')` and provides reports on key usage, missing, and unused keys.
It can also pre-fill missing keys, including from Google Translate, and it can remove unused keys as well.

i18n-tasks can be used with any project using [i18n][i18n-gem] (default in Rails), or similar, even if it isn't ruby.

<img width="539" height="331" src="https://raw.github.com/glebm/i18n-tasks/master/doc/img/i18n-tasks.png">

## Installation

Add to Gemfile:

```ruby
gem 'i18n-tasks', '~> 0.6.2'
```

Copy default [config file](#configuration) (optional):

```console
$ cp $(i18n-tasks gem-path)/templates/config/i18n-tasks.yml config/
```

Copy [rspec test](#rspec-integration) (optional):

```console
$ cp $(i18n-tasks gem-path)/templates/rspec/i18n_spec.rb spec/
```

## Usage

Run `i18n-tasks` to get the list of tasks with short descriptions.

```bash
$ i18n-tasks
Usage: i18n-tasks [command] [options]
    -v, --version      Print the version
    -h, --help         Display this help message.

Available commands:

  missing             show missing translations
  unused              show unused translations
  eq-base             show translations equal to base value
  find                show where the keys are used in the code
  data                show locale data
  translate-missing   translate missing keys with Google Translate
  add-missing         add missing keys to the locales
  normalize           normalize translation data: sort and move to the right files
  remove-unused       remove unused keys
  config              display i18n-tasks configuration
  xlsx-report         save missing and unused translations to an Excel file
  irb                 REPL session within i18n-tasks context
  gem-path            show path to the gem

See `<command> --help` for more information on a specific command.
```

Show tasks accept a format option, and all but `find` accept locales as arguments, e.g:

```bash
$ i18n-tasks data --help
Usage: i18n-tasks data [options]
    -l, --locales      Filter by locale(s), comma-separated list (en,fr) or all (default), or pass arguments without -l
    -f, --format       Output format: terminal-table, yaml, json, keys, inspect. Default: terminal-table.
    -h, --help         Display this help message.
$ i18n-tasks data -fkeys en es fr
```

#### Add missing keys

You can add missing values, generated from the key (for base locale) or copied from the base locale (for other locales).
To add missing values to the base locale only:

```bash
# most task accept locales as first argument. `base` and `all` are special
i18n-tasks add-missing base
# add-missing accepts a placeholder argument, with optional base_value interpolation
i18n-tasks add-missing -p 'PLEASE-TRANSLATE %{base_value}' fr
```

#### Google Translate missing keys

Translate missing values with Google Translate ([more below on the API key](#translation-config)).

```bash
i18n-tasks translate-missing
# accepts from and locales options:
i18n-tasks translate-missing --from base es fr
```

Sort the keys and write them to their respective files with `i18n-tasks normalize`.
This always happens on `i18n-tasks add-missing` and `i18n-tasks translate-missing`.

```bash
i18n-tasks normalize
```

#### Find usages

See where the keys are used with `i18n-tasks find`:

```bash
i18n-tasks find common.help
i18n-tasks find 'auth.*'
i18n-tasks find '{number,currency}.format.*'
```

![i18n-screenshot][screenshot-find]

### Find / remove unused keys

```bash
i18n-tasks unused
i18n-tasks remove-unused
```

#### Features

Relative keys (`t '.title'`) and plural keys (`key.{one,many,other,...}`) are fully supported.
Scope argument is supported, but only when it is the first keyword argument ([improvements welcome](/lib/i18n/tasks/scanners/pattern_with_scope_scanner.rb)):

    ```ruby
    # this is supported
    t :invalid, scope: [:auth, :password], attempts: 5
    # but not this
    t :invalid, attempts: 5, scope: [:auth, :password]
    ```

Unused report will detect certain dynamic key forms and not report them, e.g.:

```ruby<commit_msg>readme: strict mode [ci-skip]<commit_after># i18n-tasks [![Build Status][badge-travis]][travis] [![Coverage Status][badge-coveralls]][coveralls] [![Code Climate][badge-code-climate]][code-climate] [![Gemnasium][badge-gemnasium]][gemnasium]

i18n-tasks helps you find and manage missing and unused translations.

The default approach to locale data management with gems such as [i18n][i18n-gem] is flawed.
If you use a key that does not exist, this will only blow up at runtime. Keys left over from removed code accumulate
in the resource files and introduce unnecessary overhead on the translators. Translation files can quickly turn to disarray.

i18n-tasks improves this by analysing code statically, without running it. It scans calls such as `I18n.t('some.key')` and provides reports on key usage, missing, and unused keys.
It can also pre-fill missing keys, including from Google Translate, and it can remove unused keys as well.

i18n-tasks can be used with any project using [i18n][i18n-gem] (default in Rails), or similar, even if it isn't ruby.

<img width="539" height="331" src="https://raw.github.com/glebm/i18n-tasks/master/doc/img/i18n-tasks.png">

## Installation

Add to Gemfile:

```ruby
gem 'i18n-tasks', '~> 0.6.2'
```

Copy default [config file](#configuration) (optional):

```console
$ cp $(i18n-tasks gem-path)/templates/config/i18n-tasks.yml config/
```

Copy [rspec test](#rspec-integration) (optional):

```console
$ cp $(i18n-tasks gem-path)/templates/rspec/i18n_spec.rb spec/
```

## Usage

Run `i18n-tasks` to get the list of tasks with short descriptions.

```bash
$ i18n-tasks
Usage: i18n-tasks [command] [options]
    -v, --version      Print the version
    -h, --help         Display this help message.

Available commands:

  missing             show missing translations
  unused              show unused translations
  eq-base             show translations equal to base value
  find                show where the keys are used in the code
  data                show locale data
  translate-missing   translate missing keys with Google Translate
  add-missing         add missing keys to the locales
  normalize           normalize translation data: sort and move to the right files
  remove-unused       remove unused keys
  config              display i18n-tasks configuration
  xlsx-report         save missing and unused translations to an Excel file
  irb                 REPL session within i18n-tasks context
  gem-path            show path to the gem

See `<command> --help` for more information on a specific command.
```

Show tasks accept a format option, and all but `find` accept locales as arguments, e.g:

```bash
$ i18n-tasks data --help
Usage: i18n-tasks data [options]
    -l, --locales      Filter by locale(s), comma-separated list (en,fr) or all (default), or pass arguments without -l
    -f, --format       Output format: terminal-table, yaml, json, keys, inspect. Default: terminal-table.
    -h, --help         Display this help message.
$ i18n-tasks data -fkeys en es fr
```

#### Add missing keys

You can add missing values, generated from the key (for base locale) or copied from the base locale (for other locales).
To add missing values to the base locale only:

```bash
# most task accept locales as first argument. `base` and `all` are special
i18n-tasks add-missing base
# add-missing accepts a placeholder argument, with optional base_value interpolation
i18n-tasks add-missing -p 'PLEASE-TRANSLATE %{base_value}' fr
```

#### Google Translate missing keys

Translate missing values with Google Translate ([more below on the API key](#translation-config)).

```bash
i18n-tasks translate-missing
# accepts from and locales options:
i18n-tasks translate-missing --from base es fr
```

Sort the keys and write them to their respective files with `i18n-tasks normalize`.
This always happens on `i18n-tasks add-missing` and `i18n-tasks translate-missing`.

```bash
i18n-tasks normalize
```

#### Find usages

See where the keys are used with `i18n-tasks find`:

```bash
i18n-tasks find common.help
i18n-tasks find 'auth.*'
i18n-tasks find '{number,currency}.format.*'
```

![i18n-screenshot][screenshot-find]

### Find / remove unused keys

```bash
i18n-tasks unused
i18n-tasks remove-unused
```

These tasks will infer dynamic key usage such as `t("category.\#{category.name}")` by default.
Pass `-s` or `--strict` to disable this feature.

#### Features

Relative keys (`t '.title'`) and plural keys (`key.{one,many,other,...}`) are fully supported.
Scope argument is supported, but only when it is the first keyword argument ([improvements welcome](/lib/i18n/tasks/scanners/pattern_with_scope_scanner.rb)):

    ```ruby
    # this is supported
    t :invalid, scope: [:auth, :password], attempts: 5
    # but not this
    t :invalid, attempts: 5, scope: [:auth, :password]
    ```

Unused report will detect certain dynamic key forms and not report them, e.g.:

```ruby
{'fraction_non_alphanumeric': 0.10466193269527632, 'fraction_numerical': 0.018730060718328702, 'mean_word_length': 3.6320305052430886, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 9, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1933241', 'n_tokens_mistral': 3048, 'n_tokens_neox': 2821, 'n_words': 1156}