wca_i18n 0.4.2 → 0.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.gitignore +1 -0
- data/.travis.yml +8 -2
- data/Gemfile.lock +2 -2
- data/README.md +15 -5
- data/lib/wca_i18n/translation.rb +2 -21
- data/lib/wca_i18n/version.rb +1 -1
- data/lib/wca_i18n/yaml_to_enriched_ruby_hash.rb +96 -0
- data/wca_i18n.gemspec +2 -2
- metadata +6 -6
- data/lib/wca_i18n/yaml_with_comments.rb +0 -68
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 9554abfdee1791abd95ba8b9b598bfffd143c9cd55e16829118e4e4ab84777d2
|
|
4
|
+
data.tar.gz: bcab8fe2d2baf5ef5432abfdd0c1155e4d9666ad293c73fdbbef5818f2dd0753
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6e7f180bd18fab47d8c437281cec14895b49c02c8cea40fd88157c82a1ddc44b1868fc35399e2b576745fb80ac2753ca57e602a46a88049ff51cf108e52e0369
|
|
7
|
+
data.tar.gz: fa57f2ac88ea7da0a00d33573ba0d26d6be9226f3174f2e31ccfe31b7bf40f6bc212b782f709bb4cb45c7a1655a72cfc34bc58982e84b2691a39a390eeaacaca
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
sudo: false
|
|
2
2
|
language: ruby
|
|
3
3
|
rvm:
|
|
4
|
-
- 2.
|
|
5
|
-
before_install: gem install bundler -v 1.16.
|
|
4
|
+
- 2.5.0
|
|
5
|
+
before_install: gem install bundler -v 1.16.1
|
|
6
|
+
deploy:
|
|
7
|
+
provider: rubygems
|
|
8
|
+
api_key:
|
|
9
|
+
secure: LOAbx7/3XEoTqOS91rFP6U9CA8wAYThY8eAuZxQh0VVAi6EushRNQQJ21EFtatRB86/VNZ2fLQe3fDYQltKDrGjEcf/jT3j0PAMUbvhFIS8OlOFPUdK/TPfssPcrDzU8u7YJ3WZ4X+mAimCOokXoJ8ueqeNuhpCV3rXdxaVcxn0C0r4dzfzsPWihle3wopBak13hnZ2baiHGt8INWVO+kcukeW0ldscwt1A8XiCggBWpFHtsRHU+ki1UWNXIw5NKy4/hLVuDyy9FRi4ofOXvdW0R8Pybg5Aqvx9rs91Xkv6sQt1dPYy5QAblF2KidHfDXPk7uuJKYEO04MMLxKsqO39CpckxoYyS8qmDn9On6s/flVElye95+4ZgjYsiSrx4U1OnP0rgFMCbh9jh29w5e7T4MwaKkEqbK2KZGD0z9unbm5+Klk4+jI5BdgFNw8sw4W/1T1xaNO8FWWlq6OKk+U2MIsVXZqWy1mIEO14+eEODauFrFYh+BzigjG66oMnLt0G6D6xDJWSGKgPhbS8BvGWmTeNT5gDLizG+cHhV4RxsPCq3+NPXhNtTFXHXZHb7XWMTgIUd3r5aBSmkY6yfmWjUqgWtJYAdzjkL3hHMx14iatMz5tN3ApWu3It8o9wOFTfwU4lkqQO8h20wtPmZOmAPic4Id9z3CRPkU3GKsao=
|
|
10
|
+
on:
|
|
11
|
+
tags: true
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# WcaI18n [](https://travis-ci.org/thewca/wca_i18n)
|
|
2
2
|
|
|
3
3
|
Use this Gem to diff Rails translations.
|
|
4
4
|
|
|
@@ -34,18 +34,28 @@ $ wca_i18n en.yml *.yml
|
|
|
34
34
|
There are two parts to this library: `WcaI18n::YAMLWithComments` (a YAML parser
|
|
35
35
|
that preserves comments) and `WcaI18n::Translation` (used to load and diff
|
|
36
36
|
translation YAML files). Until we have better documentation, it's best to look
|
|
37
|
-
at our [specs](https://github.com/thewca/
|
|
37
|
+
at our [specs](https://github.com/thewca/wca_i18n/tree/master/spec) for how to
|
|
38
38
|
them.
|
|
39
39
|
|
|
40
40
|
## Development
|
|
41
41
|
|
|
42
|
-
After checking out the repo, run `bin/setup` to install dependencies. Then, run
|
|
42
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run
|
|
43
|
+
`bin/rspec` to run the tests. You can also run `bin/console` for an interactive
|
|
44
|
+
prompt that will allow you to experiment.
|
|
43
45
|
|
|
44
|
-
To install this gem onto your local machine, run `bundle exec rake install`.
|
|
46
|
+
To install this gem onto your local machine, run `bundle exec rake install`.
|
|
47
|
+
|
|
48
|
+
## Releasing
|
|
49
|
+
|
|
50
|
+
To release a new version, update the version number in `version.rb`, run
|
|
51
|
+
`bundle`, commit your changes, and then run `gem_push=no rake release`, which
|
|
52
|
+
will create a git tag for the version and push git commits and tags. After
|
|
53
|
+
this, Travis should run against the newly created tag, and push the `.gem` file
|
|
54
|
+
to [rubygems.org](https://rubygems.org/gems/wca_i18n).
|
|
45
55
|
|
|
46
56
|
## Contributing
|
|
47
57
|
|
|
48
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/thewca/
|
|
58
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/thewca/wca_i18n.
|
|
49
59
|
|
|
50
60
|
## License
|
|
51
61
|
|
data/lib/wca_i18n/translation.rb
CHANGED
|
@@ -1,18 +1,15 @@
|
|
|
1
1
|
require "json"
|
|
2
2
|
require "digest"
|
|
3
|
-
require "wca_i18n/
|
|
3
|
+
require "wca_i18n/yaml_to_enriched_ruby_hash"
|
|
4
4
|
|
|
5
5
|
module WcaI18n
|
|
6
|
-
TranslatedLeaf = Struct.new(:translated, :original_hash)
|
|
7
|
-
|
|
8
6
|
class Translation
|
|
9
|
-
PLURALIZATION_KEYS = %w(zero one two few many other).freeze
|
|
10
7
|
|
|
11
8
|
attr_accessor :locale, :data
|
|
12
9
|
|
|
13
10
|
def initialize(locale, file_content)
|
|
14
11
|
self.locale = locale.to_s
|
|
15
|
-
self.data =
|
|
12
|
+
self.data = YAMLToEnrichedRubyHash.parse(file_content)
|
|
16
13
|
end
|
|
17
14
|
|
|
18
15
|
def compare_to(base)
|
|
@@ -26,17 +23,6 @@ module WcaI18n
|
|
|
26
23
|
original_str = Digest::SHA1.hexdigest(to_digest)[0..6]
|
|
27
24
|
end
|
|
28
25
|
|
|
29
|
-
private def commented_yaml_to_translated_yaml(commented_value)
|
|
30
|
-
if leaf?(commented_value.value)
|
|
31
|
-
original_hash = extract_original_hash_from_comment(commented_value.comment)
|
|
32
|
-
return TranslatedLeaf.new(commented_value.strip_comments, original_hash)
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
commented_value.value.map do |key, value|
|
|
36
|
-
[key, commented_yaml_to_translated_yaml(value)]
|
|
37
|
-
end.to_h
|
|
38
|
-
end
|
|
39
|
-
|
|
40
26
|
private def diff_recursive(base, translation, context)
|
|
41
27
|
diff = { missing: [], unused: [], outdated: [] }
|
|
42
28
|
base_leaf = base.is_a?(TranslatedLeaf)
|
|
@@ -91,11 +77,6 @@ module WcaI18n
|
|
|
91
77
|
end
|
|
92
78
|
end
|
|
93
79
|
|
|
94
|
-
private def leaf?(node)
|
|
95
|
-
# If the node is a pluralization it's also a leaf!
|
|
96
|
-
node.nil? || node.is_a?(String) || self.class.pluralization?(node)
|
|
97
|
-
end
|
|
98
|
-
|
|
99
80
|
def self.pluralization?(node)
|
|
100
81
|
node.is_a?(Hash) && (node.keys & PLURALIZATION_KEYS).any?
|
|
101
82
|
end
|
data/lib/wca_i18n/version.rb
CHANGED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
require "psych"
|
|
2
|
+
|
|
3
|
+
module WcaI18n
|
|
4
|
+
PLURALIZATION_KEYS = %w(zero one two few many other).freeze
|
|
5
|
+
ORIGINAL_HASH_TAG = "#original_hash: ".freeze
|
|
6
|
+
TranslatedLeaf = Struct.new(:translated, :original_hash)
|
|
7
|
+
|
|
8
|
+
# Re-implement some parts of the ToRuby emitter to inject our TranslatedLeaf where needs be
|
|
9
|
+
class YAMLToEnrichedRubyHash < Psych::Visitors::ToRuby
|
|
10
|
+
def self.create(original_hashes_map)
|
|
11
|
+
class_loader = Psych::ClassLoader.new
|
|
12
|
+
scanner = Psych::ScalarScanner.new class_loader
|
|
13
|
+
new(scanner, class_loader, original_hashes_map)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def self.parse(text)
|
|
17
|
+
tree = Psych.parser.parse(text)
|
|
18
|
+
emitter = self.create(text)
|
|
19
|
+
# Not sure why, but "accept" returns an array with one element.
|
|
20
|
+
# Probably because the root of the YAML is a sequence by default?
|
|
21
|
+
emitter.accept(tree.handler.root).first
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def initialize(*args, text)
|
|
25
|
+
super(*args)
|
|
26
|
+
_build_original_hashes_by_line_from_text(text)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def pluralization_map?(v)
|
|
30
|
+
return false unless v.is_a?(Psych::Nodes::Mapping)
|
|
31
|
+
v.children.each_slice(2) do |k,v|
|
|
32
|
+
return true if WcaI18n::PLURALIZATION_KEYS.include?(accept(k))
|
|
33
|
+
end
|
|
34
|
+
return false
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Copy from the revive_hash method in https://github.com/ruby/psych/blob/e9e4567adefc52e6511df7060851bce9fe408082/lib/psych/visitors/to_ruby.rb
|
|
38
|
+
# Except we override the generic case with our code.
|
|
39
|
+
def revive_hash hash, o
|
|
40
|
+
o.children.each_slice(2) { |k,v|
|
|
41
|
+
key = accept(k)
|
|
42
|
+
val = accept(v)
|
|
43
|
+
|
|
44
|
+
if key == SHOVEL && k.tag != "tag:yaml.org,2002:str"
|
|
45
|
+
case v
|
|
46
|
+
when Nodes::Alias, Nodes::Mapping
|
|
47
|
+
begin
|
|
48
|
+
hash.merge! val
|
|
49
|
+
rescue TypeError
|
|
50
|
+
hash[key] = val
|
|
51
|
+
end
|
|
52
|
+
when Nodes::Sequence
|
|
53
|
+
begin
|
|
54
|
+
h = {}
|
|
55
|
+
val.reverse_each do |value|
|
|
56
|
+
h.merge! value
|
|
57
|
+
end
|
|
58
|
+
hash.merge! h
|
|
59
|
+
rescue TypeError
|
|
60
|
+
hash[key] = val
|
|
61
|
+
end
|
|
62
|
+
else
|
|
63
|
+
hash[key] = val
|
|
64
|
+
end
|
|
65
|
+
else
|
|
66
|
+
# This is where we handle the translated key
|
|
67
|
+
if v.is_a?(Psych::Nodes::Scalar) && !WcaI18n::PLURALIZATION_KEYS.include?(key)
|
|
68
|
+
# For scalar value, the start line registered is the correct line
|
|
69
|
+
# We assume that the '#original_hash: ' comment comes on the line before.
|
|
70
|
+
original_hash = @original_hashes_by_line.delete(v.start_line - 1)
|
|
71
|
+
val = WcaI18n::TranslatedLeaf.new(val, original_hash)
|
|
72
|
+
end
|
|
73
|
+
if pluralization_map?(v)
|
|
74
|
+
# For mappings, the start line registered is the line of the first key/value!
|
|
75
|
+
original_hash = @original_hashes_by_line.delete(v.start_line - 2)
|
|
76
|
+
val = WcaI18n::TranslatedLeaf.new(val, original_hash)
|
|
77
|
+
end
|
|
78
|
+
hash[key] = val
|
|
79
|
+
end
|
|
80
|
+
}
|
|
81
|
+
hash
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def _build_original_hashes_by_line_from_text(text)
|
|
85
|
+
@original_hashes_by_line = {}.tap do |hash|
|
|
86
|
+
# Build a hash mapping a line number to its comment
|
|
87
|
+
text.each_line.with_index do |line, index|
|
|
88
|
+
stripped_line = line.strip
|
|
89
|
+
if stripped_line.start_with?(ORIGINAL_HASH_TAG)
|
|
90
|
+
hash[index] = stripped_line[ORIGINAL_HASH_TAG.length..-1]
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
data/wca_i18n.gemspec
CHANGED
|
@@ -6,7 +6,7 @@ require "wca_i18n/version"
|
|
|
6
6
|
Gem::Specification.new do |spec|
|
|
7
7
|
spec.name = "wca_i18n"
|
|
8
8
|
spec.version = WcaI18n::VERSION
|
|
9
|
-
spec.authors = ["
|
|
9
|
+
spec.authors = ["WCA Software Team"]
|
|
10
10
|
spec.email = ["software@worldcubeassociation.org"]
|
|
11
11
|
|
|
12
12
|
spec.summary = %q{Track how up to date Rails translations are.}
|
|
@@ -26,5 +26,5 @@ Gem::Specification.new do |spec|
|
|
|
26
26
|
spec.add_development_dependency "byebug", "~> 9.0"
|
|
27
27
|
spec.add_runtime_dependency "colorize", "~> 0.8"
|
|
28
28
|
|
|
29
|
-
spec.required_ruby_version = '>= 2.
|
|
29
|
+
spec.required_ruby_version = '>= 2.5'
|
|
30
30
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: wca_i18n
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.4.
|
|
4
|
+
version: 0.4.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
|
-
-
|
|
7
|
+
- WCA Software Team
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2018-
|
|
11
|
+
date: 2018-09-02 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|
|
@@ -104,7 +104,7 @@ files:
|
|
|
104
104
|
- lib/wca_i18n.rb
|
|
105
105
|
- lib/wca_i18n/translation.rb
|
|
106
106
|
- lib/wca_i18n/version.rb
|
|
107
|
-
- lib/wca_i18n/
|
|
107
|
+
- lib/wca_i18n/yaml_to_enriched_ruby_hash.rb
|
|
108
108
|
- wca_i18n.gemspec
|
|
109
109
|
homepage: https://github.com/thewca/wca_i18n
|
|
110
110
|
licenses:
|
|
@@ -118,7 +118,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
118
118
|
requirements:
|
|
119
119
|
- - ">="
|
|
120
120
|
- !ruby/object:Gem::Version
|
|
121
|
-
version: '2.
|
|
121
|
+
version: '2.5'
|
|
122
122
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
123
123
|
requirements:
|
|
124
124
|
- - ">="
|
|
@@ -126,7 +126,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
126
126
|
version: '0'
|
|
127
127
|
requirements: []
|
|
128
128
|
rubyforge_project:
|
|
129
|
-
rubygems_version: 2.
|
|
129
|
+
rubygems_version: 2.7.7
|
|
130
130
|
signing_key:
|
|
131
131
|
specification_version: 4
|
|
132
132
|
summary: Track how up to date Rails translations are.
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
require "yaml"
|
|
2
|
-
|
|
3
|
-
module WcaI18n
|
|
4
|
-
class YAMLWithComments < Struct.new(:comment, :value)
|
|
5
|
-
def self.parse(text)
|
|
6
|
-
_decorate_with_comments(YAML.safe_load(text), [], text)[1]
|
|
7
|
-
end
|
|
8
|
-
|
|
9
|
-
def strip_comments
|
|
10
|
-
stripped_value = self.value
|
|
11
|
-
|
|
12
|
-
if stripped_value.kind_of?(Hash)
|
|
13
|
-
stripped_value = stripped_value.map do |key, value|
|
|
14
|
-
[key, value.strip_comments]
|
|
15
|
-
end.to_h
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
stripped_value
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def self._decorate_with_comments(node, context, text)
|
|
22
|
-
if node.kind_of?(Hash)
|
|
23
|
-
node = node.map do |key, value|
|
|
24
|
-
text, decorated = _decorate_with_comments(value, [*context, key], text)
|
|
25
|
-
[key, decorated]
|
|
26
|
-
end.to_h
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
trimmed_text, comment = _extract_comment(text, context)
|
|
30
|
-
[trimmed_text, YAMLWithComments.new(comment, node)]
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
def self._extract_comment(text, context)
|
|
34
|
-
return ["", ""] if context.empty?
|
|
35
|
-
|
|
36
|
-
# Match any character, including newline.
|
|
37
|
-
some_chars = /[\s\S]*?/
|
|
38
|
-
|
|
39
|
-
comment_lines_group = /((?:^\s*#.*\n)*)/
|
|
40
|
-
|
|
41
|
-
match_parent = ""
|
|
42
|
-
context[0...-1].each do |key|
|
|
43
|
-
match_parent = "#{match_parent}#{some_chars}#{build_key_matcher(key)}"
|
|
44
|
-
end
|
|
45
|
-
regexp = /(#{match_parent}#{some_chars})#{comment_lines_group}\s*#{build_key_matcher(context[-1])}/
|
|
46
|
-
|
|
47
|
-
comment = nil
|
|
48
|
-
text = text.sub(regexp) do
|
|
49
|
-
# Group 1 is everything before the comment and the key.
|
|
50
|
-
before = $1
|
|
51
|
-
# Group 2 contains the comments matched before the key.
|
|
52
|
-
comments = $2
|
|
53
|
-
comment = comments.split('#').map(&:strip).reject(&:empty?).join("\n")
|
|
54
|
-
|
|
55
|
-
# We return the beginning without the key, so that the current hash + key
|
|
56
|
-
# are removed from the text, but the parents and the value stay in.
|
|
57
|
-
before
|
|
58
|
-
end
|
|
59
|
-
throw "Could not find key: #{context} in given yaml text" unless comment
|
|
60
|
-
|
|
61
|
-
[text, comment]
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
def self.build_key_matcher(key)
|
|
65
|
-
/['\"]?#{key}['\"]?:/
|
|
66
|
-
end
|
|
67
|
-
end
|
|
68
|
-
end
|