Bug 1492664 - generate portable URLs for Android mach commands; r=nalexander
[gecko.git] / build / upload.py
blob89de5e6a7aec5c9e7314dd1ad1aeafc9ced82a42
1 #!/usr/bin/python
3 # This Source Code Form is subject to the terms of the Mozilla Public
4 # License, v. 2.0. If a copy of the MPL was not distributed with this
5 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
7 # When run directly, this script expects the following environment variables
8 # to be set:
9 # UPLOAD_PATH : path on that host to put the files in
11 # Files are simply copied to UPLOAD_PATH.
13 # All files to be uploaded should be passed as commandline arguments to this
14 # script. The script takes one other parameter, --base-path, which you can use
15 # to indicate that files should be uploaded including their paths relative
16 # to the base path.
18 import sys
19 import os
20 import shutil
21 from optparse import OptionParser
24 def OptionalEnvironmentVariable(v):
25 """Return the value of the environment variable named v, or None
26 if it's unset (or empty)."""
27 if v in os.environ and os.environ[v] != "":
28 return os.environ[v]
29 return None
32 def FixupMsysPath(path):
33 """MSYS helpfully translates absolute pathnames in environment variables
34 and commandline arguments into Windows native paths. This sucks if you're
35 trying to pass an absolute path on a remote server. This function attempts
36 to un-mangle such paths."""
37 if 'OSTYPE' in os.environ and os.environ['OSTYPE'] == 'msys':
38 # sort of awful, find out where our shell is (should be in msys/bin)
39 # and strip the first part of that path out of the other path
40 if 'SHELL' in os.environ:
41 sh = os.environ['SHELL']
42 msys = sh[:sh.find('/bin')]
43 if path.startswith(msys):
44 path = path[len(msys):]
45 return path
48 def GetBaseRelativePath(path, local_file, base_path):
49 """Given a remote path to upload to, a full path to a local file, and an
50 optional full path that is a base path of the local file, construct the
51 full remote path to place the file in. If base_path is not None, include
52 the relative path from base_path to file."""
53 if base_path is None or not local_file.startswith(base_path):
54 return path
56 dir = os.path.dirname(local_file)
57 # strip base_path + extra slash and make it unixy
58 dir = dir[len(base_path) + 1:].replace('\\', '/')
59 return path + dir
62 def CopyFilesLocally(path, files, verbose=False, base_path=None):
63 """Copy each file in the list of files to `path`. The `base_path` argument is treated
64 as it is by UploadFiles."""
65 if not path.endswith("/"):
66 path += "/"
67 if base_path is not None:
68 base_path = os.path.abspath(base_path)
69 for file in files:
70 file = os.path.abspath(file)
71 if not os.path.isfile(file):
72 raise IOError("File not found: %s" % file)
73 # first ensure that path exists remotely
74 target_path = GetBaseRelativePath(path, file, base_path)
75 if not os.path.exists(target_path):
76 os.makedirs(target_path)
77 if verbose:
78 print("Copying " + file + " to " + target_path)
79 shutil.copy(file, target_path)
82 if __name__ == '__main__':
83 path = OptionalEnvironmentVariable('UPLOAD_PATH')
85 if sys.platform == 'win32':
86 if path is not None:
87 path = FixupMsysPath(path)
89 parser = OptionParser(usage="usage: %prog [options] <files>")
90 parser.add_option("-b", "--base-path",
91 action="store",
92 help="Preserve file paths relative to this path when uploading. "
93 "If unset, all files will be uploaded directly to UPLOAD_PATH.")
94 (options, args) = parser.parse_args()
95 if len(args) < 1:
96 print("You must specify at least one file to upload")
97 sys.exit(1)
99 try:
100 CopyFilesLocally(path, args, base_path=options.base_path,
101 verbose=True)
102 except IOError as strerror:
103 print(strerror)
104 sys.exit(1)