Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Léo-Paul Géneau
gitlab-ce
Commits
4761235f
Commit
4761235f
authored
Aug 31, 2017
by
Bob Van Landuyt
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Validate unescaped `%` chars in PO files
parent
538104bd
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
140 additions
and
4 deletions
+140
-4
lib/gitlab/i18n/po_linter.rb
lib/gitlab/i18n/po_linter.rb
+18
-3
lib/gitlab/i18n/translation_entry.rb
lib/gitlab/i18n/translation_entry.rb
+18
-0
spec/fixtures/unescaped_chars.po
spec/fixtures/unescaped_chars.po
+21
-0
spec/lib/gitlab/i18n/po_linter_spec.rb
spec/lib/gitlab/i18n/po_linter_spec.rb
+13
-1
spec/lib/gitlab/i18n/translation_entry_spec.rb
spec/lib/gitlab/i18n/translation_entry_spec.rb
+70
-0
No files found.
lib/gitlab/i18n/po_linter.rb
View file @
4761235f
...
@@ -63,10 +63,25 @@ module Gitlab
...
@@ -63,10 +63,25 @@ module Gitlab
validate_variables
(
errors
,
entry
)
validate_variables
(
errors
,
entry
)
validate_newlines
(
errors
,
entry
)
validate_newlines
(
errors
,
entry
)
validate_number_of_plurals
(
errors
,
entry
)
validate_number_of_plurals
(
errors
,
entry
)
validate_unescaped_chars
(
errors
,
entry
)
errors
errors
end
end
def
validate_unescaped_chars
(
errors
,
entry
)
if
entry
.
msgid_contains_unescaped_chars?
errors
<<
'contains unescaped `%`, escape it using `%%`'
end
if
entry
.
plural_id_contains_unescaped_chars?
errors
<<
'plural id contains unescaped `%`, escape it using `%%`'
end
if
entry
.
translations_contain_unescaped_chars?
errors
<<
'translation contains unescaped `%`, escape it using `%%`'
end
end
def
validate_number_of_plurals
(
errors
,
entry
)
def
validate_number_of_plurals
(
errors
,
entry
)
return
unless
metadata_entry
&
.
expected_plurals
return
unless
metadata_entry
&
.
expected_plurals
return
unless
entry
.
translated?
return
unless
entry
.
translated?
...
@@ -79,15 +94,15 @@ module Gitlab
...
@@ -79,15 +94,15 @@ module Gitlab
def
validate_newlines
(
errors
,
entry
)
def
validate_newlines
(
errors
,
entry
)
if
entry
.
msgid_contains_newlines?
if
entry
.
msgid_contains_newlines?
errors
<<
"is defined over multiple lines, this breaks some tooling."
errors
<<
'is defined over multiple lines, this breaks some tooling.'
end
end
if
entry
.
plural_id_contains_newlines?
if
entry
.
plural_id_contains_newlines?
errors
<<
"plural is defined over multiple lines, this breaks some tooling."
errors
<<
'plural is defined over multiple lines, this breaks some tooling.'
end
end
if
entry
.
translations_contain_newlines?
if
entry
.
translations_contain_newlines?
errors
<<
"has translations defined over multiple lines, this breaks some tooling."
errors
<<
'has translations defined over multiple lines, this breaks some tooling.'
end
end
end
end
...
...
lib/gitlab/i18n/translation_entry.rb
View file @
4761235f
module
Gitlab
module
Gitlab
module
I18n
module
I18n
class
TranslationEntry
class
TranslationEntry
PERCENT_REGEX
=
/(?:^|[^%])%(?!{\w*}|[a-z%])/
.
freeze
attr_reader
:nplurals
,
:entry_data
attr_reader
:nplurals
,
:entry_data
def
initialize
(
entry_data
,
nplurals
)
def
initialize
(
entry_data
,
nplurals
)
...
@@ -64,6 +66,22 @@ module Gitlab
...
@@ -64,6 +66,22 @@ module Gitlab
all_translations
.
any?
{
|
translation
|
translation
.
is_a?
(
Array
)
}
all_translations
.
any?
{
|
translation
|
translation
.
is_a?
(
Array
)
}
end
end
def
msgid_contains_unescaped_chars?
contains_unescaped_chars?
(
msgid
)
end
def
plural_id_contains_unescaped_chars?
contains_unescaped_chars?
(
plural_id
)
end
def
translations_contain_unescaped_chars?
all_translations
.
any?
{
|
translation
|
contains_unescaped_chars?
(
translation
)
}
end
def
contains_unescaped_chars?
(
string
)
string
=~
PERCENT_REGEX
end
private
private
def
translation_keys
def
translation_keys
...
...
spec/fixtures/unescaped_chars.po
0 → 100644
View file @
4761235f
# Spanish translations for gitlab package.
# Copyright (C) 2017 THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the gitlab package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2017.
#
msgid ""
msgstr ""
"Project-Id-Version: gitlab 1.0.0\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2017-07-13 12:10-0500\n"
"Language-Team: Spanish\n"
"Language: es\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"Last-Translator: Bob Van Landuyt <bob@gitlab.com>\n"
"X-Generator: Poedit 2.0.2\n"
msgid "You are going to transfer %{project_name_with_namespace} to another owner. Are you ABSOLUTELY sure?"
msgstr "將要把 %{project_name_with_namespace} 的所有權轉移給另一個人。真的「100%確定」要這麼做嗎?"
spec/lib/gitlab/i18n/po_linter_spec.rb
View file @
4761235f
...
@@ -110,6 +110,17 @@ describe Gitlab::I18n::PoLinter do
...
@@ -110,6 +110,17 @@ describe Gitlab::I18n::PoLinter do
is_expected
.
not_to
be_empty
is_expected
.
not_to
be_empty
end
end
end
end
context
'with unescaped chars'
do
let
(
:po_path
)
{
'spec/fixtures/unescaped_chars.po'
}
it
'contains an error'
do
message_id
=
'You are going to transfer %{project_name_with_namespace} to another owner. Are you ABSOLUTELY sure?'
expected_error
=
'translation contains unescaped `%`, escape it using `%%`'
expect
(
errors
[
message_id
]).
to
include
(
expected_error
)
end
end
end
end
describe
'#parse_po'
do
describe
'#parse_po'
do
...
@@ -157,13 +168,14 @@ describe Gitlab::I18n::PoLinter do
...
@@ -157,13 +168,14 @@ describe Gitlab::I18n::PoLinter do
end
end
describe
'#validate_entry'
do
describe
'#validate_entry'
do
it
'validates the flags, variable usage,
and newline
s'
do
it
'validates the flags, variable usage,
newlines, and unescaped char
s'
do
fake_entry
=
double
fake_entry
=
double
expect
(
linter
).
to
receive
(
:validate_flags
).
with
([],
fake_entry
)
expect
(
linter
).
to
receive
(
:validate_flags
).
with
([],
fake_entry
)
expect
(
linter
).
to
receive
(
:validate_variables
).
with
([],
fake_entry
)
expect
(
linter
).
to
receive
(
:validate_variables
).
with
([],
fake_entry
)
expect
(
linter
).
to
receive
(
:validate_newlines
).
with
([],
fake_entry
)
expect
(
linter
).
to
receive
(
:validate_newlines
).
with
([],
fake_entry
)
expect
(
linter
).
to
receive
(
:validate_number_of_plurals
).
with
([],
fake_entry
)
expect
(
linter
).
to
receive
(
:validate_number_of_plurals
).
with
([],
fake_entry
)
expect
(
linter
).
to
receive
(
:validate_unescaped_chars
).
with
([],
fake_entry
)
linter
.
validate_entry
(
fake_entry
)
linter
.
validate_entry
(
fake_entry
)
end
end
...
...
spec/lib/gitlab/i18n/translation_entry_spec.rb
View file @
4761235f
...
@@ -130,4 +130,74 @@ describe Gitlab::I18n::TranslationEntry do
...
@@ -130,4 +130,74 @@ describe Gitlab::I18n::TranslationEntry do
expect
(
entry
.
translations_contain_newlines?
).
to
be_truthy
expect
(
entry
.
translations_contain_newlines?
).
to
be_truthy
end
end
end
end
describe
'#contains_unescaped_chars'
do
let
(
:data
)
{
{
msgid:
''
}
}
let
(
:entry
)
{
described_class
.
new
(
data
,
2
)
}
it
'is true when the msgid is an array'
do
string
=
'「100%確定」'
expect
(
entry
.
contains_unescaped_chars?
(
string
)).
to
be_truthy
end
it
'is false when the `%` char is escaped'
do
string
=
'「100%%確定」'
expect
(
entry
.
contains_unescaped_chars?
(
string
)).
to
be_falsy
end
it
'is false when using an unnamed variable'
do
string
=
'「100%d確定」'
expect
(
entry
.
contains_unescaped_chars?
(
string
)).
to
be_falsy
end
it
'is false when using a named variable'
do
string
=
'「100%{named}確定」'
expect
(
entry
.
contains_unescaped_chars?
(
string
)).
to
be_falsy
end
it
'is true when an unnamed variable is not closed'
do
string
=
'「100%{named確定」'
expect
(
entry
.
contains_unescaped_chars?
(
string
)).
to
be_truthy
end
it
'is true when the string starts with a `%`'
do
string
=
'%10'
expect
(
entry
.
contains_unescaped_chars?
(
string
)).
to
be_truthy
end
end
describe
'#msgid_contains_unescaped_chars'
do
it
'is true when the msgid contains a `%`'
do
data
=
{
msgid:
'「100%確定」'
}
entry
=
described_class
.
new
(
data
,
2
)
expect
(
entry
).
to
receive
(
:contains_unescaped_chars?
).
and_call_original
expect
(
entry
.
msgid_contains_unescaped_chars?
).
to
be_truthy
end
end
describe
'#plural_id_contains_unescaped_chars'
do
it
'is true when the plural msgid contains a `%`'
do
data
=
{
msgid_plural:
'「100%確定」'
}
entry
=
described_class
.
new
(
data
,
2
)
expect
(
entry
).
to
receive
(
:contains_unescaped_chars?
).
and_call_original
expect
(
entry
.
plural_id_contains_unescaped_chars?
).
to
be_truthy
end
end
describe
'#translations_contain_unescaped_chars'
do
it
'is true when the translation contains a `%`'
do
data
=
{
msgstr:
'「100%確定」'
}
entry
=
described_class
.
new
(
data
,
2
)
expect
(
entry
).
to
receive
(
:contains_unescaped_chars?
).
and_call_original
expect
(
entry
.
translations_contain_unescaped_chars?
).
to
be_truthy
end
end
end
end
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment