Skip to content
This repository was archived by the owner on Oct 18, 2024. It is now read-only.

Commit 323beda

Browse files
committed
Added script to generate translation reports
1 parent e2a572a commit 323beda

File tree

12 files changed

+597
-19
lines changed

12 files changed

+597
-19
lines changed

.github/workflows/android_workflow.yml

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,22 @@ jobs:
3535
dependencies-cache-enabled: true
3636
configuration-cache-enabled: true
3737

38-
- name: Upload artifact
38+
- name: Generate translation report
39+
run: |
40+
chmod +x ./gradlew
41+
./gradlew :app:checkTranslations
42+
shell: bash
43+
44+
- name: Upload APK
3945
uses: actions/upload-artifact@v2
4046
if: ${{ !github.head_ref }}
4147
with:
4248
name: apk-debug
43-
path: app/build/outputs/apk/debug/app-debug.apk
49+
path: app/build/outputs/apk/debug/app-debug.apk
50+
51+
- name: Upload translation report
52+
uses: actions/upload-artifact@v2
53+
if: ${{ !github.head_ref }}
54+
with:
55+
name: translation-report
56+
path: build/translation-reports/

.idea/google-java-format.xml

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.tools/strings-check.php

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
#!/usr/bin/php -q
2+
<?php
3+
4+
// Android translation helper tool
5+
// cross checks two strings.xml files to find diffs
6+
//
7+
// usage: ./strings-check.php values/base.xml values-lang/translated.xml
8+
//
9+
// Written by Marcin Orlowski <mail (@) marcinorlowski (.) com>
10+
//
11+
// 2010-07-03: Initial release
12+
// 2017-04-25: Code cleanup; Added exit code
13+
14+
class Convert {
15+
16+
public function XmlToArray( $n )
17+
{
18+
$xml_array = array();
19+
$occurance = array();
20+
21+
foreach($n->childNodes as $nc) {
22+
if (isset($occurance[$nc->nodeName])) {
23+
$occurance[$nc->nodeName]++;
24+
} else {
25+
$occurance[$nc->nodeName] = 1;
26+
}
27+
}
28+
29+
foreach($n->childNodes as $nc) {
30+
if( $nc->hasChildNodes() ) {
31+
$childNodes = $nc->childNodes;
32+
$children = $childNodes->length;
33+
34+
if ($children>1) {
35+
$xml_array[$nc->nodeName][] = $this->XmlToArray($nc);
36+
37+
$counter = count($xml_array[$nc->nodeName])-1;
38+
39+
$attrs = $nc->attributes;
40+
for ($k = 0; $k < $attrs->length; $k++) {
41+
$xml_array[$nc->nodeName][$counter]['attribute'][$attrs->item($k)->nodeName] = $attrs->item($k)->nodeValue;
42+
}
43+
//$counter++;
44+
} else {
45+
$xml_array[$nc->nodeName][]['cdata'] = $nc->nodeValue;
46+
$counter = count($xml_array[$nc->nodeName])-1;
47+
$attrs = $nc->attributes;
48+
for ($k = 0; $k < $attrs->length; $k++) {
49+
$xml_array[$nc->nodeName][$counter]['attribute'][$attrs->item($k)->nodeName] = $attrs->item($k)->nodeValue;
50+
}
51+
}
52+
} else {
53+
if( $nc->hasAttributes() ) {
54+
$attrs = $nc->attributes;
55+
for ($k = 0; $k < $attrs->length; $k++) {
56+
$xml_array[$nc->nodeName][0]['attribute'][$attrs->item($k)->nodeName]= $attrs->item($k)->nodeValue;
57+
}
58+
}
59+
}
60+
}
61+
62+
return $xml_array;
63+
}
64+
65+
public function GetLabels( $fileName )
66+
{
67+
$xml = new DOMDocument('1.0','UTF-8');
68+
$xml->load( $fileName );
69+
70+
$data = $this->XmlToArray( $xml );
71+
72+
$result = array();
73+
74+
foreach( $data['resources'][0]['string'] AS $entry ) {
75+
$tmp = sprintf("%s", trim($entry['attribute']['name']));
76+
$result[$tmp] = $tmp;
77+
}
78+
79+
return $result;
80+
}
81+
82+
// class convert
83+
}
84+
85+
86+
if( $_SERVER['argc'] != 3 ) {
87+
printf("Usage: %s strings-BASE.xml string-LANG.xml\n", $_SERVER['argv'][0] );
88+
die( "*** Aborted\n");
89+
}
90+
91+
$fileBase = $_SERVER['argv'][1];
92+
$fileLang = $_SERVER['argv'][2];
93+
94+
if( file_exists( $fileBase ) == FALSE ) {
95+
die( sprintf("*** Missing BASE file '%s'\n", $fileBase ));
96+
}
97+
98+
if( file_exists( $fileLang ) == FALSE ) {
99+
die( sprintf("*** Missing LANG file '%s'\n", $fileLang ) );
100+
}
101+
102+
103+
$convert = new Convert();
104+
$dataLang = $convert->GetLabels( $fileLang );
105+
$dataBase = $convert->GetLabels( $fileBase );
106+
107+
$cntLang = $cntBase = 0;
108+
109+
echo "\n";
110+
111+
// comparing
112+
printf("Missing in LANG (You need to translate these)\n");
113+
printf("File: %s\n", $fileLang);
114+
printf("------------------------- BEGIN ----------------------\n");
115+
foreach( $dataBase as $string ) {
116+
if( !array_key_exists($string, $dataLang)) {
117+
printf("%s\n", $string);
118+
$cntLang++;
119+
}
120+
}
121+
printf("-------------------------- END -----------------------\n");
122+
123+
echo "\n\n";
124+
printf("Not present in BASE (you need to remove it from LANG)\n");
125+
printf("File: %s\n", $fileBase);
126+
printf("------------------------- BEGIN ----------------------\n");
127+
foreach( $dataLang as $string ) {
128+
if( !array_key_exists($string, $dataBase)) {
129+
printf("%s\n", $string);
130+
$cntBase++;
131+
}
132+
}
133+
printf("-------------------------- END -----------------------\n");
134+
135+
echo "\n\nSummary\n----------------\n";
136+
137+
echo "BASE file: '{$fileBase}'\n";
138+
echo "LANG file: '{$fileLang}'\n";
139+
echo "\n";
140+
141+
$rc = 1;
142+
if( ($cntLang == 0) && ($cntBase==0) ) {
143+
echo "OK. Files seem to be up to date.\n";
144+
$rc = 0;
145+
} else {
146+
if( $cntLang > 0 ) {
147+
printf( "%4d missing strings.\n", $cntLang );
148+
}
149+
150+
if( $cntBase > 0 ) {
151+
printf("%4d orphaned strings.\n", $cntBase );
152+
}
153+
}
154+
155+
echo "\n";
156+
157+
exit($rc);

app/build.gradle

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -134,8 +134,4 @@ dependencies {
134134
implementation fileTree(dir: 'libs', include: ['*.jar'])
135135

136136
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5'
137-
}
138-
139-
140-
141-
137+
}

build.gradle

Lines changed: 58 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ buildscript {
88
versionCode = 200
99
versionName = "2.0-beta"
1010
packageName = "com.itsaky.androidide"
11-
11+
1212
javaSourceVersion = JavaVersion.VERSION_11
1313
javaTargetVersion = JavaVersion.VERSION_11
1414
}
@@ -17,9 +17,9 @@ buildscript {
1717
google()
1818
mavenLocal()
1919
mavenCentral()
20-
maven { url 'https://jitpack.io'}
20+
maven { url 'https://jitpack.io' }
2121
}
22-
22+
2323
dependencies {
2424
classpath 'com.android.tools.build:gradle:7.1.2'
2525
classpath 'com.google.gms:google-services:4.3.10'
@@ -30,24 +30,70 @@ buildscript {
3030

3131
subprojects {
3232
apply from: "${rootDir}/gradle/dependencies.gradle"
33+
34+
task checkTranslations() {
35+
36+
def php = new File ("/usr/bin/php")
37+
if (!php.exists()) {
38+
project.logger.lifecycle("'${php.absolutePath}' not found. Skipping translation check.")
39+
return
40+
}
41+
42+
def resDir = project.file("src/main/res")
43+
def strings = new File(resDir, "values/strings.xml")
44+
def reportDir = new File(project.rootProject.buildDir, "translation-reports")
45+
reportDir.delete()
46+
47+
if (resDir.exists() && strings.exists()) {
48+
def translationDirs = resDir.listFiles((FileFilter) (file -> {
49+
return file.isDirectory() && file.getName().startsWith("values-") }))
50+
for (def dir : translationDirs) {
51+
final var translation = new File(dir, "strings.xml")
52+
if (translation.exists()) {
53+
def out = new File(reportDir, "${project.path.replace(':', '/')}/${dir.name}.txt")
54+
if (!out.parentFile.exists()) {
55+
out.parentFile.mkdirs()
56+
}
57+
58+
if (out.exists()) {
59+
out.delete()
60+
}
61+
out.createNewFile()
62+
63+
def result = exec {
64+
ignoreExitValue true
65+
standardOutput new FileOutputStream(out)
66+
commandLine "${php.absolutePath}",
67+
"${project.rootProject.file(".tools/strings-check.php")}",
68+
"${strings.absolutePath}",
69+
"${translation.absolutePath}"
70+
}
71+
72+
if (result.getExitValue() == 0) {
73+
out.delete()
74+
} else {
75+
project.logger.lifecycle("Translation report for '${project.path}/${dir.name}' is written to '${out.absolutePath}'")
76+
}
77+
78+
} else {
79+
project.logger.info("No translation file specifed for '${dir.name}'. Skipping..")
80+
}
81+
}
82+
} else {
83+
project.logger.info("Default strings.xml file does not exist for project '${project.name}'")
84+
}
85+
}
3386
}
3487

3588
allprojects {
3689
repositories {
3790
google()
3891
mavenLocal()
3992
mavenCentral()
40-
maven { url 'https://jitpack.io'}
93+
maven { url 'https://jitpack.io' }
4194
}
4295
}
4396

4497
task clean(type: Delete) {
4598
delete rootProject.buildDir
46-
}
47-
48-
49-
50-
51-
52-
53-
99+
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
2+
Missing in LANG (You need to translate these)
3+
File: /mnt/d/projects/androidstudioprojects/androidide/app/src/main/res/values-de/strings.xml
4+
------------------------- BEGIN ----------------------
5+
template_libgdx
6+
template_description_libgdx
7+
idepref_editor_ligatures_title
8+
idepref_editor_ligatures_summary
9+
yes
10+
no
11+
title_use_popup_actions
12+
msg_use_popup_actions
13+
title_use_horizontal_popup
14+
msg_use_horizontal_popup
15+
msg_apk_install_intent_failed
16+
msg_viewaction_add_attr
17+
msg_search_attrs
18+
msg_attr_added
19+
msg_attr_not_updated
20+
hint_dimension_val
21+
hint_dimension_res
22+
hint_boolean_res
23+
msg_file_tree
24+
hint_color_resource
25+
title_color_picker
26+
hint_string_value
27+
hint_string_resource
28+
hint_resource_reference
29+
-------------------------- END -----------------------
30+
31+
32+
Not present in BASE (you need to remove it from LANG)
33+
File: /mnt/d/projects/androidstudioprojects/androidide/app/src/main/res/values/strings.xml
34+
------------------------- BEGIN ----------------------
35+
title_developers
36+
msg_developers
37+
cancel
38+
msg_sdk_info_load_failed
39+
msg_no_code_actions
40+
msg_starting_completion_failed
41+
menu_project_info
42+
header_module_info
43+
msg_module_count
44+
msg_task_count
45+
msg_dependency_count
46+
msg_package_name
47+
msg_min_sdk
48+
msg_target_sdk
49+
show_files
50+
msg_failed_save
51+
idepref_build_editgradleproperties_title
52+
idepref_build_editgradleproperties_summary
53+
err_completion
54+
err_no_server_implementation
55+
err_init_server
56+
err_cannot_save_files
57+
err_cannot_start_server
58+
err_cannot_write_socket
59+
err_server_disconnected
60+
msg_attr_edit_hint
61+
sym_equal
62+
msg_attr_namespace
63+
msg_unknown_package
64+
msg_attr_editor_select_view
65+
msg_attr_editor_no_attrs
66+
msg_enter_attr_value
67+
msg_enter_dimension_value
68+
msg_attr_editor_null
69+
-------------------------- END -----------------------
70+
71+
72+
Summary
73+
----------------
74+
BASE file: '/mnt/d/projects/androidstudioprojects/androidide/app/src/main/res/values/strings.xml'
75+
LANG file: '/mnt/d/projects/androidstudioprojects/androidide/app/src/main/res/values-de/strings.xml'
76+
77+
24 missing strings.
78+
34 orphaned strings.
79+

0 commit comments

Comments
 (0)