lib/abak-flow/request.rb in abak-flow-0.3.2 vs lib/abak-flow/request.rb in abak-flow-1.0.0
- old
+ new
@@ -1,234 +1,124 @@
-# -*- encoding: utf-8 -*-
+# coding: utf-8
+require "commander/import"
+require "ansi/code"
+
module Abak::Flow
- program :name, 'Утилита для оформления pull request на github.com'
+ program :name, "Утилита для оформления pull request на github.com"
program :version, Abak::Flow::VERSION
- program :description, 'Утилита, заточенная под git-flow но с использованием github.com'
+ program :description, "Утилита, заточенная под git-flow но с использованием github.com"
default_command :help
- command :publish do |c|
- c.syntax = 'git request publish <Заголовок>'
- c.description = 'Оформить pull request из текущей ветки (feature -> develop, hotfix -> master)'
- # Опции нужны, если человек хочет запушить `` ветку, с именем отличным от стандарта
- c.option '--head STRING', String, 'Имя ветки, которую нужно принять в качестве изменений'
- c.option '--base STRING', String, 'Имя ветки, в которую нужно принять изменения'
+ command :checkup do |c|
+ c.syntax = "git request checkup"
+ c.description = "Проверить все ли настроено для работы с github и удаленными репозиториями"
c.action do |args, options|
- jira_browse_url = 'http://jira.dev.apress.ru/browse/'
+ m = Manager.new
+ v = Visitor.new(m.configuration, m.repository, call: :ready?, look_for: :errors)
- config = Abak::Flow::Config.current
- github_client = Abak::Flow::GithubClient.connect(config)
- request = Abak::Flow::PullRequest.new(config, :head => options.head, :base => options.base)
-
- title = args.first.to_s.strip
- body = 'Я забыл какая это задача :('
-
- if request.default_task =~ /^\w+\-\d{1,}$/
- title = request.default_task if title.empty?
- body = jira_browse_url + request.default_task
+ if v.ready?
+ say ANSI.green { I18n.t("commands.checkup.success") }
+ else
+ say ANSI.red { I18n.t("commands.checkup.fail") }
+ say ANSI.yellow { v.output }
end
-
- request.title = title
- request.body = body
-
- exit unless request.valid?
-
- # Запушим текущую ветку на origin
- say "=> Обновляю ветку #{request.current_branch} на origin"
- Hub::Runner.execute('push', 'origin', request.current_branch)
-
- # Запостим pull request на upstream
- say '=> Делаю pull request на upstream'
- begin
- result = github_client.create_pull_request(request.from_repo, request.base, request.head, request.title, request.body)
- say color(result._links.html.href, :green).to_s
- rescue => e
- say color(e.message, :error).to_s
- say "\nПроблемы? Попробуйте заглянуть сюда:"
- say color('=> cписок кодов статуса ответа http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html', :info).to_s
- end
end
- end
+ end # command :checkup
- command :update do |c|
- c.syntax = 'git request update'
- c.description = 'Обновить ветку на удаленном (origin) репозитории'
+ command :compare do |c|
+ c.syntax = "git request compare"
+ c.description = "Сравнить свою ветку с веткой upstream репозитория"
- c.option '--branch STRING', String, 'Имя ветки, которую нужно обновить'
+ c.option "--base STRING", String, "Имя ветки с которой нужно сравнить"
+ c.option "--head STRING", String, "Имя ветки которую нужно сравнить"
c.action do |args, options|
- config = Abak::Flow::Config.current
- request = Abak::Flow::PullRequest.new(config, :strategy => :update)
+ # TODO : Вот это дубль, хочется его как-то более красиво
+ m = Manager.new
+ v = Visitor.new(m.configuration, m.repository, call: :ready?, look_for: :errors)
- exit unless request.valid?
+ unless v.ready?
+ say ANSI.red { I18n.t("commands.compare.fail") }
+ say ANSI.yellow { v.output }
- # Запушим текущую ветку на origin
- branch = options.branch || request.current_branch
- say "=> Обновляю ветку #{branch} на origin"
- Hub::Runner.execute('push', 'origin', branch)
- end
- end
-
- command :feature do |c|
- c.syntax = 'git request feature <Название задачи>'
- c.description = 'Создать ветку для выполнения задачи. Лучше всего, если название задачи, будет ее номером из jira'
-
- c.action do |args, options|
- config = Abak::Flow::Config.current
-
- task = args.shift.to_s
-
- if task.empty?
- say color('Необходимо указать имя задачи, а лучше всего ее номер из jira', :error).to_s
- exit
+ exit 1
end
- unless task =~ /^\w+\-\d{1,}$/
- say '=> Вы приняли верное решение :)' && exit if agree("Лучше всего завести задачу с именем примерно такого формата PC-001, может попробуем заново? [y/n]:")
- end
+ current = m.git.current_branch
+ head = Branch.new(options.head || current, m)
+ base = Branch.new(options.base || head.pick_up_base_name, m)
- Hub::Runner.execute('flow', 'feature', 'start', task)
- end
- end
+ if head.current?
+ say ANSI.white {
+ I18n.t("commands.compare.updating",
+ branch: ANSI.bold { head },
+ upstream: ANSI.bold { "#{m.repository.origin}" }) }
- command :hotfix do |c|
- c.syntax = 'git request hotfix <Название задачи>'
- c.description = 'Создать ветку для выполнения bugfix задачи. Лучше всего, если название задачи, будет ее номером из jira'
-
- c.action do |args, options|
- config = Abak::Flow::Config.current
-
- task = args.shift.to_s
-
- if task.empty?
- say color('Необходимо указать имя задачи, а лучше всего ее номер из jira', :error).to_s
- exit
+ head.update
+ else
+ say ANSI.yellow {
+ I18n.t("commands.compare.diverging",
+ branch: ANSI.bold { head }) }
end
- unless task =~ /^\w+\-\d{1,}$/
- say '=> Вы приняли верное решение :)' && exit if agree("Лучше всего завести задачу с именем примерно такого формата PC-001, может попробуем заново? [y/n]:")
- end
-
- Hub::Runner.execute('flow', 'hotfix', 'start', task)
+ say ANSI.green { head.compare_link(base) }
end
- end
+ end # command :compare
- command :done do |c|
- c.syntax = 'git request done'
- c.description = 'Завершить pull request. По умолчанию удаляются ветки как локальная (local), так и удаленная (origin)'
+ command :publish do |c|
+ c.syntax = "git request publish"
+ c.description = "Оформить pull request в upstream репозиторий"
- c.option '--branch STRING', String, 'Имя ветки pull request которой нужно закрыть'
- c.option '--all', 'Удаляет ветку в локальном репозитории и в удалнном (local + origin) (по умолчанию)'
- c.option '--local', 'Удаляет ветку только в локальном репозитории (local)'
- c.option '--origin', 'Удаляет ветку в удаленном репозитории (origin)'
+ c.option "--title STRING", String, "Заголовок для вашего pull request"
+ c.option "--body STRING", String, "Текст для вашего pull request"
+ c.option "--base STRING", String, "Имя ветки, в которую нужно принять изменения"
c.action do |args, options|
- config = Abak::Flow::Config.current
- request = Abak::Flow::PullRequest.new(config, :strategy => :done)
- branch = options.branch || request.current_branch
+ m = Manager.new
- exit unless request.valid?
+ head = Branch.new(m.git.current_branch, m)
+ base = Branch.new(options.base || head.pick_up_base_name, m)
- type = :all
- if [options.local, options.origin].compact.count == 1
- type = options.local ? :local : :origin
- end
+ title = options.title || head.pick_up_title
+ body = [
+ options.body || (head.mappable? ? nil : I18n.t("commands.publish.nothing")),
+ head.pick_up_body
+ ].compact * "\n\n"
- warning = color('Внимание! Alarm! Danger! Achtung!', :error).to_s +
- "\nЕсли вы удалите ветку на удаленном (remote) репозитории, а ваш pull request еще не приняли, вы рискуете потерять проделанную работу.\nВы уверены, что хотите продолжить?"
- if [:all, :origin].include?(type)
- say '=> Вы приняли верное решение :)' && exit unless agree("#{warning} [y/n]:")
- end
+ p = PullRequest.new({base: base, head: head, title: title, body: body}, m)
+ v = Visitor.new(m.configuration, m.repository, p, call: :ready?, look_for: :errors)
- # TODO Проверку на наличие ветки на origin
- if [:all, :origin].include?(type)
- say "=> Удаляю ветку #{branch} на origin"
- Hub::Runner.execute('push', request.origin_repo, ':' + branch)
- end
+ unless v.ready?
+ say ANSI.red { I18n.t("commands.publish.fail") }
+ say ANSI.yellow { v.output }
- if [:all, :local].include?(type)
- say "=> Удаляю локальную ветку #{branch}"
- Hub::Runner.execute('checkout', 'develop')
- Hub::Runner.execute('branch', '-D', branch)
+ exit 1
end
- end
- end
- # TODO Отрефакторить эту какашку
- command :readycheck do |c|
- c.syntax = 'git request readycheck'
- c.description = 'Проверить все ли настроено для работы с github и удаленным (origin) репозиторием'
+ say ANSI.white {
+ I18n.t("commands.publish.updating",
+ branch: ANSI.bold { head },
+ upstream: ANSI.bold { "#{m.repository.origin}" }) }
- c.action do |args, options|
- config = Abak::Flow::Config.current
- request = Abak::Flow::PullRequest.new(config, :strategy => :readycheck)
+ head.update
- if config.proxy?
- message = "== В качестве прокси будет установлено значение #{config.proxy} =="
- say color('=' * message.length, :info).to_s
- say color(message, :info).to_s
- say color('=' * message.length + "\n", :info).to_s
- end
+ say ANSI.white {
+ I18n.t("commands.publish.requesting",
+ branch: ANSI.bold { "#{m.repository.origin.owner}:#{head}" },
+ upstream: ANSI.bold { "#{m.repository.upstream.owner}:#{base}" }) }
- say color('Хм ... кажется у вас все готово к работе', :debug).to_s if request.valid?
- end
- end
-
- command :garbage do |c|
- c.syntax = 'git request status'
- c.description = 'Проверить пригодность удаленных (origin) веток и возможность их уничтожения (ветки master, develop игнорируются)'
+ v = Visitor.new(p, call: :publish, look_for: :errors)
+ if v.ready?
+ say ANSI.green {
+ I18n.t("commands.publish.success",
+ link: ANSI.bold { p.link }) }
+ else
+ say ANSI.red { I18n.t("commands.publish.fail") }
+ say ANSI.yellow { v.output }
- c.action do |args, options|
- config = Abak::Flow::Config.current
- github_client = Abak::Flow::GithubClient.connect(config)
- request = Abak::Flow::PullRequest.new(config, :strategy => :status)
-
- exit unless request.valid?
-
- messages = {unused: ["отсутствует в upstream репозитории", :notice],
- differ: ["отличается от origin репозитория", :warning],
- missing: ["отсутствует в локальном репозитории", :warning]}
-
- say "=> Обновляю данные о репозитории upstream"
- %w(origin upstream).each { |remote| Hub::Runner.execute('fetch', remote, '-p') }
-
- say "=> Загружаю список веток для origin"
- branches = github_client.branches(request.origin_project).
- reject { |branch| %w(master develop).include? branch.name }
-
- say "=> На origin найдено веток: #{branches.count}\n\n"
- branches.each_with_index do |branch, index|
- index += 1
-
- base = Abak::Flow::PullRequest.branch_by_prefix branch.name.split('/').first
-
- upstream_branch = %x(git branch -r --contain #{branch.commit.sha} | grep upstream/#{base} 2> /dev/null).strip
- local_sha = %x(git show #{branch.name} --format=%H --no-notes 2> /dev/null | head -n 1).strip
-
- statuses = {
- unused: upstream_branch.empty?,
- differ: !local_sha.empty? && local_sha != branch.commit.sha,
- missing: local_sha.empty?
- }
-
- unless statuses.values.inject &:|
- say color("#{index}) #{branch.name} → можно удалить", :debug).to_s
- say "\n"
- next
- end
-
- diagnoses = statuses.select { |_,bool| bool }.
- map { |name,_| messages[name].first }.
- map { |msg| "#{' ' * (index.to_s.length + 2)} ↪ #{msg}" }.
- join("\n")
-
- if statuses.select { |_,bool| bool }.keys == [:missing]
- say color("#{index}) #{branch.name} → потенциально можно удалить", :warning).to_s
- say "#{diagnoses}\n\n"
- else
- say "#{index}) #{branch.name}\n#{diagnoses}\n\n"
- end
+ exit 3
end
end
- end
-end
\ No newline at end of file
+ end # command :publish
+end