~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/inventory.py

  • Committer: mbp at sourcefrog
  • Date: 2005-04-11 02:50:08 UTC
  • Revision ID: mbp@sourcefrog.net-20050411025008-855e0e0637ff8a49
- Don't put profiling temp file in current directory

Show diffs side-by-side

added added

removed removed

Lines of Context:
14
14
# along with this program; if not, write to the Free Software
15
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
16
 
 
17
"""Inventories map files to their name in a revision."""
 
18
 
 
19
# TODO: Maybe store inventory_id in the file?  Not really needed.
 
20
 
 
21
__author__ = "Martin Pool <mbp@canonical.com>"
 
22
 
17
23
 
18
24
# This should really be an id randomly assigned when the tree is
19
25
# created, but it's not for now.
29
35
    from elementtree.ElementTree import Element, ElementTree, SubElement
30
36
 
31
37
from xml import XMLMixin
32
 
from errors import bailout, BzrError, BzrCheckError
 
38
from errors import bailout, BzrError
33
39
 
34
40
import bzrlib
35
41
from bzrlib.osutils import uuid, quotefn, splitpath, joinpath, appendpath
91
97
    >>> i.id2path('2326')
92
98
    'src/wibble/wibble.c'
93
99
 
94
 
    TODO: Maybe also keep the full path of the entry, and the children?
 
100
    :todo: Maybe also keep the full path of the entry, and the children?
95
101
           But those depend on its position within a particular inventory, and
96
102
           it would be nice not to need to hold the backpointer here.
97
103
    """
98
104
 
99
105
    # TODO: split InventoryEntry into subclasses for files,
100
106
    # directories, etc etc.
101
 
 
102
 
    text_sha1 = None
103
 
    text_size = None
104
107
    
105
108
    def __init__(self, file_id, name, kind, parent_id, text_id=None):
106
109
        """Create an InventoryEntry
115
118
        '123'
116
119
        >>> e = InventoryEntry('123', 'src/hello.c', 'file', ROOT_ID)
117
120
        Traceback (most recent call last):
118
 
        BzrCheckError: InventoryEntry name 'src/hello.c' is invalid
 
121
        BzrError: ("InventoryEntry name is not a simple filename: 'src/hello.c'", [])
119
122
        """
120
 
        if '/' in name or '\\' in name:
121
 
            raise BzrCheckError('InventoryEntry name %r is invalid' % name)
 
123
        
 
124
        if len(splitpath(name)) != 1:
 
125
            bailout('InventoryEntry name is not a simple filename: %r'
 
126
                    % name)
122
127
        
123
128
        self.file_id = file_id
124
129
        self.name = name
125
130
        self.kind = kind
126
131
        self.text_id = text_id
127
132
        self.parent_id = parent_id
 
133
        self.text_sha1 = None
 
134
        self.text_size = None
128
135
        if kind == 'directory':
129
136
            self.children = {}
130
137
        elif kind == 'file':
246
253
class Inventory(XMLMixin):
247
254
    """Inventory of versioned files in a tree.
248
255
 
249
 
    This describes which file_id is present at each point in the tree,
250
 
    and possibly the SHA-1 or other information about the file.
251
 
    Entries can be looked up either by path or by file_id.
 
256
    An Inventory acts like a set of InventoryEntry items.  You can
 
257
    also look files up by their file_id or name.
 
258
    
 
259
    May be read from and written to a metadata file in a tree.  To
 
260
    manipulate the inventory (for example to add a file), it is read
 
261
    in, modified, and then written back out.
252
262
 
253
263
    The inventory represents a typical unix file tree, with
254
264
    directories containing files and subdirectories.  We never store
286
296
    </inventory>
287
297
 
288
298
    """
 
299
 
 
300
    ## TODO: Make sure only canonical filenames are stored.
 
301
 
 
302
    ## TODO: Do something sensible about the possible collisions on
 
303
    ## case-losing filesystems.  Perhaps we should just always forbid
 
304
    ## such collisions.
 
305
 
 
306
    ## TODO: No special cases for root, rather just give it a file id
 
307
    ## like everything else.
 
308
 
 
309
    ## TODO: Probably change XML serialization to use nesting
 
310
 
289
311
    def __init__(self):
290
312
        """Create or read an inventory.
291
313
 
323
345
            yield name, ie
324
346
            if ie.kind == 'directory':
325
347
                for cn, cie in self.iter_entries(from_dir=ie.file_id):
326
 
                    yield os.path.join(name, cn), cie
 
348
                    yield '/'.join((name, cn)), cie
327
349
                    
328
350
 
329
351
 
371
393
        >>> inv['123123'].name
372
394
        'hello.c'
373
395
        """
 
396
        if file_id == None:
 
397
            raise BzrError("can't look up file_id None")
 
398
            
374
399
        try:
375
400
            return self._byid[file_id]
376
401
        except KeyError:
377
 
            if file_id == None:
378
 
                raise BzrError("can't look up file_id None")
379
 
            else:
380
 
                raise BzrError("file_id {%s} not in inventory" % file_id)
381
 
 
382
 
 
383
 
    def get_file_kind(self, file_id):
384
 
        return self._byid[file_id].kind
 
402
            raise BzrError("file_id {%s} not in inventory" % file_id)
 
403
 
385
404
 
386
405
    def get_child(self, parent_id, filename):
387
406
        return self[parent_id].children.get(filename)
538
557
 
539
558
        # get all names, skipping root
540
559
        p = [self[fid].name for fid in self.get_idpath(file_id)[1:]]
541
 
        return os.sep.join(p)
 
560
        return '/'.join(p)
542
561
            
543
562
 
544
563