/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
0.5.7 by John Arbash Meinel
Added a bunch more information about changesets. Can now read back in all of the meta information.
1
#!/usr/bin/env python
2
"""\
3
Common entries, like strings, etc, for the changeset reading + writing code.
4
"""
5
1185.82.15 by Aaron Bentley
Disabled validate_revisions (needs info it doesn't have), updated API to repos
6
from sha import sha
7
0.5.79 by John Arbash Meinel
Added common to the set of tests, fixed a problem with time conversions.
8
import bzrlib
1185.82.15 by Aaron Bentley
Disabled validate_revisions (needs info it doesn't have), updated API to repos
9
from bzrlib.testament import Testament
0.5.79 by John Arbash Meinel
Added common to the set of tests, fixed a problem with time conversions.
10
1185.82.26 by Aaron Bentley
Get changeset merges closer to working
11
header_str = 'Bazaar changeset v'
1185.82.38 by Aaron Bentley
Changed changeset version number to 0.7
12
version = (0, 7)
0.5.7 by John Arbash Meinel
Added a bunch more information about changesets. Can now read back in all of the meta information.
13
14
def get_header():
15
    return [
16
        header_str + '.'.join([str(v) for v in version]),
17
        ''
18
    ]
19
0.5.36 by John Arbash Meinel
Updated so that read_changeset is able to parse the output
20
def canonicalize_revision(branch, revnos):
21
    """Turn some sort of revision information into a single
22
    set of from-to revision ids.
23
24
    A revision id can be None if there is no associated revison.
25
26
    :param revnos:  A list of revisions to lookup, should be at most 2 long
27
    :return: (old, new)
28
    """
29
    # If only 1 entry is given, then we assume we want just the
30
    # changeset between that entry and it's base (we assume parents[0])
31
    if len(revnos) == 0:
32
        revnos = [None, None]
33
    elif len(revnos) == 1:
34
        revnos = [None, revnos[0]]
35
36
    if revnos[1] is None:
37
        new = branch.last_patch()
38
    else:
39
        new = branch.lookup_revision(revnos[1])
40
    if revnos[0] is None:
0.5.58 by John Arbash Meinel
Fixed a bug in the case that there are no revision committed yet.
41
        if new is None:
42
            old = None
43
        else:
0.5.59 by John Arbash Meinel
Several fixes for handling the case where you are doing a changeset against revno=0 (Null base)
44
            oldrev = branch.get_revision(new)
45
            if len(oldrev.parents) == 0:
46
                old = None
47
            else:
48
                old = oldrev.parents[0].revision_id
0.5.36 by John Arbash Meinel
Updated so that read_changeset is able to parse the output
49
    else:
50
        old = branch.lookup_revision(revnos[0])
51
52
    return old, new
53
1185.82.82 by Aaron Bentley
Remove more unused code
54
       
0.5.55 by John Arbash Meinel
Lots of updates. Using a minimized annotations for changesets.
55
def encode(s):
56
    """Take a unicode string, and make sure to escape it for
57
    use in a changeset.
58
59
    Note: It can be either a normal, or a unicode string
60
61
    >>> encode(u'abcdefg')
62
    'abcdefg'
0.5.79 by John Arbash Meinel
Added common to the set of tests, fixed a problem with time conversions.
63
    >>> encode(u'a b\\tc\\nd\\\\e')
0.5.87 by John Arbash Meinel
Handling international characters, added more test cases.
64
    'a b\\tc\\nd\\\\e'
0.5.79 by John Arbash Meinel
Added common to the set of tests, fixed a problem with time conversions.
65
    >>> encode('a b\\tc\\nd\\e')
0.5.87 by John Arbash Meinel
Handling international characters, added more test cases.
66
    'a b\\tc\\nd\\\\e'
0.5.55 by John Arbash Meinel
Lots of updates. Using a minimized annotations for changesets.
67
    >>> encode(u'\\u1234\\u0020')
0.5.87 by John Arbash Meinel
Handling international characters, added more test cases.
68
    '\\xe1\\x88\\xb4 '
0.5.55 by John Arbash Meinel
Lots of updates. Using a minimized annotations for changesets.
69
    >>> encode('abcdefg')
70
    'abcdefg'
71
    >>> encode(u'')
72
    ''
73
    >>> encode('')
74
    ''
75
    """
0.5.87 by John Arbash Meinel
Handling international characters, added more test cases.
76
    return s.encode('utf-8')
0.5.55 by John Arbash Meinel
Lots of updates. Using a minimized annotations for changesets.
77
78
def decode(s):
79
    """Undo the encode operation, returning a unicode string.
80
81
    >>> decode('abcdefg')
82
    u'abcdefg'
0.5.87 by John Arbash Meinel
Handling international characters, added more test cases.
83
    >>> decode('a b\\tc\\nd\\\\e')
0.5.79 by John Arbash Meinel
Added common to the set of tests, fixed a problem with time conversions.
84
    u'a b\\tc\\nd\\\\e'
0.5.87 by John Arbash Meinel
Handling international characters, added more test cases.
85
    >>> decode('\\xe1\\x88\\xb4 ')
0.5.55 by John Arbash Meinel
Lots of updates. Using a minimized annotations for changesets.
86
    u'\\u1234 '
87
    >>> for s in ('test', 'strings'):
88
    ...   if decode(encode(s)) != s:
89
    ...     print 'Failed: %r' % s # There should be no failures
90
91
    """
0.5.87 by John Arbash Meinel
Handling international characters, added more test cases.
92
    return s.decode('utf-8')
0.5.55 by John Arbash Meinel
Lots of updates. Using a minimized annotations for changesets.
93
0.5.39 by John Arbash Meinel
(broken) Working on changing the processing to use a ChangesetTree.
94
def format_highres_date(t, offset=0):
95
    """Format a date, such that it includes higher precision in the
96
    seconds field.
97
0.5.40 by John Arbash Meinel
Added some highres formatting of datestamps.
98
    :param t:   The local time in fractional seconds since the epoch
0.5.39 by John Arbash Meinel
(broken) Working on changing the processing to use a ChangesetTree.
99
    :type t: float
100
    :param offset:  The timezone offset in integer seconds
101
    :type offset: int
102
0.5.40 by John Arbash Meinel
Added some highres formatting of datestamps.
103
    Example: format_highres_date(time.time(), -time.timezone)
104
    this will return a date stamp for right now,
105
    formatted for the local timezone.
106
0.5.39 by John Arbash Meinel
(broken) Working on changing the processing to use a ChangesetTree.
107
    >>> from bzrlib.osutils import format_date
108
    >>> format_date(1120153132.350850105, 0)
109
    'Thu 2005-06-30 17:38:52 +0000'
110
    >>> format_highres_date(1120153132.350850105, 0)
111
    'Thu 2005-06-30 17:38:52.350850105 +0000'
112
    >>> format_date(1120153132.350850105, -5*3600)
113
    'Thu 2005-06-30 12:38:52 -0500'
114
    >>> format_highres_date(1120153132.350850105, -5*3600)
115
    'Thu 2005-06-30 12:38:52.350850105 -0500'
0.5.40 by John Arbash Meinel
Added some highres formatting of datestamps.
116
    >>> format_highres_date(1120153132.350850105, 7200)
117
    'Thu 2005-06-30 19:38:52.350850105 +0200'
0.5.39 by John Arbash Meinel
(broken) Working on changing the processing to use a ChangesetTree.
118
    """
119
    import time
120
    assert isinstance(t, float)
121
    
122
    # This has to be formatted for "original" date, so that the
123
    # revision XML entry will be reproduced faithfully.
124
    if offset == None:
125
        offset = 0
126
    tt = time.gmtime(t + offset)
127
128
    return (time.strftime("%a %Y-%m-%d %H:%M:%S", tt)
129
            + ('%.9f' % (t - int(t)))[1:] # Get the high-res seconds, but ignore the 0
130
            + ' %+03d%02d' % (offset / 3600, (offset / 60) % 60))
131
132
def unpack_highres_date(date):
133
    """This takes the high-resolution date stamp, and
134
    converts it back into the tuple (timestamp, timezone)
0.5.79 by John Arbash Meinel
Added common to the set of tests, fixed a problem with time conversions.
135
    Where timestamp is in real UTC since epoch seconds, and timezone is an integer
0.5.39 by John Arbash Meinel
(broken) Working on changing the processing to use a ChangesetTree.
136
    number of seconds offset.
137
138
    :param date: A date formated by format_highres_date
139
    :type date: string
140
0.5.40 by John Arbash Meinel
Added some highres formatting of datestamps.
141
    >>> import time, random
142
    >>> unpack_highres_date('Thu 2005-06-30 12:38:52.350850105 -0500')
143
    (1120153132.3508501, -18000)
144
    >>> unpack_highres_date('Thu 2005-06-30 17:38:52.350850105 +0000')
145
    (1120153132.3508501, 0)
146
    >>> unpack_highres_date('Thu 2005-06-30 19:38:52.350850105 +0200')
147
    (1120153132.3508501, 7200)
148
    >>> from bzrlib.osutils import local_time_offset
149
    >>> t = time.time()
150
    >>> o = local_time_offset()
151
    >>> t2, o2 = unpack_highres_date(format_highres_date(t, o))
152
    >>> t == t2
153
    True
154
    >>> o == o2
155
    True
0.5.90 by John Arbash Meinel
Switching from random walk, to random progression
156
    >>> t -= 24*3600*365*2 # Start 2 years ago
157
    >>> o = -12*3600
0.5.40 by John Arbash Meinel
Added some highres formatting of datestamps.
158
    >>> for count in xrange(500):
0.5.90 by John Arbash Meinel
Switching from random walk, to random progression
159
    ...   t += random.random()*24*3600*30
160
    ...   o = ((o/3600 + 13) % 25 - 12)*3600 # Add 1 wrap around from [-12, 12]
0.5.40 by John Arbash Meinel
Added some highres formatting of datestamps.
161
    ...   date = format_highres_date(t, o)
162
    ...   t2, o2 = unpack_highres_date(date)
163
    ...   if t != t2 or o != o2:
164
    ...      print 'Failed on date %r, %s,%s diff:%s' % (date, t, o, t2-t)
0.5.79 by John Arbash Meinel
Added common to the set of tests, fixed a problem with time conversions.
165
    ...      break
0.5.40 by John Arbash Meinel
Added some highres formatting of datestamps.
166
0.5.39 by John Arbash Meinel
(broken) Working on changing the processing to use a ChangesetTree.
167
    """
0.5.79 by John Arbash Meinel
Added common to the set of tests, fixed a problem with time conversions.
168
    import time, calendar
0.5.40 by John Arbash Meinel
Added some highres formatting of datestamps.
169
    # Up until the first period is a datestamp that is generated
170
    # as normal from time.strftime, so use time.strptime to
171
    # parse it
172
    dot_loc = date.find('.')
173
    if dot_loc == -1:
174
        raise ValueError('Date string does not contain high-precision seconds: %r' % date)
175
    base_time = time.strptime(date[:dot_loc], "%a %Y-%m-%d %H:%M:%S")
176
    fract_seconds, offset = date[dot_loc:].split()
177
    fract_seconds = float(fract_seconds)
178
    offset = int(offset)
179
    offset = int(offset / 100) * 3600 + offset % 100
180
    
0.5.79 by John Arbash Meinel
Added common to the set of tests, fixed a problem with time conversions.
181
    # time.mktime returns localtime, but calendar.timegm returns UTC time
182
    timestamp = calendar.timegm(base_time)
183
    timestamp -= offset
0.5.40 by John Arbash Meinel
Added some highres formatting of datestamps.
184
    # Add back in the fractional seconds
185
    timestamp += fract_seconds
186
    return (timestamp, offset)
0.5.39 by John Arbash Meinel
(broken) Working on changing the processing to use a ChangesetTree.
187
1185.82.15 by Aaron Bentley
Disabled validate_revisions (needs info it doesn't have), updated API to repos
188
189
def testament_sha1(repository, revision_id):
190
    text = Testament.from_revision(repository, revision_id).as_short_text()
191
    s = sha(text)
192
    return s.hexdigest()
193
 
194
0.5.39 by John Arbash Meinel
(broken) Working on changing the processing to use a ChangesetTree.
195
if __name__ == '__main__':
196
    import doctest
197
    doctest.testmod()
0.5.40 by John Arbash Meinel
Added some highres formatting of datestamps.
198