22
from StringIO import StringIO
24
from bzrlib.errors import NoWorkingTree
25
from bzrlib.log import show_log, log_formatter
23
26
from bzrlib.rio import RioReader, RioWriter, Stanza
24
from bzrlib.errors import NoWorkingTree
25
27
from errors import UncleanError
27
29
def is_clean(branch):
29
Raise an UncleanError if there is anything unclean about this
30
"""Check if a branch is clean.
32
32
:param branch: The branch to check for changes
33
33
TODO: jam 20051228 This might be better to ask for a WorkingTree
34
34
instead of a Branch.
35
:return: (is_clean, message)
37
38
new_tree = branch.working_tree()
38
39
except NoWorkingTree:
39
40
# Trees without a working tree can't be dirty :)
42
43
# Look for unknown files in the new tree
43
44
for info in new_tree.list_files():
45
46
file_class = info[1]
46
47
if file_class == '?':
47
raise UncleanError(branch, 'path %s is unknown' % (path,))
48
return False, 'path %s is unknown' % (path,)
49
50
from bzrlib.diff import compare_trees
50
51
# See if there is anything that has been changed
51
52
old_tree = branch.basis_tree()
52
53
delta = compare_trees(old_tree, new_tree, want_unchanged=False)
53
54
if len(delta.added) > 0:
54
raise UncleanError(branch, 'have added files: %r' % (delta.added,))
55
return False, 'have added files: %r' % (delta.added,)
55
56
if len(delta.removed) > 0:
56
raise UncleanError(branch, 'have removed files: %r' % (delta.removed,))
57
return False, 'have removed files: %r' % (delta.removed,)
57
58
if len(delta.modified) > 0:
58
raise UncleanError(branch, 'have modified files: %r' % (delta.modified,))
59
return False, 'have modified files: %r' % (delta.modified,)
59
60
if len(delta.renamed) > 0:
60
raise UncleanError(branch, 'have renamed files: %r' % (delta.renamed,))
61
return False, 'have renamed files: %r' % (delta.renamed,)
63
68
def generate_rio_version(branch, to_file,
64
69
check_for_clean=False,
65
70
include_revision_history=False,
66
include_log_info=False,
67
include_log_deltas=False):
71
include_log_info=False):
68
72
"""Create the version file for this project.
70
74
:param branch: The branch to write information about
75
79
:param include_revision_history: Write out the list of revisions
76
80
:param include_log_info: Include log information (log summary, etc),
77
81
only valid if include_revision_history is also True
78
:param include_log_deltas: Include information about what changed in
79
each revision. Only valid if include_log_info is also True
82
84
# TODO: jam 20051228 This might be better as the datestamp
83
85
# of the last commit
84
86
info.add('date', time.strftime('%Y-%m-%d %H:%M:%S (%A, %B %d, %Y, %Z)'))
85
87
info.add('revno', str(branch.revno()))
86
89
last_rev = branch.last_revision()
87
90
if last_rev is not None:
88
91
info.add('revision_id', last_rev)
89
93
if branch.nick is not None:
90
94
info.add('branch_nick', branch.nick)
91
96
if check_for_clean:
97
clean, message = is_clean(branch)
99
info.add('clean', 'True')
95
101
info.add('clean', 'False')
103
if include_revision_history:
104
revs = branch.revision_history()
105
if not include_log_info:
106
info.add('revisions', '\n'.join(revs))
97
info.add('clean', 'True')
110
rev = branch.get_revision(rev_id)
111
log.add('revision', rev_id)
112
log.add('message', rev.message)
114
log_writer = RioWriter(to_file=sio)
115
log_writer.write_stanza(log)
116
info.add('revisions_and_message', sio.getvalue())
98
118
writer = RioWriter(to_file=to_file)
99
119
writer.write_stanza(info)
101
version_formats = {None:generate_rio_version, 'rio':generate_rio_version}
121
version_formats['rio'] = generate_rio_version
123
version_formats[None] = generate_rio_version
125
_py_version_template = '''#!/usr/bin/env python
127
This file is automatically generated by utilities.generate_version()
128
It uses the current working tree to determine the revision.
133
revision_id = %(revision_id)r
134
branch_nick = %(branch_nick)r
135
build_date = %(date)r
137
revisions = %(revisions)r
139
if __name__ == '__main__':
140
print 'Revision: %%d' %% (revno, )
141
print 'nick: %%s' %% (branch_nick, )
142
print 'Revision id: %%s' %% (revision_id, )
145
def generate_python_version(branch, to_file,
146
check_for_clean=False,
147
include_revision_history=False,
148
include_log_info=False,
150
"""Create a python version file for this project.
152
:param branch: The branch to write information about
153
:param to_file: The file to write the information
154
:param check_for_clean: If true, check if the branch is clean.
155
This can be expensive for large trees. This is also only
156
valid for branches with working trees.
157
:param include_revision_history: Write out the list of revisions
158
:param include_log_info: Include log information (log summary, etc),
159
only valid if include_revision_history is also True
161
info = {'date':time.strftime('%Y-%m-%d %H:%M:%S (%A, %B %d, %Y, %Z)')
162
, 'revno':branch.revno()
163
, 'revision_id':branch.last_revision()
165
, 'branch_nick':branch.nick
169
if include_revision_history:
170
revs = branch.revision_history()
171
if not include_log_info:
172
info['revisions'] = revs
176
rev = branch.get_revision(rev_id)
177
log.append((rev_id, rev.message))
178
info['revisions'] = log
184
info['clean'] = False
186
to_file.write(_py_version_template % info)
188
version_formats['python'] = generate_python_version