Skip to content

Commit f434f20

Browse files
akoclaude
andcommitted
fix: JSON number type inference and mxcli new locale duplicates
Fix mendixlabs#9: Numbers like 41850.0 were inferred as Integer because Go's %v drops the .0 suffix. Now checks the raw JSON text for a decimal point. Fix #1: mx create-project generates duplicate locale files in nested subdirectories under themesource/atlas_core/locales/, causing MxBuild to crash with "An item with the same key has already been added". Strip these duplicates after project creation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 2b2e0b8 commit f434f20

File tree

2 files changed

+54
-1
lines changed

2 files changed

+54
-1
lines changed

cmd/mxcli/cmd_new.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,13 @@ Examples:
8888
os.Exit(1)
8989
}
9090

91+
// Clean up duplicate locale files that mx create-project generates.
92+
// MxBuild's AtlasPlugin.LoadTranslations crashes with "An item with the same
93+
// key has already been added" when duplicate translation.json files exist.
94+
if removed := cleanupDuplicateLocaleFiles(absDir); removed > 0 {
95+
fmt.Printf(" Cleaned %d duplicate locale file(s)\n", removed)
96+
}
97+
9198
// Verify .mpr was created — mx create-project names the file after --app-name
9299
mprPath := filepath.Join(absDir, appName+".mpr")
93100
if _, err := os.Stat(mprPath); os.IsNotExist(err) {
@@ -153,6 +160,51 @@ Examples:
153160
},
154161
}
155162

163+
// cleanupDuplicateLocaleFiles removes duplicate locale files that mx create-project
164+
// generates in themesource/atlas_core/. MxBuild crashes when multiple translation.json
165+
// files map to the same locale key (e.g., "en-US").
166+
//
167+
// Studio Pro-created projects have locale files only at:
168+
// themesource/atlas_core/locales/<locale>/translation.json
169+
//
170+
// mx create-project additionally creates duplicates in nested subdirectories
171+
// (e.g., locales/en-US/atlas_core/locales/en-US/translation.json).
172+
// We keep only the top-level files and remove any deeper duplicates.
173+
func cleanupDuplicateLocaleFiles(projectDir string) int {
174+
localesDir := filepath.Join(projectDir, "themesource", "atlas_core", "locales")
175+
if _, err := os.Stat(localesDir); os.IsNotExist(err) {
176+
return 0
177+
}
178+
179+
removed := 0
180+
// Walk locale directories (en-US, nl-NL, etc.)
181+
entries, err := os.ReadDir(localesDir)
182+
if err != nil {
183+
return 0
184+
}
185+
for _, entry := range entries {
186+
if !entry.IsDir() {
187+
continue
188+
}
189+
localeDir := filepath.Join(localesDir, entry.Name())
190+
// Check for nested subdirectories that duplicate the locale
191+
subEntries, err := os.ReadDir(localeDir)
192+
if err != nil {
193+
continue
194+
}
195+
for _, sub := range subEntries {
196+
if sub.IsDir() {
197+
// Any subdirectory under a locale dir is a duplicate tree
198+
dupPath := filepath.Join(localeDir, sub.Name())
199+
if err := os.RemoveAll(dupPath); err == nil {
200+
removed++
201+
}
202+
}
203+
}
204+
}
205+
return removed
206+
}
207+
156208
func init() {
157209
newCmd.Flags().String("version", "", "Mendix version (e.g., 11.8.0) — required")
158210
newCmd.Flags().String("output-dir", "", "Output directory (default: ./<app-name>)")

sdk/mpr/writer_jsonstructure.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,8 @@ func (b *snippetBuilder) buildElementFromRawValue(exposedName, path, jsonKey str
302302
}
303303
return buildValueElement(exposedName, path, primitiveType, fmt.Sprintf("%q", v))
304304
case float64:
305-
if v == math.Trunc(v) && !strings.Contains(fmt.Sprintf("%v", v), ".") {
305+
// Check the raw JSON text for a decimal point — Go's %v drops ".0" from 41850.0
306+
if v == math.Trunc(v) && !strings.Contains(trimmed, ".") {
306307
return buildValueElement(exposedName, path, "Integer", fmt.Sprintf("%v", int64(v)))
307308
}
308309
return buildValueElement(exposedName, path, "Decimal", fmt.Sprintf("%v", v))

0 commit comments

Comments
 (0)