diff --git a/0pdd.rb b/0pdd.rb index 42434c88..db7a70c0 100644 --- a/0pdd.rb +++ b/0pdd.rb @@ -326,7 +326,7 @@ github = GithubRepo.new(settings.github, json, settings.config) return 'Thanks' unless github.is_valid unless ENV['RACK_ENV'] == 'test' - process_request(json, github) + process_request(github) puts "GitHub hook from #{github.repo.name}" end "Thanks #{github.repo.name}" @@ -379,28 +379,6 @@ def merged(hash) out end -# @todo #41:30min Make this vcs independent. Move to github vsc object. -def repo(json) - uri = json['repository']['ssh_url'] || json['repository']['url'] - name = json['repository']['full_name'] - default_branch = json['repository']['master_branch'] - head_commit_hash = json['head_commit']['id'] - begin - settings.github.repository(name)['default_branch'] - rescue Octokit::InvalidRepository => e - raise "Repository #{name} is not available: #{e.message}" - rescue Octokit::NotFound - error 400 - end - GitRepo.new( - uri: uri, - name: name, - id_rsa: @config['id_rsa'], - master: default_branch, - head_commit_hash: head_commit_hash - ) -end - def storage(repo) SyncStorage.new( UpgradedStorage.new( @@ -433,27 +411,20 @@ def storage(repo) ) end -def process_request(json, vcs) - repo = repo(json) +def process_request(vcs) JobDetached.new( - repo, + vcs, JobCommitErrors.new( - name, - settings.github, - json['head_commit']['id'], + vcs, JobEmailed.new( - name, - settings.github, - repo, + vcs, JobRecorded.new( - name, - settings.github, + vcs, JobStarred.new( - name, - settings.github, + vcs, Job.new( - repo, - storage(name), + vcs, + storage(vcs.repo.name, vcs.name), SentryTickets.new( EmailedTickets.new( vcs, diff --git a/objects/jobs/job.rb b/objects/jobs/job.rb index ef8f386c..98ab72d9 100644 --- a/objects/jobs/job.rb +++ b/objects/jobs/job.rb @@ -19,31 +19,36 @@ # SOFTWARE. require 'mail' -require_relative '../puzzles' require_relative '../diff' +require_relative '../puzzles' # # One job. # class Job - def initialize(repo, storage, tickets) - @repo = repo + def initialize(vcs, storage, tickets) + @vcs = vcs @storage = storage @tickets = tickets + @initial_puzzles = nil end def proceed - @repo.push - before = @storage.load - Puzzles.new(@repo, @storage).deploy(@tickets) + @vcs.repo.push + @initial_puzzles = @storage.load + Puzzles.new(@vcs.repo, @storage).deploy(@tickets) return if opts.include?('on-scope') - Diff.new(before, @storage.load).notify(@tickets) + Diff.new(@initial_puzzles, @storage.load).notify(@tickets) + rescue Octokit::ClientError => e + # TODO: this is a temporary solution, we should use a logger + save(@initial_puzzles) if @initial_puzzles + throw e end private def opts - array = @repo.config.dig('alerts', 'suppress') + array = @vcs.repo.config.dig('alerts', 'suppress') array.nil? || !array.is_a?(Array) ? [] : array end end diff --git a/objects/jobs/job_commiterrors.rb b/objects/jobs/job_commiterrors.rb index 7b7da09c..9f1bf8a5 100644 --- a/objects/jobs/job_commiterrors.rb +++ b/objects/jobs/job_commiterrors.rb @@ -22,30 +22,27 @@ # # Job that posts exceptions as commit messages. -# API: http://octokit.github.io/octokit.rb/method_list.html # class JobCommitErrors - def initialize(name, github, commit, job) - @name = name - @github = github - @commit = commit + def initialize(vcs, job) + @vcs = vcs @job = job end def proceed @job.proceed rescue Exception => e - done = @github.create_commit_comment( - @name, @commit, + done = @vcs.create_commit_comment( + @vcs.repo.head_commit_hash, "I wasn't able to retrieve PDD puzzles from the code base and \ -submit them to GitHub. If you \ +submit them to #{@vcs.name}. If you \ think that it's a bug on our side, please submit it to \ [yegor256/0pdd](https://github.com/yegor256/0pdd/issues):\n\n\ > #{Truncated.new(e.message.gsub(/\s/, ' '), 300)}\n\n Please, copy and paste this stack trace to GitHub:\n\n ```\n#{e.class.name}\n#{e.message}\n#{e.backtrace.join("\n")}\n```" ) - puts "Comment posted about an error: #{done['html_url']}" + puts "Comment posted about an error: #{done[:html_url]}" raise e end end diff --git a/objects/jobs/job_detached.rb b/objects/jobs/job_detached.rb index f24683a3..15ce80e6 100644 --- a/objects/jobs/job_detached.rb +++ b/objects/jobs/job_detached.rb @@ -24,8 +24,8 @@ # One job. # class JobDetached - def initialize(repo, job) - @repo = repo + def initialize(vcs, job) + @vcs = vcs @job = job end @@ -40,7 +40,7 @@ def proceed private def exclusive - lock = @repo.lock + lock = @vcs.repo.lock FileUtils.mkdir_p(File.dirname(lock)) f = File.open(lock, File::RDWR | File::CREAT, 0o644) f.flock(File::LOCK_EX) diff --git a/objects/jobs/job_emailed.rb b/objects/jobs/job_emailed.rb index ea9bb715..d41e754e 100644 --- a/objects/jobs/job_emailed.rb +++ b/objects/jobs/job_emailed.rb @@ -24,23 +24,22 @@ # Job that emails if exception occurs. # class JobEmailed - def initialize(name, github, repo, job) - @name = name - @github = github - @repo = repo + def initialize(vcs, job) + @vcs = vcs @job = job end def proceed @job.proceed rescue Exception => e - yaml = @repo.config + yaml = @vcs.repo.config emails = yaml['errors'] || [] emails << 'admin@0pdd.com' trace = e.message + "\n\n" + e.backtrace.join("\n") - name = @name - repo_owner_login = repo_user_login(name) + name = @vcs.repo.name + repo_owner_login = repo_user_login repo_owner_email = user_email(repo_owner_login) + repository_link = @vcs.repository_link emails.each do |email| mail = Mail.new do from '0pdd ' @@ -49,7 +48,7 @@ def proceed text_part do content_type 'text/plain; charset=UTF-8' body "Hey,\n\n\ -There is a problem in https://github.com/#{name}:\n\n\ +There is a problem in #{repository_link}:\n\n\ #{trace}\n\n\ If you think it's our bug, please submit it to GitHub: \ https://github.com/yegor256/0pdd/issues\n\n\ @@ -60,7 +59,7 @@ def proceed content_type 'text/html; charset=UTF-8' body "

Hey,

There is a problem in - #{name}:

+ #{name}:

#{trace}

If you think it's our bug, please submit it to GitHub. @@ -77,11 +76,11 @@ def proceed private - def repo_user_login(repo_name) - repo_name.split('/').first + def repo_user_login + @vcs.repo.name.split('/').first end - def user_email(login) - @github.user(login)[:email] + def user_email(username) + @vcs.user(username)[:email] end end diff --git a/objects/jobs/job_recorded.rb b/objects/jobs/job_recorded.rb index 9261e626..ed7139a6 100644 --- a/objects/jobs/job_recorded.rb +++ b/objects/jobs/job_recorded.rb @@ -22,17 +22,16 @@ # Job that records all requests. # class JobRecorded - def initialize(name, github, job) - @name = name - @github = github + def initialize(vcs, job) + @vcs = vcs @job = job end def proceed @job.proceed - return if @github.repository(@name)['private'] + return if @vcs.repository[:private] open('/tmp/0pdd-done.txt', 'a+') do |f| - f.puts(@name) + f.puts(@vcs.repo.name) end end end diff --git a/objects/jobs/job_starred.rb b/objects/jobs/job_starred.rb index c7753845..ade9d885 100644 --- a/objects/jobs/job_starred.rb +++ b/objects/jobs/job_starred.rb @@ -23,15 +23,14 @@ # API: http://octokit.github.io/octokit.rb/method_list.html # class JobStarred - def initialize(name, github, job) - @name = name - @github = github + def initialize(vcs, job) + @vcs = vcs @job = job end def proceed output = @job.proceed - @github.star(@name) + @vcs.star output end end diff --git a/test/fake_repo.rb b/test/fake_repo.rb index 7a46273b..b2fe6df5 100644 --- a/test/fake_repo.rb +++ b/test/fake_repo.rb @@ -22,12 +22,15 @@ require 'tempfile' class FakeRepo - def lock - Tempfile.new('0pdd-lock') + attr_reader :name, :config + + def initialize(options = {}) + @name = options[:name] || 'GITHUB' + @config = options[:config] || {} end - def config - {} + def lock + Tempfile.new('0pdd-lock') end def xml diff --git a/test/test_job.rb b/test/test_job.rb index 47e0a47e..7dabeed0 100644 --- a/test/test_job.rb +++ b/test/test_job.rb @@ -23,6 +23,7 @@ require 'tmpdir' require_relative 'test__helper' require_relative 'fake_repo' +require_relative 'fake_github' require_relative 'fake_tickets' require_relative 'fake_storage' require_relative '../objects/jobs/job' @@ -35,8 +36,10 @@ class TestJob < Test::Unit::TestCase def test_simple_scenario Dir.mktmpdir 'test' do |d| + repo = FakeRepo.new + vcs = FakeGithub.new(repo: repo) Job.new( - FakeRepo.new, + vcs, SafeStorage.new(FakeStorage.new(d)), FakeTickets.new ).proceed diff --git a/test/test_job_commiterrors.rb b/test/test_job_commiterrors.rb index bb1ae258..e8dc5ccd 100644 --- a/test/test_job_commiterrors.rb +++ b/test/test_job_commiterrors.rb @@ -29,8 +29,13 @@ # License:: MIT class TestJobCommitErrors < Test::Unit::TestCase class Stub - attr_reader :reported - def create_commit_comment(_, _, text) + attr_reader :name, :reported, :repo + def initialize(repo) + @repo = repo + @name = 'GITHUB' + end + + def create_commit_comment(_, text) @reported = text end end @@ -40,12 +45,12 @@ def test_timeout_scenario def job.proceed raise 'Intended to be here' end - github = Stub.new + vcs = Stub.new(object(head_commit_hash: '123')) begin - JobCommitErrors.new('yegor256/0pdd', github, '12345678', job).proceed + JobCommitErrors.new(vcs, job).proceed rescue StandardError => e assert(!e.nil?) end - assert(!github.reported.empty?) + assert(!vcs.reported.empty?) end end diff --git a/test/test_job_detached.rb b/test/test_job_detached.rb index 763fb9ea..66d4e174 100644 --- a/test/test_job_detached.rb +++ b/test/test_job_detached.rb @@ -32,8 +32,9 @@ def test_simple_scenario def job.proceed # nothing end - JobDetached.new( - FakeRepo.new, job - ).proceed + require_relative 'fake_repo' + vcs = object(repo: nil) + vcs.repo = FakeRepo.new + JobDetached.new(vcs, job).proceed end end diff --git a/test/test_job_emailed.rb b/test/test_job_emailed.rb index 74bbb2a0..1ce44d17 100644 --- a/test/test_job_emailed.rb +++ b/test/test_job_emailed.rb @@ -38,21 +38,21 @@ def fake_job def test_simple_scenario repo = FakeRepo.new - github = FakeGithub.new + vcs = FakeGithub.new(repo: repo) job = fake_job - JobEmailed.new('yegor256/0pdd', github, repo, job).proceed + JobEmailed.new(vcs, job).proceed end def test_exception_mail_to_repo_owner_as_cc exception_class = Exception repo = FakeRepo.new - github = FakeGithub.new + vcs = FakeGithub.new(repo: repo) job = fake_job job.expects(:proceed).raises(exception_class) Mail::Message.any_instance.stubs(:deliver!) Mail::Message.any_instance.expects(:cc=).with('foobar@example.com') assert_raise Exception do - JobEmailed.new('yegor256/0pdd', github, repo, job).proceed + JobEmailed.new(vcs, job).proceed end end end