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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a63c65881f6f00e2479a19d8ff925581cc8b2c10
4
- data.tar.gz: e309c3690f95a66a36f5d9b3e743e160dc8a78f4
3
+ metadata.gz: cee1db178f1ad7cdc40a20d13eb5e7f22aa8da3e
4
+ data.tar.gz: ad1b43ad46d06e5c2bfadb35e19e64153ce17ced
5
5
  SHA512:
6
- metadata.gz: c41e8fc0e628f7c00078046a2cc467fbd62777ba7ff848eafcce1503bdc37c05dc5ac7a5aaa342c01636ca7feae4ee04e9848bb10203862db9f5c4b440819df6
7
- data.tar.gz: 254e2b871687f9023df759b2df134976a93270eb179c9a1471c11bfc4d6f34933ff9771678868f668a2ef9914bc5144330544d718ab17798e8fde8bcc15c2ba0
6
+ metadata.gz: 76946e935626508ed67deddaa9aae76947c43eac2a776b077f848ed2e5945e52832832c8d6305f1219b171392ac71bdd1b89027a6267274fb022e3819ab41d8f
7
+ data.tar.gz: 4a6b2dc8948e3c03a051631f47524ee00c77c070f538cee59cd5d56516cf3b5ff19ee0803b21e538f0d0b593dc0d3884d87de69d906b12dde071c14f4baff5ed
@@ -28,7 +28,7 @@ module Txgh
28
28
 
29
29
  def github_api
30
30
  @github_api ||= Txgh::GithubApi.create_from_credentials(
31
- repo_config['api_username'], repo_config['api_token']
31
+ repo_config['api_username'], repo_config['api_token'], repo_config['name']
32
32
  )
33
33
  end
34
34
  end
@@ -34,7 +34,7 @@ module Txgh
34
34
  private
35
35
 
36
36
  def download
37
- github_repo.api.download(github_repo.name, payload, ref)
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
@@ -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(repo, sha)
25
- client.tree(repo, sha, recursive: 1)
25
+ def tree(sha)
26
+ client.tree(repo_name, sha, recursive: 1)
26
27
  end
27
28
 
28
- def blob(repo, sha)
29
- client.blob(repo, sha)
29
+ def blob(sha)
30
+ client.blob(repo_name, sha)
30
31
  end
31
32
 
32
- def create_ref(repo, branch, sha)
33
- client.create_ref(repo, branch, sha) rescue false
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(repo, branch, content_map, message)
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(repo, { path: path, ref: branch })
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
- repo, path, message, current_sha, new_contents, options
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 commit(repo, branch, content_map, message, allow_empty = false)
59
- parent = client.ref(repo, branch)
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 get_commit(repo, sha)
85
- client.commit(repo, sha)
63
+ def get_ref(ref)
64
+ client.ref(repo_name, ref)
86
65
  end
87
66
 
88
- def get_ref(repo, ref)
89
- client.ref(repo, ref)
90
- end
67
+ def download(path, branch)
68
+ file = client.contents(repo_name, { path: path, ref: branch }).to_h
91
69
 
92
- def download(repo, path, branch)
93
- master = client.ref(repo, branch)
94
- commit = client.commit(repo, master[:object][:sha])
95
- tree = client.tree(repo, commit[:commit][:tree][:sha], recursive: 1)
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(repo, sha, state, options = {})
104
- client.create_status(repo, sha, state, options)
81
+ def create_status(sha, state, options = {})
82
+ client.create_status(repo_name, sha, state, options)
105
83
  end
106
84
 
107
85
  end
@@ -29,7 +29,7 @@ module Txgh
29
29
 
30
30
  def update(sha)
31
31
  repo.api.create_status(
32
- repo.name, sha, state, {
32
+ sha, state, {
33
33
  context: context, target_url: target_url, description: description
34
34
  }
35
35
  )
data/lib/txgh/pusher.rb CHANGED
@@ -19,7 +19,7 @@ module Txgh
19
19
  end
20
20
 
21
21
  def push_resource(tx_resource)
22
- ref = repo.api.get_ref(repo.name, branch || repo.branch)
22
+ ref = repo.api.get_ref(branch || repo.branch)
23
23
  updater.update_resource(tx_resource, ref[:object][:sha])
24
24
  end
25
25
 
@@ -19,7 +19,7 @@ module Txgh
19
19
 
20
20
  if translations
21
21
  repo.api.update_contents(
22
- repo.name, branch, { file_name => translations }, message
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(repo.name, branch)
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'] || '').to_s
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,
@@ -101,7 +101,7 @@ module Txgh
101
101
  end
102
102
 
103
103
  def git_download(resource, branch)
104
- repo.api.download(repo.name, resource.source_file, branch)
104
+ repo.api.download(resource.source_file, branch)[:content]
105
105
  end
106
106
 
107
107
  def transifex_api
@@ -12,48 +12,36 @@ module Txgh
12
12
  @logger = logger || Logger.new(STDOUT)
13
13
  end
14
14
 
15
- # For each modified resource, get its content and update the content
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
- logger.info('process updated resource')
22
- tree_sha = repo.api.get_commit(repo.name, commit_sha)['commit']['tree']['sha']
23
- tree = repo.api.tree(repo.name, tree_sha)
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, commit_sha)
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: commit_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, contents_of(file['sha']))
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(repo.name, file['path'], repo.diff_point)
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, :L10N_resource_slug,
9
- :translation_file, :lang_map, :translation_path, :original_resource_slug,
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
@@ -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
@@ -1,3 +1,3 @@
1
1
  module Txgh
2
- VERSION = '6.0.0.beta1'
2
+ VERSION = '6.0.0'
3
3
  end
@@ -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(repo.name, './tx.config', 'my_branch')
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
  [