2
# Copyright (C) 2007-2009 Guillermo Gonzalez
4
# The code taken from bzrlib is under: Copyright (C) 2005-2007 Canonical Ltd
6
# This program is free software; you can redistribute it and/or modify
7
# it under the terms of the GNU General Public License as published by
8
# the Free Software Foundation; either version 2 of the License, or
9
# (at your option) any later version.
11
# This program is distributed in the hope that it will be useful,
12
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
# GNU General Public License for more details.
16
# You should have received a copy of the GNU General Public License
17
# along with this program; if not, write to the Free Software
18
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
25
from bzrlib.lazy_import import lazy_import
26
lazy_import(globals(), """
38
from bzrlib.option import Option, custom_help
39
from bzrlib.commands import display_command
43
from xml_errors import handle_error_xml
47
version_info = info.bzr_plugin_version
48
plugin_name = info.bzr_plugin_name
50
null_option = option.Option('null',
51
help='Write an ascii NUL (\\0) as the final char.')
54
class cmd_xmlstatus(commands.Command):
55
"""Display status summary.
57
This reports on versioned and unknown files, reporting them
58
grouped by state. Possible states are:
61
Versioned in the working copy but not in the previous revision.
64
Versioned in the previous revision but removed or deleted
68
Path of this file changed from the previous revision;
69
the text may also have changed. This includes files whose
70
parent directory was renamed.
73
Text has changed since the previous revision.
76
File kind has been changed (e.g. from file to directory).
79
Not versioned and not matching an ignore pattern.
81
To see ignored files use 'bzr ignored'. For details on the
82
changes to file texts, use 'bzr diff'.
84
Note that --short or -S gives status flags for each item, similar
85
to Subversion's status command. To get output similar to svn -q,
88
If no arguments are specified, the status of the entire working
89
directory is shown. Otherwise, only the status of the specified
90
files or directories is reported. If a directory is given, status
91
is reported for everything inside that directory.
93
If a revision argument is given, the status is calculated against
94
that revision, or between two revisions if two are provided.
97
takes_args = ['file*']
98
takes_options = ['show-ids', 'revision', 'change',
99
Option('versioned', help='Only show versioned files.',
103
encoding_type = 'replace'
107
def run(self, file_list=None, revision=None, versioned=False, null=False):
108
from statusxml import show_tree_status_xml
109
tree, file_list = builtins.tree_files(file_list)
113
show_tree_status_xml(tree, show_ids=True,
114
specific_files=file_list, revision=revision,
115
to_file=to_file, versioned=versioned)
118
self.outf.write('\n')
121
class cmd_xmlannotate(commands.Command):
122
"""Show the origin of each line in a file.
124
This prints out the given file with an annotation on the left side
125
indicating which revision, author and date introduced the change.
127
If the origin is the same for a run of consecutive lines, it is
128
shown only at the top, unless the --all option is given.
131
takes_args = ['filename']
132
takes_options = ['revision', 'show-ids', null_option]
134
encoding_type = 'exact'
138
def run(self, filename, revision=None, show_ids=False, null=False):
139
from annotatexml import annotate_file_xml
140
wt, branch, relpath = \
141
bzrdir.BzrDir.open_containing_tree_or_branch(filename)
146
wt_root_path = wt.id2abspath(wt.get_root_id())
149
revision_id = branch.last_revision()
150
elif len(revision) != 1:
151
raise bzrlib.errors.BzrCommandError(
152
'xmlannotate --revision takes exactly 1 argument')
154
revision_id = revision[0].in_history(branch).rev_id
155
tree = branch.repository.revision_tree(revision_id)
157
file_id = wt.path2id(relpath)
159
file_id = tree.path2id(relpath)
161
raise bzrlib.errors.NotVersionedError(filename)
163
file_version = tree.inventory[file_id].revision
164
# always run with --all and --long options
165
# to get the author of each line
166
annotate_file_xml(branch=branch, rev_id=file_version,
167
file_id=file_id, to_file=self.outf, show_ids=show_ids,
168
wt_root_path=wt_root_path, file_path=relpath)
170
self.outf.write('\0')
171
self.outf.write('\n')
179
class cmd_xmlmissing(commands.Command):
180
"""Show unmerged/unpulled revisions between two branches.
182
OTHER_BRANCH may be local or remote.
185
takes_args = ['other_branch?']
187
Option('reverse', 'Reverse the order of revisions.'),
189
'Display changes in the local branch only.'),
190
Option('this' , 'Same as --mine-only.'),
191
Option('theirs-only',
192
'Display changes in the remote branch only.'),
193
Option('other', 'Same as --theirs-only.'),
198
encoding_type = 'replace'
202
def run(self, *args, **kwargs):
203
from missingxml import show_missing_xml
205
if self.outf is None:
206
self.outf = sys.stdout
208
show_missing_xml(self, log_format=logxml.XMLLogFormatter,
210
if getattr(kwargs, 'null', False):
211
self.outf.write('\0')
212
self.outf.write('\n')
215
class cmd_xmlinfo(commands.Command):
216
"""Show information about a working tree, branch or repository.
218
This command will show all known locations and formats associated to the
219
tree, branch or repository. Statistical information is included with
222
Branches and working trees will also report any missing revisions.
225
takes_args = ['location?']
226
takes_options = ['verbose', null_option]
227
encoding_type = 'replace'
231
def run(self, *args, **kwargs):
233
if kwargs.has_key('location'):
234
location = kwargs['location']
235
if kwargs.has_key('verbose') and kwargs['verbose']:
239
from infoxml import show_bzrdir_info_xml
241
from bzrlib.urlutils import normalize_url
242
location = normalize_url(location)
243
show_bzrdir_info_xml(bzrdir.BzrDir.open_containing(location)[0],
244
verbose=noise_level, outfile=self.outf)
245
if getattr(kwargs, 'null', False):
246
self.outf.write('\0')
247
self.outf.write('\n')
250
class cmd_xmlplugins(commands.Command):
251
"""List the installed plugins.
253
This command displays the list of installed plugins including
254
version of plugin and a short description of each.
258
takes_options = ['verbose', null_option]
262
def run(self, *args, **kwargs):
264
from inspect import getdoc
265
if self.outf is None:
266
self.outf = sys.stdout
268
self.outf.write('<?xml version="1.0" encoding="%s"?>' % \
269
bzrlib.osutils.get_user_encoding())
270
self.outf.write('<plugins>')
271
from writer import _escape_cdata
272
for name, plugin in bzrlib.plugin.plugins().items():
273
self.outf.write('<plugin>')
274
self.outf.write('<name>%s</name>' % name)
275
self.outf.write('<version>%s</version>' % plugin.__version__)
276
self.outf.write('<path>%s</path>' % plugin.path())
277
d = getdoc(plugin.module)
279
self.outf.write('<doc>%s</doc>' % _escape_cdata(d))
280
self.outf.write('</plugin>')
281
self.outf.write('</plugins>')
282
if getattr(kwargs, 'null', False):
283
self.outf.write('\0')
284
self.outf.write('\n')
287
class cmd_xmlversion(commands.Command):
288
"""Show version of bzr."""
290
encoding_type = 'replace'
291
takes_options = [Option("short", help="Only print the version number."),
296
def run(self, short=False, null=False):
297
from versionxml import show_version_xml
301
self.outf.write('<?xml version="1.0" encoding="%s"?>' % \
302
bzrlib.osutils.get_user_encoding())
304
to_file.write("<version><bazaar><version>" + \
305
bzrlib.version_string + \
306
"</version></bazaar></version>")
308
show_version_xml(to_file=to_file)
314
def xmllog_options():
315
# Take a copy of the log options before modifying it
316
opts = builtins.cmd_log.takes_options[:]
317
opts.append(null_option)
318
# Remove log_format since we requires our own
319
opts.remove('log-format')
323
class cmd_xmllog(builtins.cmd_log):
324
"""Show log of a branch, file, or directory as XML."""
327
takes_options = xmllog_options()
331
def run(self, *args, **kwargs):
332
# Force our specific formatter
333
kwargs['log_format'] = logxml.XMLLogFormatter
334
# Filter out our specific option
336
null = kwargs.pop('null')
339
exit_val = builtins.cmd_log.run(self, *args, **kwargs)
341
self.outf.write('\0')
342
self.outf.write('\n')
346
class cmd_xmlls(builtins.cmd_ls):
347
"""XML representation of the list of files in a tree.
351
_see_also = ['xmlstatus']
352
takes_args = ['path?']
353
# TODO: Take a revision or remote path and list that tree instead.
357
Option('non-recursive',
358
help='Don\'t recurse into subdirectories.'),
360
help='Print paths relative to the root of the branch.'),
361
Option('unknown', help='Print unknown files.'),
362
Option('versioned', help='Print versioned files.',
364
Option('ignored', help='Print ignored files.'),
366
help='List entries of a particular kind: file, ' + \
367
'directory, symlink.',
371
encoding_type = 'replace'
376
def run(self, *args, **kwargs):
378
self.outf.write('<?xml version="1.0" encoding="%s"?>' % \
379
bzrlib.osutils.get_user_encoding())
380
lsxml.show_ls_xml(self.outf, *args, **kwargs)
381
if getattr(kwargs, 'null', False):
382
self.outf.write('\0')
383
self.outf.write('\n')
385
class cmd_start_xmlrpc(commands.Command):
386
"""Start the xmlrpc service."""
390
Option('hostname', argname='HOSTNAME', type=str,
391
help='Use the specified hostname, defaults to localhost.'),
392
Option('port', argname='PORT', type=int,
393
help='Use the specified port, defaults to 11111.'),
398
def run(self, port=11111, hostname='localhost', verbose=False):
400
hostname = socket.gethostname()
403
self.outf.write('Listening on http://'+hostname+':'+str(port)+'\n')
406
self.server = service.BzrXMLRPCServer((hostname, port),
407
logRequests=verbose, to_file=self.outf)
410
self.server.serve_forever()
412
self.server.shutdown()
415
class cmd_stop_xmlrpc(commands.Command):
416
"""Stops a xmlrpc service."""
420
Option('hostname', argname='HOSTNAME', type=str,
421
help='Use the specified hostname, defaults to localhost.'),
422
Option('port', argname='PORT', type=int,
423
help='Use the specified port, defaults to 11111.'),
428
def run(self, port=11111, hostname='localhost', verbose=False):
429
url = "http://"+hostname+":"+str(port)
431
self.outf.write('Stopping xmlrpc service on ' + url + '\n')
433
from xmlrpclib import Server