UploadUtils

Upload files to host. These means of uploading are current supported: ftp, sftp, scp and rsync.

    user       Username for host.
    host       Host server's domain name.
    root       Document root path on host.
    copy       Directory of files to publish, or
               Files to publish using from and to.

    dryrun     If true only pretend to upload.
    quiet      Supress all output.
    verbose    Provide extra details.

The copy parameter allows you to simply specify a file or directory which will be published to host‘s document root location.

If you need more control over which files to publish where, you can use the copy parameter instead. Provide an array of pattern strings in the form of "{from} {to}". If the desitination is the host‘s document root you do not need to specify the {to} part. For example:

    copy = [ 'web/*', 'doc/api/* doc/api' ]

The first copies the files under your project‘s web directory to the host‘s document root. The second copies your projects doc/api files to the doc/api location on the host.

The internal template used for the outbound destination is ‘username@host:root/’.

Methods
files ftp rsync sftp stage_linkdir stage_transfer upload upload_parameters
Public Instance methods
files( dir, copy )

Put together the list of files to copy.

# File lib/more/facets/uploadutils.rb, line 280
  def files( dir, copy )
    Dir.chdir(dir) do
      del, add = copy.partition{ |f| /^[-]/ =~ f }

      # remove - and + prefixes
      del.collect!{ |f| f.sub(/^[-]/,'') }
      add.collect!{ |f| f.sub(/^[+]/,'') }

      #del.concat(must_exclude)

      files = []
      add.each{ |g| files += Dir.multiglob(g) }
      del.each{ |g| files -= Dir.multiglob(g) }

      files.collect!{ |f| f.sub(/^\//,'') }

      return files
    end
  end
ftp( keys )

Use ftp to upload files.

# File lib/more/facets/uploadutils.rb, line 116
  def ftp( keys )
    keys = upload_parameters(keys)

    # set transfer rules
    if keys.stage
      trans = stage_transfer(keys.stage)
    else
      files(keys.dir, keys.copy).each do |from|
        trans << [from,from]
      end
    end

    # append location of publication dir to from
    dir = keys.dir
    trans.collect!{ |from,to| [File.join(dir,from), to] }

    if keys.dryrun
      puts "ftp open #{keys.user}@#{keys.host}:#{keys.root}/"
      keys.trans.each do |f, t|
        puts "ftp put #{f} #{t}"
      end
    else
      require 'net/ftp'
      Net::FTP.open(keys.host) do |ftp|
        ftp.login(keys.user) #password?
        ftp.chdir(keys.root)
        keys.trans.each do |f, t|
          puts "ftp #{f} #{t}" unless keys.quiet
          ftp.putbinaryfile( f, t, 1024 )
        end
      end
    end
  end
rsync( keys )

Use rsync to upload files.

# File lib/more/facets/uploadutils.rb, line 192
  def rsync( keys )
    keys = upload_parameters(keys)

    flags = []
    flags << "-n" if keys.dryrun
    flags << "-q" if keys.quiet
    flags << "-v" if keys.verbose
    flags << "--progress" unless keys.quiet
    flags = flags.join(' ').strip
    flags = ' ' + flags unless flags.empty?

    manfile = 'Publish.txt'

    if keys.stage
      dir = stage_linkdir(keys.dir, keys.stage)
      Dir.chdir(dir) do
        cpy = files(keys.copy)
      end
      manifest = File.join(dir,manfile)
      cmd = %{rsync#{flags} -L -arz --files-from='#{manifest}' #{dir} #{keys.user}@#{keys.host}:/#{keys.root}}
    else
      dir = keys.dir
      cpy = files(dir, keys.copy)
      manifest = File.join(dir,manfile)
      cmd = %{rsync#{flags} -arz --files-from='#{manifest}' #{dir} #{keys.user}@#{keys.host}:/#{keys.root}}
    end

    #Dir.chdir(keys.dir) do
      begin
        File.open(manifest, 'w'){ |f| f << cpy.join("\n") }
        ENV['RSYNC_PASSWORD'] = keys.pass if keys.pass
        puts cmd unless keys.quiet
        system cmd
      ensure
        ENV.delete('RSYNC_PASSWORD') if keys.pass
      end
    #end

  end
sftp( keys )

Use sftp to upload files.

# File lib/more/facets/uploadutils.rb, line 154
  def sftp( keys )
    keys = upload_parameters(keys)

    # set transfer rules
    if keys.stage
      trans = stage_transfer(keys.stage)
    else
      files(keys.dir, keys.copy).each do |from|
        trans << [from,from]
      end
    end

    # append location of publication dir to from
    dir = keys.dir
    trans.collect!{ |from,to| [File.join(dir,from), to] }

    if keys.dryrun
      puts "sftp open #{keys.user}@#{keys.host}:#{keys.root}/"
      keys.trans.each do |f,t|
        puts "sftp put #{f} #{t}"
      end
    else
      require 'net/sftp'
      Net::SFTP.start(keys.host, keys.user, keys.pass) do |sftp|
        #sftp.login( user )
        sftp.chdir(keys.root)
        keys.trans.each do |f,t|
          puts "sftp #{f} #{t}" unless keys.quiet
          sftp.put_file(f,t) #, 1024 )
        end
      end
    end
  end
stage_linkdir( dir, list )

When using stage options this will create temporary linked location.

# File lib/more/facets/uploadutils.rb, line 326
  def stage_linkdir( dir, list )
    folder = File.join(Dir.tmpdir, 'ratchets', 'project', object_id.abs.to_s)
    FileUtils.mkdir_p(folder)

    Dir.chdir(dir) do
      stage_transfer(list).each do |file, to|
        link = File.join(folder,to)
        FileUtils.ln_s(link,file)
      end
    end

    return folder
  end
stage_transfer( list )

Combine three part stage list into a two part from->to list.

Using the stage list of three space separated fields.

  fromdir file todir

This is used to generate a from -> to list of the form:

 fromdir/file todir/file
# File lib/more/facets/uploadutils.rb, line 311
  def stage_transfer( list )
    trans = []
    list.each do |line|
      trans << Shellwords.shellwords(line)
    end

    trans.collect! do |from, base, to|
      file = File.join(from,base)
      to = File.join(to,base)
      [from, to]
    end
  end
upload( protocol, opts )

Upload via given protocol.

# File lib/more/facets/uploadutils.rb, line 108
  def upload( protocol, opts )
    send(protocol.to_s.downcase,opts)
  end
upload_parameters( keys )

parse publishing options.

# File lib/more/facets/uploadutils.rb, line 236
  def upload_parameters( keys )
    keys = OpenObject.new(keys)

    keys.copy = keys.copy || '**/*'
    keys.host = keys.host || keys.domain
    keys.user = keys.user || keys.username
    keys.root = keys.root || '/'
    #keys.pass = keys.pass || keys.password

    # validate
    raise ArgumentError, "missing publish parameter -- dir" unless keys.dir
    raise ArgumentError, "missing publish parameter -- host" unless keys.host
    raise ArgumentError, "missing publish parameter -- user" unless keys.user
    #raise ArgumentError, "missing publish parameter -- copy" unless keys.copy
    #raise ArgumentError, "missing publish parameter -- root" unless keys.root

    keys.root = '' if keys.root.nil?
    keys.root.sub!(/^\//,'')

    if String===keys.copy and File.directory?(keys.copy)
      copy = File.join(keys.copy, '*')
    end
    keys.copy = [keys.copy].flatten.compact

#     trans = []
#     keys.copy.each do |from|
#       #from, to = *Shellwords.shellwords(c)
#       #to = from if to.nil?
#       #to = to[1..-1] if to[0,1] == '/'
#       from.sub('*','**/*') unless from =~ /\*\*/
#       files = Dir.glob(from)
#       files.each do |f|
#         #t = File.join(to,File.basename(f))
#         #t = t[1..-1] if t[0,1] == '/'
#         trans << [f,f]
#       end
#     end
#     keys.trans = trans

    return keys
  end