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