summaryrefslogtreecommitdiffstats
path: root/build/upload.py
diff options
context:
space:
mode:
Diffstat (limited to 'build/upload.py')
-rw-r--r--build/upload.py106
1 files changed, 106 insertions, 0 deletions
diff --git a/build/upload.py b/build/upload.py
new file mode 100644
index 0000000000..75eb163b24
--- /dev/null
+++ b/build/upload.py
@@ -0,0 +1,106 @@
+#!/usr/bin/python
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+# When run directly, this script expects the following environment variables
+# to be set:
+# UPLOAD_PATH : path on that host to put the files in
+#
+# Files are simply copied to UPLOAD_PATH.
+#
+# All files to be uploaded should be passed as commandline arguments to this
+# script. The script takes one other parameter, --base-path, which you can use
+# to indicate that files should be uploaded including their paths relative
+# to the base path.
+
+import os
+import shutil
+import sys
+from optparse import OptionParser
+
+
+def OptionalEnvironmentVariable(v):
+ """Return the value of the environment variable named v, or None
+ if it's unset (or empty)."""
+ if v in os.environ and os.environ[v] != "":
+ return os.environ[v]
+ return None
+
+
+def FixupMsysPath(path):
+ """MSYS helpfully translates absolute pathnames in environment variables
+ and commandline arguments into Windows native paths. This sucks if you're
+ trying to pass an absolute path on a remote server. This function attempts
+ to un-mangle such paths."""
+ if "OSTYPE" in os.environ and os.environ["OSTYPE"] == "msys":
+ # sort of awful, find out where our shell is (should be in msys2/usr/bin
+ # or msys/bin) and strip the first part of that path out of the other path
+ if "SHELL" in os.environ:
+ sh = os.environ["SHELL"]
+ msys = sh[: sh.find("/bin")]
+ if path.startswith(msys):
+ path = path[len(msys) :]
+ return path
+
+
+def GetBaseRelativePath(path, local_file, base_path):
+ """Given a remote path to upload to, a full path to a local file, and an
+ optional full path that is a base path of the local file, construct the
+ full remote path to place the file in. If base_path is not None, include
+ the relative path from base_path to file."""
+ if base_path is None or not local_file.startswith(base_path):
+ return path
+
+ dir = os.path.dirname(local_file)
+ # strip base_path + extra slash and make it unixy
+ dir = dir[len(base_path) + 1 :].replace("\\", "/")
+ return path + dir
+
+
+def CopyFilesLocally(path, files, verbose=False, base_path=None):
+ """Copy each file in the list of files to `path`. The `base_path` argument is treated
+ as it is by UploadFiles."""
+ if not path.endswith("/"):
+ path += "/"
+ if base_path is not None:
+ base_path = os.path.abspath(base_path)
+ for file in files:
+ file = os.path.abspath(file)
+ if not os.path.isfile(file):
+ raise IOError("File not found: %s" % file)
+ # first ensure that path exists remotely
+ target_path = GetBaseRelativePath(path, file, base_path)
+ if not os.path.exists(target_path):
+ os.makedirs(target_path)
+ if verbose:
+ print("Copying " + file + " to " + target_path)
+ shutil.copy(file, target_path)
+
+
+if __name__ == "__main__":
+ path = OptionalEnvironmentVariable("UPLOAD_PATH")
+
+ if sys.platform == "win32":
+ if path is not None:
+ path = FixupMsysPath(path)
+
+ parser = OptionParser(usage="usage: %prog [options] <files>")
+ parser.add_option(
+ "-b",
+ "--base-path",
+ action="store",
+ help="Preserve file paths relative to this path when uploading. "
+ "If unset, all files will be uploaded directly to UPLOAD_PATH.",
+ )
+ (options, args) = parser.parse_args()
+ if len(args) < 1:
+ print("You must specify at least one file to upload")
+ sys.exit(1)
+
+ try:
+ CopyFilesLocally(path, args, base_path=options.base_path, verbose=True)
+ except IOError as strerror:
+ print(strerror)
+ sys.exit(1)