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   
27 -def is_available():
28 """check if cvs is installed""" 29 exitcode, output, error = run_command(["cvs", "--version"]) 30 return exitcode == 0
31 32
33 -class cvs(GenericRevisionControlSystem):
34 """Class to manage items under revision control of CVS.""" 35 36 RCS_METADIR = "CVS" 37 SCAN_PARENTS = False 38
39 - def _readfile(self, cvsroot, path, revision=None):
40 """ 41 Read a single file from the CVS repository without checking out a full 42 working directory. 43 44 @param cvsroot: the CVSROOT for the repository 45 @param path: path to the file relative to cvs root 46 @param revision: revision or tag to get (retrieves from HEAD if None) 47 """ 48 command = ["cvs", "-d", cvsroot, "-Q", "co", "-p"] 49 if revision: 50 command.extend(["-r", revision]) 51 # the path is the last argument 52 command.append(path) 53 exitcode, output, error = run_command(command) 54 if exitcode != 0: 55 raise IOError("[CVS] Could not read '%s' from '%s': %s / %s" % \ 56 (path, cvsroot, output, error)) 57 return output
58
59 - def getcleanfile(self, revision=None):
60 """Get the content of the file for the given revision""" 61 parentdir = os.path.dirname(self.location_abs) 62 cvsdir = os.path.join(parentdir, "CVS") 63 cvsroot = open(os.path.join(cvsdir, "Root"), "r").read().strip() 64 cvspath = open(os.path.join(cvsdir, "Repository"), "r").read().strip() 65 cvsfilename = os.path.join(cvspath, os.path.basename(self.location_abs)) 66 if revision is None: 67 cvsentries = open(os.path.join(cvsdir, "Entries"), "r").readlines() 68 revision = self._getcvstag(cvsentries) 69 if revision == "BASE": 70 cvsentries = open(os.path.join(cvsdir, "Entries"), "r").readlines() 71 revision = self._getcvsrevision(cvsentries) 72 return self._readfile(cvsroot, cvsfilename, revision)
73
74 - def update(self, revision=None):
75 """Does a clean update of the given path""" 76 working_dir = os.path.dirname(self.location_abs) 77 filename = self.location_abs 78 filename_backup = filename + os.path.extsep + "bak" 79 # rename the file to be updated 80 try: 81 os.rename(filename, filename_backup) 82 except OSError, error: 83 raise IOError("[CVS] could not move the file '%s' to '%s': %s" % \ 84 (filename, filename_backup, error)) 85 command = ["cvs", "-Q", "update", "-C"] 86 if revision: 87 command.extend(["-r", revision]) 88 # the filename is the last argument 89 command.append(os.path.basename(filename)) 90 # run the command within the given working_dir 91 exitcode, output, error = run_command(command, working_dir) 92 # restore backup in case of an error - remove backup for success 93 try: 94 if exitcode != 0: 95 os.rename(filename_backup, filename) 96 else: 97 os.remove(filename_backup) 98 except OSError: 99 pass 100 # raise an error or return successfully - depending on the CVS command 101 if exitcode != 0: 102 raise IOError("[CVS] Error running CVS command '%s': %s" \ 103 % (command, error)) 104 else: 105 return output
106
107 - def commit(self, message=None, author=None):
108 """Commits the file and supplies the given commit message if present 109 110 the 'author' parameter is not suitable for CVS, thus it is ignored 111 """ 112 working_dir = os.path.dirname(self.location_abs) 113 filename = os.path.basename(self.location_abs) 114 command = ["cvs", "-Q", "commit"] 115 if message: 116 command.extend(["-m", message]) 117 # the filename is the last argument 118 command.append(filename) 119 exitcode, output, error = run_command(command, working_dir) 120 # raise an error or return successfully - depending on the CVS command 121 if exitcode != 0: 122 raise IOError("[CVS] Error running CVS command '%s': %s" \ 123 % (command, error)) 124 else: 125 return output
126
127 - def _getcvsrevision(self, cvsentries):
128 """returns the revision number the file was checked out with by looking 129 in the lines of cvsentries 130 """ 131 filename = os.path.basename(self.location_abs) 132 for cvsentry in cvsentries: 133 # an entries line looks like the following: 134 # /README.TXT/1.19/Sun Dec 16 06:00:12 2001// 135 cvsentryparts = cvsentry.split("/") 136 if len(cvsentryparts) < 6: 137 continue 138 if os.path.normcase(cvsentryparts[1]) == os.path.normcase(filename): 139 return cvsentryparts[2].strip() 140 return None
141
142 - def _getcvstag(self, cvsentries):
143 """Returns the sticky tag the file was checked out with by looking in 144 the lines of cvsentries. 145 """ 146 filename = os.path.basename(self.location_abs) 147 for cvsentry in cvsentries: 148 # an entries line looks like the following: 149 # /README.TXT/1.19/Sun Dec 16 06:00:12 2001// 150 cvsentryparts = cvsentry.split("/") 151 if len(cvsentryparts) < 6: 152 continue 153 if os.path.normcase(cvsentryparts[1]) == os.path.normcase(filename): 154 if cvsentryparts[5].startswith("T"): 155 return cvsentryparts[5][1:].strip() 156 return None
157