txgh 5.3.4 → 5.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/lib/txgh/resource_deleter.rb +50 -0
  3. data/lib/txgh/version.rb +1 -1
  4. data/lib/txgh.rb +1 -6
  5. data/spec/resource_deleter_spec.rb +48 -0
  6. data/spec/spec_helper.rb +0 -8
  7. data/txgh.gemspec +1 -5
  8. metadata +6 -113
  9. data/lib/ext/zipline/output_stream.rb +0 -62
  10. data/lib/txgh/app.rb +0 -140
  11. data/lib/txgh/github_request_auth.rb +0 -28
  12. data/lib/txgh/handlers/download_handler.rb +0 -87
  13. data/lib/txgh/handlers/github/delete_handler.rb +0 -65
  14. data/lib/txgh/handlers/github/handler.rb +0 -20
  15. data/lib/txgh/handlers/github/ping_handler.rb +0 -18
  16. data/lib/txgh/handlers/github/push_handler.rb +0 -124
  17. data/lib/txgh/handlers/github/request_handler.rb +0 -113
  18. data/lib/txgh/handlers/github.rb +0 -11
  19. data/lib/txgh/handlers/response.rb +0 -17
  20. data/lib/txgh/handlers/stream_response.rb +0 -39
  21. data/lib/txgh/handlers/tgz_stream_response.rb +0 -41
  22. data/lib/txgh/handlers/transifex/hook_handler.rb +0 -94
  23. data/lib/txgh/handlers/transifex/request_handler.rb +0 -78
  24. data/lib/txgh/handlers/transifex.rb +0 -8
  25. data/lib/txgh/handlers/triggers/handler.rb +0 -52
  26. data/lib/txgh/handlers/triggers/pull_handler.rb +0 -20
  27. data/lib/txgh/handlers/triggers/push_handler.rb +0 -20
  28. data/lib/txgh/handlers/triggers.rb +0 -9
  29. data/lib/txgh/handlers/zip_stream_response.rb +0 -21
  30. data/lib/txgh/handlers.rb +0 -12
  31. data/lib/txgh/transifex_request_auth.rb +0 -53
  32. data/spec/app_spec.rb +0 -347
  33. data/spec/github_request_auth_spec.rb +0 -39
  34. data/spec/handlers/download_handler_spec.rb +0 -91
  35. data/spec/handlers/github/delete_handler_spec.rb +0 -71
  36. data/spec/handlers/github/ping_handler_spec.rb +0 -16
  37. data/spec/handlers/github/push_handler_spec.rb +0 -106
  38. data/spec/handlers/tgz_stream_response_spec.rb +0 -59
  39. data/spec/handlers/transifex/hook_handler_spec.rb +0 -136
  40. data/spec/handlers/zip_stream_response_spec.rb +0 -58
  41. data/spec/helpers/github_payload_builder.rb +0 -141
  42. data/spec/helpers/integration_setup.rb +0 -47
  43. data/spec/integration/cassettes/github_l10n_hook_endpoint.yml +0 -536
  44. data/spec/integration/cassettes/pull.yml +0 -47
  45. data/spec/integration/cassettes/push.yml +0 -544
  46. data/spec/integration/cassettes/transifex_hook_endpoint.yml +0 -221
  47. data/spec/integration/config/tx.config +0 -10
  48. data/spec/integration/hooks_spec.rb +0 -159
  49. data/spec/integration/payloads/github_postbody.json +0 -161
  50. data/spec/integration/payloads/github_postbody_l10n.json +0 -136
  51. data/spec/integration/payloads/github_postbody_release.json +0 -136
  52. data/spec/integration/triggers_spec.rb +0 -45
  53. data/spec/transifex_request_auth_spec.rb +0 -39
@@ -1,87 +0,0 @@
1
- module Txgh
2
- module Handlers
3
- class DownloadHandler
4
- DEFAULT_FORMAT = '.zip'
5
-
6
- # includes response helpers in both the class and the singleton class
7
- include ResponseHelpers
8
-
9
- class << self
10
- def handle_request(request, logger = nil)
11
- handle_safely do
12
- config = config_from(request)
13
- project, repo = [config.transifex_project, config.github_repo]
14
- params = params_from(request)
15
- handler = new(project, repo, params, logger)
16
- handler.execute
17
- end
18
- end
19
-
20
- private
21
-
22
- def config_from(request)
23
- Txgh::Config::KeyManager.config_from_project(
24
- request.params.fetch('project_slug')
25
- )
26
- end
27
-
28
- def params_from(request)
29
- request.params.merge(
30
- 'format' => format_from(request)
31
- )
32
- end
33
-
34
- def format_from(request)
35
- # sinatra is dumb and doesn't include any of the URL captures in the
36
- # request params or env hash
37
- File.extname(request.env['REQUEST_PATH'])
38
- end
39
-
40
- def handle_safely
41
- yield
42
- rescue => e
43
- respond_with_error(500, "Internal server error: #{e.message}", e)
44
- end
45
- end
46
-
47
- attr_reader :project, :repo, :params, :logger
48
-
49
- def initialize(project, repo, params, logger)
50
- @project = project
51
- @repo = repo
52
- @params = params
53
- @logger = logger
54
- end
55
-
56
- def execute
57
- downloader = ResourceDownloader.new(
58
- project, repo, params['branch'], languages: project.languages
59
- )
60
-
61
- response_class.new(attachment, downloader.each)
62
- end
63
-
64
- private
65
-
66
- def attachment
67
- project.name
68
- end
69
-
70
- def format
71
- params.fetch('format', DEFAULT_FORMAT)
72
- end
73
-
74
- def response_class
75
- case format
76
- when '.zip'
77
- ZipStreamResponse
78
- when '.tgz'
79
- TgzStreamResponse
80
- else
81
- raise TxghInternalError,
82
- "'#{format}' is not a valid download format"
83
- end
84
- end
85
- end
86
- end
87
- end
@@ -1,65 +0,0 @@
1
- module Txgh
2
- module Handlers
3
- module Github
4
- class DeleteHandler < Handler
5
-
6
- include CategorySupport
7
-
8
- def execute
9
- delete_resources if should_handle_request?
10
- respond_with(200, true)
11
- end
12
-
13
- private
14
-
15
- def delete_resources
16
- tx_resources.each do |tx_resource|
17
- logger.info("Deleting #{tx_resource.resource_slug}")
18
- project.api.delete_resource(tx_resource)
19
- end
20
- end
21
-
22
- def tx_resources
23
- project.api.get_resources(project.name).map do |resource_hash|
24
- categories = deserialize_categories(resource_hash['categories'])
25
- resource_branch = Utils.absolute_branch(categories['branch'])
26
-
27
- if resource_branch == branch
28
- tx_branch_resource_from(resource_hash, branch)
29
- end
30
- end.compact
31
- end
32
-
33
- def tx_branch_resource_from(resource_hash, branch)
34
- TxBranchResource.new(
35
- tx_resource_from(resource_hash, branch), branch
36
- )
37
- end
38
-
39
- # project_slug, resource_slug, type, source_lang, source_file, lang_map, translation_file
40
- def tx_resource_from(resource_hash, branch)
41
- TxResource.new(
42
- project.name,
43
- TxBranchResource.deslugify(resource_hash['slug'], branch),
44
- resource_hash['i18n_type'],
45
- resource_hash['source_language_code'],
46
- resource_hash['name'],
47
- '', nil
48
- )
49
- end
50
-
51
- def should_handle_request?
52
- # ref_type can be either 'branch' or 'tag' - we only care about branches
53
- payload['ref_type'] == 'branch' &&
54
- repo.should_process_ref?(branch) &&
55
- project.auto_delete_resources?
56
- end
57
-
58
- def branch
59
- Utils.absolute_branch(payload['ref'].sub(/^refs\//, ''))
60
- end
61
-
62
- end
63
- end
64
- end
65
- end
@@ -1,20 +0,0 @@
1
- require 'logger'
2
-
3
- module Txgh
4
- module Handlers
5
- module Github
6
- class Handler
7
- include ResponseHelpers
8
-
9
- attr_reader :project, :repo, :payload, :logger
10
-
11
- def initialize(options = {})
12
- @project = options.fetch(:project)
13
- @repo = options.fetch(:repo)
14
- @payload = options.fetch(:payload)
15
- @logger = options.fetch(:logger) { Logger.new(STDOUT) }
16
- end
17
- end
18
- end
19
- end
20
- end
@@ -1,18 +0,0 @@
1
- module Txgh
2
- module Handlers
3
- module Github
4
- # Handles github's ping event, which is a test event fired whenever a new
5
- # webhook is set up.
6
- class PingHandler
7
- include ResponseHelpers
8
-
9
- def initialize(options = {})
10
- end
11
-
12
- def execute
13
- respond_with(200, {})
14
- end
15
- end
16
- end
17
- end
18
- end
@@ -1,124 +0,0 @@
1
- require 'base64'
2
- require 'set'
3
-
4
- module Txgh
5
- module Handlers
6
- module Github
7
- class PushHandler < Handler
8
-
9
- def execute
10
- # Check if the branch in the hook data is the configured branch we want
11
- logger.info("request github branch: #{branch}")
12
- logger.info("config github branch: #{repo.github_config_branch}")
13
-
14
- if should_process?
15
- logger.info('found branch in github request')
16
-
17
- tx_resources = tx_resources_for(branch)
18
-
19
- modified_resources = added_and_modified_resources_for(tx_resources)
20
- modified_resources += l10n_resources_for(tx_resources)
21
-
22
- if repo.github_config_branch.include?('tags/')
23
- modified_resources += tag_resources_for(tx_resources)
24
- end
25
-
26
- # Handle DBZ 'L10N' special case
27
- if branch.include?("L10N")
28
- logger.info('processing L10N tag')
29
-
30
- # Create a new branch off tag commit
31
- if branch.include?('tags/L10N')
32
- repo.api.create_ref(repo.name, 'heads/L10N', payload['head_commit']['id'])
33
- end
34
- end
35
-
36
- updater = ResourceUpdater.new(project, repo, logger)
37
- categories = { 'author' => payload['head_commit']['committer']['name'] }
38
- ref = repo.api.get_ref(repo.name, branch)
39
-
40
- modified_resources.each do |resource|
41
- updater.update_resource(resource, ref[:object][:sha], categories)
42
- end
43
- end
44
-
45
- respond_with(200, true)
46
- end
47
-
48
- private
49
-
50
- def tag_resources_for(tx_resources)
51
- payload['head_commit']['modified'].each_with_object(Set.new) do |modified, ret|
52
- logger.info("processing modified file: #{modified}")
53
-
54
- if tx_resources.include?(modified)
55
- ret << tx_resources[modified]
56
- end
57
- end
58
- end
59
-
60
- def l10n_resources_for(tx_resources)
61
- payload['head_commit']['modified'].each_with_object(Set.new) do |modified, ret|
62
- if tx_resources.include?(modified)
63
- logger.info("setting new resource: #{tx_resources[modified].L10N_resource_slug}")
64
- ret << tx_resources[modified]
65
- end
66
- end
67
- end
68
-
69
- # finds the resources that were updated in each commit
70
- def added_and_modified_resources_for(tx_resources)
71
- payload['commits'].each_with_object(Set.new) do |commit, ret|
72
- logger.info('processing commit')
73
-
74
- (commit['modified'] + commit['added']).each do |file|
75
- logger.info("processing added/modified file: #{file}")
76
-
77
- if tx_resources.include?(file)
78
- ret << tx_resources[file]
79
- end
80
- end
81
- end
82
- end
83
-
84
- # Build an index of known Tx resources, by source file
85
- def tx_resources_for(branch)
86
- tx_config.resources.each_with_object({}) do |resource, ret|
87
- logger.info('processing resource')
88
-
89
- # If we're processing by branch, create a branch resource. Otherwise,
90
- # use the original resource.
91
- ret[resource.source_file] = if repo.process_all_branches?
92
- TxBranchResource.new(resource, branch) # maybe find instead?
93
- else
94
- resource
95
- end
96
- end
97
- end
98
-
99
- def tx_config
100
- @tx_config ||= Txgh::Config::TxManager.tx_config(project, repo, branch)
101
- end
102
-
103
- def branch
104
- @ref ||= payload['ref'].sub(/^refs\//, '')
105
- end
106
-
107
- def should_process?
108
- should_process_branch? && should_process_commit?
109
- end
110
-
111
- def should_process_branch?
112
- repo.should_process_ref?(branch)
113
- end
114
-
115
- def should_process_commit?
116
- # return false if 'after' commit sha is all zeroes (indicates branch
117
- # has been deleted)
118
- !(payload.fetch('after', '') =~ /\A0+\z/)
119
- end
120
-
121
- end
122
- end
123
- end
124
- end
@@ -1,113 +0,0 @@
1
- require 'json'
2
-
3
- module Txgh
4
- module Handlers
5
- module Github
6
- class RequestHandler
7
- class << self
8
-
9
- include ResponseHelpers
10
-
11
- def handle_request(request, logger)
12
- case request.env['HTTP_X_GITHUB_EVENT']
13
- when 'push'
14
- handle_push(request, logger)
15
- when 'delete'
16
- handle_delete(request, logger)
17
- when 'ping'
18
- handle_ping(request, logger)
19
- else
20
- handle_unexpected
21
- end
22
- end
23
-
24
- private
25
-
26
- def handle_push(request, logger)
27
- klass = Txgh::Handlers::Github::PushHandler
28
- new(request, logger).handle(klass)
29
- end
30
-
31
- def handle_delete(request, logger)
32
- klass = Txgh::Handlers::Github::DeleteHandler
33
- new(request, logger).handle(klass)
34
- end
35
-
36
- def handle_ping(request, logger)
37
- klass = Txgh::Handlers::Github::PingHandler
38
- new(request, logger).handle(klass)
39
- end
40
-
41
- def handle_unexpected
42
- respond_with_error(400, 'Unexpected event type')
43
- end
44
-
45
- end
46
-
47
- include ResponseHelpers
48
-
49
- attr_reader :request, :logger
50
-
51
- def initialize(request, logger)
52
- @request = request
53
- @logger = logger
54
- end
55
-
56
- def handle(klass)
57
- handle_safely do
58
- handler = klass.new(
59
- project: config.transifex_project,
60
- repo: config.github_repo,
61
- payload: payload,
62
- logger: logger
63
- )
64
-
65
- handler.execute
66
- end
67
- end
68
-
69
- private
70
-
71
- def handle_safely
72
- if authentic_request?
73
- yield
74
- else
75
- respond_with_error(401, 'Unauthorized')
76
- end
77
- rescue => e
78
- respond_with_error(500, "Internal server error: #{e.message}", e)
79
- end
80
-
81
- def payload
82
- @payload ||= if request.params[:payload]
83
- JSON.parse(request.params[:payload])
84
- else
85
- JSON.parse(request.body.read)
86
- end
87
- end
88
-
89
- def github_repo_name
90
- payload['repository']['full_name']
91
- end
92
-
93
- def config
94
- @config ||= Txgh::Config::KeyManager.config_from_repo(github_repo_name)
95
- end
96
-
97
- def repo
98
- config.github_repo
99
- end
100
-
101
- def authentic_request?
102
- if repo.webhook_protected?
103
- GithubRequestAuth.authentic_request?(
104
- request, repo.webhook_secret
105
- )
106
- else
107
- true
108
- end
109
- end
110
- end
111
- end
112
- end
113
- end
@@ -1,11 +0,0 @@
1
- module Txgh
2
- module Handlers
3
- module Github
4
- autoload :DeleteHandler, 'txgh/handlers/github/delete_handler'
5
- autoload :Handler, 'txgh/handlers/github/handler'
6
- autoload :PingHandler, 'txgh/handlers/github/ping_handler'
7
- autoload :PushHandler, 'txgh/handlers/github/push_handler'
8
- autoload :RequestHandler, 'txgh/handlers/github/request_handler'
9
- end
10
- end
11
- end
@@ -1,17 +0,0 @@
1
- module Txgh
2
- module Handlers
3
- class Response
4
- attr_reader :status, :body, :error
5
-
6
- def initialize(status, body, error = nil)
7
- @status = status
8
- @body = body
9
- @error = error
10
- end
11
-
12
- def streaming?
13
- false
14
- end
15
- end
16
- end
17
- end
@@ -1,39 +0,0 @@
1
- require 'mime/types'
2
-
3
- module Txgh
4
- module Handlers
5
- class StreamResponse
6
- attr_reader :attachment, :enum
7
-
8
- def initialize(attachment, enum)
9
- @attachment = attachment
10
- @enum = enum
11
- end
12
-
13
- def write_to(stream)
14
- raise NotImplementedError,
15
- "please implement #{__method__} in derived classes"
16
- end
17
-
18
- def file_extension
19
- raise NotImplementedError,
20
- "please implement #{__method__} in derived classes"
21
- end
22
-
23
- def headers
24
- @headers ||= {
25
- 'Content-Disposition' => "attachment; filename=\"#{attachment}#{file_extension}\"",
26
- 'Content-Type' => MIME::Types.type_for(file_extension).first.content_type
27
- }
28
- end
29
-
30
- def streaming?
31
- true
32
- end
33
-
34
- def error
35
- nil
36
- end
37
- end
38
- end
39
- end
@@ -1,41 +0,0 @@
1
- require 'rubygems/package'
2
- require 'stringio'
3
- require 'zlib'
4
-
5
- module Txgh
6
- module Handlers
7
- class TgzStreamResponse < StreamResponse
8
- PERMISSIONS = 0644
9
-
10
- def write_to(stream)
11
- Zlib::GzipWriter.wrap(stream) do |gz|
12
- pipe = StringIO.new('', 'wb')
13
- tar = Gem::Package::TarWriter.new(pipe)
14
-
15
- enum.each do |file_name, contents|
16
- tar.add_file(file_name, PERMISSIONS) do |f|
17
- f.write(contents)
18
- end
19
-
20
- flush(tar, pipe, gz)
21
- stream.flush
22
- end
23
-
24
- flush(tar, pipe, gz)
25
- end
26
- end
27
-
28
- def file_extension
29
- '.tgz'
30
- end
31
-
32
- private
33
-
34
- def flush(tar, pipe, gz)
35
- tar.flush
36
- gz.write(pipe.string)
37
- pipe.reopen('')
38
- end
39
- end
40
- end
41
- end
@@ -1,94 +0,0 @@
1
- require 'logger'
2
-
3
- module Txgh
4
- module Handlers
5
- module Transifex
6
- class HookHandler
7
- include CategorySupport
8
- include ResponseHelpers
9
-
10
- attr_reader :project, :repo, :resource_slug, :language, :logger
11
-
12
- def initialize(options = {})
13
- @project = options.fetch(:project)
14
- @repo = options.fetch(:repo)
15
- @resource_slug = options.fetch(:resource_slug)
16
- @language = options.fetch(:language)
17
- @logger = options.fetch(:logger) { Logger.new(STDOUT) }
18
- end
19
-
20
- def execute
21
- logger.info(resource_slug)
22
-
23
- check_error_response || begin
24
- committer = ResourceCommitter.new(project, repo, logger)
25
- committer.commit_resource(tx_resource, branch, language)
26
- respond_with(200, true)
27
- end
28
- end
29
-
30
- private
31
-
32
- def check_error_response
33
- check_supported_language || check_tx_config || check_tx_resource
34
- end
35
-
36
- def check_supported_language
37
- respond_with(304, true) unless supported_language?
38
- end
39
-
40
- def check_tx_config
41
- unless tx_config
42
- respond_with_error(
43
- 404, "Could not find configuration for branch '#{branch}'"
44
- )
45
- end
46
- end
47
-
48
- def check_tx_resource
49
- unless tx_resource
50
- respond_with_error(
51
- 404, "Could not find resource '#{resource_slug}' in config"
52
- )
53
- end
54
- end
55
-
56
- def tx_config
57
- @tx_config ||= Txgh::Config::TxManager.tx_config(project, repo, branch)
58
- rescue ConfigNotFoundError, TxghError
59
- nil
60
- end
61
-
62
- def branch
63
- @branch ||= begin
64
- branch_candidate = if process_all_branches?
65
- resource = project.api.get_resource(project.name, resource_slug)
66
- categories = deserialize_categories(Array(resource['categories']))
67
- categories['branch']
68
- else
69
- repo.branch || 'master'
70
- end
71
-
72
- Utils.absolute_branch(branch_candidate)
73
- end
74
- end
75
-
76
- def tx_resource
77
- @tx_resource ||= if process_all_branches?
78
- tx_config.resource(resource_slug, branch)
79
- else
80
- tx_config.resource(resource_slug)
81
- end
82
- end
83
-
84
- def process_all_branches?
85
- repo.process_all_branches?
86
- end
87
-
88
- def supported_language?
89
- project.supported_language?(language)
90
- end
91
- end
92
- end
93
- end
94
- end