@@ -8,9 +8,41 @@ const path = require("path");
8
8
const en = JSON . parse ( fs . readFileSync ( "lang/ui.en.json" ) ) ;
9
9
const validKeys = new Set ( Object . keys ( en ) ) ;
10
10
11
- fs . readdirSync ( "lang" )
11
+ const variableRegExp = / ( { [ a - z A - Z 0 - 9 ] + } ) / g;
12
+
13
+ // This is just a best effort check that variables haven't been changed.
14
+ const areTranslationsValid = ( file , enJson , translatedJson ) => {
15
+ let valid = true ;
16
+ const keys = Object . keys ( en ) ;
17
+ for ( const k of keys ) {
18
+ const en = enJson [ k ] . defaultMessage ;
19
+ const translated = translatedJson [ k ] . defaultMessage ;
20
+ if ( en . match ( / , p l u r a l / ) ) {
21
+ // Skip ICU strings as we don't understand them.
22
+ continue ;
23
+ }
24
+ const variablesEn = new Set ( en . match ( variableRegExp ) ?? [ ] ) ;
25
+ const variablesTranslated = new Set ( translated . match ( variableRegExp ) ?? [ ] ) ;
26
+ const areSetsEqual = ( a , b ) =>
27
+ a . size === b . size && Array . from ( a ) . every ( ( value ) => b . has ( value ) ) ;
28
+ if ( ! areSetsEqual ( variablesEn , variablesTranslated ) ) {
29
+ if ( valid ) {
30
+ console . error ( file ) ;
31
+ valid = false ;
32
+ }
33
+ console . error ( ` ${ en } ` ) ;
34
+ console . error ( ` ${ translated } ` ) ;
35
+ console . error ( ` Differing variables!` ) ;
36
+ console . error ( ) ;
37
+ }
38
+ }
39
+ return valid ;
40
+ } ;
41
+
42
+ const valid = fs
43
+ . readdirSync ( "lang" )
12
44
. filter ( ( f ) => f . endsWith ( ".json" ) )
13
- . forEach ( ( messages ) => {
45
+ . map ( ( messages ) => {
14
46
const file = path . join ( "lang" , messages ) ;
15
47
const data = {
16
48
// Ensure we fallback to English even if we haven't roundtripped via Crowdin yet.
@@ -26,4 +58,7 @@ fs.readdirSync("lang")
26
58
const result = Object . create ( null ) ;
27
59
sortedKeys . forEach ( ( k ) => ( result [ k ] = data [ k ] ) ) ;
28
60
fs . writeFileSync ( file , JSON . stringify ( result , null , 2 ) ) ;
29
- } ) ;
61
+ return areTranslationsValid ( file , en , result ) ;
62
+ } )
63
+ . reduce ( ( prev , curr ) => prev && curr , true ) ;
64
+ process . exit ( valid ? 0 : 2 ) ;
0 commit comments