1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
|
# Copyright (C) 2004 Aaron Bentley
# <aaron.bentley@utoronto.ca>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
import sys
import os
import shutil
sys.path=[os.path.realpath(os.path.dirname(__file__)+"/..")]+sys.path
import arch
import pylon
import pylon.util
from pylon import errors
import cmdutil
import commands
__docformat__ = "restructuredtext"
__doc__ = "Native replay command"
def read_changeset(revision):
my_dir = pylon.util.tmpdir(os.getcwd())
changeset = revision.get_patch(my_dir)
real = pylon.read_arch_changeset(changeset)
shutil.rmtree(my_dir)
return real
class ComposeHandler:
def __init__(self, tree, reverse, munge_opts):
self.tree = tree
self.reverse = reverse
self.munge_opts = munge_opts
self.last_changeset = None
def handle_revision(self, revision):
if self.last_changeset is None:
cmdutil.chatter("Reading %s" % str(revision))
self.last_changeset = read_changeset(revision)
else:
cmdutil.chatter("Combining with %s" % str(revision))
next_changeset = read_changeset(revision)
self.last_changeset = pylon.compose_changesets(self.last_changeset,
next_changeset)
return 0
def finalize(self):
if self.last_changeset is None:
return False
cmdutil.chatter("Applying changeset")
inventory = pylon.get_id_filename_map(self.tree)
pylon.add_inventory_missing(inventory, self.last_changeset,
self.reverse)
pylon.apply_changeset(self.last_changeset, inventory, self.tree,
pylon.ArchConflictHandler(self.tree),
self.reverse)
return True
class ApplyNativeHandler:
def __init__(self, tree, reverse, munge_opts):
self.tree = tree
self.reverse = reverse
self.did_nothing = True
self.munge_opts = munge_opts
def handle_revision(self, revision):
self.did_nothing = False
cmdutil.chatter("Applying %s" % str(revision))
self.last_changeset = read_changeset(revision)
inventory = pylon.get_id_filename_map(self.tree)
pylon.add_inventory_missing(inventory, self.last_changeset,
self.reverse)
conflict_handler = pylon.ArchConflictHandler(self.tree)
pylon.apply_changeset(self.last_changeset, inventory, self.tree,
conflict_handler, self.reverse)
if conflict_handler.stop_conflicts:
return 1
else:
return 0
def finalize(self):
return not self.did_nothing
class ApplyHandler:
def __init__(self, tree, reverse, munge_opts):
self.tree = tree
self.reverse = reverse
self.did_nothing = True
self.munge_opts = munge_opts
def handle_revision(self, revision):
self.did_nothing = False
cmdutil.chatter("Applying %s" % str(revision))
result = pylon.replay(self.tree, revision, cmdutil.colorize,
reverse=self.reverse, munge_opts=self.munge_opts)
return result
def finalize(self):
return not self.did_nothing
class Replay(commands.BaseCommand):
"""Apply a revision's changeset to the current tree"""
def __init__(self):
self.description = self.__doc__
def get_completer(self, arg, index):
return cmdutil.merge_completions(arch.tree_root("."), arg, index)
def do_command(self, cmdargs):
try:
tree = arch.tree_root(".")
except arch.errors.TreeRootError, e:
raise errors.CommandFailedWrapper(e)
parser = self.get_parser()
(options, args) = parser.parse_args(cmdargs)
action = options.type
if action == "default":
action = "skip-present"
if options.logs_only:
munge_opts = pylon.MungeOpts()
munge_opts.all_types(True)
munge_opts.add_keep_pattern('^\./\{arch\}/[^=].*')
else:
munge_opts = None
if len(args) == 0:
args.append(None)
if munge_opts is not None or action == "skip-conflicts":
revision_handler = ApplyHandler(tree, options.reverse, munge_opts)
else:
revision_handler = options.method(tree, options.reverse, munge_opts)
if isinstance(revision_handler, ComposeHandler):
if options.reverse:
options.reverse_list = not options.reverse_list
for arg in args:
revisions = None
if options.type == "default" and arg is not None:
result = cmdutil.determine_version_revision_tree(arg, tree)
if isinstance(result, arch.Revision):
revisions = [result]
if revisions == None:
revisions = cmdutil.revision_iterator(tree, action, [arg],
options.reverse_list,
options.modified,
options.shallow)
for revision in revisions:
if isinstance(revision, arch.Patchlog):
revision = revision.revision
cmdutil.ensure_archive_registered(revision.archive)
status = revision_handler.handle_revision(revision)
if status != 0:
return status
if not revision_handler.finalize():
cmdutil.chatter("Tree is already up to date")
return 0
def get_parser(self):
parser = cmdutil.CmdOptionParser("fai revisions [revision]")
select = cmdutil.OptionGroup(parser, "Selection options",
"Control which revisions are applied. These options"
" are mutually exclusive. If more than one is"
" specified, the last is used.")
cmdutil.add_revision_iter_options(select)
select.add_option("--skip-conflicts", action="store_const",
const="skip-conflicts", dest="type",
help="Revisions that can be applied without"
"producing conflicts")
parser.add_option_group(select)
parser.add_option("-r", "--reverse", action="store_true",
dest="reverse", help="Apply changeset(s) in reverse")
parser.add_option("--reverse-list", action="store_true",
dest="reverse_list",
help="Apply revisions in reverse order")
parser.add_option("--patch-logs-only", action="store_true",
dest="logs_only",
help="Apply log changes only")
native = "read_arch_changeset" in dir(pylon)
parser.set_defaults(method=ApplyHandler)
if native:
parser.add_option("--native", action="store_const", dest="method",
help="Use native changeset method",
const=ApplyNativeHandler)
parser.add_option("--combine", action="store_const", dest="method",
help="Combine changesets before applying",
const=ComposeHandler)
return parser
def help(self, parser=None):
"""
Prints a help message.
:param parser: If supplied, the parser to use for generating help. If \
not supplied, it is retrieved.
:type parser: cmdutil.CmdOptionParser
"""
if parser==None:
parser=self.get_parser()
parser.print_help()
def add_command(commands):
commands["replay"] = Replay
# arch-tag: cd6b5159-30ee-410b-8ad4-7437b75f98cd
|