Package translate :: Package storage :: Package versioncontrol :: Module cvs
[hide private]
[frames] | no frames]

Source Code for Module translate.storage.versioncontrol.cvs

  1  #!/usr/bin/env python 
  2  # -*- coding: utf-8 -*- 
  3  #  
  4  # Copyright 2004-2007 Zuza Software Foundation 
  5  #  
  6  # This file is part of translate. 
  7  # 
  8  # translate is free software; you can redistribute it and/or modify 
  9  # it under the terms of the GNU General Public License as published by 
 10  # the Free Software Foundation; either version 2 of the License, or 
 11  # (at your option) any later version. 
 12  #  
 13  # translate is distributed in the hope that it will be useful, 
 14  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
 15  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 16  # GNU General Public License for more details. 
 17  # 
 18  # You should have received a copy of the GNU General Public License 
 19  # along with translate; if not, write to the Free Software 
 20  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 21   
 22  import os 
 23  from translate.storage.versioncontrol import run_command 
 24  from translate.storage.versioncontrol import GenericRevisionControlSystem 
 25   
26 -class cvs(GenericRevisionControlSystem):
27 """Class to manage items under revision control of CVS.""" 28 29 RCS_METADIR = "CVS" 30 SCAN_PARENTS = False 31
32 - def _readfile(self, cvsroot, path, revision=None):
33 """ 34 Read a single file from the CVS repository without checking out a full 35 working directory. 36 37 @param cvsroot: the CVSROOT for the repository 38 @param path: path to the file relative to cvs root 39 @param revision: revision or tag to get (retrieves from HEAD if None) 40 """ 41 command = ["cvs", "-d", cvsroot, "-Q", "co", "-p"] 42 if revision: 43 command.extend(["-r", revision]) 44 # the path is the last argument 45 command.append(path) 46 exitcode, output, error = run_command(command) 47 if exitcode != 0: 48 raise IOError("[CVS] Could not read '%s' from '%s': %s / %s" % \ 49 (path, cvsroot, output, error)) 50 return output
51
52 - def getcleanfile(self, revision=None):
53 """Get the content of the file for the given revision""" 54 parentdir = os.path.dirname(self.location_abs) 55 cvsdir = os.path.join(parentdir, "CVS") 56 cvsroot = open(os.path.join(cvsdir, "Root"), "r").read().strip() 57 cvspath = open(os.path.join(cvsdir, "Repository"), "r").read().strip() 58 cvsfilename = os.path.join(cvspath, os.path.basename(self.location_abs)) 59 if revision is None: 60 cvsentries = open(os.path.join(cvsdir, "Entries"), "r").readlines() 61 revision = self._getcvstag(cvsentries) 62 if revision == "BASE": 63 cvsentries = open(os.path.join(cvsdir, "Entries"), "r").readlines() 64 revision = self._getcvsrevision(cvsentries) 65 return self._readfile(cvsroot, cvsfilename, revision)
66
67 - def update(self, revision=None):
68 """Does a clean update of the given path""" 69 working_dir = os.path.dirname(self.location_abs) 70 filename = os.path.basename(self.location_abs) 71 filename_backup = filename + os.path.extsep + "bak" 72 original_dir = os.getcwd() 73 if working_dir: 74 try: 75 # first: check if we are allowed to _change_ to the current dir 76 # (of course, we are already here, but that does not mean so much) 77 os.chdir(original_dir) 78 except OSError, error: 79 raise IOError("[CVS] could not change to directory (%s): %s" \ 80 % (original_dir, error)) 81 try: 82 # change to the parent directory of the CVS managed file 83 os.chdir(working_dir) 84 except OSError, error: 85 raise IOError("[CVS] could not change to directory (%s): %s" \ 86 % (working_dir, error)) 87 try: 88 os.rename(filename, filename_backup) 89 except OSError, error: 90 # something went wrong - go back to the original directory 91 try: 92 os.chdir(original_dir) 93 except OSError: 94 pass 95 raise IOError("[CVS] could not move the file '%s' to '%s': %s" % \ 96 (filename, filename_backup, error)) 97 command = ["cvs", "-Q", "update", "-C"] 98 if revision: 99 command.extend(["-r", revision]) 100 # the filename is the last argument 101 command.append(filename) 102 exitcode, output, error = run_command(command) 103 # restore backup in case of an error - remove backup for success 104 try: 105 if exitcode != 0: 106 os.rename(filename_backup, filename) 107 else: 108 os.remove(filename_backup) 109 except OSError: 110 pass 111 # always go back to the original directory 112 try: 113 os.chdir(original_dir) 114 except OSError: 115 pass 116 # raise an error or return successfully - depending on the CVS command 117 if exitcode != 0: 118 raise IOError("[CVS] Error running CVS command '%s': %s" % (command, error)) 119 else: 120 return output
121
122 - def commit(self, message=None):
123 """Commits the file and supplies the given commit message if present""" 124 working_dir = os.path.dirname(self.location_abs) 125 filename = os.path.basename(self.location_abs) 126 original_dir = os.getcwd() 127 if working_dir: 128 try: 129 # first: check if we are allowed to _change_ to the current dir 130 # (of course, we are already here, but that does not mean so much) 131 os.chdir(original_dir) 132 except OSError, error: 133 raise IOError("[CVS] could not change to directory (%s): %s" \ 134 % (original_dir, error)) 135 try: 136 # change to the parent directory of the CVS managed file 137 os.chdir(working_dir) 138 except OSError, error: 139 raise IOError("[CVS] could not change to directory (%s): %s" \ 140 % (working_dir, error)) 141 command = ["cvs", "-Q", "commit"] 142 if message: 143 command.extend(["-m", message]) 144 # the filename is the last argument 145 command.append(filename) 146 exitcode, output, error = run_command(command) 147 # always go back to the original directory 148 try: 149 os.chdir(original_dir) 150 except OSError: 151 pass 152 # raise an error or return successfully - depending on the CVS command 153 if exitcode != 0: 154 raise IOError("[CVS] Error running CVS command '%s': %s" % (command, error)) 155 else: 156 return output
157
158 - def _getcvsrevision(self, cvsentries):
159 """returns the revision number the file was checked out with by looking 160 in the lines of cvsentries 161 """ 162 filename = os.path.basename(self.location_abs) 163 for cvsentry in cvsentries: 164 # an entries line looks like the following: 165 # /README.TXT/1.19/Sun Dec 16 06:00:12 2001// 166 cvsentryparts = cvsentry.split("/") 167 if len(cvsentryparts) < 6: 168 continue 169 if os.path.normcase(cvsentryparts[1]) == os.path.normcase(filename): 170 return cvsentryparts[2].strip() 171 return None
172
173 - def _getcvstag(self, cvsentries):
174 """Returns the sticky tag the file was checked out with by looking in 175 the lines of cvsentries. 176 """ 177 filename = os.path.basename(self.location_abs) 178 for cvsentry in cvsentries: 179 # an entries line looks like the following: 180 # /README.TXT/1.19/Sun Dec 16 06:00:12 2001// 181 cvsentryparts = cvsentry.split("/") 182 if len(cvsentryparts) < 6: 183 continue 184 if os.path.normcase(cvsentryparts[1]) == os.path.normcase(filename): 185 if cvsentryparts[5].startswith("T"): 186 return cvsentryparts[5][1:].strip() 187 return None
188