Skip to content

Commit fa05bce

Browse files
authored
Merge pull request #358 from wordpress-mobile/merge-android-strings-avoid-moves
2 parents 9ba87e4 + 3348f39 commit fa05bce

File tree

3 files changed

+48
-52
lines changed

3 files changed

+48
-52
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ _None_
1818
### Bug Fixes
1919

2020
* Fix `ios_lint_localizations` action so that it no longer mistakely reports missing keys not yet translated in the other locales' `.strings` as violations. [#353]
21+
* Fix `an_localize_libs` so that it does not move XML nodes around when merging lib strings (and replace them in-place instead). [#358]
2122

2223
### Internal Changes
2324

lib/fastlane/plugin/wpmreleasetoolkit/helper/android/android_localize_helper.rb

Lines changed: 45 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,19 @@ module Android
1111
module LocalizeHelper
1212
LIB_SOURCE_XML_ATTR = 'a8c-src-lib'.freeze
1313

14-
# Checks if string_line has the content_override flag set
15-
def self.skip_string_by_tag(string_line)
16-
skip = string_line.attr('content_override') == 'true' unless string_line.attr('content_override').nil?
14+
# Checks if `string_node` has the content_override flag set
15+
def self.skip_string_by_tag?(string_node)
16+
skip = string_node.attr('content_override') == 'true' unless string_node.attr('content_override').nil?
1717
if skip
18-
UI.message " - Skipping #{string_line.attr('name')} string"
18+
UI.message " - Skipping #{string_node.attr('name')} string"
1919
return true
2020
end
2121

2222
return false
2323
end
2424

25-
# Checks if string_name is in the excluesion list
26-
def self.skip_string_by_exclusion_list(library, string_name)
25+
# Checks if `string_name` is in the exclusion list
26+
def self.skip_string_by_exclusion_list?(library, string_name)
2727
return false if library[:exclusions].nil?
2828

2929
skip = library[:exclusions].include?(string_name)
@@ -43,66 +43,65 @@ def self.add_xml_attributes!(string_node, library)
4343
string_node[LIB_SOURCE_XML_ATTR] = library[:source_id] unless library[:source_id].nil?
4444
end
4545

46-
# Merge string_line into main_string
47-
def self.merge_string(main_strings, library, string_line)
48-
string_name = string_line.attr('name')
49-
string_content = string_line.content
46+
# Merge a single `lib_string_node` XML node into the `main_strings_xml``
47+
def self.merge_string_node(main_strings_xml, library, lib_string_node)
48+
string_name = lib_string_node.attr('name')
49+
string_content = lib_string_node.content
5050

5151
# Skip strings in the exclusions list
52-
return :skipped if skip_string_by_exclusion_list(library, string_name)
52+
return :skipped if skip_string_by_exclusion_list?(library, string_name)
5353

5454
# Search for the string in the main file
5555
result = :added
56-
main_strings.xpath('//string').each do |this_string|
57-
if this_string.attr('name') == string_name
56+
main_strings_xml.xpath('//string').each do |main_string_node|
57+
if main_string_node.attr('name') == string_name
5858
# Skip if the string has the content_override tag
59-
return :skipped if skip_string_by_tag(this_string)
59+
return :skipped if skip_string_by_tag?(main_string_node)
6060

6161
# If nodes are equivalent, skip
62-
return :found if string_line =~ this_string
62+
return :found if lib_string_node =~ main_string_node
6363

6464
# The string needs an update
65-
result = :updated
66-
if this_string.attr('tools:ignore').nil?
67-
# It can be updated, so remove the current one and move ahead
68-
this_string.remove
69-
break
65+
if main_string_node.attr('tools:ignore').nil?
66+
# No `tools:ignore` attribute; completely replace existing main string node with lib's one
67+
add_xml_attributes!(lib_string_node, library)
68+
main_string_node.replace lib_string_node
7069
else
71-
# It has the tools:ignore flag, so update the content without touching the other attributes
72-
this_string.content = string_content
73-
add_xml_attributes!(this_string, library)
74-
return result
70+
# Has the `tools:ignore` flag; update the content without touching the other existing attributes
71+
add_xml_attributes!(main_string_node, library)
72+
main_string_node.content = string_content
7573
end
74+
return :updated
7675
end
7776
end
7877

7978
# String not found, or removed because needing update and not in the exclusion list: add to the main file
80-
add_xml_attributes!(string_line, library)
81-
main_strings.xpath('//string').last().add_next_sibling("\n#{' ' * 4}#{string_line.to_xml().strip}")
79+
add_xml_attributes!(lib_string_node, library)
80+
main_strings_xml.xpath('//string').last().add_next_sibling("\n#{' ' * 4}#{lib_string_node.to_xml().strip}")
8281
return result
8382
end
8483

85-
# Verify a string
86-
def self.verify_string(main_strings, library, string_line)
87-
string_name = string_line.attr('name')
88-
string_content = string_line.content
84+
# Verify a string node from a library has properly been merged into the main one
85+
def self.verify_string(main_strings_xml, library, lib_string_node)
86+
string_name = lib_string_node.attr('name')
87+
string_content = lib_string_node.content
8988

9089
# Skip strings in the exclusions list
91-
return if skip_string_by_exclusion_list(library, string_name)
90+
return if skip_string_by_exclusion_list?(library, string_name)
9291

9392
# Search for the string in the main file
94-
main_strings.xpath('//string').each do |this_string|
95-
if this_string.attr('name') == string_name
93+
main_strings_xml.xpath('//string').each do |main_string_node|
94+
if main_string_node.attr('name') == string_name
9695
# Skip if the string has the content_override tag
97-
return if skip_string_by_tag(this_string)
96+
return if skip_string_by_tag?(main_string_node)
9897

99-
# Update if needed
100-
UI.user_error!("String #{string_name} [#{string_content}] has been updated in the main file but not in the library #{library[:library]}.") if this_string.content != string_content
98+
# Check if up-to-date
99+
UI.user_error!("String #{string_name} [#{string_content}] has been updated in the main file but not in the library #{library[:library]}.") if main_string_node.content != string_content
101100
return
102101
end
103102
end
104103

105-
# String not found and not in the exclusion list:
104+
# String not found and not in the exclusion list
106105
UI.user_error!("String #{string_name} [#{string_content}] was found in library #{library[:library]} but not in the main file.")
107106
end
108107

@@ -122,23 +121,23 @@ def self.verify_string(main_strings, library, string_line)
122121
#
123122
def self.merge_lib(main, library)
124123
UI.message("Merging #{library[:library]} strings into #{main}")
125-
main_strings = File.open(main) { |f| Nokogiri::XML(f, nil, Encoding::UTF_8.to_s) }
126-
lib_strings = File.open(library[:strings_path]) { |f| Nokogiri::XML(f, nil, Encoding::UTF_8.to_s) }
124+
main_strings_xml = File.open(main) { |f| Nokogiri::XML(f, nil, Encoding::UTF_8.to_s) }
125+
lib_strings_xml = File.open(library[:strings_path]) { |f| Nokogiri::XML(f, nil, Encoding::UTF_8.to_s) }
127126

128127
updated_count = 0
129128
untouched_count = 0
130129
added_count = 0
131130
skipped_count = 0
132-
lib_strings.xpath('//string').each do |string_line|
133-
res = merge_string(main_strings, library, string_line)
131+
lib_strings_xml.xpath('//string').each do |string_node|
132+
res = merge_string_node(main_strings_xml, library, string_node)
134133
case res
135134
when :updated
136-
UI.verbose "#{string_line.attr('name')} updated."
135+
UI.verbose "#{string_node.attr('name')} updated."
137136
updated_count = updated_count + 1
138137
when :found
139138
untouched_count = untouched_count + 1
140139
when :added
141-
UI.verbose "#{string_line.attr('name')} added."
140+
UI.verbose "#{string_node.attr('name')} added."
142141
added_count = added_count + 1
143142
when :skipped
144143
skipped_count = skipped_count + 1
@@ -148,7 +147,7 @@ def self.merge_lib(main, library)
148147
end
149148

150149
File.open(main, 'w:UTF-8') do |f|
151-
f.write(main_strings.to_xml(indent: 4))
150+
f.write(main_strings_xml.to_xml(indent: 4))
152151
end
153152

154153
UI.message("Done (#{added_count} added, #{updated_count} updated, #{untouched_count} untouched, #{skipped_count} skipped).")
@@ -164,8 +163,8 @@ def self.verify_diff(diff_string, main_strings, lib_strings, library)
164163

165164
diff_string = diff_string.slice(0..(end_index - 1))
166165

167-
lib_strings.xpath('//string').each do |string_line|
168-
res = verify_string(main_strings, library, string_line) if string_line.attr('name') == diff_string
166+
lib_strings.xpath('//string').each do |string_node|
167+
res = verify_string(main_strings, library, string_node) if string_node.attr('name') == diff_string
169168
end
170169
end
171170
end

spec/an_localize_libs_action_spec.rb

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,6 @@ def write_android_xml(path, lines)
7575

7676
expected = [
7777
'<string name="override-true" content_override="true">from app override-true</string>',
78-
'', '', # FIXME: Current implementation adds empty lines; we should get rid of those at some point
7978
'<string name="override-false">from lib override-false</string>',
8079
'<string name="override-missing">from lib override-missing</string>',
8180
]
@@ -118,11 +117,9 @@ def write_android_xml(path, lines)
118117

119118
expected = [
120119
'<string name="override-true" content_override="true">from app override-true</string>',
121-
'', # FIXME: Current implementation adds empty lines; we should get rid of those at some point
122-
'<string name="lib1-key" a8c-src-lib="lib1-id">Key only present in lib1</string>',
123120
'<string name="override-missing" a8c-src-lib="lib2-id">from lib2 override-missing</string>',
121+
'<string name="lib1-key" a8c-src-lib="lib1-id">Key only present in lib1</string>',
124122
'<string name="lib2-key" a8c-src-lib="lib2-id">Key only present in lib2</string>',
125-
'', # FIXME: Current implementation adds empty lines; we should get rid of those at some point
126123
]
127124
expect(File.read(app_strings_path)).to eq(android_xml_with_lines(expected))
128125
end
@@ -212,9 +209,8 @@ def write_android_xml(path, lines)
212209

213210
expected = [
214211
'<string name="override-true" content_override="true">from app override-true</string>',
215-
'', # FIXME: Current implementation adds empty lines; we should get rid of those at some point
216-
'<string name="override-missing">from app override-missing</string>',
217212
'<string name="override-false">from lib override-false</string>',
213+
'<string name="override-missing">from app override-missing</string>',
218214
]
219215
expect(File.read(app_strings_path)).to eq(android_xml_with_lines(expected))
220216
end

0 commit comments

Comments
 (0)