phraseapp_updater 0.1.4 → 0.1.5
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 +4 -4
- data/README.markdown +7 -5
- data/bin/phraseapp_updater +19 -8
- data/lib/phraseapp_updater.rb +8 -6
- data/lib/phraseapp_updater/locale_file.rb +20 -13
- data/lib/phraseapp_updater/locale_file/json_file.rb +29 -0
- data/lib/phraseapp_updater/locale_file/loader.rb +24 -0
- data/lib/phraseapp_updater/locale_file/yaml_file.rb +20 -0
- data/lib/phraseapp_updater/phraseapp_api.rb +5 -4
- data/lib/phraseapp_updater/version.rb +1 -1
- data/lib/phraseapp_updater/yml_config_loader.rb +28 -3
- metadata +6 -4
- data/lib/phraseapp_updater/locale_file_loader.rb +0 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a0c061126d02d4f01d387770c2c9340336be6e5f
|
4
|
+
data.tar.gz: 31e72d551e6852fa680e477c2e0a9ba185bd5160
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6b64d248d78459245df8f5f17121b85268f11cf35273addb88d8d8f876e3d24325644d6ba7696f112bca6003aefc5c8e3ac752c3a4a64e6959246bfe89d93203
|
7
|
+
data.tar.gz: 4ada8a07261f8e5966a6a72ed5f8223bf18999704fccfaa1f1f7c6dc4d98506b8195ed8a179b1287aef6fe88e4031ba431bffbe71e76dd5d7cc5a651a2fae848
|
data/README.markdown
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
[](https://travis-ci.org/iknow/phraseapp_updater)
|
4
4
|
|
5
|
-
**Version** 0.1.
|
5
|
+
**Version** 0.1.5
|
6
6
|
|
7
7
|
This is a tool for merging PhraseApp locale data with locale data
|
8
8
|
committed in your project.
|
@@ -89,7 +89,7 @@ committed to your application's respository. These will be used in the
|
|
89
89
|
merge with the files on PhraseApp.
|
90
90
|
|
91
91
|
```
|
92
|
-
phraseapp_updater push --new_locales_path="/data/previous", --previous_locales_path="/data/new" --phraseapp_api_key="yourkey" --phraseapp_project_id="projectid"
|
92
|
+
phraseapp_updater push --new_locales_path="/data/previous", --previous_locales_path="/data/new" --phraseapp_api_key="yourkey" --phraseapp_project_id="projectid --file_format=json"
|
93
93
|
```
|
94
94
|
|
95
95
|
The arguments provided to the command can also be specified as shell
|
@@ -100,6 +100,7 @@ PA_NEW_LOCALES_PATH
|
|
100
100
|
PA_PREVIOUS_LOCALES_PATH
|
101
101
|
PA_API_KEY
|
102
102
|
PA_PROJECT_ID
|
103
|
+
PA_FILE_FORMAT
|
103
104
|
```
|
104
105
|
|
105
106
|
Additionally, PhraseApp credentials can be loaded from a
|
@@ -118,7 +119,7 @@ If you want to pull without this fallback behavior, PhraseApp's [client](https:/
|
|
118
119
|
is the best tool to use.
|
119
120
|
|
120
121
|
```
|
121
|
-
phraseapp_updater pull --fallback_path="/data/app/locales" --phraseapp_api_key="yourkey" --phraseapp_project_id="projectid"
|
122
|
+
phraseapp_updater pull --fallback_path="/data/app/locales" --phraseapp_api_key="yourkey" --phraseapp_project_id="projectid --file_format=json""
|
122
123
|
```
|
123
124
|
|
124
125
|
The PhraseApp data passed to the command can also be specified as shell
|
@@ -127,6 +128,7 @@ variables:
|
|
127
128
|
```
|
128
129
|
PA_API_KEY
|
129
130
|
PA_PROJECT_ID
|
131
|
+
PA_FILE_FORMAT
|
130
132
|
```
|
131
133
|
|
132
134
|
Additionally, PhraseApp credentials can be loaded from a
|
@@ -138,8 +140,8 @@ Ruby
|
|
138
140
|
`PhraseAppUpdater.push` and `PhraseAppUpdater.pull` are analogous to the command line versions:
|
139
141
|
|
140
142
|
```ruby
|
141
|
-
PhraseAppUpdater.
|
142
|
-
PhraseAppUpdater.
|
143
|
+
PhraseAppUpdater.new("api_key", "project_id", "file_format").push("previous/path", "current/path")
|
144
|
+
PhraseAppUpdater.new("api_key", "project_id", "file_format").pull("fallback/path")
|
143
145
|
```
|
144
146
|
|
145
147
|
|
data/bin/phraseapp_updater
CHANGED
@@ -11,9 +11,10 @@ class PhraseAppUpdaterCLI < Thor
|
|
11
11
|
option :config_file_path, type: :string, desc: "Path to .phraseapp.yml config file to read API key and project ID."
|
12
12
|
option :store_results_path, type: :string, desc: "Path to write the resolved files. Shell variable: PA_STORE_RESULTS_PATH"
|
13
13
|
option :store_phraseapp_originals_path, type: :string, desc: "Path to write the files downloaded from PhraseApp before the merge. Shell variable: PA_STORE_PHRASEAPP_ORIGINALS_PATH"
|
14
|
+
option :file_format, type: :string, desc: "Filetype of localization files."
|
14
15
|
|
15
16
|
def push
|
16
|
-
phraseapp_api_key, phraseapp_project_id =
|
17
|
+
phraseapp_api_key, phraseapp_project_id, file_format = load_phraseapp_configuration(options)
|
17
18
|
|
18
19
|
new_locales_path = options.fetch(:new_locales_path, ENV["PA_NEW_LOCALES_PATH"]).to_s
|
19
20
|
validate_readable_path!('new_locales_path', new_locales_path)
|
@@ -28,7 +29,7 @@ class PhraseAppUpdaterCLI < Thor
|
|
28
29
|
validate_writable_path!('store_phraseapp_originals_path', store_phraseapp_originals_path)
|
29
30
|
|
30
31
|
begin
|
31
|
-
result = PhraseAppUpdater.new(phraseapp_api_key, phraseapp_project_id).push(previous_locales_path, new_locales_path)
|
32
|
+
result = PhraseAppUpdater.new(phraseapp_api_key, phraseapp_project_id, file_format).push(previous_locales_path, new_locales_path)
|
32
33
|
|
33
34
|
unless store_results_path.empty?
|
34
35
|
write_locale_files(store_results_path, result.resolved_files)
|
@@ -41,8 +42,10 @@ class PhraseAppUpdaterCLI < Thor
|
|
41
42
|
puts "Bad PhraseApp API key."
|
42
43
|
rescue PhraseAppUpdater::PhraseAppAPI::BadProjectIDError => e
|
43
44
|
puts "Bad PhraseApp project ID: #{phraseapp_project_id}"
|
45
|
+
rescue PhraseAppUpdater::LocaleFile::BadFileTypeError => e
|
46
|
+
puts "Bad filetype for localization files: #{e.message}"
|
44
47
|
rescue StandardError => e
|
45
|
-
puts "Unknown error when pushing files"
|
48
|
+
puts "Unknown error when pushing files."
|
46
49
|
raise e
|
47
50
|
end
|
48
51
|
end
|
@@ -56,7 +59,7 @@ class PhraseAppUpdaterCLI < Thor
|
|
56
59
|
option :config_file_path, type: :string, desc: "Path to .phraseapp.yml config file to read API key and project ID."
|
57
60
|
|
58
61
|
def pull
|
59
|
-
phraseapp_api_key, phraseapp_project_id =
|
62
|
+
phraseapp_api_key, phraseapp_project_id, file_format = load_phraseapp_configuration(options)
|
60
63
|
|
61
64
|
fallback_path = options[:fallback_path]
|
62
65
|
validate_readable_path!('fallback_path', fallback_path)
|
@@ -65,12 +68,14 @@ class PhraseAppUpdaterCLI < Thor
|
|
65
68
|
validate_writable_path!('destination_path', destination_path)
|
66
69
|
|
67
70
|
begin
|
68
|
-
files = PhraseAppUpdater.new(phraseapp_api_key, phraseapp_project_id).pull(fallback_path)
|
71
|
+
files = PhraseAppUpdater.new(phraseapp_api_key, phraseapp_project_id, file_format).pull(fallback_path)
|
69
72
|
write_locale_files(destination_path, files)
|
70
73
|
rescue PhraseAppUpdater::PhraseAppAPI::BadAPIKeyError => e
|
71
74
|
puts "Bad PhraseApp API key."
|
72
75
|
rescue PhraseAppUpdater::PhraseAppAPI::BadProjectIDError => e
|
73
76
|
puts "Bad PhraseApp project ID: #{phraseapp_project_id}"
|
77
|
+
rescue PhraseAppUpdater::LocaleFile::BadFileTypeError => e
|
78
|
+
puts "Bad filetype for localization files: #{e.message}"
|
74
79
|
rescue StandardError => e
|
75
80
|
puts "Unknown error when pulling files"
|
76
81
|
raise e
|
@@ -92,10 +97,10 @@ class PhraseAppUpdaterCLI < Thor
|
|
92
97
|
|
93
98
|
private
|
94
99
|
|
95
|
-
def
|
100
|
+
def load_phraseapp_configuration(options)
|
96
101
|
if options[:config_file_path]
|
97
102
|
|
98
|
-
if
|
103
|
+
if [:phraseapp_api_key, :phraseapp_project_id, :file_format].any? { |option| options.has_key?(:option) }
|
99
104
|
raise RuntimeError.new("Provided both a path to PhraseApp config file and command line arguments. Specify only one. #{options}")
|
100
105
|
end
|
101
106
|
|
@@ -103,9 +108,11 @@ class PhraseAppUpdaterCLI < Thor
|
|
103
108
|
|
104
109
|
phraseapp_api_key = config.api_key
|
105
110
|
phraseapp_project_id = config.project_id
|
111
|
+
file_format = config.file_format
|
106
112
|
else
|
107
113
|
phraseapp_api_key = options.fetch(:phraseapp_api_key, ENV["PA_API_KEY"]).to_s
|
108
114
|
phraseapp_project_id = options.fetch(:phraseapp_project_id, ENV["PA_PROJECT_ID"]).to_s
|
115
|
+
file_format = options.fetch(:file_format, ENV["PA_FILE_FORMAT"]).to_s
|
109
116
|
end
|
110
117
|
|
111
118
|
if phraseapp_api_key.empty?
|
@@ -116,7 +123,11 @@ class PhraseAppUpdaterCLI < Thor
|
|
116
123
|
raise RuntimeError.new("Must provide Phraseapp project ID. --phraseapp_project_id or PA_PROJECT_ID")
|
117
124
|
end
|
118
125
|
|
119
|
-
|
126
|
+
if file_format.empty?
|
127
|
+
raise RuntimeError.new("Must provide file format for Phraseapp project. --file_format or PA_FILE_FORMAT")
|
128
|
+
end
|
129
|
+
|
130
|
+
return [phraseapp_api_key, phraseapp_project_id, file_format]
|
120
131
|
end
|
121
132
|
|
122
133
|
def validate_path!(name, path)
|
data/lib/phraseapp_updater.rb
CHANGED
@@ -2,15 +2,16 @@ require 'phraseapp_updater/version'
|
|
2
2
|
require 'phraseapp_updater/index_by'
|
3
3
|
require 'phraseapp_updater/differ'
|
4
4
|
require 'phraseapp_updater/locale_file'
|
5
|
-
require 'phraseapp_updater/
|
5
|
+
require 'phraseapp_updater/locale_file/loader'
|
6
6
|
require 'phraseapp_updater/phraseapp_api'
|
7
7
|
require 'phraseapp_updater/yml_config_loader'
|
8
8
|
|
9
9
|
class PhraseAppUpdater
|
10
10
|
using IndexBy
|
11
11
|
|
12
|
-
def initialize(phraseapp_api_key, phraseapp_project_id)
|
13
|
-
@
|
12
|
+
def initialize(phraseapp_api_key, phraseapp_project_id, file_format)
|
13
|
+
@locale_file_class = LocaleFile.class_for_file_format(file_format)
|
14
|
+
@phraseapp_api = PhraseAppAPI.new(phraseapp_api_key, phraseapp_project_id, @locale_file_class)
|
14
15
|
end
|
15
16
|
|
16
17
|
def self.load_config(config_file_path)
|
@@ -38,7 +39,7 @@ class PhraseAppUpdater
|
|
38
39
|
primary: new_locale_file.parsed_content,
|
39
40
|
secondary: phraseapp_file.parsed_content)
|
40
41
|
|
41
|
-
|
42
|
+
@locale_file_class.from_hash(previous_locale_file.name, resolved_content)
|
42
43
|
end
|
43
44
|
|
44
45
|
# Upload all of the secondary languages first,
|
@@ -88,7 +89,7 @@ class PhraseAppUpdater
|
|
88
89
|
fallback = clear_empty_strings!(fallback_files[phraseapp_without_unverified_file.name].parsed_content)
|
89
90
|
|
90
91
|
restore_unverified_originals!(fallback, with_unverified, without_unverified)
|
91
|
-
|
92
|
+
@locale_file_class.from_hash(phraseapp_without_unverified_file.name, without_unverified)
|
92
93
|
end
|
93
94
|
end
|
94
95
|
|
@@ -107,8 +108,9 @@ class PhraseAppUpdater
|
|
107
108
|
end
|
108
109
|
|
109
110
|
def load_locale_files(*paths)
|
111
|
+
loader = LocaleFile::Loader.new(@locale_file_class::EXTENSION)
|
110
112
|
paths.map do |path|
|
111
|
-
|
113
|
+
loader.filenames(path).map { |l| loader.load(l) }
|
112
114
|
end
|
113
115
|
end
|
114
116
|
|
@@ -1,18 +1,28 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
|
4
|
-
# We're working with pure JSON, not
|
5
|
-
# serialized Ruby objects
|
6
|
-
Oj.default_options = {mode: :strict}
|
1
|
+
require "phraseapp_updater/locale_file/json_file"
|
2
|
+
require "phraseapp_updater/locale_file/yaml_file"
|
7
3
|
|
8
4
|
class PhraseAppUpdater
|
9
5
|
class LocaleFile
|
10
6
|
attr_reader :name, :content, :parsed_content
|
11
7
|
|
8
|
+
class BadFileTypeError < StandardError ; end
|
9
|
+
|
12
10
|
def self.from_hash(name, hash)
|
13
|
-
new(
|
11
|
+
raise RuntimeError.new("Must be implemented in a subclass.")
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.class_for_file_format(type)
|
15
|
+
case type.downcase
|
16
|
+
when "json"
|
17
|
+
JSONFile
|
18
|
+
when "yml", "yaml"
|
19
|
+
YAMLFile
|
20
|
+
else
|
21
|
+
raise BadFileTypeError.new("Invalid file type: #{type}")
|
22
|
+
end
|
14
23
|
end
|
15
24
|
|
25
|
+
# Expects a Ruby hash
|
16
26
|
def initialize(name, content)
|
17
27
|
@name = name
|
18
28
|
@content = content
|
@@ -25,20 +35,17 @@ class PhraseAppUpdater
|
|
25
35
|
end
|
26
36
|
|
27
37
|
def name_with_extension
|
28
|
-
"#{name}.
|
38
|
+
"#{name}.#{self.class::EXTENSION}"
|
29
39
|
end
|
30
40
|
|
31
41
|
private
|
32
42
|
|
33
43
|
def parse(content)
|
34
|
-
|
35
|
-
rescue MultiJson::ParseError => e
|
36
|
-
raise ArgumentError.new("Provided content was not valid JSON")
|
44
|
+
raise RuntimeError.new("Must be implemented in a subclass.")
|
37
45
|
end
|
38
46
|
|
39
47
|
def format_content!
|
40
|
-
|
41
|
-
@content = MultiJson.dump(MultiJson.load(@content), pretty: true)
|
48
|
+
raise RuntimeError.new("Must be implemented in a subclass.")
|
42
49
|
end
|
43
50
|
end
|
44
51
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'multi_json'
|
2
|
+
require 'oj'
|
3
|
+
|
4
|
+
# We're working with pure JSON, not
|
5
|
+
# serialized Ruby objects
|
6
|
+
Oj.default_options = {mode: :strict}
|
7
|
+
|
8
|
+
class PhraseAppUpdater
|
9
|
+
class LocaleFile
|
10
|
+
class JSONFile < LocaleFile
|
11
|
+
EXTENSION = "json"
|
12
|
+
def self.from_hash(name, hash)
|
13
|
+
new(name, MultiJson.dump(hash))
|
14
|
+
end
|
15
|
+
|
16
|
+
def parse(content)
|
17
|
+
MultiJson.load(content)
|
18
|
+
rescue MultiJson::ParseError => e
|
19
|
+
raise ArgumentError.new("Provided content was not valid JSON: #{e}")
|
20
|
+
end
|
21
|
+
|
22
|
+
def format_content!
|
23
|
+
# Add indentation for better diffs
|
24
|
+
@content = MultiJson.dump(MultiJson.load(@content), pretty: true)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'phraseapp_updater/locale_file'
|
2
|
+
|
3
|
+
class PhraseAppUpdater
|
4
|
+
class LocaleFile
|
5
|
+
class Loader
|
6
|
+
def initialize(extension)
|
7
|
+
@extension = extension
|
8
|
+
end
|
9
|
+
|
10
|
+
def load(filename)
|
11
|
+
unless File.readable?(filename) && File.file?(filename)
|
12
|
+
raise RuntimeError.new("Couldn't read localization file at #{filename}")
|
13
|
+
end
|
14
|
+
|
15
|
+
LocaleFile.class_for_file_format(@extension).new(File.basename(filename).chomp(".#{@extension}"), File.read(filename))
|
16
|
+
end
|
17
|
+
|
18
|
+
def filenames(locale_directory)
|
19
|
+
Dir["#{locale_directory}/*.#{@extension}"]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'psych'
|
2
|
+
class PhraseAppUpdater
|
3
|
+
class LocaleFile
|
4
|
+
class YAMLFile < LocaleFile
|
5
|
+
EXTENSION = "yml"
|
6
|
+
def self.from_hash(name, hash)
|
7
|
+
new(name, Psych.dump(hash))
|
8
|
+
end
|
9
|
+
|
10
|
+
def parse(content)
|
11
|
+
Psych.load(content)
|
12
|
+
rescue Psych::SyntaxError => e
|
13
|
+
raise ArgumentError.new("Provided content was not valid YAML")
|
14
|
+
end
|
15
|
+
|
16
|
+
def format_content!
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -4,9 +4,10 @@ require 'thread'
|
|
4
4
|
|
5
5
|
class PhraseAppUpdater
|
6
6
|
class PhraseAppAPI
|
7
|
-
def initialize(api_key, project_id)
|
8
|
-
@client
|
9
|
-
@project_id
|
7
|
+
def initialize(api_key, project_id, locale_file_class)
|
8
|
+
@client = PhraseApp::Client.new(PhraseApp::Auth::Credentials.new(token: api_key))
|
9
|
+
@project_id = project_id
|
10
|
+
@locale_file_class = locale_file_class
|
10
11
|
end
|
11
12
|
|
12
13
|
def download_locales
|
@@ -23,7 +24,7 @@ class PhraseAppUpdater
|
|
23
24
|
puts "Downloading file for #{locale}"
|
24
25
|
download_file(locale, skip_unverified)
|
25
26
|
end.map do |locale, file_contents|
|
26
|
-
|
27
|
+
@locale_file_class.new(locale.name, file_contents)
|
27
28
|
end
|
28
29
|
end
|
29
30
|
|
@@ -2,7 +2,7 @@ require 'yaml'
|
|
2
2
|
|
3
3
|
class PhraseAppUpdater
|
4
4
|
class YMLConfigLoader
|
5
|
-
attr_reader :api_key, :project_id
|
5
|
+
attr_reader :api_key, :project_id, :file_format
|
6
6
|
def initialize(file_path)
|
7
7
|
unless File.readable?(file_path)
|
8
8
|
raise RuntimeError.new("Can't read config file at #{file_path}")
|
@@ -14,8 +14,33 @@ class PhraseAppUpdater
|
|
14
14
|
raise RuntimeError.new("Couldn't parse file contents: #{File.read(file_path)}")
|
15
15
|
end
|
16
16
|
|
17
|
-
|
18
|
-
|
17
|
+
config = parsed_yaml.fetch("phraseapp")
|
18
|
+
|
19
|
+
@api_key = config.fetch("access_token")
|
20
|
+
@project_id = config.fetch("project_id")
|
21
|
+
|
22
|
+
push_file_format = config.fetch("push").fetch("sources").first.fetch("params").fetch("file_format")
|
23
|
+
pull_file_format = config.fetch("pull").fetch("targets").first.fetch("params").fetch("file_format")
|
24
|
+
|
25
|
+
unless push_file_format == pull_file_format
|
26
|
+
raise ArgumentError.new("Push and pull must be the same format")
|
27
|
+
end
|
28
|
+
|
29
|
+
@file_format = convert(push_file_format)
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def convert(phraseapp_file_format)
|
36
|
+
case phraseapp_file_format
|
37
|
+
when "nested_json"
|
38
|
+
"json"
|
39
|
+
when "yml"
|
40
|
+
"yml"
|
41
|
+
else
|
42
|
+
raise ArugmentError.new("Unsupported type: #{phraseapp_file_format}")
|
43
|
+
end
|
19
44
|
end
|
20
45
|
end
|
21
46
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: phraseapp_updater
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kevin Griffin
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-02
|
11
|
+
date: 2017-08-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
@@ -174,7 +174,9 @@ files:
|
|
174
174
|
- lib/phraseapp_updater/differ.rb
|
175
175
|
- lib/phraseapp_updater/index_by.rb
|
176
176
|
- lib/phraseapp_updater/locale_file.rb
|
177
|
-
- lib/phraseapp_updater/
|
177
|
+
- lib/phraseapp_updater/locale_file/json_file.rb
|
178
|
+
- lib/phraseapp_updater/locale_file/loader.rb
|
179
|
+
- lib/phraseapp_updater/locale_file/yaml_file.rb
|
178
180
|
- lib/phraseapp_updater/phraseapp_api.rb
|
179
181
|
- lib/phraseapp_updater/version.rb
|
180
182
|
- lib/phraseapp_updater/yml_config_loader.rb
|
@@ -199,7 +201,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
199
201
|
version: '0'
|
200
202
|
requirements: []
|
201
203
|
rubyforge_project:
|
202
|
-
rubygems_version: 2.
|
204
|
+
rubygems_version: 2.6.11
|
203
205
|
signing_key:
|
204
206
|
specification_version: 4
|
205
207
|
summary: A three-way differ for PhraseApp projects.
|
@@ -1,18 +0,0 @@
|
|
1
|
-
require 'phraseapp_updater/locale_file'
|
2
|
-
|
3
|
-
class PhraseAppUpdater
|
4
|
-
class LocaleFileLoader
|
5
|
-
def self.load(filename)
|
6
|
-
unless File.readable?(filename) && File.file?(filename)
|
7
|
-
raise RuntimeError.new("Couldn't read localization file at #{filename}")
|
8
|
-
end
|
9
|
-
|
10
|
-
LocaleFile.new(File.basename(filename).chomp(".json"), File.read(filename))
|
11
|
-
end
|
12
|
-
|
13
|
-
def self.filenames(locale_directory)
|
14
|
-
Dir["#{locale_directory}/*.json"]
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|