This commit fixes a bunch of issues at the same time, as they are all
related to path handling:
- `pathlib.Path.resolve()` or `.absolute()` are replaced by
`bpathlib.make_absolute()`. The latter does NOT follow symlinks and does
NOT network mounts from a drive letter to UNC notation. This also has
advantages on non-Windows sytems, as it allows BAT-packing a directory
structure with symlinked files (such as a Shaman checkout).
- Better handling of drive letters, and of paths that cross drive
boundaries.
- Better testing of Windows-specific cases when running the tests on
Windows, and of POSIX-specific cases on other platforms.
Thanks to @wisaac for starting this patch in D6676.
Thanks to @jbakker for pointing out the drive letter issue. This fixes
T70655.
The logging is sent to stdout already (which is captured and printed by
PyTest), so having PyTest also capture and print logging just doubles
the output.
No functional changes.
This may also fix a Windows compatibility issue related to path
normalisation. Untested as it's hard to reproduce, but at least it
shouldn't hurt either.
External files with the same path on different drives are packed as a
single file. In this commit the drive letter is taken into account when
determining the path inside `_outside_project`, so that they are distinct.
The Shaman server is a file storage system that identifies files by
SHA256sum and file length. BAT can send packs there by only uploading
changed/new files. The BAT pack is reproduced at the Shaman server's
checkout directory by creating symlinks to the files in its file
storage.
Retrying sending files:
When we can defer uploading a file (that is, when we have other files to
upload as well, and we could send the current file at a later moment) we
send an `X-Shaman-Can-Defer-Upload: true` header in the file upload
request. In that case, when someone else is already uploading that file,
a `208 Already Reported` response is sent and the connection is closed.
Python's Requests library unfortunately won't give us that response if
we're still streaming the request, and raise a ConnectionError exception
instead. This exception can mean two things:
- If the `X-Shaman-Can-Defer-Upload: true` header was sent: someone else
is currently uploading that file, so defer it.
- If that header was not sent: that file is already completely uploaded
and does not need to be uploaded again.
Instead of retrying each failed file, after a few failures we now just
resend the definition file to get a new list of files to upload, then
send those. This should considerably reduce the number of HTTP calls
when multiple clients are uploading the same set of files.