zenflow 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
 - data/.gitignore +6 -0
 - data/.rspec +2 -0
 - data/.ruby-gemset +1 -0
 - data/.ruby-version +1 -0
 - data/.zenflow +10 -0
 - data/CHANGELOG.md +0 -0
 - data/Gemfile +3 -0
 - data/Gemfile.lock +95 -0
 - data/Guardfile +6 -0
 - data/LICENSE.md +22 -0
 - data/README.markdown +92 -0
 - data/VERSION.yml +5 -0
 - data/bin/zenflow +17 -0
 - data/lib/zenflow.rb +35 -0
 - data/lib/zenflow/cli.rb +130 -0
 - data/lib/zenflow/commands/deploy.rb +33 -0
 - data/lib/zenflow/commands/feature.rb +10 -0
 - data/lib/zenflow/commands/hotfix.rb +15 -0
 - data/lib/zenflow/commands/release.rb +16 -0
 - data/lib/zenflow/commands/reviews.rb +12 -0
 - data/lib/zenflow/helpers/ask.rb +66 -0
 - data/lib/zenflow/helpers/branch.rb +80 -0
 - data/lib/zenflow/helpers/branch_command.rb +95 -0
 - data/lib/zenflow/helpers/branch_commands/abort.rb +21 -0
 - data/lib/zenflow/helpers/branch_commands/branches.rb +21 -0
 - data/lib/zenflow/helpers/branch_commands/compare.rb +20 -0
 - data/lib/zenflow/helpers/branch_commands/deploy.rb +29 -0
 - data/lib/zenflow/helpers/branch_commands/diff.rb +19 -0
 - data/lib/zenflow/helpers/branch_commands/finish.rb +68 -0
 - data/lib/zenflow/helpers/branch_commands/review.rb +58 -0
 - data/lib/zenflow/helpers/branch_commands/start.rb +39 -0
 - data/lib/zenflow/helpers/branch_commands/update.rb +22 -0
 - data/lib/zenflow/helpers/changelog.rb +100 -0
 - data/lib/zenflow/helpers/config.rb +36 -0
 - data/lib/zenflow/helpers/github.rb +40 -0
 - data/lib/zenflow/helpers/help.rb +37 -0
 - data/lib/zenflow/helpers/log.rb +21 -0
 - data/lib/zenflow/helpers/pull_request.rb +68 -0
 - data/lib/zenflow/helpers/repo.rb +13 -0
 - data/lib/zenflow/helpers/shell.rb +89 -0
 - data/lib/zenflow/helpers/version.rb +87 -0
 - data/lib/zenflow/version.rb +3 -0
 - data/spec/fixtures/VERSION.yml +5 -0
 - data/spec/fixtures/cassettes/create_bad_pull_request.yml +57 -0
 - data/spec/fixtures/cassettes/create_pull_request.yml +68 -0
 - data/spec/fixtures/cassettes/existing_pull_request.yml +145 -0
 - data/spec/fixtures/cassettes/pull_request_by_ref.yml +145 -0
 - data/spec/fixtures/cassettes/pull_request_find.yml +70 -0
 - data/spec/fixtures/cassettes/pull_request_for_non-existent_ref.yml +145 -0
 - data/spec/fixtures/cassettes/pull_request_list.yml +74 -0
 - data/spec/fixtures/cassettes/unexisting_pull_request.yml +145 -0
 - data/spec/spec_helper.rb +36 -0
 - data/spec/support/shared_examples_for_version_number.rb +19 -0
 - data/spec/zenflow/commands/deploy_spec.rb +48 -0
 - data/spec/zenflow/commands/feature_spec.rb +11 -0
 - data/spec/zenflow/commands/hotfix_spec.rb +14 -0
 - data/spec/zenflow/commands/release_spec.rb +15 -0
 - data/spec/zenflow/commands/reviews_spec.rb +15 -0
 - data/spec/zenflow/helpers/ask_spec.rb +115 -0
 - data/spec/zenflow/helpers/branch_command_spec.rb +310 -0
 - data/spec/zenflow/helpers/branch_spec.rb +300 -0
 - data/spec/zenflow/helpers/changelog_spec.rb +188 -0
 - data/spec/zenflow/helpers/cli_spec.rb +277 -0
 - data/spec/zenflow/helpers/github_spec.rb +45 -0
 - data/spec/zenflow/helpers/help_spec.rb +36 -0
 - data/spec/zenflow/helpers/log_spec.rb +31 -0
 - data/spec/zenflow/helpers/pull_request_spec.rb +108 -0
 - data/spec/zenflow/helpers/shell_spec.rb +135 -0
 - data/spec/zenflow/helpers/version_spec.rb +111 -0
 - data/zenflow.gemspec +33 -0
 - metadata +273 -0
 
| 
         @@ -0,0 +1,33 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Zenflow
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
              def self.Deploy(to, opts={})
         
     | 
| 
      
 4 
     | 
    
         
            +
                Branch.push(to)
         
     | 
| 
      
 5 
     | 
    
         
            +
                if opts[:migrations]
         
     | 
| 
      
 6 
     | 
    
         
            +
                  Log("Deploying with migrations to #{to}")
         
     | 
| 
      
 7 
     | 
    
         
            +
                  Shell["cap #{to} deploy:migrations"]
         
     | 
| 
      
 8 
     | 
    
         
            +
                else
         
     | 
| 
      
 9 
     | 
    
         
            +
                  Log("Deploying to #{to}")
         
     | 
| 
      
 10 
     | 
    
         
            +
                  Shell["cap #{to} deploy"]
         
     | 
| 
      
 11 
     | 
    
         
            +
                end
         
     | 
| 
      
 12 
     | 
    
         
            +
              end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
              class Deploy < Thor
         
     | 
| 
      
 15 
     | 
    
         
            +
                class_option :migrations, type: :boolean, desc: "Run migrations during deployment", aliases: :m
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                desc "qa", "Deploy to qa."
         
     | 
| 
      
 18 
     | 
    
         
            +
                def qa
         
     | 
| 
      
 19 
     | 
    
         
            +
                  Zenflow::Deploy("qa", options)
         
     | 
| 
      
 20 
     | 
    
         
            +
                end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                desc "staging", "Deploy to staging."
         
     | 
| 
      
 23 
     | 
    
         
            +
                def staging
         
     | 
| 
      
 24 
     | 
    
         
            +
                  Zenflow::Deploy("staging", options)
         
     | 
| 
      
 25 
     | 
    
         
            +
                end
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                desc "production", "Deploy to production."
         
     | 
| 
      
 28 
     | 
    
         
            +
                def production
         
     | 
| 
      
 29 
     | 
    
         
            +
                  Zenflow::Deploy("production", options)
         
     | 
| 
      
 30 
     | 
    
         
            +
                end
         
     | 
| 
      
 31 
     | 
    
         
            +
              end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,15 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Zenflow
         
     | 
| 
      
 2 
     | 
    
         
            +
              class Hotfix < BranchCommand
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
                flow "hotfix"
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
                branch source: Zenflow::Config[:release_branch]
         
     | 
| 
      
 7 
     | 
    
         
            +
                branch deploy: Zenflow::Config[:staging_branch]
         
     | 
| 
      
 8 
     | 
    
         
            +
                branch deploy: Zenflow::Config[:qa_branch]
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                changelog :rotate
         
     | 
| 
      
 11 
     | 
    
         
            +
                version :patch
         
     | 
| 
      
 12 
     | 
    
         
            +
                tag true
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
              end
         
     | 
| 
      
 15 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,16 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Zenflow
         
     | 
| 
      
 2 
     | 
    
         
            +
              class Release < BranchCommand
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
                flow "release"
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
                branch source: Zenflow::Config[:development_branch]
         
     | 
| 
      
 7 
     | 
    
         
            +
                branch deploy: Zenflow::Config[:staging_branch]
         
     | 
| 
      
 8 
     | 
    
         
            +
                branch deploy: Zenflow::Config[:qa_branch]
         
     | 
| 
      
 9 
     | 
    
         
            +
                branch destination: Zenflow::Config[:release_branch]
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                changelog :rotate
         
     | 
| 
      
 12 
     | 
    
         
            +
                version :minor
         
     | 
| 
      
 13 
     | 
    
         
            +
                tag true
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
              end
         
     | 
| 
      
 16 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,12 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Zenflow
         
     | 
| 
      
 2 
     | 
    
         
            +
              class Reviews < Thor
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
                desc "list", "Show all open reviews."
         
     | 
| 
      
 5 
     | 
    
         
            +
                def list
         
     | 
| 
      
 6 
     | 
    
         
            +
                  Zenflow::Log(Terminal::Table.new(rows: Zenflow::PullRequest.list.map {|request|
         
     | 
| 
      
 7 
     | 
    
         
            +
                    [request["number"], request["head"]["ref"]]
         
     | 
| 
      
 8 
     | 
    
         
            +
                  }).to_s, indent: false, arrows: false, color: false)
         
     | 
| 
      
 9 
     | 
    
         
            +
                end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
              end
         
     | 
| 
      
 12 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,66 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Zenflow
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
              def self.Ask(question, options={})
         
     | 
| 
      
 4 
     | 
    
         
            +
                response = Zenflow::Query.ask_question(question, options)
         
     | 
| 
      
 5 
     | 
    
         
            +
                Zenflow::Query.handle_response(response, options)
         
     | 
| 
      
 6 
     | 
    
         
            +
              rescue StandardError => e
         
     | 
| 
      
 7 
     | 
    
         
            +
                puts e.message
         
     | 
| 
      
 8 
     | 
    
         
            +
                options[:response] = nil
         
     | 
| 
      
 9 
     | 
    
         
            +
                retry
         
     | 
| 
      
 10 
     | 
    
         
            +
              rescue Interrupt => e
         
     | 
| 
      
 11 
     | 
    
         
            +
                puts
         
     | 
| 
      
 12 
     | 
    
         
            +
                puts "-----> Exiting...".cyan
         
     | 
| 
      
 13 
     | 
    
         
            +
                LogToFile("-----> Received interrupt. Exiting...")
         
     | 
| 
      
 14 
     | 
    
         
            +
                exit(1)
         
     | 
| 
      
 15 
     | 
    
         
            +
              end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
              class Query
         
     | 
| 
      
 18 
     | 
    
         
            +
                def self.ask_question(question, options={})
         
     | 
| 
      
 19 
     | 
    
         
            +
                  if options[:response].to_s.strip != ""
         
     | 
| 
      
 20 
     | 
    
         
            +
                    response = options[:response]
         
     | 
| 
      
 21 
     | 
    
         
            +
                  else
         
     | 
| 
      
 22 
     | 
    
         
            +
                    response = Zenflow::Query.prompt_for_answer(question, options)
         
     | 
| 
      
 23 
     | 
    
         
            +
                  end
         
     | 
| 
      
 24 
     | 
    
         
            +
                  Zenflow::LogToFile("Response: #{response}")
         
     | 
| 
      
 25 
     | 
    
         
            +
                  response
         
     | 
| 
      
 26 
     | 
    
         
            +
                end
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
                def self.prompt_for_answer(question, options={})
         
     | 
| 
      
 29 
     | 
    
         
            +
                  prompt = ">> #{question} "
         
     | 
| 
      
 30 
     | 
    
         
            +
                  prompt << "[#{options[:options].join('/')}] " if options[:options]
         
     | 
| 
      
 31 
     | 
    
         
            +
                  prompt << "[#{options[:default]}] " if options[:default] && !options[:options]
         
     | 
| 
      
 32 
     | 
    
         
            +
                  Zenflow::LogToFile("Asked: #{prompt}")
         
     | 
| 
      
 33 
     | 
    
         
            +
                  print prompt
         
     | 
| 
      
 34 
     | 
    
         
            +
                  $stdin.gets.chomp
         
     | 
| 
      
 35 
     | 
    
         
            +
                end
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                def self.handle_response(response, options={})
         
     | 
| 
      
 38 
     | 
    
         
            +
                  if !Zenflow::Query.valid_response?(response, options)
         
     | 
| 
      
 39 
     | 
    
         
            +
                    raise Zenflow::Query.build_error_message(response, options)
         
     | 
| 
      
 40 
     | 
    
         
            +
                  end
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                  return options[:default].downcase if response == ""
         
     | 
| 
      
 43 
     | 
    
         
            +
                  return response.downcase if response == "Y" || response == "N"
         
     | 
| 
      
 44 
     | 
    
         
            +
                  response
         
     | 
| 
      
 45 
     | 
    
         
            +
                end
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
                def self.valid_response?(response, options={})
         
     | 
| 
      
 48 
     | 
    
         
            +
                  return false if options[:options] && !options[:options].include?(response)
         
     | 
| 
      
 49 
     | 
    
         
            +
                  return false if options[:validate] && options[:validate].is_a?(Regexp) && !response[options[:validate]]
         
     | 
| 
      
 50 
     | 
    
         
            +
                  return false if options[:required] && response == ""
         
     | 
| 
      
 51 
     | 
    
         
            +
                  true
         
     | 
| 
      
 52 
     | 
    
         
            +
                end
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
                def self.build_error_message(response, options={})
         
     | 
| 
      
 55 
     | 
    
         
            +
                  if options[:required]
         
     | 
| 
      
 56 
     | 
    
         
            +
                    message = "You must respond to this prompt."
         
     | 
| 
      
 57 
     | 
    
         
            +
                  elsif options[:error_message]
         
     | 
| 
      
 58 
     | 
    
         
            +
                    message = options[:error_message]
         
     | 
| 
      
 59 
     | 
    
         
            +
                  else
         
     | 
| 
      
 60 
     | 
    
         
            +
                    message = %{"#{response}" is not a valid response.}
         
     | 
| 
      
 61 
     | 
    
         
            +
                  end
         
     | 
| 
      
 62 
     | 
    
         
            +
                  "-----> #{message} Try again.".red
         
     | 
| 
      
 63 
     | 
    
         
            +
                end
         
     | 
| 
      
 64 
     | 
    
         
            +
              end
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,80 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Zenflow
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Branch
         
     | 
| 
      
 3 
     | 
    
         
            +
                class << self
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
                  def list(prefix)
         
     | 
| 
      
 6 
     | 
    
         
            +
                    branches = Zenflow::Shell.run "git branch | grep #{prefix}", :silent => true
         
     | 
| 
      
 7 
     | 
    
         
            +
                    return ['!! NONE !!'] if branches.empty?
         
     | 
| 
      
 8 
     | 
    
         
            +
                    branches.split("\n").map{|branch| branch.sub(/.*#{prefix}\/?/, "") }
         
     | 
| 
      
 9 
     | 
    
         
            +
                  end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                  def current(prefix)
         
     | 
| 
      
 12 
     | 
    
         
            +
                    branch = Zenflow::Shell.run("git branch | grep '* #{prefix}'", :silent => true)
         
     | 
| 
      
 13 
     | 
    
         
            +
                    branch.chomp.sub(/\* #{prefix}\/?/, "") unless branch.empty?
         
     | 
| 
      
 14 
     | 
    
         
            +
                  end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                  def update(name)
         
     | 
| 
      
 17 
     | 
    
         
            +
                    Zenflow::Log("Updating the #{name} branch")
         
     | 
| 
      
 18 
     | 
    
         
            +
                    Zenflow::Shell["git checkout #{name} && git pull"]
         
     | 
| 
      
 19 
     | 
    
         
            +
                  end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                  def create(name, base)
         
     | 
| 
      
 22 
     | 
    
         
            +
                    Zenflow::Log("Creating the #{name} branch based on #{base}")
         
     | 
| 
      
 23 
     | 
    
         
            +
                    Zenflow::Shell["git checkout -b #{name} #{base}"]
         
     | 
| 
      
 24 
     | 
    
         
            +
                  end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                  def push(name)
         
     | 
| 
      
 27 
     | 
    
         
            +
                    Zenflow::Log("Pushing the #{name} branch to #{Zenflow::Config[:remote] || 'origin'}")
         
     | 
| 
      
 28 
     | 
    
         
            +
                    Zenflow::Shell["git push #{Zenflow::Config[:remote] || 'origin'} #{name}"]
         
     | 
| 
      
 29 
     | 
    
         
            +
                    if Zenflow::Config[:backup_remote]
         
     | 
| 
      
 30 
     | 
    
         
            +
                      Zenflow::Log("Pushing the #{name} branch to #{Zenflow::Config[:backup_remote]}")
         
     | 
| 
      
 31 
     | 
    
         
            +
                      Zenflow::Shell["git push #{Zenflow::Config[:backup_remote]} #{name}"]
         
     | 
| 
      
 32 
     | 
    
         
            +
                    end
         
     | 
| 
      
 33 
     | 
    
         
            +
                  end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                  def push_tags
         
     | 
| 
      
 36 
     | 
    
         
            +
                    Zenflow::Log("Pushing tags to #{Zenflow::Config[:remote] || 'origin'}")
         
     | 
| 
      
 37 
     | 
    
         
            +
                    Zenflow::Shell["git push #{Zenflow::Config[:remote] || 'origin'} --tags"]
         
     | 
| 
      
 38 
     | 
    
         
            +
                    if Zenflow::Config[:backup_remote]
         
     | 
| 
      
 39 
     | 
    
         
            +
                      Zenflow::Log("Pushing tags to #{Zenflow::Config[:backup_remote]}")
         
     | 
| 
      
 40 
     | 
    
         
            +
                      Zenflow::Shell["git push #{Zenflow::Config[:backup_remote]} --tags"]
         
     | 
| 
      
 41 
     | 
    
         
            +
                    end
         
     | 
| 
      
 42 
     | 
    
         
            +
                  end
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                  def track(name)
         
     | 
| 
      
 45 
     | 
    
         
            +
                    Zenflow::Log("Tracking the #{name} branch against #{Zenflow::Config[:remote] || 'origin'}/#{name}")
         
     | 
| 
      
 46 
     | 
    
         
            +
                    Zenflow::Shell["git branch --set-upstream-to=#{Zenflow::Config[:remote] || 'origin'}/#{name} #{name}"]
         
     | 
| 
      
 47 
     | 
    
         
            +
                  end
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
                  def checkout(name)
         
     | 
| 
      
 50 
     | 
    
         
            +
                    Zenflow::Log("Switching to the #{name} branch")
         
     | 
| 
      
 51 
     | 
    
         
            +
                    Zenflow::Shell["git checkout #{name}"]
         
     | 
| 
      
 52 
     | 
    
         
            +
                  end
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
                  def merge(name)
         
     | 
| 
      
 55 
     | 
    
         
            +
                    Zenflow::Log("Merging in the #{name} branch")
         
     | 
| 
      
 56 
     | 
    
         
            +
                    Zenflow::Shell["git merge --no-ff #{name}"]
         
     | 
| 
      
 57 
     | 
    
         
            +
                  end
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
                  def tag(name=nil, description=nil)
         
     | 
| 
      
 60 
     | 
    
         
            +
                    Zenflow::Log("Tagging the release")
         
     | 
| 
      
 61 
     | 
    
         
            +
                    Zenflow::Shell["git tag -a '#{name || Zenflow::Ask('Name of the tag:', :required => true)}' -m '#{Zenflow::Shell.shell_escape_for_single_quoting((description || Zenflow::Ask('Tag message:', :required => true)).to_s)}'"]
         
     | 
| 
      
 62 
     | 
    
         
            +
                  end
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
                  def delete_remote(name)
         
     | 
| 
      
 65 
     | 
    
         
            +
                    Zenflow::Log("Removing the remote branch from #{Zenflow::Config[:remote] || 'origin'}")
         
     | 
| 
      
 66 
     | 
    
         
            +
                    Zenflow::Shell["git branch -r | grep #{Zenflow::Config[:remote] || 'origin'}/#{name} && git push #{Zenflow::Config[:remote] || 'origin'} :#{name} || echo ''"]
         
     | 
| 
      
 67 
     | 
    
         
            +
                    if Zenflow::Config[:backup_remote]
         
     | 
| 
      
 68 
     | 
    
         
            +
                      Zenflow::Log("Removing the remote branch from #{Zenflow::Config[:backup_remote]}")
         
     | 
| 
      
 69 
     | 
    
         
            +
                      Zenflow::Shell["git branch -r | grep #{Zenflow::Config[:backup_remote]}/#{name} && git push #{Zenflow::Config[:backup_remote]} :#{name} || echo ''"]
         
     | 
| 
      
 70 
     | 
    
         
            +
                    end
         
     | 
| 
      
 71 
     | 
    
         
            +
                  end
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
      
 73 
     | 
    
         
            +
                  def delete_local(name, options={})
         
     | 
| 
      
 74 
     | 
    
         
            +
                    Zenflow::Log("Removing the local branch")
         
     | 
| 
      
 75 
     | 
    
         
            +
                    Zenflow::Shell["git branch -#{options[:force] ? 'D' : 'd'} #{name}"]
         
     | 
| 
      
 76 
     | 
    
         
            +
                  end
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
                end
         
     | 
| 
      
 79 
     | 
    
         
            +
              end
         
     | 
| 
      
 80 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,95 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Zenflow
         
     | 
| 
      
 2 
     | 
    
         
            +
              class BranchCommand < Thor
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
                include Zenflow::BranchCommands::Abort
         
     | 
| 
      
 5 
     | 
    
         
            +
                include Zenflow::BranchCommands::Branches
         
     | 
| 
      
 6 
     | 
    
         
            +
                include Zenflow::BranchCommands::Compare
         
     | 
| 
      
 7 
     | 
    
         
            +
                include Zenflow::BranchCommands::Deploy
         
     | 
| 
      
 8 
     | 
    
         
            +
                include Zenflow::BranchCommands::Diff
         
     | 
| 
      
 9 
     | 
    
         
            +
                include Zenflow::BranchCommands::Finish
         
     | 
| 
      
 10 
     | 
    
         
            +
                include Zenflow::BranchCommands::Review
         
     | 
| 
      
 11 
     | 
    
         
            +
                include Zenflow::BranchCommands::Start
         
     | 
| 
      
 12 
     | 
    
         
            +
                include Zenflow::BranchCommands::Update
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                no_commands do
         
     | 
| 
      
 15 
     | 
    
         
            +
                  def flow
         
     | 
| 
      
 16 
     | 
    
         
            +
                    self.class.flow
         
     | 
| 
      
 17 
     | 
    
         
            +
                  end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                  def branch(key)
         
     | 
| 
      
 20 
     | 
    
         
            +
                    val = all_branches(key)
         
     | 
| 
      
 21 
     | 
    
         
            +
                    if val.size == 1
         
     | 
| 
      
 22 
     | 
    
         
            +
                      val.first
         
     | 
| 
      
 23 
     | 
    
         
            +
                    else
         
     | 
| 
      
 24 
     | 
    
         
            +
                      val
         
     | 
| 
      
 25 
     | 
    
         
            +
                    end
         
     | 
| 
      
 26 
     | 
    
         
            +
                  end
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
                  def all_branches(key)
         
     | 
| 
      
 29 
     | 
    
         
            +
                    self.class.branch[key]
         
     | 
| 
      
 30 
     | 
    
         
            +
                  end
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                  def version
         
     | 
| 
      
 33 
     | 
    
         
            +
                    self.class.version
         
     | 
| 
      
 34 
     | 
    
         
            +
                  end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                  def changelog
         
     | 
| 
      
 37 
     | 
    
         
            +
                    self.class.changelog
         
     | 
| 
      
 38 
     | 
    
         
            +
                  end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                  def tag
         
     | 
| 
      
 41 
     | 
    
         
            +
                    self.class.tag
         
     | 
| 
      
 42 
     | 
    
         
            +
                  end
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                  def delete_branches
         
     | 
| 
      
 45 
     | 
    
         
            +
                    Zenflow::Branch.delete_remote("#{flow}/#{branch_name}") if !options[:offline]
         
     | 
| 
      
 46 
     | 
    
         
            +
                    Zenflow::Branch.delete_local("#{flow}/#{branch_name}", force: true)
         
     | 
| 
      
 47 
     | 
    
         
            +
                  end
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
                end
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
              protected
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
                def branch_name
         
     | 
| 
      
 55 
     | 
    
         
            +
                  @branch_name ||= Zenflow::Branch.current(flow) ||
         
     | 
| 
      
 56 
     | 
    
         
            +
                                   Zenflow::Ask("Name of the #{flow}:",
         
     | 
| 
      
 57 
     | 
    
         
            +
                                       required:      true,
         
     | 
| 
      
 58 
     | 
    
         
            +
                                       validate:      /^[-0-9a-z]+$/,
         
     | 
| 
      
 59 
     | 
    
         
            +
                                       error_message: "Names can only contain dashes, 0-9, and a-z").downcase
         
     | 
| 
      
 60 
     | 
    
         
            +
                end
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
                # DSL METHODS
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
                def self.flow(flow=nil)
         
     | 
| 
      
 66 
     | 
    
         
            +
                  @flow = flow if flow
         
     | 
| 
      
 67 
     | 
    
         
            +
                  @flow
         
     | 
| 
      
 68 
     | 
    
         
            +
                end
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
                def self.branch(branch={})
         
     | 
| 
      
 71 
     | 
    
         
            +
                  @branch ||= {}
         
     | 
| 
      
 72 
     | 
    
         
            +
                  branch.keys.each do |key|
         
     | 
| 
      
 73 
     | 
    
         
            +
                    @branch[key] ||= []
         
     | 
| 
      
 74 
     | 
    
         
            +
                    @branch[key] << branch[key]
         
     | 
| 
      
 75 
     | 
    
         
            +
                  end
         
     | 
| 
      
 76 
     | 
    
         
            +
                  @branch
         
     | 
| 
      
 77 
     | 
    
         
            +
                end
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
                def self.version(version=nil)
         
     | 
| 
      
 80 
     | 
    
         
            +
                  @version = version if version
         
     | 
| 
      
 81 
     | 
    
         
            +
                  @version
         
     | 
| 
      
 82 
     | 
    
         
            +
                end
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
                def self.changelog(changelog=nil)
         
     | 
| 
      
 85 
     | 
    
         
            +
                  @changelog = changelog if changelog
         
     | 
| 
      
 86 
     | 
    
         
            +
                  @changelog
         
     | 
| 
      
 87 
     | 
    
         
            +
                end
         
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
      
 89 
     | 
    
         
            +
                def self.tag(tag=nil)
         
     | 
| 
      
 90 
     | 
    
         
            +
                  @tag = tag if tag
         
     | 
| 
      
 91 
     | 
    
         
            +
                  @tag
         
     | 
| 
      
 92 
     | 
    
         
            +
                end
         
     | 
| 
      
 93 
     | 
    
         
            +
             
     | 
| 
      
 94 
     | 
    
         
            +
              end
         
     | 
| 
      
 95 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,21 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Zenflow
         
     | 
| 
      
 2 
     | 
    
         
            +
              module BranchCommands
         
     | 
| 
      
 3 
     | 
    
         
            +
                module Abort
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
                  def self.included(thor)
         
     | 
| 
      
 6 
     | 
    
         
            +
                    thor.class_eval do
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                      desc "abort", "Aborts the branch and cleans up"
         
     | 
| 
      
 9 
     | 
    
         
            +
                      option :offline, type: :boolean, desc: "Runs in offline mode"
         
     | 
| 
      
 10 
     | 
    
         
            +
                      def abort
         
     | 
| 
      
 11 
     | 
    
         
            +
                        branch_name
         
     | 
| 
      
 12 
     | 
    
         
            +
                        Zenflow::Branch.checkout(branch(:source))
         
     | 
| 
      
 13 
     | 
    
         
            +
                        delete_branches
         
     | 
| 
      
 14 
     | 
    
         
            +
                      end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                    end
         
     | 
| 
      
 17 
     | 
    
         
            +
                  end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                end
         
     | 
| 
      
 20 
     | 
    
         
            +
              end
         
     | 
| 
      
 21 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,21 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Zenflow
         
     | 
| 
      
 2 
     | 
    
         
            +
              module BranchCommands
         
     | 
| 
      
 3 
     | 
    
         
            +
                module Branches
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
                  def self.included(thor)
         
     | 
| 
      
 6 
     | 
    
         
            +
                    thor.class_eval do
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                      desc "branches", "List branches"
         
     | 
| 
      
 9 
     | 
    
         
            +
                      def branches
         
     | 
| 
      
 10 
     | 
    
         
            +
                        Zenflow::Log("Available #{flow} branches:")
         
     | 
| 
      
 11 
     | 
    
         
            +
                        Zenflow::Branch.list(flow).each do |branch|
         
     | 
| 
      
 12 
     | 
    
         
            +
                          Zenflow::Log("* #{branch}", indent: true, color: false)
         
     | 
| 
      
 13 
     | 
    
         
            +
                        end
         
     | 
| 
      
 14 
     | 
    
         
            +
                      end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                    end
         
     | 
| 
      
 17 
     | 
    
         
            +
                  end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                end
         
     | 
| 
      
 20 
     | 
    
         
            +
              end
         
     | 
| 
      
 21 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,20 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Zenflow
         
     | 
| 
      
 2 
     | 
    
         
            +
              module BranchCommands
         
     | 
| 
      
 3 
     | 
    
         
            +
                module Compare
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
                  def self.included(thor)
         
     | 
| 
      
 6 
     | 
    
         
            +
                    thor.class_eval do
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                      desc "compare", "Launch GitHub compare view against the latest code"
         
     | 
| 
      
 9 
     | 
    
         
            +
                      def compare
         
     | 
| 
      
 10 
     | 
    
         
            +
                        branch_name
         
     | 
| 
      
 11 
     | 
    
         
            +
                        Zenflow::Log("Opening GitHub compare view for #{branch(:source)}...#{flow}/#{branch_name}")
         
     | 
| 
      
 12 
     | 
    
         
            +
                        Zenflow::Shell["open https://github.com/#{Zenflow::Repo.slug}/compare/#{branch(:source)}...#{flow}/#{branch_name}"]
         
     | 
| 
      
 13 
     | 
    
         
            +
                      end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                    end
         
     | 
| 
      
 16 
     | 
    
         
            +
                  end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                end
         
     | 
| 
      
 19 
     | 
    
         
            +
              end
         
     | 
| 
      
 20 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,29 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Zenflow
         
     | 
| 
      
 2 
     | 
    
         
            +
              module BranchCommands
         
     | 
| 
      
 3 
     | 
    
         
            +
                module Deploy
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
                  def self.included(thor)
         
     | 
| 
      
 6 
     | 
    
         
            +
                    thor.class_eval do
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                      desc "deploy [OPTIONS]", "Deploy"
         
     | 
| 
      
 9 
     | 
    
         
            +
                      option :migrations, type: :boolean, desc: "Run migrations during deployment", aliases: :m
         
     | 
| 
      
 10 
     | 
    
         
            +
                      def deploy
         
     | 
| 
      
 11 
     | 
    
         
            +
                        branch_name
         
     | 
| 
      
 12 
     | 
    
         
            +
                        if !Zenflow::Config[:deployable]
         
     | 
| 
      
 13 
     | 
    
         
            +
                          Zenflow::Log("This project is not deployable right now", color: :red)
         
     | 
| 
      
 14 
     | 
    
         
            +
                          exit(1)
         
     | 
| 
      
 15 
     | 
    
         
            +
                        end
         
     | 
| 
      
 16 
     | 
    
         
            +
                        all_branches(:deploy).each do |branch|
         
     | 
| 
      
 17 
     | 
    
         
            +
                          Zenflow::Branch.update(branch)
         
     | 
| 
      
 18 
     | 
    
         
            +
                          Zenflow::Branch.merge("#{flow}/#{branch_name}")
         
     | 
| 
      
 19 
     | 
    
         
            +
                          Zenflow::Deploy(branch, options)
         
     | 
| 
      
 20 
     | 
    
         
            +
                        end
         
     | 
| 
      
 21 
     | 
    
         
            +
                        Zenflow::Branch.checkout("#{flow}/#{branch_name}")
         
     | 
| 
      
 22 
     | 
    
         
            +
                      end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                    end
         
     | 
| 
      
 25 
     | 
    
         
            +
                  end
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                end
         
     | 
| 
      
 28 
     | 
    
         
            +
              end
         
     | 
| 
      
 29 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,19 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Zenflow
         
     | 
| 
      
 2 
     | 
    
         
            +
              module BranchCommands
         
     | 
| 
      
 3 
     | 
    
         
            +
                module Diff
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
                  def self.included(thor)
         
     | 
| 
      
 6 
     | 
    
         
            +
                    thor.class_eval do
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                      desc "diff", "Launch a diff against the latest code"
         
     | 
| 
      
 9 
     | 
    
         
            +
                      def diff
         
     | 
| 
      
 10 
     | 
    
         
            +
                        Zenflow::Log("Displaying diff with #{branch(:source)}")
         
     | 
| 
      
 11 
     | 
    
         
            +
                        Zenflow::Shell["git difftool #{branch(:source)}"]
         
     | 
| 
      
 12 
     | 
    
         
            +
                      end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                    end
         
     | 
| 
      
 15 
     | 
    
         
            +
                  end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                end
         
     | 
| 
      
 18 
     | 
    
         
            +
              end
         
     | 
| 
      
 19 
     | 
    
         
            +
            end
         
     |