Skip to content

Commit

Permalink
Bundle Git deployer
Browse files Browse the repository at this point in the history
  • Loading branch information
denisdefreyne committed Jan 5, 2017
1 parent 149cdc3 commit 47cfd60
Show file tree
Hide file tree
Showing 6 changed files with 677 additions and 1 deletion.
2 changes: 2 additions & 0 deletions lib/nanoc/deploying/deployers.rb
Expand Up @@ -2,9 +2,11 @@ module Nanoc::Deploying
# @api private
module Deployers
autoload 'Fog', 'nanoc/deploying/deployers/fog'
autoload 'Git', 'nanoc/deploying/deployers/git'
autoload 'Rsync', 'nanoc/deploying/deployers/rsync'

Nanoc::Deploying::Deployer.register '::Nanoc::Deploying::Deployers::Fog', :fog
Nanoc::Deploying::Deployer.register '::Nanoc::Deploying::Deployers::Git', :git
Nanoc::Deploying::Deployer.register '::Nanoc::Deploying::Deployers::Rsync', :rsync
end
end
119 changes: 119 additions & 0 deletions lib/nanoc/deploying/deployers/git.rb
@@ -0,0 +1,119 @@
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::Extra::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

# @see Nanoc::Extra::Deployer#run
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

0 comments on commit 47cfd60

Please sign in to comment.