130
133
except (IOError, OSError),e:
131
134
self._translate_error(e, path)
133
def put(self, relpath, f, mode=None):
134
"""Copy the file-like or string object into the location.
136
def put_file(self, relpath, f, mode=None):
137
"""Copy the file-like object into the location.
136
139
:param relpath: Location to put the contents, relative to base.
137
:param f: File-like or string object.
140
:param f: File-like object.
141
:param mode: The mode for the newly created file,
142
None means just use the default
139
from bzrlib.atomicfile import AtomicFile
143
147
path = self._abspath(relpath)
144
148
check_legal_path(path)
145
fp = AtomicFile(path, 'wb', new_mode=mode)
149
fp = atomicfile.AtomicFile(path, 'wb', new_mode=mode)
146
150
except (IOError, OSError),e:
147
151
self._translate_error(e, path)
158
def put_bytes(self, relpath, bytes, mode=None):
159
"""Copy the string into the location.
161
:param relpath: Location to put the contents, relative to base.
167
path = self._abspath(relpath)
168
check_legal_path(path)
169
fp = atomicfile.AtomicFile(path, 'wb', new_mode=mode)
170
except (IOError, OSError),e:
171
self._translate_error(e, path)
178
def _put_non_atomic_helper(self, relpath, writer,
180
create_parent_dir=False,
182
"""Common functionality information for the put_*_non_atomic.
184
This tracks all the create_parent_dir stuff.
186
:param relpath: the path we are putting to.
187
:param writer: A function that takes an os level file descriptor
188
and writes whatever data it needs to write there.
189
:param mode: The final file mode.
190
:param create_parent_dir: Should we be creating the parent directory
193
abspath = self._abspath(relpath)
195
# os.open() will automatically use the umask
200
fd = os.open(abspath, _put_non_atomic_flags, local_mode)
201
except (IOError, OSError),e:
202
# We couldn't create the file, maybe we need to create
203
# the parent directory, and try again
204
if (not create_parent_dir
205
or e.errno not in (errno.ENOENT,errno.ENOTDIR)):
206
self._translate_error(e, relpath)
207
parent_dir = os.path.dirname(abspath)
209
self._translate_error(e, relpath)
210
self._mkdir(parent_dir, mode=dir_mode)
211
# We created the parent directory, lets try to open the
214
fd = os.open(abspath, _put_non_atomic_flags, local_mode)
215
except (IOError, OSError), e:
216
self._translate_error(e, relpath)
219
if mode is not None and mode != S_IMODE(st.st_mode):
220
# Because of umask, we may still need to chmod the file.
221
# But in the general case, we won't have to
222
os.chmod(abspath, mode)
227
def put_file_non_atomic(self, relpath, f, mode=None,
228
create_parent_dir=False,
230
"""Copy the file-like object into the target location.
232
This function is not strictly safe to use. It is only meant to
233
be used when you already know that the target does not exist.
234
It is not safe, because it will open and truncate the remote
235
file. So there may be a time when the file has invalid contents.
237
:param relpath: The remote location to put the contents.
238
:param f: File-like object.
239
:param mode: Possible access permissions for new file.
240
None means do not set remote permissions.
241
:param create_parent_dir: If we cannot create the target file because
242
the parent directory does not exist, go ahead and
243
create it, and then try again.
246
self._pump_to_fd(f, fd)
247
self._put_non_atomic_helper(relpath, writer, mode=mode,
248
create_parent_dir=create_parent_dir,
251
def put_bytes_non_atomic(self, relpath, bytes, mode=None,
252
create_parent_dir=False, dir_mode=None):
255
self._put_non_atomic_helper(relpath, writer, mode=mode,
256
create_parent_dir=create_parent_dir,
154
259
def iter_files_recursive(self):
155
260
"""Iter the relative paths of files in the transports sub-tree."""
156
261
queue = list(self.list_dir(u'.'))
166
def mkdir(self, relpath, mode=None):
167
"""Create a directory at the given path."""
271
def _mkdir(self, abspath, mode=None):
272
"""Create a real directory, filtering through mode"""
274
# os.mkdir() will filter through umask
171
# os.mkdir() will filter through umask
175
path = self._abspath(relpath)
176
os.mkdir(path, local_mode)
279
os.mkdir(abspath, local_mode)
177
280
if mode is not None:
178
281
# It is probably faster to just do the chmod, rather than
179
282
# doing a stat, and then trying to compare
181
except (IOError, OSError),e:
182
self._translate_error(e, path)
184
def append(self, relpath, f, mode=None):
283
os.chmod(abspath, mode)
284
except (IOError, OSError),e:
285
self._translate_error(e, abspath)
287
def mkdir(self, relpath, mode=None):
288
"""Create a directory at the given path."""
289
self._mkdir(self._abspath(relpath), mode=mode)
291
def _get_append_file(self, relpath, mode=None):
292
"""Call os.open() for the given relpath"""
293
file_abspath = self._abspath(relpath)
295
# os.open() will automatically use the umask
300
return file_abspath, os.open(file_abspath, _append_flags, local_mode)
301
except (IOError, OSError),e:
302
self._translate_error(e, relpath)
304
def _check_mode_and_size(self, file_abspath, fd, mode=None):
305
"""Check the mode of the file, and return the current size"""
307
if mode is not None and mode != S_IMODE(st.st_mode):
308
# Because of umask, we may still need to chmod the file.
309
# But in the general case, we won't have to
310
os.chmod(file_abspath, mode)
313
def append_file(self, relpath, f, mode=None):
185
314
"""Append the text in the file-like object into the final location."""
186
abspath = self._abspath(relpath)
188
# os.open() will automatically use the umask
193
fd = os.open(abspath, _append_flags, local_mode)
194
except (IOError, OSError),e:
195
self._translate_error(e, relpath)
199
if mode is not None and mode != S_IMODE(st.st_mode):
200
# Because of umask, we may still need to chmod the file.
201
# But in the general case, we won't have to
202
os.chmod(abspath, mode)
315
file_abspath, fd = self._get_append_file(relpath, mode=mode)
317
result = self._check_mode_and_size(file_abspath, fd, mode=mode)
203
318
self._pump_to_fd(f, fd)
323
def append_bytes(self, relpath, bytes, mode=None):
324
"""Append the text in the string into the final location."""
325
file_abspath, fd = self._get_append_file(relpath, mode=mode)
327
result = self._check_mode_and_size(file_abspath, fd, mode=mode)
208
333
def _pump_to_fd(self, fromfile, to_fd):
209
334
"""Copy contents of one file to another."""