~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/transport/local.py

  • Committer: Jelmer Vernooij
  • Date: 2005-10-19 09:34:39 UTC
  • mfrom: (1185.16.78)
  • mto: (1185.16.102)
  • mto: This revision was merged to the branch mainline in revision 1488.
  • Revision ID: jelmer@samba.org-20051019093439-e1d8e3508d1ba46b
MergeĀ fromĀ Martin

Show diffs side-by-side

added added

removed removed

Lines of Context:
13
13
# You should have received a copy of the GNU General Public License
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
 
"""Implementation of Transport for the local filesystem.
17
 
"""
18
 
 
 
16
 
 
17
"""Transport for the local filesystem.
 
18
 
 
19
This is a fairly thin wrapper on regular file IO."""
 
20
 
 
21
import os
 
22
import errno
 
23
import shutil
 
24
from stat import ST_MODE, S_ISDIR, ST_SIZE
 
25
import tempfile
 
26
 
 
27
from bzrlib.trace import mutter
19
28
from bzrlib.transport import Transport, register_transport, \
20
29
    TransportError, NoSuchFile, FileExists
21
 
import os, errno
 
30
from bzrlib.osutils import abspath
22
31
 
23
32
class LocalTransportError(TransportError):
24
33
    pass
25
34
 
 
35
 
26
36
class LocalTransport(Transport):
27
37
    """This is the transport agent for local filesystem access."""
28
38
 
33
43
        # realpath is incompatible with symlinks. When we traverse
34
44
        # up we might be able to normpath stuff. RBC 20051003
35
45
        super(LocalTransport, self).__init__(
36
 
            os.path.normpath(os.path.abspath(base)))
 
46
            os.path.normpath(abspath(base)))
37
47
 
38
48
    def should_cache(self):
39
49
        return False
60
70
        """Return the local path portion from a given absolute path.
61
71
        """
62
72
        from bzrlib.osutils import relpath
 
73
        if abspath is None:
 
74
            abspath = '.'
63
75
        return relpath(self.base, abspath)
64
76
 
65
77
    def has(self, relpath):
78
90
                raise NoSuchFile('File or directory %r does not exist' % path, orig_error=e)
79
91
            raise LocalTransportError(orig_error=e)
80
92
 
81
 
    def get_partial(self, relpath, start, length=None):
82
 
        """Get just part of a file.
83
 
 
84
 
        :param relpath: Path to the file, relative to base
85
 
        :param start: The starting position to read from
86
 
        :param length: The length to read. A length of None indicates
87
 
                       read to the end of the file.
88
 
        :return: A file-like object containing at least the specified bytes.
89
 
                 Some implementations may return objects which can be read
90
 
                 past this length, but this is not guaranteed.
91
 
        """
92
 
        # LocalTransport.get_partial() doesn't care about the length
93
 
        # argument, because it is using a local file, and thus just
94
 
        # returns the file seek'ed to the appropriate location.
95
 
        try:
96
 
            path = self.abspath(relpath)
97
 
            f = open(path, 'rb')
98
 
            f.seek(start, 0)
99
 
            return f
100
 
        except IOError,e:
101
 
            if e.errno == errno.ENOENT:
102
 
                raise NoSuchFile('File %r does not exist' % path, orig_error=e)
103
 
            raise LocalTransportError(orig_error=e)
104
 
 
105
93
    def put(self, relpath, f):
106
94
        """Copy the file-like or string object into the location.
107
95
 
123
111
        finally:
124
112
            fp.close()
125
113
 
 
114
    def iter_files_recursive(self):
 
115
        """Iter the relative paths of files in the transports sub-tree."""
 
116
        queue = list(self.list_dir('.'))
 
117
        while queue:
 
118
            relpath = queue.pop(0)
 
119
            st = self.stat(relpath)
 
120
            if S_ISDIR(st[ST_MODE]):
 
121
                for i, basename in enumerate(self.list_dir(relpath)):
 
122
                    queue.insert(i, relpath+'/'+basename)
 
123
            else:
 
124
                yield relpath
 
125
 
126
126
    def mkdir(self, relpath):
127
127
        """Create a directory at the given path."""
128
128
        try:
227
227
        from bzrlib.lock import WriteLock
228
228
        return WriteLock(self.abspath(relpath))
229
229
 
 
230
 
 
231
class ScratchTransport(LocalTransport):
 
232
    """A transport that works in a temporary dir and cleans up after itself.
 
233
    
 
234
    The dir only exists for the lifetime of the Python object.
 
235
    Obviously you should not put anything precious in it.
 
236
    """
 
237
 
 
238
    def __init__(self, base=None):
 
239
        if base is None:
 
240
            base = tempfile.mkdtemp()
 
241
        super(ScratchTransport, self).__init__(base)
 
242
 
 
243
    def __del__(self):
 
244
        shutil.rmtree(self.base, ignore_errors=True)
 
245
        mutter("%r destroyed" % self)
 
246
 
230
247
# If nothing else matches, try the LocalTransport
231
248
register_transport(None, LocalTransport)
232
249
register_transport('file://', LocalTransport)