~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/transport/local.py

  • Committer: Ian Clatworthy
  • Date: 2009-09-09 11:43:10 UTC
  • mto: (4634.37.2 prepare-2.0)
  • mto: This revision was merged to the branch mainline in revision 4689.
  • Revision ID: ian.clatworthy@canonical.com-20090909114310-glw7tv76i5gnx9pt
put rules back in Makefile supporting plain-style docs

Show diffs side-by-side

added added

removed removed

Lines of Context:
12
12
#
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
 
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
16
 
17
17
"""Transport for the local filesystem.
18
18
 
63
63
            base = urlutils.local_path_to_url(base)
64
64
        if base[-1] != '/':
65
65
            base = base + '/'
 
66
 
 
67
        # Special case : windows has no "root", but does have
 
68
        # multiple lettered drives inside it. #240910
 
69
        if sys.platform == 'win32' and base == 'file:///':
 
70
            base = ''
 
71
            self._local_base = ''
 
72
            super(LocalTransport, self).__init__(base)
 
73
            return
 
74
 
66
75
        super(LocalTransport, self).__init__(base)
67
76
        self._local_base = urlutils.local_path_from_url(base)
68
77
 
69
78
    def clone(self, offset=None):
70
79
        """Return a new LocalTransport with root at self.base + offset
71
 
        Because the local filesystem does not require a connection, 
 
80
        Because the local filesystem does not require a connection,
72
81
        we can just return a new object.
73
82
        """
74
83
        if offset is None:
96
105
    def abspath(self, relpath):
97
106
        """Return the full url to the given relative URL."""
98
107
        # TODO: url escape the result. RBC 20060523.
99
 
        assert isinstance(relpath, basestring), (type(relpath), relpath)
100
108
        # jam 20060426 Using normpath on the real path, because that ensures
101
109
        #       proper handling of stuff like
102
110
        path = osutils.normpath(osutils.pathjoin(
103
111
                    self._local_base, urlutils.unescape(relpath)))
 
112
        # on windows, our _local_base may or may not have a drive specified
 
113
        # (ie, it may be "/" or "c:/foo").
 
114
        # If 'relpath' is '/' we *always* get back an abspath without
 
115
        # the drive letter - but if our transport already has a drive letter,
 
116
        # we want our abspaths to have a drive letter too - so handle that
 
117
        # here.
 
118
        if (sys.platform == "win32" and self._local_base[1:2] == ":"
 
119
            and path == '/'):
 
120
            path = self._local_base[:3]
 
121
 
104
122
        return urlutils.local_path_to_url(path)
105
123
 
106
124
    def local_abspath(self, relpath):
109
127
        This function only exists for the LocalTransport, since it is
110
128
        the only one that has direct local access.
111
129
        This is mostly for stuff like WorkingTree which needs to know
112
 
        the local working directory.
113
 
        
 
130
        the local working directory.  The returned path will always contain
 
131
        forward slashes as the path separator, regardless of the platform.
 
132
 
114
133
        This function is quite expensive: it calls realpath which resolves
115
134
        symlinks.
116
135
        """
152
171
 
153
172
        :param relpath: Location to put the contents, relative to base.
154
173
        :param f:       File-like object.
155
 
        :param mode: The mode for the newly created file, 
 
174
        :param mode: The mode for the newly created file,
156
175
                     None means just use the default
157
176
        """
158
177
 
164
183
        except (IOError, OSError),e:
165
184
            self._translate_error(e, path)
166
185
        try:
167
 
            self._pump(f, fp)
 
186
            length = self._pump(f, fp)
168
187
            fp.commit()
169
188
        finally:
170
189
            fp.close()
 
190
        return length
171
191
 
172
192
    def put_bytes(self, relpath, bytes, mode=None):
173
193
        """Copy the string into the location.
184
204
        except (IOError, OSError),e:
185
205
            self._translate_error(e, path)
186
206
        try:
187
 
            fp.write(bytes)
 
207
            if bytes:
 
208
                fp.write(bytes)
188
209
            fp.commit()
189
210
        finally:
190
211
            fp.close()
265
286
    def put_bytes_non_atomic(self, relpath, bytes, mode=None,
266
287
                             create_parent_dir=False, dir_mode=None):
267
288
        def writer(fd):
268
 
            os.write(fd, bytes)
 
289
            if bytes:
 
290
                os.write(fd, bytes)
269
291
        self._put_non_atomic_helper(relpath, writer, mode=mode,
270
292
                                    create_parent_dir=create_parent_dir,
271
293
                                    dir_mode=dir_mode)
306
328
        """See Transport.open_write_stream."""
307
329
        # initialise the file
308
330
        self.put_bytes_non_atomic(relpath, "", mode=mode)
309
 
        handle = open(self._abspath(relpath), 'wb')
 
331
        abspath = self._abspath(relpath)
 
332
        handle = open(abspath, 'wb')
 
333
        if mode is not None:
 
334
            self._check_mode_and_size(abspath, handle.fileno(), mode)
310
335
        transport._file_streams[self.abspath(relpath)] = handle
311
336
        return transport.FileFileStream(self, relpath, handle)
312
337
 
347
372
        file_abspath, fd = self._get_append_file(relpath, mode=mode)
348
373
        try:
349
374
            result = self._check_mode_and_size(file_abspath, fd, mode=mode)
350
 
            os.write(fd, bytes)
 
375
            if bytes:
 
376
                os.write(fd, bytes)
351
377
        finally:
352
378
            os.close(fd)
353
379
        return result
374
400
    def rename(self, rel_from, rel_to):
375
401
        path_from = self._abspath(rel_from)
376
402
        try:
377
 
            # *don't* call bzrlib.osutils.rename, because we want to 
 
403
            # *don't* call bzrlib.osutils.rename, because we want to
378
404
            # detect errors on rename
379
405
            os.rename(path_from, self._abspath(rel_to))
380
406
        except (IOError, OSError),e:
507
533
        self._local_base = urlutils._win32_local_path_from_url(base)
508
534
 
509
535
    def abspath(self, relpath):
510
 
        assert isinstance(relpath, basestring), (type(relpath), relpath)
511
536
        path = osutils.normpath(osutils.pathjoin(
512
537
                    self._local_base, urlutils.unescape(relpath)))
513
538
        return urlutils._win32_local_path_to_url(path)
514
539
 
515
540
    def clone(self, offset=None):
516
541
        """Return a new LocalTransport with root at self.base + offset
517
 
        Because the local filesystem does not require a connection, 
 
542
        Because the local filesystem does not require a connection,
518
543
        we can just return a new object.
519
544
        """
520
545
        if offset is None:
531
556
 
532
557
class LocalURLServer(Server):
533
558
    """A pretend server for local transports, using file:// urls.
534
 
    
 
559
 
535
560
    Of course no actual server is required to access the local filesystem, so
536
561
    this just exists to tell the test code how to get to it.
537
562
    """
538
563
 
539
564
    def setUp(self):
540
565
        """Setup the server to service requests.
541
 
        
 
566
 
542
567
        :param decorated_transport: ignored by this implementation.
543
568
        """
544
569