Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bundle Git deployer #997

Merged
merged 1 commit into from Jan 9, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions lib/nanoc/deploying/deployers.rb
Expand Up @@ -3,4 +3,5 @@ module Nanoc::Deploying::Deployers
end

require_relative 'deployers/fog'
require_relative 'deployers/git'
require_relative 'deployers/rsync'
118 changes: 118 additions & 0 deletions lib/nanoc/deploying/deployers/git.rb
@@ -0,0 +1,118 @@
module Nanoc::Deploying::Deployers
# A deployer that deploys a site using [Git](http://git-scm.com).
#
# @example A deployment configuration for GitHub Pages:
#
# deploy:
# default:
# kind: git
# remote: git@github.com:myself/myproject.git
# branch: gh-pages
# forced: true
#
class Git < ::Nanoc::Deploying::Deployer
identifier :git

module Errors
class Generic < ::Nanoc::Error
end

class OutputDirDoesNotExist < Generic
def initialize(path)
super("The directory to deploy, #{path}, does not exist.")
end
end

class OutputDirIsNotAGitRepo < Generic
def initialize(path)
super("The directory to deploy, #{path}, is not a Git repository.")
end
end

class RemoteDoesNotExist < Generic
def initialize(remote)
super("The remote to deploy to, #{remote}, does not exist.")
end
end

class BranchDoesNotExist < Generic
def initialize(branch)
super("The branch to deploy, #{branch}, does not exist.")
end
end
end

def run
unless File.exist?(source_path)
raise Errors::OutputDirDoesNotExist.new(source_path)
end

remote = config.fetch(:remote, 'origin')
branch = config.fetch(:branch, 'master')
forced = config.fetch(:forced, false)

puts "Deploying via git to remote='#{remote}' and branch='#{branch}'"

Dir.chdir(source_path) do
unless File.exist?('.git')
raise Errors::OutputDirIsNotAGitRepo.new(source_path)
end

# Verify existence of remote, if remote is not a URL
if remote_is_name?(remote)
begin
run_cmd(%W(git config --get remote.#{remote}.url))
rescue Nanoc::Extra::Piper::Error
raise Errors::RemoteDoesNotExist.new(remote)
end
end

# If the branch exists then switch to it, otherwise prompt the user to create one.
begin
run_cmd_unless_dry(%W(git checkout #{branch}))
rescue Nanoc::Extra::Piper::Error
raise Errors::BranchDoesNotExist.new(branch)
end

return if clean_repo?

msg = "Automated commit at #{Time.now.utc} by Nanoc #{Nanoc::VERSION}"
author = 'Nanoc <>'
run_cmd_unless_dry(%w(git add -A))
run_cmd_unless_dry(%W(git commit -a --author #{author} -m #{msg}))

if forced
run_cmd_unless_dry(%W(git push -f #{remote} #{branch}))
else
run_cmd_unless_dry(%W(git push #{remote} #{branch}))
end
end
end

private

def remote_is_name?(remote)
remote !~ /:\/\/|@.+:/
end

def run_cmd(cmd)
piper = Nanoc::Extra::Piper.new(stdout: $stdout, stderr: $stderr)
piper.run(cmd, nil)
end

def run_cmd_unless_dry(cmd)
if dry_run
puts cmd.join(' ')
else
run_cmd(cmd)
end
end

def clean_repo?
stdout = StringIO.new
piper = Nanoc::Extra::Piper.new(stdout: stdout, stderr: $stderr)
piper.run(%w(git status --porcelain), nil)
stdout.string.empty?
end
end
end
2 changes: 1 addition & 1 deletion spec/nanoc/cli/commands/deploy_spec.rb
Expand Up @@ -75,7 +75,7 @@
let(:run) { Nanoc::CLI.run(command) }

it 'lists all deployers' do
expect { run }.to output(/Available deployers:\n fog\n rsync/).to_stdout
expect { run }.to output(/Available deployers:\n fog\n git\n rsync/).to_stdout
end

include_examples 'no effective deploy'
Expand Down