~jelmer/bzr-xmloutput/no-revision-history

« back to all changes in this revision

Viewing changes to __init__.py

  • Committer: Guillermo Gonzalez
  • Author(s): Jelmer Vernooij
  • Date: 2011-03-09 23:05:27 UTC
  • mfrom: (150.2.1 trunk)
  • Revision ID: guillo.gonzo@gmail.com-20110309230527-lqwt272otza8s6rt
Lazily load bzr-xmloutput commands.

Show diffs side-by-side

added added

removed removed

Lines of Context:
30
30
bzrlib.status, bzrlib.delta.TreeDelta.show and bzrlib.log.LongLogFormatter)
31
31
"""
32
32
import info
33
 
import bzrlib
34
 
from bzrlib.lazy_import import lazy_import
35
 
lazy_import(globals(), """
36
 
import sys
37
33
from bzrlib import (
38
 
    builtins,
39
 
    bzrdir,
40
 
    commands,
41
 
    option,
42
34
    log,
43
 
    workingtree,
44
 
    errors
45
35
    )
46
36
 
47
 
from bzrlib.option import Option, custom_help
48
 
from bzrlib.commands import display_command, register_command
49
 
import logxml
50
 
import service
51
 
import socket
52
 
from xml_errors import handle_error_xml
53
 
""")
54
 
 
 
37
from bzrlib.commands import plugin_cmds
55
38
 
56
39
version_info = info.bzr_plugin_version
57
40
plugin_name = info.bzr_plugin_name
58
41
 
59
 
null_option = option.Option('null',
60
 
                            help='Write an ascii NUL (\\0) as the final char.')
61
 
 
62
 
 
63
 
class cmd_xmlstatus(commands.Command):
64
 
    """Display status summary.
65
 
 
66
 
    This reports on versioned and unknown files, reporting them
67
 
    grouped by state.  Possible states are:
68
 
 
69
 
    added
70
 
        Versioned in the working copy but not in the previous revision.
71
 
 
72
 
    removed
73
 
        Versioned in the previous revision but removed or deleted
74
 
        in the working copy.
75
 
 
76
 
    renamed
77
 
        Path of this file changed from the previous revision;
78
 
        the text may also have changed.  This includes files whose
79
 
        parent directory was renamed.
80
 
 
81
 
    modified
82
 
        Text has changed since the previous revision.
83
 
 
84
 
    kind changed
85
 
        File kind has been changed (e.g. from file to directory).
86
 
 
87
 
    unknown
88
 
        Not versioned and not matching an ignore pattern.
89
 
 
90
 
    To see ignored files use 'bzr ignored'.  For details on the
91
 
    changes to file texts, use 'bzr diff'.
92
 
 
93
 
    Note that --short or -S gives status flags for each item, similar
94
 
    to Subversion's status command. To get output similar to svn -q,
95
 
    use bzr -SV.
96
 
 
97
 
    If no arguments are specified, the status of the entire working
98
 
    directory is shown.  Otherwise, only the status of the specified
99
 
    files or directories is reported.  If a directory is given, status
100
 
    is reported for everything inside that directory.
101
 
 
102
 
    If a revision argument is given, the status is calculated against
103
 
    that revision, or between two revisions if two are provided.
104
 
    """
105
 
    hidden = True
106
 
    takes_args = ['file*']
107
 
    takes_options = ['show-ids', 'revision', 'change',
108
 
                     Option('versioned', help='Only show versioned files.',
109
 
                            short_name='V'),
110
 
                     null_option
111
 
                     ]
112
 
    encoding_type = 'replace'
113
 
 
114
 
    @display_command
115
 
    @handle_error_xml
116
 
    def run(self, file_list=None, revision=None, versioned=False, null=False):
117
 
        from statusxml import show_tree_status_xml
118
 
        tree, file_list = builtins.tree_files(file_list)
119
 
        to_file = self.outf
120
 
        if to_file is None:
121
 
            to_file = sys.stdout
122
 
        show_tree_status_xml(tree, show_ids=True,
123
 
            specific_files=file_list, revision=revision,
124
 
            to_file=to_file, versioned=versioned)
125
 
        if null:
126
 
            to_file.write('\0')
127
 
        self.outf.write('\n')
128
 
 
129
 
 
130
 
class cmd_xmlannotate(commands.Command):
131
 
    """Show the origin of each line in a file.
132
 
 
133
 
    This prints out the given file with an annotation on the left side
134
 
    indicating which revision, author and date introduced the change.
135
 
 
136
 
    If the origin is the same for a run of consecutive lines, it is
137
 
    shown only at the top, unless the --all option is given.
138
 
    """
139
 
    hidden = True
140
 
    takes_args = ['filename']
141
 
    takes_options = ['revision', 'show-ids', null_option]
142
 
 
143
 
    encoding_type = 'exact'
144
 
 
145
 
    @display_command
146
 
    @handle_error_xml
147
 
    def run(self, filename, revision=None, show_ids=False, null=False):
148
 
        from annotatexml import annotate_file_xml
149
 
        wt, branch, relpath = \
150
 
            bzrdir.BzrDir.open_containing_tree_or_branch(filename)
151
 
        if wt is not None:
152
 
            wt.lock_read()
153
 
        else:
154
 
            branch.lock_read()
155
 
        wt_root_path = wt.id2abspath(wt.get_root_id())
156
 
        try:
157
 
            if revision is None:
158
 
                revision_id = branch.last_revision()
159
 
            elif len(revision) != 1:
160
 
                raise bzrlib.errors.BzrCommandError(
161
 
                    'xmlannotate --revision takes exactly 1 argument')
162
 
            else:
163
 
                revision_id = revision[0].in_history(branch).rev_id
164
 
            tree = branch.repository.revision_tree(revision_id)
165
 
            if wt is not None:
166
 
                file_id = wt.path2id(relpath)
167
 
            else:
168
 
                file_id = tree.path2id(relpath)
169
 
            if file_id is None:
170
 
                raise bzrlib.errors.NotVersionedError(filename)
171
 
 
172
 
            file_version = tree.inventory[file_id].revision
173
 
            # always run with --all and --long options
174
 
            # to get the author of each line
175
 
            annotate_file_xml(branch=branch, rev_id=file_version,
176
 
                    file_id=file_id, to_file=self.outf, show_ids=show_ids,
177
 
                    wt_root_path=wt_root_path, file_path=relpath)
178
 
            if null:
179
 
                self.outf.write('\0')
180
 
            self.outf.write('\n')
181
 
        finally:
182
 
            if wt is not None:
183
 
                wt.unlock()
184
 
            else:
185
 
                branch.unlock()
186
 
 
187
 
 
188
 
class cmd_xmlmissing(commands.Command):
189
 
    """Show unmerged/unpulled revisions between two branches.
190
 
 
191
 
    OTHER_BRANCH may be local or remote.
192
 
    """
193
 
    hidden = True
194
 
    takes_args = ['other_branch?']
195
 
    takes_options = [
196
 
            Option('reverse', 'Reverse the order of revisions.'),
197
 
            Option('mine-only',
198
 
                   'Display changes in the local branch only.'),
199
 
            Option('this' , 'Same as --mine-only.'),
200
 
            Option('theirs-only',
201
 
                   'Display changes in the remote branch only.'),
202
 
            Option('other', 'Same as --theirs-only.'),
203
 
            'show-ids',
204
 
            'verbose',
205
 
            null_option
206
 
            ]
207
 
    encoding_type = 'replace'
208
 
 
209
 
    @display_command
210
 
    @handle_error_xml
211
 
    def run(self, *args, **kwargs):
212
 
        from missingxml import show_missing_xml
213
 
 
214
 
        if self.outf is None:
215
 
            self.outf = sys.stdout
216
 
 
217
 
        show_missing_xml(self, log_format=logxml.XMLLogFormatter,
218
 
                         *args, **kwargs)
219
 
        if getattr(kwargs, 'null', False):
220
 
            self.outf.write('\0')
221
 
        self.outf.write('\n')
222
 
 
223
 
 
224
 
class cmd_xmlinfo(commands.Command):
225
 
    """Show information about a working tree, branch or repository.
226
 
 
227
 
    This command will show all known locations and formats associated to the
228
 
    tree, branch or repository.  Statistical information is included with
229
 
    each report.
230
 
 
231
 
    Branches and working trees will also report any missing revisions.
232
 
    """
233
 
    hidden = True
234
 
    takes_args = ['location?']
235
 
    takes_options = ['verbose', null_option]
236
 
    encoding_type = 'replace'
237
 
 
238
 
    @display_command
239
 
    @handle_error_xml
240
 
    def run(self, *args, **kwargs):
241
 
        location = None
242
 
        if kwargs.has_key('location'):
243
 
            location = kwargs['location']
244
 
        if kwargs.has_key('verbose') and kwargs['verbose']:
245
 
            noise_level = 2
246
 
        else:
247
 
            noise_level = 0
248
 
        from infoxml import show_bzrdir_info_xml
249
 
        if location != None:
250
 
            from bzrlib.urlutils import normalize_url
251
 
            location = normalize_url(location)
252
 
        show_bzrdir_info_xml(bzrdir.BzrDir.open_containing(location)[0],
253
 
                             verbose=noise_level, outfile=self.outf)
254
 
        if getattr(kwargs, 'null', False):
255
 
            self.outf.write('\0')
256
 
        self.outf.write('\n')
257
 
 
258
 
 
259
 
class cmd_xmlplugins(commands.Command):
260
 
    """List the installed plugins.
261
 
 
262
 
    This command displays the list of installed plugins including
263
 
    version of plugin and a short description of each.
264
 
 
265
 
    """
266
 
    hidden = True
267
 
    takes_options = ['verbose', null_option]
268
 
 
269
 
    @display_command
270
 
    @handle_error_xml
271
 
    def run(self, *args, **kwargs):
272
 
        import bzrlib.plugin
273
 
        from inspect import getdoc
274
 
        if self.outf is None:
275
 
            self.outf = sys.stdout
276
 
 
277
 
        self.outf.write('<?xml version="1.0" encoding="%s"?>' % \
278
 
                bzrlib.osutils.get_user_encoding())
279
 
        self.outf.write('<plugins>')
280
 
        from writer import _escape_cdata
281
 
        for name, plugin in bzrlib.plugin.plugins().items():
282
 
            self.outf.write('<plugin>')
283
 
            self.outf.write('<name>%s</name>' % name)
284
 
            self.outf.write('<version>%s</version>' % plugin.__version__)
285
 
            self.outf.write('<path>%s</path>' % plugin.path())
286
 
            d = getdoc(plugin.module)
287
 
            if d:
288
 
                self.outf.write('<doc>%s</doc>' % _escape_cdata(d))
289
 
            self.outf.write('</plugin>')
290
 
        self.outf.write('</plugins>')
291
 
        if getattr(kwargs, 'null', False):
292
 
            self.outf.write('\0')
293
 
        self.outf.write('\n')
294
 
 
295
 
 
296
 
class cmd_xmlversion(commands.Command):
297
 
    """Show version of bzr."""
298
 
    hidden = True
299
 
    encoding_type = 'replace'
300
 
    takes_options = [Option("short", help="Only print the version number."),
301
 
                    null_option]
302
 
 
303
 
    @display_command
304
 
    @handle_error_xml
305
 
    def run(self, short=False, null=False):
306
 
        from versionxml import show_version_xml
307
 
        to_file = self.outf
308
 
        if to_file is None:
309
 
            to_file = sys.stdout
310
 
        self.outf.write('<?xml version="1.0" encoding="%s"?>' % \
311
 
                bzrlib.osutils.get_user_encoding())
312
 
        if short:
313
 
            to_file.write("<version><bazaar><version>" + \
314
 
            bzrlib.version_string + \
315
 
            "</version></bazaar></version>")
316
 
        else:
317
 
            show_version_xml(to_file=to_file)
318
 
        if null:
319
 
            to_file.write('\0')
320
 
        to_file.write('\n')
321
 
 
322
 
 
323
 
def xmllog_options():
324
 
    # Take a copy of the log options before modifying it
325
 
    opts = builtins.cmd_log.takes_options[:]
326
 
    opts.append(null_option)
327
 
    # Remove log_format since we requires our own
328
 
    opts.remove('log-format')
329
 
    return opts
330
 
 
331
 
 
332
 
class cmd_xmllog(builtins.cmd_log):
333
 
    """Show log of a branch, file, or directory as XML."""
334
 
    hidden = True
335
 
 
336
 
    takes_options = xmllog_options()
337
 
 
338
 
    @display_command
339
 
    @handle_error_xml
340
 
    def run(self, *args, **kwargs):
341
 
        # Force our specific formatter
342
 
        kwargs['log_format'] = logxml.XMLLogFormatter
343
 
        # Filter out our specific option
344
 
        try:
345
 
            null = kwargs.pop('null')
346
 
        except KeyError:
347
 
            null = False
348
 
        exit_val =  builtins.cmd_log.run(self, *args, **kwargs)
349
 
        if null:
350
 
            self.outf.write('\0')
351
 
        self.outf.write('\n')
352
 
        return exit_val
353
 
 
354
 
 
355
 
class cmd_xmlls(builtins.cmd_ls):
356
 
    """XML representation of the list of files in a tree.
357
 
    """
358
 
 
359
 
    hidden = True
360
 
    _see_also = ['xmlstatus']
361
 
    takes_args = ['path?']
362
 
    # TODO: Take a revision or remote path and list that tree instead.
363
 
    takes_options = [
364
 
            'verbose',
365
 
            'revision',
366
 
            Option('non-recursive',
367
 
                   help='Don\'t recurse into subdirectories.'),
368
 
            Option('from-root',
369
 
                   help='Print paths relative to the root of the branch.'),
370
 
            Option('unknown', help='Print unknown files.'),
371
 
            Option('versioned', help='Print versioned files.',
372
 
                   short_name='V'),
373
 
            Option('ignored', help='Print ignored files.'),
374
 
            Option('kind',
375
 
                   help='List entries of a particular kind: file, ' + \
376
 
                   'directory, symlink.',
377
 
                   type=unicode),
378
 
            null_option
379
 
            ]
380
 
    encoding_type = 'replace'
381
 
 
382
 
 
383
 
    @display_command
384
 
    @handle_error_xml
385
 
    def run(self, *args, **kwargs):
386
 
        import lsxml
387
 
        self.outf.write('<?xml version="1.0" encoding="%s"?>' % \
388
 
                bzrlib.osutils.get_user_encoding())
389
 
        lsxml.show_ls_xml(self.outf, *args, **kwargs)
390
 
        if getattr(kwargs, 'null', False):
391
 
            self.outf.write('\0')
392
 
        self.outf.write('\n')
393
 
 
394
 
class cmd_start_xmlrpc(commands.Command):
395
 
    """Start the xmlrpc service."""
396
 
 
397
 
    hidden = True
398
 
    takes_options = [
399
 
            Option('hostname', argname='HOSTNAME', type=str,
400
 
                help='Use the specified hostname, defaults to localhost.'),
401
 
            Option('port', argname='PORT', type=int,
402
 
                help='Use the specified port, defaults to 11111.'),
403
 
            'verbose',
404
 
            ]
405
 
 
406
 
    @display_command
407
 
    def run(self, port=11111, hostname='localhost', verbose=False):
408
 
        if hostname is None:
409
 
            hostname = socket.gethostname()
410
 
 
411
 
        if verbose:
412
 
            self.outf.write('Listening on http://'+hostname+':'+str(port)+'\n')
413
 
            self.outf.flush()
414
 
 
415
 
        self.server = service.BzrXMLRPCServer((hostname, port),
416
 
                                     logRequests=verbose, to_file=self.outf)
417
 
 
418
 
        try:
419
 
            self.server.serve_forever()
420
 
        finally:
421
 
            self.server.shutdown()
422
 
 
423
 
 
424
 
class cmd_stop_xmlrpc(commands.Command):
425
 
    """Stops a xmlrpc service."""
426
 
 
427
 
    hidden = True
428
 
    takes_options = [
429
 
            Option('hostname', argname='HOSTNAME', type=str,
430
 
                help='Use the specified hostname, defaults to localhost.'),
431
 
            Option('port', argname='PORT', type=int,
432
 
                help='Use the specified port, defaults to 11111.'),
433
 
            'verbose',
434
 
            ]
435
 
 
436
 
    @display_command
437
 
    def run(self, port=11111, hostname='localhost', verbose=False):
438
 
        url = "http://"+hostname+":"+str(port)
439
 
        if verbose:
440
 
            self.outf.write('Stopping xmlrpc service on ' + url + '\n')
441
 
            self.outf.flush()
442
 
        from xmlrpclib import Server
443
 
        server = Server(url)
444
 
        server.quit()
445
 
 
446
 
register_command(cmd_xmlstatus, decorate=True)
447
 
register_command(cmd_xmlannotate, decorate=True)
448
 
register_command(cmd_xmlmissing, decorate=True)
449
 
register_command(cmd_xmlinfo, decorate=True)
450
 
register_command(cmd_xmlplugins, decorate=True)
451
 
register_command(cmd_xmlversion, decorate=True)
452
 
register_command(cmd_start_xmlrpc, decorate=True)
453
 
register_command(cmd_stop_xmlrpc, decorate=True)
454
 
register_command(cmd_xmllog, decorate=True)
455
 
register_command(cmd_xmlls, decorate=True)
456
 
log.log_formatter_registry.register('xml', logxml.XMLLogFormatter,
457
 
                              'Detailed XML log format')
 
42
for cmd in [
 
43
    "xmlstatus",
 
44
    "xmlannotate",
 
45
    "xmlmissing",
 
46
    "xmlinfo",
 
47
    "xmlplugins",
 
48
    "xmlversion",
 
49
    "start_xmlrpc",
 
50
    "stop_xmlrpc",
 
51
    "xmllog",
 
52
    "xmlls"]:
 
53
    plugin_cmds.register_lazy(
 
54
        "cmd_%s" % cmd, [],
 
55
        "bzrlib.plugins.xmloutput.cmds")
 
56
log.log_formatter_registry.register_lazy('xml',
 
57
    "bzrlib.plugins.xmloutput.logxml", "XMLLogFormatter",
 
58
    'Detailed XML log format')
458
59
 
459
60
 
460
61
def load_tests(basic_tests, module, loader):