1 # (Be in -*- python -*- mode.)
3 # ====================================================================
4 # Copyright (c) 2000-2008 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 a class to store information about a CVS file."""
21 from cvs2svn_lib
.common
import path_join
22 from cvs2svn_lib
.context
import Ctx
25 class CVSPath(object):
26 """Represent a CVS file or directory.
30 id -- (int) unique ID for this CVSPath. At any moment, there is
31 at most one CVSPath instance with a particular ID. (This
32 means that object identity is the same as object equality, and
33 objects can be used as map keys even though they don't have a
36 project -- (Project) the project containing this CVSPath.
38 parent_directory -- (CVSDirectory or None) the CVSDirectory
39 containing this CVSPath.
41 basename -- (string) the base name of this CVSPath (no ',v'). The
42 basename of the root directory of a project is ''.
44 ordinal -- (int) the order that this instance should be sorted
45 relative to other CVSPath instances. This member is set based
46 on the ordering imposed by slow_compare() by CollectData after
47 all CVSFiles have been processed. Comparisons of CVSPath
48 using __cmp__() simply compare the ordinals.
60 def __init__(self
, id, project
, parent_directory
, basename
):
62 self
.project
= project
63 self
.parent_directory
= parent_directory
64 self
.basename
= basename
66 def __getstate__(self
):
67 """This method must only be called after ordinal has been set."""
70 self
.id, self
.project
.id,
71 self
.parent_directory
, self
.basename
,
75 def __setstate__(self
, state
):
78 self
.parent_directory
, self
.basename
,
81 self
.project
= Ctx()._projects
[project_id
]
83 def get_ancestry(self
):
84 """Return a list of the CVSPaths leading from the root path to SELF.
86 Return the CVSPaths in a list, starting with
87 self.project.get_root_cvs_directory() and ending with self."""
93 p
= p
.parent_directory
98 def get_cvs_path(self
):
99 """Return the canonical path within the Project.
103 - Uses forward slashes
105 - Doesn't include ',v' for files
107 - This doesn't include the 'Attic' segment of the path unless the
108 file is to be left in an Attic directory in the SVN repository;
109 i.e., if a filename exists in and out of Attic and the
110 --retain-conflicting-attic-files option was specified.
114 return path_join(*[p
.basename
for p
in self
.get_ancestry()[1:]])
116 cvs_path
= property(get_cvs_path
)
118 def _get_dir_components(self
):
119 """Return a list containing the components of the path leading to SELF.
121 The return value contains the base names of all of the parent
122 directories (except for the root directory) and SELF."""
124 return [p
.basename
for p
in self
.get_ancestry()[1:]]
127 """Compare two CVSPath instances for equality.
129 This method is supplied to avoid using __cmp__() for comparing for
134 def slow_compare(a
, b
):
136 # Sort first by project:
137 cmp(a
.project
, b
.project
)
138 # Then by directory components:
139 or cmp(a
._get
_dir
_components
(), b
._get
_dir
_components
())
143 """This method must only be called after ordinal has been set."""
145 return cmp(a
.ordinal
, b
.ordinal
)
148 class CVSDirectory(CVSPath
):
149 """Represent a CVS directory.
153 id -- (int or None) unique id for this file. If None, a new id is
156 project -- (Project) the project containing this file.
158 parent_directory -- (CVSDirectory or None) the CVSDirectory
159 containing this CVSDirectory.
161 basename -- (string) the base name of this CVSDirectory (no ',v').
167 def __init__(self
, id, project
, parent_directory
, basename
):
168 """Initialize a new CVSDirectory object."""
170 CVSPath
.__init
__(self
, id, project
, parent_directory
, basename
)
172 def get_filename(self
):
173 """Return the filesystem path to this CVSPath in the CVS repository."""
175 if self
.parent_directory
is None:
176 return self
.project
.project_cvs_repos_path
179 self
.parent_directory
.get_filename(), self
.basename
182 filename
= property(get_filename
)
184 def __getstate__(self
):
185 return CVSPath
.__getstate
__(self
)
187 def __setstate__(self
, state
):
188 CVSPath
.__setstate
__(self
, state
)
191 """For convenience only. The format is subject to change at any time."""
193 return self
.cvs_path
+ '/'
196 return 'CVSDirectory<%x>(%r)' % (self
.id, str(self
),)
199 class CVSFile(CVSPath
):
200 """Represent a CVS file.
204 id -- (int) unique id for this file.
206 project -- (Project) the project containing this file.
208 parent_directory -- (CVSDirectory) the CVSDirectory containing
211 basename -- (string) the base name of this CVSFile (no ',v').
213 _in_attic -- (bool) True if RCS file is in an Attic subdirectory
214 that is not considered the parent directory. (If a file is
215 in-and-out-of-attic and one copy is to be left in Attic after
216 the conversion, then the Attic directory is that file's
217 PARENT_DIRECTORY and _IN_ATTIC is False.)
219 executable -- (bool) True iff RCS file has executable bit set.
221 file_size -- (long) size of the RCS file in bytes.
223 mode -- (string or None) 'kkv', 'kb', etc.
225 PARENT_DIRECTORY might contain an 'Attic' component if it should be
226 retained in the SVN repository; i.e., if the same filename exists out
227 of Attic and the --retain-conflicting-attic-files option was specified.
240 self
, id, project
, parent_directory
, basename
, in_attic
,
241 executable
, file_size
, mode
, description
243 """Initialize a new CVSFile object."""
245 CVSPath
.__init
__(self
, id, project
, parent_directory
, basename
)
246 self
._in
_attic
= in_attic
247 self
.executable
= executable
248 self
.file_size
= file_size
250 self
.description
= description
252 assert self
.parent_directory
is not None
254 def get_filename(self
):
255 """Return the filesystem path to this CVSPath in the CVS repository."""
259 self
.parent_directory
.filename
, 'Attic', self
.basename
+ ',v'
263 self
.parent_directory
.filename
, self
.basename
+ ',v'
266 filename
= property(get_filename
)
268 def __getstate__(self
):
270 CVSPath
.__getstate
__(self
),
271 self
._in
_attic
, self
.executable
, self
.file_size
, self
.mode
, self
.description
274 def __setstate__(self
, state
):
277 self
._in
_attic
, self
.executable
, self
.file_size
, self
.mode
, self
.description
279 CVSPath
.__setstate
__(self
, cvs_path_state
)
282 """For convenience only. The format is subject to change at any time."""
287 return 'CVSFile<%x>(%r)' % (self
.id, str(self
),)