lib/abak-flow/pull_request.rb in abak-flow-0.3.2 vs lib/abak-flow/pull_request.rb in abak-flow-1.0.0

- old
+ new

@@ -1,221 +1,61 @@ -# -*- encoding: utf-8 -*- +# coding: utf-8 +require "ruler" + module Abak::Flow class PullRequest - extend Forwardable + include Ruler - attr_reader :repository, :request_params - attr_reader :config, :validator + attr_reader :errors, :link - def initialize(config, options) - strategy = options.delete(:strategy) || :publish + def initialize(params, manager) + @manager = manager + @errors = [] - @repository = Hub::Commands.send(:local_repo) - @request_params = OpenStruct.new(options) - @config = config - - @validator = Validator.new(strategy, self) + @head = params.fetch(:head) + @base = params.fetch(:base) + @title = params.fetch(:title) + @body = params.fetch(:body) end - delegate [:validate!, :valid?] => :validator - delegate [:base=, :head=, :title=, :body=] => :request_params + def ready? + @errors = [] - def default_task - @default_task ||= current_branch.split('/').push(nil)[1].to_s - end + multi_ruleset do + fact(:head_is_incorrect) { not @head.valid? } + fact(:base_is_incorrect) { not @base.valid? } + fact(:title_is_incorrect) { @title.empty? } + fact(:body_is_incorrect) { @body.empty? } - def branch_prefix - @branch_prefix ||= current_branch.include?('/') ? current_branch.split('/').first : '' - end - - def current_branch - @current_branch ||= repository.current_branch.short_name - end - - def from_repo - @from_repo ||= begin - upstream_project = repository.remote_by_name('upstream').project - "#{upstream_project.owner}/#{upstream_project.name}" + rule([:head_is_incorrect]) { @errors << I18n.t("pull_request.errors.head_is_incorrect") } + rule([:base_is_incorrect]) { @errors << I18n.t("pull_request.errors.base_is_incorrect") } + rule([:title_is_incorrect]) { @errors << I18n.t("pull_request.errors.title_is_incorrect") } + rule([:body_is_incorrect]) { @errors << I18n.t("pull_request.errors.body_is_incorrect") } end - end - alias_method :upstream_project, :from_repo - - def origin_project - @origin_project ||= begin - origin_project = repository.remote_by_name('origin').project - "#{origin_project.owner}/#{origin_project.name}" - end - end - - def origin_repo - @origin_repo ||= repository.main_project.remote.name - end - def base - exit unless validator.valid? - - branch = Abak::Flow::PullRequest.branch_by_prefix(branch_prefix) - - request_params.base || "#{repository.remote_by_name('upstream').project.owner}:#{branch}" + @errors.empty? ? true : false end - def head - exit unless validator.valid? - - request_params.head || "#{repository.repo_owner}:#{current_branch}" + def display_name + I18n.t("pull_request.name") end - def title - exit unless validator.valid? + def publish + begin + head_with_repo = [@manager.repository.origin.owner, @head] * ':' - request_params.title - end + response = @manager.github.create_pull_request( + @manager.repository.upstream.to_s, @base.to_s, head_with_repo, @title, @body) - def body - exit unless validator.valid? + @link = response._links.html.href - request_params.body - end + true + rescue Exception => exception + backtrace = exception.backtrace[0...10] * "\n" - def self.branch_by_prefix(prefix) - {:feature => :develop, :hotfix => :master}.fetch(prefix.to_sym, '') - end + @errors = ["#{exception.message}\n\n#{backtrace}"] - # TODO Вынести - class Validator - attr_reader :strategy, :target_object - attr_reader :errors, :executed - - def initialize(strategy_name, target_object) - @strategy = Abak::Flow::PullRequest.const_get("Strategy#{strategy_name.capitalize}".to_sym) - @target_object = target_object - @errors = [] + false end - - def valid? - return errors.empty? if executed - - validate! - errors.empty? - end - - protected - def validate! - @executed = true - - strategy.attributes.each do |attribute| - send("validate_#{attribute}") - end - - print_errors - end - - def print_errors - errors.each do |error| - say color(error[:message], :error).to_s - say color(error[:tip], :info).to_s - end - end - - def validate_api_user - return if target_object.config.api_user? - - @errors << { - :message => 'Необходимо указать своего пользователя API github', - :tip => '=> https://github.com/Strech/abak-flow/blob/master/README.md' - } - end - - def validate_api_token - return if target_object.config.api_token? - - @errors << { - :message => 'Необходимо указать токен своего пользователя API github', - :tip => '=> https://github.com/Strech/abak-flow/blob/master/README.md' - } - end - - def validate_origin - return unless target_object.repository.remote_by_name('origin').nil? - - @errors << { - :message => 'Необходимо настроить репозиторий origin (форк) для текущего пользователя', - :tip => '=> git remote add origin https://Developer@github.com/abak-press/sample.git' - } - end - - def validate_upstream - return unless target_object.repository.remote_by_name('upstream').nil? - - @errors << { - :message => 'Необходимо настроить репозиторий upstream (главный) для текущего пользователя', - :tip => '=> git remote add upstream https://Developer@github.com/abak-press/sample.git' - } - end - - def validate_title - return unless target_object.request_params.title.empty? - - @errors << { - :message => 'Пожалуйста, укажите что-нибудь для заголовка pull request, например номер вашей задачи вот так:', - :tip => '=> git request publish "PC-001"' - } - end - - def validate_branch - return if [:master, :develop].include?(target_object.current_branch.to_sym) - - @errors << { - :message => 'Нельзя делать pull request из меток master или develop, попробуйде переключиться, например так:', - :tip => '=> git checkout master' - } - end - - def validate_deleted_branch - return unless [:master, :develop].include?(target_object.current_branch.to_sym) - - @errors << { - :message => 'Извините, но нельзя удалить ветку develop или master', - :tip => '=> git checkout feature/TASK-0001' - } - end end - - class Strategy - def self.attributes - raise NotImplementedError - end - end - - class StrategyFeature < Strategy - def self.attributes - StrategyReadycheck.attributes | [:title, :branch] - end - end - - class StrategyPublish < Strategy - def self.attributes - StrategyReadycheck.attributes | [:title] - end - end - - class StrategyUpdate < Strategy - def self.attributes - StrategyReadycheck.attributes - end - end - - class StrategyDone < Strategy - def self.attributes - StrategyReadycheck.attributes | [:deleted_branch] - end - end - - class StrategyReadycheck < Strategy - def self.attributes - [:origin, :upstream, :api_user, :api_token] - end - end - - class StrategyStatus < StrategyReadycheck; end - end -end \ No newline at end of file + end # class PullRequest +end