Skip to content

#2069 fix(cli): improve locale list parsing in init command#2095

Open
Waqasabid99 wants to merge 1 commit into
lingodotdev:mainfrom
Waqasabid99:main
Open

#2069 fix(cli): improve locale list parsing in init command#2095
Waqasabid99 wants to merge 1 commit into
lingodotdev:mainfrom
Waqasabid99:main

Conversation

@Waqasabid99
Copy link
Copy Markdown

@Waqasabid99 Waqasabid99 commented May 26, 2026

Summary

Fixes locale list parsing during lingo init by properly handling comma-separated inputs with spaces and quoted locale values.

Changes

  • Added a shared parseListInput utility for parsing comma/space separated CLI inputs
  • Trim whitespace from parsed values before locale validation
  • Added support for quoted locale inputs such as 'es', 'fr'
  • Improved parsing robustness by supporting both commas and whitespace as separators
  • Improved invalid locale error messaging with clearer formatting examples
  • Reused the parsing utility for both --targets and --paths options

Testing

Business logic tests added:

  • Verified comma-separated locale inputs with spaces (es, fr)
  • Verified quoted locale inputs ('es', 'fr' and "es", "fr")
  • Verified space-separated locale inputs (es fr)
  • Verified parsing filters empty values and trims whitespace correctly
  • Verified shared parsing behavior works for --paths
  • All tests and checks pass locally

Commands executed locally:

pnpm turbo build --force
pnpm turbo test --force
pnpm changeset status --since origin/main

Visuals

image image

Checklist

  • Changeset added
  • Tests cover business logic and edge cases
  • No breaking changes

Closes #2069

Summary by CodeRabbit

Release Notes

  • Bug Fixes

    • Fixed parsing of comma-separated locale inputs during initialization when values include spaces and quotes
  • Improvements

    • Enhanced error messages in the CLI init command to provide clearer formatting guidance for locale, bucket, and path arguments
    • Improved handling of comma- and whitespace-separated input values

Review Change Stack

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 26, 2026

📝 Walkthrough

Walkthrough

The init command's list input parsing is refactored to handle comma- and whitespace-separated values consistently across all entry points (--targets, --paths, and interactive input). A new parseListInput helper normalizes input by trimming whitespace and removing surrounding quotes, fixing the issue where entries like "es, fr" failed validation. Error messaging for invalid values is also enhanced with clearer multi-line guidance.

Changes

CLI input parsing and error handling

Layer / File(s) Summary
Input parsing utility and error messaging
packages/cli/src/cli/cmd/init.ts
parseListInput normalizes comma/whitespace-separated lists by trimming, removing quotes, and filtering empty values. Enhanced error messages for invalid inputs now display multi-line format guidance and a help instruction.
CLI argument refactoring
packages/cli/src/cli/cmd/init.ts
--targets, --paths (non-interactive), and interactive custom path entry all now use parseListInput instead of manual split logic, ensuring consistent input handling across entry points.
Release documentation and metadata
.changeset/wicked-baboons-bake.md, .changeset/config.json
Changeset entry documents the patch release for lingo.dev with fix details; changeset config reformatted for readability.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

  • lingodotdev/lingo.dev#1874: Shares demo translation JSON file reordering for de.json, es.json, and fr.json entries, though core logic changes do not overlap.

Suggested reviewers

  • vrcprl

Poem

🐰 A list input fix hops into view,
Spaces and commas now parsed just true,
No more trailing ghosts in the CLI flow—
es, fr works great, now everyone knows! ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and concisely summarizes the main change: fixing locale list parsing in the init command to handle comma-separated inputs with spaces.
Description check ✅ Passed The description covers all required sections: Summary, Changes, Testing (with specific test cases marked complete), Visuals (terminal screenshots), and Checklist with all items checked, plus the issue reference.
Linked Issues check ✅ Passed The PR fully addresses issue #2069 requirements: adding parseListInput utility to handle comma/space-separated inputs with trimming, supporting quoted values, improving error messages, and applying the fix to both --targets and --paths options.
Out of Scope Changes check ✅ Passed All changes are directly related to fixing locale list parsing: CLI parsing logic updates, changeset documentation, and translation file reordering (likely formatting consistency). No unrelated modifications detected.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint skipped: no ESLint configuration detected in root package.json. To enable, add eslint to devDependencies.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (1)
packages/cli/src/cli/cmd/init.ts (1)

84-85: 💤 Low value

Premature type cast before validation.

The as LocaleCode[] cast occurs before the values are validated by resolveLocaleCode. While this is safe because validation happens immediately afterward (and throwHelpError will terminate if invalid), the cast is technically premature.

♻️ Consider deferring the cast until after validation
 .argParser((value: string) => {
-  const values = parseListInput(value) as LocaleCode[];
+  const values = parseListInput(value);
   values.forEach((value) => {
     try {
       resolveLocaleCode(value);
     } catch (e) {
       throwHelpError("locale", value);
     }
   });
-  return values;
+  return values as LocaleCode[];
 })
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/cli/src/cli/cmd/init.ts` around lines 84 - 85, The premature cast to
LocaleCode[] in the argParser should be removed: have parseListInput(value)
produce a string[] (no "as LocaleCode[]") then validate each entry with
resolveLocaleCode inside the same argParser callback and only cast/return
LocaleCode[] after successful validation; if resolveLocaleCode throws,
propagate/throwHelpError as currently done. Update the argParser callback (the
parseListInput + resolveLocaleCode logic) to defer the LocaleCode[] cast until
after validation completes.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@demo/new-compiler-vite-react-spa/public/translations/de.json`:
- Around line 5-24: The PR contains only nonfunctional reordering of translation
keys (e.g., "02704ec4e52a", "07d84d34dd3a", "0add30e37450", "2d626508fb8f",
etc.) which adds noise; revert the JSON key order to the original ordering (or
regenerate the translations file from the canonical source) so only actual CLI
parsing changes remain in the diff — undo the reordering changes in this
translations file or restore the previous version of the file containing those
keys in their original order.

In `@demo/new-compiler-vite-react-spa/public/translations/es.json`:
- Around line 5-24: Revert the cosmetic reordering of translation keys in the
es.json locale file so the entries (e.g., "02704ec4e52a", "07d84d34dd3a",
"0add30e37450", "2d626508fb8f", etc.) match the original ordering (and match
de.json/other locales), leaving only the actual CLI parsing changes in the PR;
restore the original key sequence for all three locale files to eliminate diff
noise.

In `@demo/new-compiler-vite-react-spa/public/translations/fr.json`:
- Around line 5-24: Translation entries were reordered in multiple locale files
without content changes causing noisy diffs; revert the ordering-only edits in
the three locale files so their keys and values match the base branch exactly
(restore the original ordering for keys such as "02704ec4e52a", "f11fc78c3ac0",
"de6bfb30be49", etc.), leaving only intentional translation or parsing-related
changes; update the commit to remove these generated reorderings (or reset these
files from the base branch) so the PR focuses solely on the CLI parsing fixes.

---

Nitpick comments:
In `@packages/cli/src/cli/cmd/init.ts`:
- Around line 84-85: The premature cast to LocaleCode[] in the argParser should
be removed: have parseListInput(value) produce a string[] (no "as LocaleCode[]")
then validate each entry with resolveLocaleCode inside the same argParser
callback and only cast/return LocaleCode[] after successful validation; if
resolveLocaleCode throws, propagate/throwHelpError as currently done. Update the
argParser callback (the parseListInput + resolveLocaleCode logic) to defer the
LocaleCode[] cast until after validation completes.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 4f8ce68b-b386-4fd7-a719-4639cf612956

📥 Commits

Reviewing files that changed from the base of the PR and between 974f651 and 2cba018.

📒 Files selected for processing (6)
  • .changeset/config.json
  • .changeset/wicked-baboons-bake.md
  • demo/new-compiler-vite-react-spa/public/translations/de.json
  • demo/new-compiler-vite-react-spa/public/translations/es.json
  • demo/new-compiler-vite-react-spa/public/translations/fr.json
  • packages/cli/src/cli/cmd/init.ts

Comment on lines +5 to +24
"02704ec4e52a": "Es extrahiert automatisch Text aus Ihrem JSX und übersetzt ihn in andere Sprachen.",
"07d84d34dd3a": "Fügen Sie einfach die Direktive \"use i18n\" am Anfang Ihrer Komponentendateien hinzu, und der Compiler erledigt den Rest!",
"0add30e37450": "Der Compiler analysiert Ihre React-Komponenten zur Build-Zeit und extrahiert automatisch alle übersetzbaren Strings. Anschließend generiert er Übersetzungen mit Ihrem konfigurierten Übersetzungsanbieter.",
"2d626508fb8f": "Hash-basiertes Übersetzungssystem für stabile Kennungen",
"44a3311c3a4a": "Wie es funktioniert",
"52ed9ee761d8": "Hallo Welt",
"556f5956dca7": "Willkommen zur Lingo.dev Compiler Demo",
"5c15bd35e916": "Um es zu übersetzen, müssen Sie es in '<'>{translatableText} '<'/> einschließen",
"8492c53cfbaf": "Über Lingo.dev",
"8aa4fe3f0590": "Dies ist eine Demo-Anwendung, die den Lingo.dev-Compiler für automatische Übersetzungen in React-Anwendungen präsentiert.",
"af76f667703b": "Hauptfunktionen",
"93b50fe805b7": "Text außerhalb der Komponente wird nicht übersetzt: {externalText}",
"999a96fc5866": "Automatische Extraktion übersetzbarer Texte aus JSX",
"b285bf7876d3": "Build-Zeit-Transformation ohne Laufzeit-Overhead",
"ab0450919701": "Unterstützung für mehrere Bundler (Vite, Webpack, Next.js)",
"2d626508fb8f": "Hash-basiertes Übersetzungssystem für stabile Kennungen",
"aca12d550fe2": "Unterstützung für Server- und Client-Komponenten",
"44a3311c3a4a": "Wie es funktioniert",
"0add30e37450": "Der Compiler analysiert Ihre React-Komponenten zur Build-Zeit und extrahiert automatisch alle übersetzbaren Strings. Anschließend generiert er Übersetzungen mit Ihrem konfigurierten Übersetzungsanbieter.",
"07d84d34dd3a": "Fügen Sie einfach die Direktive \"use i18n\" am Anfang Ihrer Komponentendateien hinzu, und der Compiler erledigt den Rest!",
"af76f667703b": "Hauptfunktionen",
"b285bf7876d3": "Build-Zeit-Transformation ohne Laufzeit-Overhead",
"d756b03ffbf5": "Inhalte, die Text und andere Tags enthalten, werden als eine Einheit übersetzt: {translatableMixedContextFragment}",
"daa4d8839395": "{counter} mal geklickt",
"52ed9ee761d8": "Hallo Welt",
"f11fc78c3ac0": "<b0>Gemischter</b0> Inhalt <i0>Fragment</i0>",
"556f5956dca7": "Willkommen zur Lingo.dev Compiler Demo",
"02704ec4e52a": "Es extrahiert automatisch Text aus Ihrem JSX und übersetzt ihn in andere Sprachen.",
"de6bfb30be49": "Text, der als <code0></code0> eingefügt wird, wird nicht übersetzt: {text}",
"5c15bd35e916": "Um es zu übersetzen, müssen Sie es in '<'>{translatableText} '<'/> einschließen",
"93b50fe805b7": "Text außerhalb der Komponente wird nicht übersetzt: {externalText}",
"d756b03ffbf5": "Inhalte, die Text und andere Tags enthalten, werden als eine Einheit übersetzt: {translatableMixedContextFragment}"
"f11fc78c3ac0": "<b0>Gemischter</b0> Inhalt <i0>Fragment</i0>"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Unnecessary reordering adds diff noise.

The translation entries in this file have been reordered without any content changes. Since JSON object key order is not semantically significant and the PR focuses on CLI parsing improvements, this reordering appears unrelated to the stated objectives and adds unnecessary diff noise.

Consider reverting these changes unless there's a specific reason for the reordering (e.g., alphabetical sorting for maintainability or auto-generation from the updated init command).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@demo/new-compiler-vite-react-spa/public/translations/de.json` around lines 5
- 24, The PR contains only nonfunctional reordering of translation keys (e.g.,
"02704ec4e52a", "07d84d34dd3a", "0add30e37450", "2d626508fb8f", etc.) which adds
noise; revert the JSON key order to the original ordering (or regenerate the
translations file from the canonical source) so only actual CLI parsing changes
remain in the diff — undo the reordering changes in this translations file or
restore the previous version of the file containing those keys in their original
order.

Comment on lines +5 to +24
"02704ec4e52a": "Extrae automáticamente texto de tu JSX y lo traduce a otros idiomas.",
"07d84d34dd3a": "¡Simplemente agrega la directiva \"use i18n\" en la parte superior de tus archivos de componentes, y el compilador se encarga del resto!",
"0add30e37450": "El compilador analiza tus componentes de React en tiempo de compilación y extrae automáticamente todas las cadenas traducibles. Luego genera traducciones utilizando tu proveedor de traducción configurado.",
"2d626508fb8f": "Sistema de traducción basado en hash para identificadores estables",
"44a3311c3a4a": "Cómo funciona",
"52ed9ee761d8": "Hola Mundo",
"556f5956dca7": "Bienvenido a la demo de Lingo.dev compiler",
"5c15bd35e916": "Para traducirlo tienes que envolverlo en el '<'>{translatableText} '<'/>",
"8492c53cfbaf": "Acerca de Lingo.dev",
"8aa4fe3f0590": "Esta es una aplicación de demostración que muestra el compilador Lingo.dev para traducciones automáticas en aplicaciones React.",
"af76f667703b": "Características principales",
"93b50fe805b7": "El texto externo al componente no se traduce: {externalText}",
"999a96fc5866": "Extracción automática de texto traducible desde JSX",
"b285bf7876d3": "Transformación en tiempo de compilación sin sobrecarga en tiempo de ejecución",
"ab0450919701": "Soporte para múltiples empaquetadores (Vite, Webpack, Next.js)",
"2d626508fb8f": "Sistema de traducción basado en hash para identificadores estables",
"aca12d550fe2": "Soporte para componentes de servidor y cliente",
"44a3311c3a4a": "Cómo funciona",
"0add30e37450": "El compilador analiza tus componentes de React en tiempo de compilación y extrae automáticamente todas las cadenas traducibles. Luego genera traducciones utilizando tu proveedor de traducción configurado.",
"07d84d34dd3a": "¡Simplemente agrega la directiva \"use i18n\" en la parte superior de tus archivos de componentes, y el compilador se encarga del resto!",
"af76f667703b": "Características principales",
"b285bf7876d3": "Transformación en tiempo de compilación sin sobrecarga en tiempo de ejecución",
"d756b03ffbf5": "El contenido que tiene texto y otras etiquetas dentro se traducirá como una sola entidad: {translatableMixedContextFragment}",
"daa4d8839395": "Clicado {counter} veces",
"52ed9ee761d8": "Hola Mundo",
"f11fc78c3ac0": "Contenido <b0>mixto</b0> <i0>fragmento</i0>",
"556f5956dca7": "Bienvenido a la demo de Lingo.dev compiler",
"02704ec4e52a": "Extrae automáticamente texto de tu JSX y lo traduce a otros idiomas.",
"de6bfb30be49": "El texto insertado como <code0></code0> no se traduce: {text}",
"5c15bd35e916": "Para traducirlo tienes que envolverlo en el '<'>{translatableText} '<'/>",
"93b50fe805b7": "El texto externo al componente no se traduce: {externalText}",
"d756b03ffbf5": "El contenido que tiene texto y otras etiquetas dentro se traducirá como una sola entidad: {translatableMixedContextFragment}"
"f11fc78c3ac0": "Contenido <b0>mixto</b0> <i0>fragmento</i0>"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Unnecessary reordering adds diff noise.

Similar to de.json, the translation entries have been reordered without content changes. This reordering pattern is consistent across all three locale files but doesn't appear to serve the PR objectives related to CLI parsing improvements.

Consider reverting these cosmetic changes to keep the PR focused and reduce diff noise.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@demo/new-compiler-vite-react-spa/public/translations/es.json` around lines 5
- 24, Revert the cosmetic reordering of translation keys in the es.json locale
file so the entries (e.g., "02704ec4e52a", "07d84d34dd3a", "0add30e37450",
"2d626508fb8f", etc.) match the original ordering (and match de.json/other
locales), leaving only the actual CLI parsing changes in the PR; restore the
original key sequence for all three locale files to eliminate diff noise.

Comment on lines +5 to +24
"02704ec4e52a": "Il extrait automatiquement le texte de votre JSX et le traduit dans d'autres langues.",
"07d84d34dd3a": "Ajoutez simplement la directive \"use i18n\" en haut de vos fichiers de composants, et le compilateur s'occupe du reste !",
"0add30e37450": "Le compilateur analyse vos composants React au moment de la compilation et extrait automatiquement toutes les chaînes traduisibles. Il génère ensuite des traductions en utilisant votre fournisseur de traduction configuré.",
"2d626508fb8f": "Système de traduction basé sur des hachages pour des identifiants stables",
"44a3311c3a4a": "Comment ça fonctionne",
"52ed9ee761d8": "Bonjour le monde",
"556f5956dca7": "Bienvenue dans la démo du compilateur Lingo.dev",
"5c15bd35e916": "Pour le traduire, vous devez l'envelopper dans le '<'>{translatableText} '<'/>",
"8492c53cfbaf": "À propos de Lingo.dev",
"8aa4fe3f0590": "Ceci est une application de démonstration présentant le compilateur Lingo.dev pour les traductions automatiques dans les applications React.",
"af76f667703b": "Fonctionnalités clés",
"93b50fe805b7": "Le texte externe au composant n'est pas traduit : {externalText}",
"999a96fc5866": "Extraction automatique du texte traduisible à partir de JSX",
"b285bf7876d3": "Transformation au moment de la compilation sans surcharge d'exécution",
"ab0450919701": "Prise en charge de plusieurs bundlers (Vite, Webpack, Next.js)",
"2d626508fb8f": "Système de traduction basé sur des hachages pour des identifiants stables",
"aca12d550fe2": "Prise en charge des composants serveur et client",
"44a3311c3a4a": "Comment ça fonctionne",
"0add30e37450": "Le compilateur analyse vos composants React au moment de la compilation et extrait automatiquement toutes les chaînes traduisibles. Il génère ensuite des traductions en utilisant votre fournisseur de traduction configuré.",
"07d84d34dd3a": "Ajoutez simplement la directive \"use i18n\" en haut de vos fichiers de composants, et le compilateur s'occupe du reste !",
"af76f667703b": "Fonctionnalités clés",
"b285bf7876d3": "Transformation au moment de la compilation sans surcharge d'exécution",
"d756b03ffbf5": "Le contenu qui contient du texte et d'autres balises sera traduit comme une seule entité : {translatableMixedContextFragment}",
"daa4d8839395": "Cliqué {counter} fois",
"52ed9ee761d8": "Bonjour le monde",
"f11fc78c3ac0": "<b0>Contenu</b0> mixte <i0>fragment</i0>",
"556f5956dca7": "Bienvenue dans la démo du compilateur Lingo.dev",
"02704ec4e52a": "Il extrait automatiquement le texte de votre JSX et le traduit dans d'autres langues.",
"de6bfb30be49": "Le texte inséré comme un <code0></code0> n'est pas traduit : {text}",
"5c15bd35e916": "Pour le traduire, vous devez l'envelopper dans le '<'>{translatableText} '<'/>",
"93b50fe805b7": "Le texte externe au composant n'est pas traduit : {externalText}",
"d756b03ffbf5": "Le contenu qui contient du texte et d'autres balises sera traduit comme une seule entité : {translatableMixedContextFragment}"
"f11fc78c3ac0": "<b0>Contenu</b0> mixte <i0>fragment</i0>"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Unnecessary reordering adds diff noise.

This is the third translation file with identical reordering of entries without content changes. The consistent pattern across all locale files suggests this may have been generated by running a tool, but it still adds significant diff noise unrelated to the PR's CLI parsing improvements.

Consider reverting the changes to all three translation files (de.json, es.json, fr.json) to keep this PR focused on the core parsing logic fixes.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@demo/new-compiler-vite-react-spa/public/translations/fr.json` around lines 5
- 24, Translation entries were reordered in multiple locale files without
content changes causing noisy diffs; revert the ordering-only edits in the three
locale files so their keys and values match the base branch exactly (restore the
original ordering for keys such as "02704ec4e52a", "f11fc78c3ac0",
"de6bfb30be49", etc.), leaving only intentional translation or parsing-related
changes; update the commit to remove these generated reorderings (or reset these
files from the base branch) so the PR focuses solely on the CLI parsing fixes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

lingo init: entering target locales with spaces after commas causes "Invalid locale" error

1 participant