2
# -*- encoding: utf-8 -*-
3
# Copyright (C) 2007-2009 Guillermo Gonzalez
5
# The code taken from bzrlib is under: Copyright (C) 2005-2007 Canonical Ltd
7
# This program is free software; you can redistribute it and/or modify
8
# it under the terms of the GNU General Public License as published by
9
# the Free Software Foundation; either version 2 of the License, or
10
# (at your option) any later version.
12
# This program is distributed in the hope that it will be useful,
13
# but WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
# GNU General Public License for more details.
17
# You should have received a copy of the GNU General Public License
18
# along with this program; if not, write to the Free Software
19
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24
"""This code is a modified copy from bzrlib.info (see there for copyrights and
28
__all__ = ['show_bzrdir_info_xml']
30
from bzrlib import info
31
from bzrlib.lazy_import import lazy_import
32
lazy_import(globals(), """
44
from bzrlib.errors import (NoWorkingTree, NotBranchError,
45
NoRepositoryPresent, NotLocalUrl)
48
def get_lines_xml(self):
49
"""Returns the locations lines as xml."""
50
return ["<%s>%s</%s>" % (l.replace(' ', '_'), u, l.replace(' ', '_')) \
51
for l, u in self.locs ]
53
info.LocationList.get_lines_xml = get_lines_xml
56
def show_bzrdir_info_xml(a_bzrdir, verbose=False, outfile=None):
57
"""Output to stdout the 'info' for a_bzrdir."""
61
tree = a_bzrdir.open_workingtree(
62
recommend_upgrade=False)
63
except (NoWorkingTree, NotLocalUrl):
66
branch = a_bzrdir.open_branch()
67
except NotBranchError:
70
repository = a_bzrdir.open_repository()
71
except NoRepositoryPresent:
72
# Return silently; cmd_info already returned NotBranchError
73
# if no bzrdir could be opened.
78
repository = branch.repository
82
repository = branch.repository
87
outfile.write('<?xml version="1.0"?>')
88
outfile.write('<info>')
89
show_component_info_xml(a_bzrdir, repository, branch, tree, verbose,
91
outfile.write('</info>')
96
def show_component_info_xml(control, repository, branch=None,
97
working=None, verbose=1, outfile=None):
98
"""Write info about all bzrdir components to stdout"""
105
layout = info.describe_layout(repository, branch, working)
106
formats = info.describe_format(control, repository,
107
branch, working).split(' or ')
108
outfile.write('<layout>%s</layout>' % layout)
109
outfile.write('<formats>')
111
for format in formats:
112
outfile.write('<format>%s</format>' % format)
114
outfile.write('<format>%s</format>' % formats[0])
115
outfile.write('</formats>')
116
_show_location_info_xml(info.gather_location_info(repository, branch,
118
if branch is not None:
119
_show_related_info_xml(branch, outfile)
122
_show_format_info_xml(control, repository, branch, working, outfile)
123
_show_locking_info_xml(repository, branch, working, outfile)
124
if branch is not None:
125
_show_missing_revisions_branch_xml(branch, outfile)
126
if working is not None:
127
_show_working_stats_xml(working, outfile)
128
elif branch is not None:
129
_show_missing_revisions_branch_xml(branch, outfile)
130
if branch is not None:
131
stats = _show_branch_stats_xml(branch, verbose==2, outfile)
133
stats = repository.gather_stats()
134
if branch is None and working is None:
135
_show_repository_info_xml(repository, outfile)
136
_show_repository_stats_xml(stats, outfile)
139
def _show_location_info_xml(locs, outfile):
140
"""Show known locations for working, branch and repository."""
141
outfile.write('<location>')
142
path_list = info.LocationList(osutils.getcwd())
143
for name, loc in locs:
144
path_list.add_url(name, loc)
145
outfile.writelines(path_list.get_lines_xml())
146
outfile.write('</location>')
149
def _show_related_info_xml(branch, outfile):
150
"""Show parent and push location of branch."""
151
locs = info._gather_related_branches(branch)
152
if len(locs.locs) > 0:
153
outfile.write('<related_branches>')
154
outfile.writelines(locs.get_lines_xml())
155
outfile.write('</related_branches>')
157
def _show_format_info_xml(control=None, repository=None,
158
branch=None, working=None, outfile=None):
159
"""Show known formats for control, working, branch and repository."""
160
outfile.write('<format>')
162
outfile.write('<control>%s</control>' %
163
control._format.get_format_description())
165
outfile.write('<working_tree>%s</working_tree>' %
166
working._format.get_format_description())
168
outfile.write('<branch>%s</branch>' %
169
branch._format.get_format_description())
171
outfile.write('<repository>%s</repository>' %
172
repository._format.get_format_description())
173
outfile.write('</format>')
176
def _show_locking_info_xml(repository, branch=None, working=None, outfile=None):
177
"""Show locking status of working, branch and repository."""
178
if (repository.get_physical_lock_status() or
179
(branch and branch.get_physical_lock_status()) or
180
(working and working.get_physical_lock_status())):
181
outfile.write('<lock_status>')
183
if working.get_physical_lock_status():
187
outfile.write('<working_tree>%s</<working_tree>' % status)
189
if branch.get_physical_lock_status():
193
outfile.write('<branch>%s</branch>' % status)
195
if repository.get_physical_lock_status():
199
outfile.write('<repository>%s</repository>' % status)
200
outfile.write('</lock_status>')
202
def _show_missing_revisions_branch_xml(branch, outfile):
203
"""Show missing master revisions in branch."""
204
# Try with inaccessible branch ?
205
master = branch.get_master_branch()
207
local_extra, remote_extra = missing.find_unmerged(branch, master)
209
outfile.write('<branch_stats>')
210
outfile.write('<missing_revisions>%d<missing_revisions>' %
212
outfile.write('</branch_stats>')
215
def _show_missing_revisions_working_xml(working, outfile):
216
"""Show missing revisions in working tree."""
217
branch = working.branch
218
basis = working.basis_tree()
219
branch_revno, branch_last_revision = branch.last_revision_info()
221
tree_last_id = working.get_parent_ids()[0]
225
if branch_revno and tree_last_id != branch_last_revision:
226
tree_last_revno = branch.revision_id_to_revno(tree_last_id)
227
missing_count = branch_revno - tree_last_revno
228
outfile.write('<missing_revisions>%d</missing_revisions>' %
232
def _show_working_stats_xml(working, outfile):
233
"""Show statistics about a working tree."""
234
basis = working.basis_tree()
235
delta = working.changes_from(basis, want_unchanged=True)
237
outfile.write('<working_tree_stats>')
238
_show_missing_revisions_working_xml(working, outfile)
239
outfile.write('<unchanged>%s</unchanged>' % len(delta.unchanged))
240
outfile.write('<modified>%d</modified>' % len(delta.modified))
241
outfile.write('<added>%d</added>' % len(delta.added))
242
outfile.write('<removed>%d</removed>' % len(delta.removed))
243
outfile.write('<renamed>%d</renamed>' % len(delta.renamed))
245
ignore_cnt = unknown_cnt = 0
246
for path in working.extras():
247
if working.is_ignored(path):
251
outfile.write('<unknown>%d</unknown>' % unknown_cnt)
252
outfile.write('<ignored>%d</ignored>' % ignore_cnt)
255
for path, entry in working.iter_entries_by_dir():
256
if entry.kind == 'directory' and entry.parent_id is not None:
258
outfile.write('<versioned_subdirectories>%d</versioned_subdirectories>' %
261
outfile.write('</working_tree_stats>')
264
def _show_branch_stats_xml(branch, verbose, outfile):
265
"""Show statistics about a branch."""
266
revno, head = branch.last_revision_info()
267
outfile.write('<branch_history>')
268
outfile.write('<revisions>%d</revisions>' % (revno))
269
stats = branch.repository.gather_stats(head, committers=verbose)
271
committers = stats['committers']
272
outfile.write('<committers>%d</committers>' % (committers))
274
timestamp, timezone = stats['firstrev']
275
age = int((time.time() - timestamp) / 3600 / 24)
276
outfile.write('<days_old>%d</days_old>' % (age))
277
outfile.write('<first_revision>%s</first_revision>' % \
278
osutils.format_date(timestamp, timezone))
279
timestamp, timezone = stats['latestrev']
280
outfile.write('<latest_revision>%s</latest_revision>' % \
281
osutils.format_date(timestamp, timezone))
282
outfile.write('</branch_history>')
286
def _show_repository_info_xml(repository, outfile):
287
"""Show settings of a repository."""
288
## FIXME/TODO: is this needed in the xml output?
289
#if repository.make_working_trees():
290
# print 'Create working tree for new branches inside the repository.'
293
def _show_repository_stats_xml(stats, outfile):
294
"""Show statistics about a repository."""
295
if 'revisions' in stats or 'size' in stats:
296
outfile.write('<repository_stats>')
297
if 'revisions' in stats:
298
revisions = stats['revisions']
299
outfile.write('<revisions>%d</revisions>' % (revisions))
301
outfile.write('<size unit="KiB">%d</size>' % (stats['size']/1024))
302
if 'revisions' in stats or 'size' in stats:
303
outfile.write('</repository_stats>')