# encoding: utf-8 module Nanoc3::Extra::Deployers # A deployer that deploys a site using rsync. class Rsync # Default rsync options DEFAULT_OPTIONS = [ '-glpPrtvz', '--exclude=".hg"', '--exclude=".svn"', '--exclude=".git"' ] # Creates a new deployer that uses rsync. The deployment configurations # will be read from the configuration file of the site (which is assumed # to be the current working directory). # # The deployment configurations are stored like this in the site's # configuration file: # # deploy: # NAME: # options: [ OPTIONS ] # dst: "DST" # # `NAME` is a unique name for the deployment configuration. By default, # the deployer will use the deployment configuration named `"default"`. # # `OPTIONS` is an array containing options to pass to the rsync # executable. This is not required; by default, {DEFAULT_OPTIONS} options # will be used. # # `DST` is a string containing the destination to where rsync should # upload its data. It will likely be in `host:path` format. For example, # `"example.com:/var/www/sites/mysite/html"`. It should not end with a # trailing slash. # # Example: This deployment configuration defines a "default" and a # "staging" deployment configuration. The default options are used. # # deploy: # default: # dst: "ectype:sites/stoneship/public" # staging: # dst: "ectype:sites/stoneship-staging/public" # options: [ "-glpPrtvz" ] # # When running the deployer with the `default` resp. `staging` # configurations, the following rsync commands will be executed: # # rsync -glpPrtvz --exclude=".hg" --exclude=".svn" # --exclude=".git" output ectype:sites/stoneship/public # # rsync -glpPrtvz output ectype:sites/stoneship-staging/public def initialize # Get site error 'No site configuration found' unless File.file?('config.yaml') @site = Nanoc3::Site.new('.') end # Runs the task. Possible params: # # @option params [Boolean] :dry_run (false) True if the action itself # should not be executed, but still printed; false otherwise. # # @option params [String] :config_name (:default) The name of the # deployment configuration to use. # # @return [void] def run(params={}) # Extract params config_name = params.has_key?(:config_name) ? params[:config_name].to_sym : :default dry_run = params.has_key?(:dry_run) ? params[:dry_run] : false # Validate config error 'No deploy configuration found' if @site.config[:deploy].nil? error "No deploy configuration found for #{config_name}" if @site.config[:deploy][config_name].nil? # Set arguments src = File.expand_path(@site.config[:output_dir]) + '/' dst = @site.config[:deploy][config_name][:dst] options = @site.config[:deploy][config_name][:options] || DEFAULT_OPTIONS # Validate arguments error 'No dst found in deployment configuration' if dst.nil? error 'dst requires no trailing slash' if dst[-1,1] == '/' # Run if dry_run warn 'Performing a dry-run; no actions will actually be performed' run_shell_cmd([ 'echo', 'rsync', options, src, dst ].flatten) else run_shell_cmd([ 'rsync', options, src, dst ].flatten) end end private # Prints the given message on stderr and exits. def error(msg) raise RuntimeError.new(msg) end # Runs the given shell command. This is a simple wrapper around Kernel#system. def run_shell_cmd(args) system(*args) end end end