txgh 6.0.0.beta1 → 6.0.0
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/lib/txgh/config/config_pair.rb +1 -1
- data/lib/txgh/config/providers/git_provider.rb +1 -1
- data/lib/txgh/github_api.rb +32 -54
- data/lib/txgh/github_status.rb +1 -1
- data/lib/txgh/pusher.rb +1 -1
- data/lib/txgh/resource_committer.rb +2 -2
- data/lib/txgh/resource_contents.rb +11 -2
- data/lib/txgh/resource_downloader.rb +1 -1
- data/lib/txgh/resource_updater.rb +15 -37
- data/lib/txgh/tx_branch_resource.rb +6 -3
- data/lib/txgh/tx_resource.rb +4 -4
- data/lib/txgh/version.rb +1 -1
- data/spec/config/tx_manager_spec.rb +2 -2
- data/spec/diff_calculator_spec.rb +56 -0
- data/spec/github_api_spec.rb +45 -97
- data/spec/github_status_spec.rb +2 -3
- data/spec/merge_calculator_spec.rb +46 -0
- data/spec/resource_committer_spec.rb +1 -1
- data/spec/resource_contents_spec.rb +30 -11
- data/spec/resource_downloader_spec.rb +2 -2
- data/spec/resource_updater_spec.rb +14 -30
- data/spec/tx_resource_spec.rb +0 -6
- data/txgh.gemspec +1 -1
- metadata +7 -9
- data/README.md +0 -334
- data/lib/ext/zipline/output_stream.rb +0 -62
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: cee1db178f1ad7cdc40a20d13eb5e7f22aa8da3e
|
|
4
|
+
data.tar.gz: ad1b43ad46d06e5c2bfadb35e19e64153ce17ced
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 76946e935626508ed67deddaa9aae76947c43eac2a776b077f848ed2e5945e52832832c8d6305f1219b171392ac71bdd1b89027a6267274fb022e3819ab41d8f
|
|
7
|
+
data.tar.gz: 4a6b2dc8948e3c03a051631f47524ee00c77c070f538cee59cd5d56516cf3b5ff19ee0803b21e538f0d0b593dc0d3884d87de69d906b12dde071c14f4baff5ed
|
|
@@ -34,7 +34,7 @@ module Txgh
|
|
|
34
34
|
private
|
|
35
35
|
|
|
36
36
|
def download
|
|
37
|
-
github_repo.api.download(
|
|
37
|
+
github_repo.api.download(payload, ref)[:content]
|
|
38
38
|
rescue Octokit::NotFound
|
|
39
39
|
raise Txgh::GitConfigNotFoundError, "Config file #{payload} not found in #{ref}"
|
|
40
40
|
end
|
data/lib/txgh/github_api.rb
CHANGED
|
@@ -4,41 +4,42 @@ require 'octokit'
|
|
|
4
4
|
module Txgh
|
|
5
5
|
class GithubApi
|
|
6
6
|
class << self
|
|
7
|
-
def create_from_credentials(login, access_token)
|
|
7
|
+
def create_from_credentials(login, access_token, repo_name)
|
|
8
8
|
create_from_client(
|
|
9
|
-
Octokit::Client.new(login: login, access_token: access_token)
|
|
9
|
+
Octokit::Client.new(login: login, access_token: access_token), repo_name
|
|
10
10
|
)
|
|
11
11
|
end
|
|
12
12
|
|
|
13
|
-
def create_from_client(client)
|
|
14
|
-
new(client)
|
|
13
|
+
def create_from_client(client, repo_name)
|
|
14
|
+
new(client, repo_name)
|
|
15
15
|
end
|
|
16
16
|
end
|
|
17
17
|
|
|
18
|
-
attr_reader :client
|
|
18
|
+
attr_reader :client, :repo_name
|
|
19
19
|
|
|
20
|
-
def initialize(client)
|
|
20
|
+
def initialize(client, repo_name)
|
|
21
21
|
@client = client
|
|
22
|
+
@repo_name = repo_name
|
|
22
23
|
end
|
|
23
24
|
|
|
24
|
-
def tree(
|
|
25
|
-
client.tree(
|
|
25
|
+
def tree(sha)
|
|
26
|
+
client.tree(repo_name, sha, recursive: 1)
|
|
26
27
|
end
|
|
27
28
|
|
|
28
|
-
def blob(
|
|
29
|
-
client.blob(
|
|
29
|
+
def blob(sha)
|
|
30
|
+
client.blob(repo_name, sha)
|
|
30
31
|
end
|
|
31
32
|
|
|
32
|
-
def create_ref(
|
|
33
|
-
client.create_ref(
|
|
33
|
+
def create_ref(branch, sha)
|
|
34
|
+
client.create_ref(repo_name, branch, sha) rescue false
|
|
34
35
|
end
|
|
35
36
|
|
|
36
|
-
def update_contents(
|
|
37
|
+
def update_contents(branch, content_map, message)
|
|
37
38
|
content_map.each do |path, new_contents|
|
|
38
39
|
branch = Utils.relative_branch(branch)
|
|
39
40
|
|
|
40
41
|
file = begin
|
|
41
|
-
client.contents(
|
|
42
|
+
client.contents(repo_name, { path: path, ref: branch })
|
|
42
43
|
rescue Octokit::NotFound
|
|
43
44
|
nil
|
|
44
45
|
end
|
|
@@ -49,59 +50,36 @@ module Txgh
|
|
|
49
50
|
|
|
50
51
|
if current_sha != new_sha
|
|
51
52
|
client.update_contents(
|
|
52
|
-
|
|
53
|
+
repo_name, path, message, current_sha, new_contents, options
|
|
53
54
|
)
|
|
54
55
|
end
|
|
55
56
|
end
|
|
56
57
|
end
|
|
57
58
|
|
|
58
|
-
def
|
|
59
|
-
|
|
60
|
-
base_commit = get_commit(repo, parent[:object][:sha])
|
|
61
|
-
|
|
62
|
-
tree_data = content_map.map do |path, content|
|
|
63
|
-
blob = client.create_blob(repo, content)
|
|
64
|
-
{ path: path, mode: '100644', type: 'blob', sha: blob }
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
tree_options = { base_tree: base_commit[:commit][:tree][:sha] }
|
|
68
|
-
|
|
69
|
-
tree = client.create_tree(repo, tree_data, tree_options)
|
|
70
|
-
commit = client.create_commit(
|
|
71
|
-
repo, message, tree[:sha], parent[:object][:sha]
|
|
72
|
-
)
|
|
73
|
-
|
|
74
|
-
# don't update the ref if the commit introduced no new changes
|
|
75
|
-
unless allow_empty
|
|
76
|
-
diff = client.compare(repo, parent[:object][:sha], commit[:sha])
|
|
77
|
-
return if diff[:files].empty?
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
# false means don't force push
|
|
81
|
-
client.update_ref(repo, branch, commit[:sha], false)
|
|
59
|
+
def get_commit(sha)
|
|
60
|
+
client.commit(repo_name, sha)
|
|
82
61
|
end
|
|
83
62
|
|
|
84
|
-
def
|
|
85
|
-
client.
|
|
63
|
+
def get_ref(ref)
|
|
64
|
+
client.ref(repo_name, ref)
|
|
86
65
|
end
|
|
87
66
|
|
|
88
|
-
def
|
|
89
|
-
client.
|
|
90
|
-
end
|
|
67
|
+
def download(path, branch)
|
|
68
|
+
file = client.contents(repo_name, { path: path, ref: branch }).to_h
|
|
91
69
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
if found = tree[:tree].find { |t| t[:path] == path }
|
|
98
|
-
b = blob(repo, found[:sha])
|
|
99
|
-
b['encoding'] == 'utf-8' ? b['content'] : Base64.decode64(b['content'])
|
|
70
|
+
file[:content] = case file[:encoding]
|
|
71
|
+
when 'base64'
|
|
72
|
+
Base64.decode64(file[:content])
|
|
73
|
+
else
|
|
74
|
+
file[:content].force_encoding(file[:encoding])
|
|
100
75
|
end
|
|
76
|
+
|
|
77
|
+
file.delete(:encoding)
|
|
78
|
+
file
|
|
101
79
|
end
|
|
102
80
|
|
|
103
|
-
def create_status(
|
|
104
|
-
client.create_status(
|
|
81
|
+
def create_status(sha, state, options = {})
|
|
82
|
+
client.create_status(repo_name, sha, state, options)
|
|
105
83
|
end
|
|
106
84
|
|
|
107
85
|
end
|
data/lib/txgh/github_status.rb
CHANGED
data/lib/txgh/pusher.rb
CHANGED
|
@@ -19,7 +19,7 @@ module Txgh
|
|
|
19
19
|
|
|
20
20
|
if translations
|
|
21
21
|
repo.api.update_contents(
|
|
22
|
-
|
|
22
|
+
branch, { file_name => translations }, message
|
|
23
23
|
)
|
|
24
24
|
|
|
25
25
|
fire_event_for(tx_resource, branch, language)
|
|
@@ -30,7 +30,7 @@ module Txgh
|
|
|
30
30
|
private
|
|
31
31
|
|
|
32
32
|
def fire_event_for(tx_resource, branch, language)
|
|
33
|
-
head = repo.api.get_ref(
|
|
33
|
+
head = repo.api.get_ref(branch)
|
|
34
34
|
sha = head[:object][:sha]
|
|
35
35
|
|
|
36
36
|
Txgh.events.publish(
|
|
@@ -37,7 +37,7 @@ module Txgh
|
|
|
37
37
|
|
|
38
38
|
def phrases
|
|
39
39
|
@phrases ||= extractor.from_string(raw) do |extractor|
|
|
40
|
-
extractor.extract_each.map do |key, value|
|
|
40
|
+
extractor.extract_each(preserve_arrays: true).map do |key, value|
|
|
41
41
|
{ 'key' => key, 'string' => value }
|
|
42
42
|
end
|
|
43
43
|
end
|
|
@@ -56,7 +56,7 @@ module Txgh
|
|
|
56
56
|
serializer.from_stream(stream, language) do |serializer|
|
|
57
57
|
phrases.each do |phrase|
|
|
58
58
|
serializer.write_key_value(
|
|
59
|
-
phrase['key'], (phrase['string'] || '')
|
|
59
|
+
phrase['key'], str(phrase['string'] || '')
|
|
60
60
|
)
|
|
61
61
|
end
|
|
62
62
|
end
|
|
@@ -95,6 +95,15 @@ module Txgh
|
|
|
95
95
|
|
|
96
96
|
attr_reader :raw
|
|
97
97
|
|
|
98
|
+
def str(obj)
|
|
99
|
+
case obj
|
|
100
|
+
when Array
|
|
101
|
+
obj
|
|
102
|
+
else
|
|
103
|
+
obj.to_s
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
98
107
|
def extractor
|
|
99
108
|
id = EXTRACTOR_MAP.fetch(tx_resource.type) do
|
|
100
109
|
raise TxghInternalError,
|
|
@@ -12,48 +12,36 @@ module Txgh
|
|
|
12
12
|
@logger = logger || Logger.new(STDOUT)
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
# in Transifex.
|
|
17
|
-
def update_resource(tx_resource, commit_sha, categories = {})
|
|
15
|
+
def update_resource(tx_resource, categories = {})
|
|
18
16
|
# don't process the resource unless the project slugs are the same
|
|
19
17
|
return unless tx_resource.project_slug == project.name
|
|
18
|
+
branch = tx_resource.branch || repo.diff_point
|
|
19
|
+
file = repo.api.download(tx_resource.source_file)
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
tree['tree'].each do |file|
|
|
26
|
-
logger.info("process each tree entry: #{file['path']}")
|
|
27
|
-
|
|
28
|
-
if tx_resource.source_file == file['path']
|
|
29
|
-
if repo.upload_diffs?
|
|
30
|
-
upload_diff(tx_resource, file, categories)
|
|
31
|
-
else
|
|
32
|
-
upload_whole(tx_resource, file, categories)
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
fire_event_for(tx_resource, commit_sha)
|
|
36
|
-
end
|
|
21
|
+
if repo.upload_diffs? && tx_resource.has_branch?
|
|
22
|
+
upload_diff(tx_resource, file, categories)
|
|
23
|
+
else
|
|
24
|
+
upload_whole(tx_resource, file, categories)
|
|
37
25
|
end
|
|
26
|
+
|
|
27
|
+
fire_event_for(tx_resource, file)
|
|
38
28
|
end
|
|
39
29
|
|
|
40
30
|
private
|
|
41
31
|
|
|
42
|
-
def fire_event_for(tx_resource,
|
|
32
|
+
def fire_event_for(tx_resource, file)
|
|
43
33
|
Txgh.events.publish(
|
|
44
34
|
'transifex.resource.updated', {
|
|
45
|
-
project: project, repo: repo, resource: tx_resource, sha:
|
|
35
|
+
project: project, repo: repo, resource: tx_resource, sha: file[:sha]
|
|
46
36
|
}
|
|
47
37
|
)
|
|
48
38
|
end
|
|
49
39
|
|
|
50
40
|
def upload_whole(tx_resource, file, categories)
|
|
51
|
-
content = contents_of(file['sha'])
|
|
52
|
-
|
|
53
41
|
if repo.process_all_branches?
|
|
54
|
-
upload_by_branch(tx_resource, content, categories)
|
|
42
|
+
upload_by_branch(tx_resource, file[:content], categories)
|
|
55
43
|
else
|
|
56
|
-
upload(tx_resource, content)
|
|
44
|
+
upload(tx_resource, file[:content])
|
|
57
45
|
end
|
|
58
46
|
end
|
|
59
47
|
|
|
@@ -77,11 +65,11 @@ module Txgh
|
|
|
77
65
|
end
|
|
78
66
|
|
|
79
67
|
def head_content(tx_resource, file)
|
|
80
|
-
ResourceContents.from_string(tx_resource,
|
|
68
|
+
ResourceContents.from_string(tx_resource, file[:content])
|
|
81
69
|
end
|
|
82
70
|
|
|
83
71
|
def diff_point_content(tx_resource, file)
|
|
84
|
-
raw_content = repo.api.download(
|
|
72
|
+
raw_content = repo.api.download(file[:path], repo.diff_point)
|
|
85
73
|
ResourceContents.from_string(tx_resource, raw_content)
|
|
86
74
|
end
|
|
87
75
|
|
|
@@ -108,15 +96,5 @@ module Txgh
|
|
|
108
96
|
resource = project.api.get_resource(*tx_resource.slugs)
|
|
109
97
|
deserialize_categories(Array(resource['categories']))
|
|
110
98
|
end
|
|
111
|
-
|
|
112
|
-
def contents_of(sha)
|
|
113
|
-
blob = repo.api.blob(repo.name, sha)
|
|
114
|
-
|
|
115
|
-
if blob['encoding'] == 'utf-8'
|
|
116
|
-
blob['content']
|
|
117
|
-
else
|
|
118
|
-
Base64.decode64(blob['content'])
|
|
119
|
-
end
|
|
120
|
-
end
|
|
121
99
|
end
|
|
122
100
|
end
|
|
@@ -5,9 +5,8 @@ module Txgh
|
|
|
5
5
|
extend Forwardable
|
|
6
6
|
|
|
7
7
|
def_delegators :@resource, *[
|
|
8
|
-
:project_slug, :type, :source_lang, :source_file, :
|
|
9
|
-
:
|
|
10
|
-
:to_h, :to_api_h
|
|
8
|
+
:project_slug, :type, :source_lang, :source_file, :translation_file,
|
|
9
|
+
:lang_map, :translation_path, :original_resource_slug, :to_h, :to_api_h
|
|
11
10
|
]
|
|
12
11
|
|
|
13
12
|
attr_reader :resource, :branch
|
|
@@ -50,6 +49,10 @@ module Txgh
|
|
|
50
49
|
)
|
|
51
50
|
end
|
|
52
51
|
|
|
52
|
+
def has_branch?
|
|
53
|
+
true
|
|
54
|
+
end
|
|
55
|
+
|
|
53
56
|
private
|
|
54
57
|
|
|
55
58
|
def slugified_branch
|
data/lib/txgh/tx_resource.rb
CHANGED
|
@@ -27,10 +27,6 @@ module Txgh
|
|
|
27
27
|
@translation_file = translation_file
|
|
28
28
|
end
|
|
29
29
|
|
|
30
|
-
def L10N_resource_slug
|
|
31
|
-
"L10N#{resource_slug}"
|
|
32
|
-
end
|
|
33
|
-
|
|
34
30
|
def lang_map(tx_lang)
|
|
35
31
|
@lang_map.fetch(tx_lang, tx_lang)
|
|
36
32
|
end
|
|
@@ -66,5 +62,9 @@ module Txgh
|
|
|
66
62
|
def branch
|
|
67
63
|
nil
|
|
68
64
|
end
|
|
65
|
+
|
|
66
|
+
def has_branch?
|
|
67
|
+
false
|
|
68
|
+
end
|
|
69
69
|
end
|
|
70
70
|
end
|
data/lib/txgh/version.rb
CHANGED
|
@@ -39,8 +39,8 @@ describe TxManager do
|
|
|
39
39
|
it 'loads tx config from a git repository' do
|
|
40
40
|
expect(repo.api).to(
|
|
41
41
|
receive(:download)
|
|
42
|
-
.with(
|
|
43
|
-
.and_return("[main]\nlang_map = ko:ko_KR")
|
|
42
|
+
.with('./tx.config', 'my_branch')
|
|
43
|
+
.and_return(content: "[main]\nlang_map = ko:ko_KR")
|
|
44
44
|
)
|
|
45
45
|
|
|
46
46
|
config = TxManager.tx_config(project, repo, 'my_branch')
|
|
@@ -35,6 +35,29 @@ describe DiffCalculator do
|
|
|
35
35
|
end
|
|
36
36
|
end
|
|
37
37
|
|
|
38
|
+
context 'with an array added to HEAD' do
|
|
39
|
+
let(:head_phrases) do
|
|
40
|
+
diff_point_phrases + [
|
|
41
|
+
phrase('villains', %w(Khan Chang Valeris Shinzon))
|
|
42
|
+
]
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
let(:diff_point_phrases) do
|
|
46
|
+
[
|
|
47
|
+
phrase('Bajor', 'Bajoran'),
|
|
48
|
+
phrase('Cardassia', 'Cardassian')
|
|
49
|
+
]
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
it 'includes the new array' do
|
|
53
|
+
expect(diff[:added].size).to eq(1)
|
|
54
|
+
expect(diff[:modified].size).to eq(0)
|
|
55
|
+
phrase = diff[:added].first
|
|
56
|
+
expect(phrase['key']).to eq('villains')
|
|
57
|
+
expect(phrase['string']).to eq(%w(Khan Chang Valeris Shinzon))
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
38
61
|
context 'with phrases removed from HEAD' do
|
|
39
62
|
let(:head_phrases) do
|
|
40
63
|
[]
|
|
@@ -50,6 +73,21 @@ describe DiffCalculator do
|
|
|
50
73
|
end
|
|
51
74
|
end
|
|
52
75
|
|
|
76
|
+
context 'with an array removed from HEAD' do
|
|
77
|
+
let(:head_phrases) do
|
|
78
|
+
[]
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
let(:diff_point_phrases) do
|
|
82
|
+
phrase('villains', %w(Khan Chang Valeris Shinzon))
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
it 'does not include the array' do
|
|
86
|
+
expect(diff[:added].size).to eq(0)
|
|
87
|
+
expect(diff[:modified].size).to eq(0)
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
53
91
|
context 'with phrases modified in HEAD' do
|
|
54
92
|
let(:head_phrases) do
|
|
55
93
|
[phrase('TheNextGeneration', 'Jean Luc Picard (rocks)')]
|
|
@@ -68,6 +106,24 @@ describe DiffCalculator do
|
|
|
68
106
|
end
|
|
69
107
|
end
|
|
70
108
|
|
|
109
|
+
context 'with an array modified in HEAD' do
|
|
110
|
+
let(:head_phrases) do
|
|
111
|
+
[phrase('villains', %w(Khan Chang Valeris Shinzon))]
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
let(:diff_point_phrases) do
|
|
115
|
+
[phrase('villains', %w(Khan Chang Valeris))]
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
it 'includes the entire array' do
|
|
119
|
+
expect(diff[:added].size).to eq(0)
|
|
120
|
+
expect(diff[:modified].size).to eq(1)
|
|
121
|
+
phrase = diff[:modified].first
|
|
122
|
+
expect(phrase['key']).to eq('villains')
|
|
123
|
+
expect(phrase['string']).to eq(%w(Khan Chang Valeris Shinzon))
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
71
127
|
context 'with no phrases modified, added, or removed' do
|
|
72
128
|
let(:head_phrases) do
|
|
73
129
|
[
|