2
# wc.py: functions for interacting with a Subversion working copy
4
# Subversion is a tool for revision control.
5
# See http://subversion.tigris.org for more information.
7
# ====================================================================
8
# Copyright (c) 2000-2004 CollabNet. All rights reserved.
10
# This software is licensed as described in the file COPYING, which
11
# you should have received as part of this distribution. The terms
12
# are also available at http://subversion.tigris.org/license-1.html.
13
# If newer versions of this license are posted there, you may use a
14
# newer version instead, at your option.
16
######################################################################
25
"""Describes an existing or expected state of a working copy.
27
The primary metaphor here is a dictionary of paths mapping to instances
28
of StateItem, which describe each item in a working copy.
30
Note: the paths should be *relative* to the root of the working copy.
33
def __init__(self, wc_dir, desc):
34
"Create a State using the specified description."
35
assert isinstance(desc, types.DictionaryType)
38
self.desc = desc # dictionary: path -> StateItem
40
def add(self, more_desc):
41
"Add more state items into the State."
42
assert isinstance(more_desc, types.DictionaryType)
44
self.desc.update(more_desc)
46
def remove(self, *paths):
47
"Remove a path from the state (the path must exist)."
52
"Make a deep copy of self."
54
for path, item in self.desc.items():
55
desc[path] = item.copy()
56
return State(self.wc_dir, desc)
58
def tweak(self, *args, **kw):
59
"""Tweak the items' values, optional restricting based on a filter.
61
The general form of this method is .tweak(paths..., key=value). If
62
one or more paths are provided, then those items' values are
63
modified. If no paths are given, then all items are modified.
67
apply(self.desc[path].tweak, (), kw)
69
for item in self.desc.values():
70
apply(item.tweak, (), kw)
72
def tweak_some(self, filter, **kw):
73
"Tweak the items for which the filter returns true."
74
for path, item in self.desc.items():
75
if filter(path, item):
76
apply(item.tweak, (), kw)
78
def write_to_disk(self, target_dir):
79
"""Construct a directory structure on disk, matching our state.
81
WARNING: any StateItem that does not have contents (.contents is None)
82
is assumed to be a directory.
84
if not os.path.exists(target_dir):
85
os.makedirs(target_dir)
87
for path, item in self.desc.items():
88
fullpath = os.path.join(target_dir, path)
89
if item.contents is None:
91
if not os.path.exists(fullpath):
96
# ensure its directory exists
97
dirpath = os.path.dirname(fullpath)
98
if not os.path.exists(dirpath):
101
# write out the file contents now
102
open(fullpath, 'w').write(item.contents)
105
"Return an old-style tree (for compatibility purposes)."
107
for path, item in self.desc.items():
109
if item.status is not None:
110
atts['status'] = item.status
111
if item.verb is not None:
112
atts['verb'] = item.verb
113
if item.wc_rev is not None:
114
atts['wc_rev'] = item.wc_rev
115
if item.locked is not None:
116
atts['locked'] = item.locked
117
if item.copied is not None:
118
atts['copied'] = item.copied
119
if item.switched is not None:
120
atts['switched'] = item.switched
121
if item.writelocked is not None:
122
atts['writelocked'] = item.writelocked
123
nodelist.append((os.path.normpath(os.path.join(self.wc_dir, path)),
128
return svntest.tree.build_generic_tree(nodelist)
132
"""Describes an individual item within a working copy.
134
Note that the location of this item is not specified. An external
135
mechanism, such as the State class, will provide location information
139
def __init__(self, contents=None, props=None,
140
status=None, verb=None, wc_rev=None,
141
locked=None, copied=None, switched=None, writelocked=None):
142
# provide an empty prop dict if it wasn't provided
146
### keep/make these ints one day?
147
if wc_rev is not None:
150
self.contents = contents
157
self.switched = switched
158
self.writelocked = writelocked
161
"Make a deep copy of self."
163
vars(new).update(vars(self))
164
new.props = self.props.copy()
167
def tweak(self, **kw):
168
for name, value in kw.items():
169
### refine the revision args (for now) to ensure they are strings
172
setattr(self, name, value)