module Xampl class Version @@version_limit = 5 def initialize(repo_name, repo_root) @invalid = true throw :refuse_to_version unless repo_name repo_name.gsub!(/^[\.\/]*/, '') repo_name.gsub!(/\/.*/, '') throw :refuse_to_version unless repo_name @repo_root = repo_root @repo_root << '/' unless '/'[-1] == @repo_root[-1] @repo_path = "#{@repo_root}#{repo_name}" @repo_name = repo_name throw :refuse_to_version if @repo_path == @repo_root throw :refuse_to_version unless File.directory?(@repo_path) @invalid = false end def make(version_stream, description=nil) throw :refuse_to_version if @invalid existing_versions = Dir.glob("#{@repo_root}/#{@repo_name}_#{version_stream}*") if 0 == existing_versions.size then make_first_version(version_stream, existing_versions, description) else make_new_version(version_stream, existing_versions, description) end end def make_first_version(version_stream, existing_versions, description) cmd = "cd '#{@repo_root}'; rsync -a --delete '#{@repo_name}/' '#{@repo_name}_#{version_stream}.0/'" # puts "first version: #{cmd}" system(cmd) end def make_new_version(version_stream, existing_versions, description) existing_versions.reverse! cmd = [] eliminate = [] existing_versions.each_with_index do | version, i | pushed_name = "#{@repo_name}_#{version_stream}.#{i + 1}" cmd << "mv '#{@repo_name}_#{version_stream}.#{i}' '#{pushed_name}'" eliminate << pushed_name unless i < @@version_limit end cmd << "cd '#{@repo_root}'" cmd = cmd.reverse cmd << "rsync -a --delete --checksum --link-dest='../#{@repo_name}_#{version_stream}.1' '#{@repo_name}/' '#{@repo_name}_#{version_stream}.0/'" cmd << "touch '#{@repo_name}_#{version_stream}.0'" eliminate.each do | name | cmd << "rm -rf '#{name}'" end cmd = cmd.join("; ") # puts "new version: #{cmd}" system(cmd) end end end