1   
  2   
  3   
  4   
  5   
  6   
  7   
  8   
  9   
 10   
 11   
 12   
 13   
 14   
 15   
 16   
 17   
 18   
 19   
 20   
 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           
 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   
 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                   
 76                   
 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                   
 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               
 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           
101          command.append(filename) 
102          exitcode, output, error = run_command(command) 
103           
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           
112          try: 
113              os.chdir(original_dir) 
114          except OSError: 
115              pass 
116           
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                   
130                   
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                   
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           
145          command.append(filename) 
146          exitcode, output, error = run_command(command) 
147           
148          try: 
149              os.chdir(original_dir) 
150          except OSError: 
151              pass 
152           
153          if exitcode != 0: 
154              raise IOError("[CVS] Error running CVS command '%s': %s" % (command, error)) 
155          else: 
156              return output 
 157   
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               
165               
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   
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               
180               
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