Method: Etch::Client#save_history

Defined in:
lib/etch/client.rb

#save_history(file) ⇒ Object

This subroutine maintains a revision history for the file in @historybase



1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
# File 'lib/etch/client.rb', line 1785

def save_history(file)
  histdir = File.join(@historybase, "#{file}.HISTORY")
  current = File.join(histdir, 'current')
  
  # Migrate old RCS history
  if File.file?(histdir) && File.directory?(File.join(File.dirname(histdir), 'RCS'))
    if !@dryrun
      puts "Migrating old RCS history to new format"
      rcsmax = nil
      IO.popen("rlog #{histdir}") do |pipe|
        pipe.each do |line|
          if line =~ /^head: 1.(.*)/
            rcsmax = $1.to_i
            break
          end
        end
      end
      if !rcsmax
        raise "Failed to parse RCS history rlog output"
      end
      tmphistdir = tempdir(histdir)
      1.upto(rcsmax) do |rcsrev|
        rcsrevcontents = `co -q -p1.#{rcsrev} #{histdir}`
        # rcsrev-1 because RCS starts revisions at 1.1 and we start files
        # at 0000
        File.open(File.join(tmphistdir, sprintf('%04d', rcsrev-1)), 'w') do |rcsrevfile|
          rcsrevfile.write(rcsrevcontents)
        end
      end
      FileUtils.copy(histdir, File.join(tmphistdir, 'current'))
      File.delete(histdir)
      File.rename(tmphistdir, histdir)
    end
  end

  # Make sure the directory tree for this file exists in the
  # directory we save history in.
  if !File.exist?(histdir)
    puts "Making history directory #{histdir}"
    FileUtils.mkpath(histdir) if (!@dryrun)
  end
  
  # If the history log doesn't exist and we didn't just create the original
  # backup then that indicates that the original backup was made previously
  # but the history log was not started at the same time. There are a
  # variety of reasons why this might be the case (the most likely is that
  # the original was saved manually by someone) but whatever the reason is
  # we want to use the original backup to start the history log before
  # updating the history log with the current file.
  if !File.exist?(File.join(histdir, 'current')) && !@first_update[file]
    origpath = save_orig(file)
    if File.file?(origpath) && !File.symlink?(origpath)
      puts "Starting history log with saved original file:  " +
           "#{origpath} -> #{current}"
      FileUtils.copy(origpath, current) if (!@dryrun)
    else
      puts "Starting history log with 'ls -ld' output for " +
           "saved original file:  #{origpath} -> #{current}"
      system("ls -ld #{origpath} > #{current} 2>&1") if (!@dryrun)
    end
    set_history_permissions(file)
  end
  
  # Make temporary copy of file
  newcurrent = current+'.new'
  if File.file?(file) && !File.symlink?(file)
    puts "Updating history log:  #{file} -> #{current}"
    if File.exist?(newcurrent)
      remove_file(newcurrent)
    end
    FileUtils.copy(file, newcurrent) if (!@dryrun)
  else
    puts "Updating history log with 'ls -ld' output:  #{file} -> #{current}"
    system("ls -ld #{file} > #{newcurrent} 2>&1") if (!@dryrun)
  end
  
  # Roll current to next XXXX if current != XXXX
  if File.exist?(current)
    nextfile = '0000'
    maxfile = Dir.entries(histdir).select{|e|e=~/^\d+/}.max
    if maxfile
      if compare_file_contents(File.join(histdir, maxfile), File.read(current))
        nextfile = nil
      else
        nextfile = sprintf('%04d', maxfile.to_i + 1)
      end
    end
    if nextfile
      File.rename(current, File.join(histdir, nextfile)) if (!@dryrun)
    end
  end
  
  # Move temporary copy to current
  File.rename(current+'.new', current) if (!@dryrun)
  
  set_history_permissions(file)
end