Make minimal changes to get HTML files to be valid XHTML, dropping from Strict
[cvs2svn.git] / cvs2svn_lib / common.py
blobc8cc3b75e25e88d72f9d10c10102ea5919dbdee6
1 # (Be in -*- python -*- mode.)
3 # ====================================================================
4 # Copyright (c) 2000-2006 CollabNet. All rights reserved.
6 # This software is licensed as described in the file COPYING, which
7 # you should have received as part of this distribution. The terms
8 # are also available at http://subversion.tigris.org/license-1.html.
9 # If newer versions of this license are posted there, you may use a
10 # newer version instead, at your option.
12 # This software consists of voluntary contributions made by many
13 # individuals. For exact contribution history, see the revision
14 # history and logs, available at http://cvs2svn.tigris.org/.
15 # ====================================================================
17 """This module contains common facilities used by cvs2svn."""
20 import time
22 from boolean import *
25 SVN_INVALID_REVNUM = -1
28 # Things that can happen to a file.
29 OP_NOOP = '-'
30 OP_ADD = 'A'
31 OP_DELETE = 'D'
32 OP_CHANGE = 'C'
35 # Warnings and errors start with these strings. They are typically
36 # followed by a colon and a space, as in "%s: " ==> "WARNING: ".
37 warning_prefix = "WARNING"
38 error_prefix = "ERROR"
41 class FatalException(Exception):
42 """Exception thrown on a non-recoverable error.
44 If this exception is thrown by main(), it is caught by the global
45 layer of the program, its string representation is printed, and the
46 program is ended with an exit code of 1."""
48 pass
51 class FatalError(FatalException):
52 """A FatalException that prepends error_prefix to the message."""
54 def __init__(self, msg):
55 """Use (error_prefix + ': ' + MSG + '\n') as the error message."""
57 FatalException.__init__(self, '%s: %s\n' % (error_prefix, msg,))
60 def path_join(*components):
61 """Join two or more pathname COMPONENTS, inserting '/' as needed.
62 Empty component are skipped."""
64 return '/'.join(filter(None, components))
67 def path_split(path):
68 """Split the svn pathname PATH into a pair, (HEAD, TAIL).
70 This is similar to os.path.split(), but always uses '/' as path
71 separator. PATH is an svn path, which should not start with a '/'.
72 HEAD is everything before the last slash, and TAIL is everything
73 after. If PATH ends in a slash, TAIL will be empty. If there is no
74 slash in PATH, HEAD will be empty. If PATH is empty, both HEAD and
75 TAIL are empty."""
77 pos = path.rfind('/')
78 if pos == -1:
79 return ('', path,)
80 else:
81 return (path[:pos], path[pos+1:],)
84 # Since the unofficial set also includes [/\] we need to translate those
85 # into ones that don't conflict with Subversion limitations.
86 def clean_symbolic_name(name):
87 """Return symbolic name NAME, translating characters that Subversion
88 does not allow in a pathname."""
90 name = name.replace('/','++')
91 name = name.replace('\\','--')
92 return name
95 def format_date(date):
96 """Return an svn-compatible date string for DATE (seconds since epoch).
98 A Subversion date looks like '2002-09-29T14:44:59.000000Z'."""
100 return time.strftime("%Y-%m-%dT%H:%M:%S.000000Z", time.gmtime(date))