--- a/build/cl.py
+++ b/build/cl.py
@@ -1,96 +1,96 @@
-# ***** BEGIN LICENSE BLOCK *****
-# Version: MPL 1.1/GPL 2.0/LGPL 2.1
-#
-# The contents of this file are subject to the Mozilla Public License Version
-# 1.1 (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-# http://www.mozilla.org/MPL/
-#
-# Software distributed under the License is distributed on an "AS IS" basis,
-# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
-# for the specific language governing rights and limitations under the
-# License.
-#
-# The Original Code is cl.py: a python wrapper for cl to automatically generate
-# dependency information.
-#
-# The Initial Developer of the Original Code is
-# Mozilla Foundation.
-# Portions created by the Initial Developer are Copyright (C) 2010
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-# Kyle Huey <me@kylehuey.com>
-#
-# Alternatively, the contents of this file may be used under the terms of
-# either the GNU General Public License Version 2 or later (the "GPL"), or
-# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
-# in which case the provisions of the GPL or the LGPL are applicable instead
-# of those above. If you wish to allow use of your version of this file only
-# under the terms of either the GPL or the LGPL, and not to allow others to
-# use your version of this file under the terms of the MPL, indicate your
-# decision by deleting the provisions above and replace them with the notice
-# and other provisions required by the GPL or the LGPL. If you do not delete
-# the provisions above, a recipient may use your version of this file under
-# the terms of any one of the MPL, the GPL or the LGPL.
-#
-# ***** END LICENSE BLOCK *****
-
-import os, os.path
-import subprocess
-import sys
-
-CL_INCLUDES_PREFIX = os.environ.get("CL_INCLUDES_PREFIX", "Note: including file:")
-
-def InvokeClWithDependencyGeneration(cmdline):
- target = ""
- # Figure out what the target is
- for arg in cmdline:
- if arg.startswith("-Fo"):
- target = arg[3:]
- break
-
- if target == None:
- print >>sys.stderr, "No target set" and sys.exit(1)
-
- # The deps target lives here
- depstarget = os.path.basename(target) + ".pp"
-
- cmdline += ['-showIncludes']
- cl = subprocess.Popen(cmdline, stdout=subprocess.PIPE)
-
- deps = set()
- for line in cl.stdout:
- # cl -showIncludes prefixes every header with "Note: including file:"
- # and an indentation corresponding to the depth (which we don't need)
- if line.startswith(CL_INCLUDES_PREFIX):
- dep = line[len(CL_INCLUDES_PREFIX):].strip()
- # We can't handle pathes with spaces properly in mddepend.pl, but
- # we can assume that anything in a path with spaces is a system
- # header and throw it away.
- if dep.find(' ') == -1:
- deps.add(dep)
- else:
- sys.stdout.write(line) # Make sure we preserve the relevant output
- # from cl
-
- ret = cl.wait()
- if ret != 0 or target == "":
- sys.exit(ret)
-
- depsdir = os.path.normpath(os.path.join(os.path.dirname(target), ".deps"))
- depstarget = os.path.join(depsdir, depstarget)
- if not os.path.isdir(depsdir):
- try:
- os.makedirs(depsdir)
- except OSError:
- pass # This suppresses the error we get when the dir exists, at the
- # cost of masking failure to create the directory. We'll just
- # die on the next line though, so it's not that much of a loss.
-
- f = open(depstarget, "w")
- for dep in sorted(deps):
- print >>f, "%s: %s" % (target, dep)
-
-if __name__ == "__main__":
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is cl.py: a python wrapper for cl to automatically generate
+# dependency information.
+#
+# The Initial Developer of the Original Code is
+# Mozilla Foundation.
+# Portions created by the Initial Developer are Copyright (C) 2010
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Kyle Huey <me@kylehuey.com>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+import os, os.path
+import subprocess
+import sys
+
+CL_INCLUDES_PREFIX = os.environ.get("CL_INCLUDES_PREFIX", "Note: including file:")
+
+def InvokeClWithDependencyGeneration(cmdline):
+ target = ""
+ # Figure out what the target is
+ for arg in cmdline:
+ if arg.startswith("-Fo"):
+ target = arg[3:]
+ break
+
+ if target == None:
+ print >>sys.stderr, "No target set" and sys.exit(1)
+
+ # The deps target lives here
+ depstarget = os.path.basename(target) + ".pp"
+
+ cmdline += ['-showIncludes']
+ cl = subprocess.Popen(cmdline, stdout=subprocess.PIPE)
+
+ deps = set()
+ for line in cl.stdout:
+ # cl -showIncludes prefixes every header with "Note: including file:"
+ # and an indentation corresponding to the depth (which we don't need)
+ if line.startswith(CL_INCLUDES_PREFIX):
+ dep = line[len(CL_INCLUDES_PREFIX):].strip()
+ # We can't handle pathes with spaces properly in mddepend.pl, but
+ # we can assume that anything in a path with spaces is a system
+ # header and throw it away.
+ if dep.find(' ') == -1:
+ deps.add(dep)
+ else:
+ sys.stdout.write(line) # Make sure we preserve the relevant output
+ # from cl
+
+ ret = cl.wait()
+ if ret != 0 or target == "":
+ sys.exit(ret)
+
+ depsdir = os.path.normpath(os.path.join(os.path.dirname(target), ".deps"))
+ depstarget = os.path.join(depsdir, depstarget)
+ if not os.path.isdir(depsdir):
+ try:
+ os.makedirs(depsdir)
+ except OSError:
+ pass # This suppresses the error we get when the dir exists, at the
+ # cost of masking failure to create the directory. We'll just
+ # die on the next line though, so it's not that much of a loss.
+
+ f = open(depstarget, "w")
+ for dep in sorted(deps):
+ print >>f, "%s: %s" % (target, dep)
+
+if __name__ == "__main__":
InvokeClWithDependencyGeneration(sys.argv[1:])
--- a/build/pymake/pymake/implicit.py
+++ b/build/pymake/pymake/implicit.py
@@ -1,13 +1,13 @@
-"""
-Implicit variables; perhaps in the future this will also include some implicit
-rules, at least match-anything cancellation rules.
-"""
-
-variables = {
- 'RM': '%pymake.builtins rm -f',
- 'SLEEP': '%pymake.builtins sleep',
- 'TOUCH': '%pymake.builtins touch',
- '.LIBPATTERNS': 'lib%.so lib%.a',
- '.PYMAKE': '1',
- }
-
+"""
+Implicit variables; perhaps in the future this will also include some implicit
+rules, at least match-anything cancellation rules.
+"""
+
+variables = {
+ 'RM': '%pymake.builtins rm -f',
+ 'SLEEP': '%pymake.builtins sleep',
+ 'TOUCH': '%pymake.builtins touch',
+ '.LIBPATTERNS': 'lib%.so lib%.a',
+ '.PYMAKE': '1',
+ }
+
--- a/build/upload.py
+++ b/build/upload.py
@@ -1,227 +1,227 @@
-#!/usr/bin/python
-#
-# ***** BEGIN LICENSE BLOCK *****
-# Version: MPL 1.1/GPL 2.0/LGPL 2.1
-#
-# The contents of this file are subject to the Mozilla Public License Version
-# 1.1 (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-# http://www.mozilla.org/MPL/
-#
-# Software distributed under the License is distributed on an "AS IS" basis,
-# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
-# for the specific language governing rights and limitations under the
-# License.
-#
-# The Original Code is mozilla.org code.
-#
-# The Initial Developer of the Original Code is
-# The Mozilla Foundation
-# Portions created by the Initial Developer are Copyright (C) 2008
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-# Ted Mielczarek <ted.mielczarek@gmail.com>
-#
-# Alternatively, the contents of this file may be used under the terms of
-# either the GNU General Public License Version 2 or later (the "GPL"), or
-# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
-# in which case the provisions of the GPL or the LGPL are applicable instead
-# of those above. If you wish to allow use of your version of this file only
-# under the terms of either the GPL or the LGPL, and not to allow others to
-# use your version of this file under the terms of the MPL, indicate your
-# decision by deleting the provisions above and replace them with the notice
-# and other provisions required by the GPL or the LGPL. If you do not delete
-# the provisions above, a recipient may use your version of this file under
-# the terms of any one of the MPL, the GPL or the LGPL.
-#
-# ***** END LICENSE BLOCK *****
-#
-# When run directly, this script expects the following environment variables
-# to be set:
-# UPLOAD_HOST : host to upload files to
-# UPLOAD_USER : username on that host
-# UPLOAD_PATH : path on that host to put the files in
-#
-# And will use the following optional environment variables if set:
-# UPLOAD_SSH_KEY : path to a ssh private key to use
-# UPLOAD_PORT : port to use for ssh
-# POST_UPLOAD_CMD: a commandline to run on the remote host after uploading.
-# UPLOAD_PATH and the full paths of all files uploaded will
-# be appended to the commandline.
-#
-# 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 sys, os
-from optparse import OptionParser
-from subprocess import Popen, PIPE
-from util import check_call
-
-def RequireEnvironmentVariable(v):
- """Return the value of the environment variable named v, or print
- an error and exit if it's unset (or empty)."""
- if not v in os.environ or os.environ[v] == "":
- print "Error: required environment variable %s not set" % v
- sys.exit(1)
- return os.environ[v]
-
-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 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 WindowsPathToMsysPath(path):
- """Translate a Windows pathname to an MSYS pathname.
- Necessary because we call out to ssh/scp, which are MSYS binaries
- and expect MSYS paths."""
- if sys.platform != 'win32':
- return path
- (drive, path) = os.path.splitdrive(os.path.abspath(path))
- return "/" + drive[0] + path.replace('\\','/')
-
-def AppendOptionalArgsToSSHCommandline(cmdline, port, ssh_key):
- """Given optional port and ssh key values, append valid OpenSSH
- commandline arguments to the list cmdline if the values are not None."""
- if port is not None:
- cmdline.append("-P%d" % port)
- if ssh_key is not None:
- # Don't interpret ~ paths - ssh can handle that on its own
- if not ssh_key.startswith('~'):
- ssh_key = WindowsPathToMsysPath(ssh_key)
- cmdline.extend(["-o", "IdentityFile=%s" % ssh_key])
-
-def DoSSHCommand(command, user, host, port=None, ssh_key=None):
- """Execute command on user@host using ssh. Optionally use
- port and ssh_key, if provided."""
- cmdline = ["ssh"]
- AppendOptionalArgsToSSHCommandline(cmdline, port, ssh_key)
- cmdline.extend(["%s@%s" % (user, host), command])
- cmd = Popen(cmdline, stdout=PIPE)
- retcode = cmd.wait()
- if retcode != 0:
- raise Exception("Command %s returned non-zero exit code: %i" % \
- (cmdline, retcode))
- return cmd.stdout.read().strip()
-
-def DoSCPFile(file, remote_path, user, host, port=None, ssh_key=None):
- """Upload file to user@host:remote_path using scp. Optionally use
- port and ssh_key, if provided."""
- cmdline = ["scp"]
- AppendOptionalArgsToSSHCommandline(cmdline, port, ssh_key)
- cmdline.extend([WindowsPathToMsysPath(file),
- "%s@%s:%s" % (user, host, remote_path)])
- check_call(cmdline)
-
-def GetRemotePath(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 UploadFiles(user, host, path, files, verbose=False, port=None, ssh_key=None, base_path=None, upload_to_temp_dir=False, post_upload_command=None):
- """Upload each file in the list files to user@host:path. Optionally pass
- port and ssh_key to the ssh commands. If base_path is not None, upload
- files including their path relative to base_path. If upload_to_temp_dir is
- True files will be uploaded to a temporary directory on the remote server.
- Generally, you should have a post upload command specified in these cases
- that can move them around to their correct location(s).
- If post_upload_command is not None, execute that command on the remote host
- after uploading all files, passing it the upload path, and the full paths to
- all files uploaded.
- If verbose is True, print status updates while working."""
- if upload_to_temp_dir:
- path = DoSSHCommand("mktemp -d", user, host, port=port, ssh_key=ssh_key)
- if not path.endswith("/"):
- path += "/"
- if base_path is not None:
- base_path = os.path.abspath(base_path)
- remote_files = []
- try:
- 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
- remote_path = GetRemotePath(path, file, base_path)
- DoSSHCommand("mkdir -p " + remote_path, user, host, port=port, ssh_key=ssh_key)
- if verbose:
- print "Uploading " + file
- DoSCPFile(file, remote_path, user, host, port=port, ssh_key=ssh_key)
- remote_files.append(remote_path + '/' + os.path.basename(file))
- if post_upload_command is not None:
- if verbose:
- print "Running post-upload command: " + post_upload_command
- file_list = '"' + '" "'.join(remote_files) + '"'
- DoSSHCommand('%s "%s" %s' % (post_upload_command, path, file_list), user, host, port=port, ssh_key=ssh_key)
- finally:
- if upload_to_temp_dir:
- DoSSHCommand("rm -rf %s" % path, user, host, port=port,
- ssh_key=ssh_key)
- if verbose:
- print "Upload complete"
-
-if __name__ == '__main__':
- host = RequireEnvironmentVariable('UPLOAD_HOST')
- user = RequireEnvironmentVariable('UPLOAD_USER')
- path = OptionalEnvironmentVariable('UPLOAD_PATH')
- upload_to_temp_dir = OptionalEnvironmentVariable('UPLOAD_TO_TEMP')
- port = OptionalEnvironmentVariable('UPLOAD_PORT')
- if port is not None:
- port = int(port)
- key = OptionalEnvironmentVariable('UPLOAD_SSH_KEY')
- post_upload_command = OptionalEnvironmentVariable('POST_UPLOAD_CMD')
- if (not path and not upload_to_temp_dir) or (path and upload_to_temp_dir):
- print "One (and only one of UPLOAD_PATH or UPLOAD_TO_TEMP must be " + \
- "defined."
- sys.exit(1)
- if sys.platform == 'win32':
- if path is not None:
- path = FixupMsysPath(path)
- if post_upload_command is not None:
- post_upload_command = FixupMsysPath(post_upload_command)
-
- parser = OptionParser(usage="usage: %prog [options] <files>")
- parser.add_option("-b", "--base-path",
- action="store", dest="base_path",
- 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:
- UploadFiles(user, host, path, args, base_path=options.base_path,
- port=port, ssh_key=key, upload_to_temp_dir=upload_to_temp_dir,
- post_upload_command=post_upload_command,
- verbose=True)
- except IOError, (strerror):
- print strerror
- sys.exit(1)
- except Exception, (err):
- print err
- sys.exit(2)
+#!/usr/bin/python
+#
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is mozilla.org code.
+#
+# The Initial Developer of the Original Code is
+# The Mozilla Foundation
+# Portions created by the Initial Developer are Copyright (C) 2008
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Ted Mielczarek <ted.mielczarek@gmail.com>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+#
+# When run directly, this script expects the following environment variables
+# to be set:
+# UPLOAD_HOST : host to upload files to
+# UPLOAD_USER : username on that host
+# UPLOAD_PATH : path on that host to put the files in
+#
+# And will use the following optional environment variables if set:
+# UPLOAD_SSH_KEY : path to a ssh private key to use
+# UPLOAD_PORT : port to use for ssh
+# POST_UPLOAD_CMD: a commandline to run on the remote host after uploading.
+# UPLOAD_PATH and the full paths of all files uploaded will
+# be appended to the commandline.
+#
+# 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 sys, os
+from optparse import OptionParser
+from subprocess import Popen, PIPE
+from util import check_call
+
+def RequireEnvironmentVariable(v):
+ """Return the value of the environment variable named v, or print
+ an error and exit if it's unset (or empty)."""
+ if not v in os.environ or os.environ[v] == "":
+ print "Error: required environment variable %s not set" % v
+ sys.exit(1)
+ return os.environ[v]
+
+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 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 WindowsPathToMsysPath(path):
+ """Translate a Windows pathname to an MSYS pathname.
+ Necessary because we call out to ssh/scp, which are MSYS binaries
+ and expect MSYS paths."""
+ if sys.platform != 'win32':
+ return path
+ (drive, path) = os.path.splitdrive(os.path.abspath(path))
+ return "/" + drive[0] + path.replace('\\','/')
+
+def AppendOptionalArgsToSSHCommandline(cmdline, port, ssh_key):
+ """Given optional port and ssh key values, append valid OpenSSH
+ commandline arguments to the list cmdline if the values are not None."""
+ if port is not None:
+ cmdline.append("-P%d" % port)
+ if ssh_key is not None:
+ # Don't interpret ~ paths - ssh can handle that on its own
+ if not ssh_key.startswith('~'):
+ ssh_key = WindowsPathToMsysPath(ssh_key)
+ cmdline.extend(["-o", "IdentityFile=%s" % ssh_key])
+
+def DoSSHCommand(command, user, host, port=None, ssh_key=None):
+ """Execute command on user@host using ssh. Optionally use
+ port and ssh_key, if provided."""
+ cmdline = ["ssh"]
+ AppendOptionalArgsToSSHCommandline(cmdline, port, ssh_key)
+ cmdline.extend(["%s@%s" % (user, host), command])
+ cmd = Popen(cmdline, stdout=PIPE)
+ retcode = cmd.wait()
+ if retcode != 0:
+ raise Exception("Command %s returned non-zero exit code: %i" % \
+ (cmdline, retcode))
+ return cmd.stdout.read().strip()
+
+def DoSCPFile(file, remote_path, user, host, port=None, ssh_key=None):
+ """Upload file to user@host:remote_path using scp. Optionally use
+ port and ssh_key, if provided."""
+ cmdline = ["scp"]
+ AppendOptionalArgsToSSHCommandline(cmdline, port, ssh_key)
+ cmdline.extend([WindowsPathToMsysPath(file),
+ "%s@%s:%s" % (user, host, remote_path)])
+ check_call(cmdline)
+
+def GetRemotePath(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 UploadFiles(user, host, path, files, verbose=False, port=None, ssh_key=None, base_path=None, upload_to_temp_dir=False, post_upload_command=None):
+ """Upload each file in the list files to user@host:path. Optionally pass
+ port and ssh_key to the ssh commands. If base_path is not None, upload
+ files including their path relative to base_path. If upload_to_temp_dir is
+ True files will be uploaded to a temporary directory on the remote server.
+ Generally, you should have a post upload command specified in these cases
+ that can move them around to their correct location(s).
+ If post_upload_command is not None, execute that command on the remote host
+ after uploading all files, passing it the upload path, and the full paths to
+ all files uploaded.
+ If verbose is True, print status updates while working."""
+ if upload_to_temp_dir:
+ path = DoSSHCommand("mktemp -d", user, host, port=port, ssh_key=ssh_key)
+ if not path.endswith("/"):
+ path += "/"
+ if base_path is not None:
+ base_path = os.path.abspath(base_path)
+ remote_files = []
+ try:
+ 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
+ remote_path = GetRemotePath(path, file, base_path)
+ DoSSHCommand("mkdir -p " + remote_path, user, host, port=port, ssh_key=ssh_key)
+ if verbose:
+ print "Uploading " + file
+ DoSCPFile(file, remote_path, user, host, port=port, ssh_key=ssh_key)
+ remote_files.append(remote_path + '/' + os.path.basename(file))
+ if post_upload_command is not None:
+ if verbose:
+ print "Running post-upload command: " + post_upload_command
+ file_list = '"' + '" "'.join(remote_files) + '"'
+ DoSSHCommand('%s "%s" %s' % (post_upload_command, path, file_list), user, host, port=port, ssh_key=ssh_key)
+ finally:
+ if upload_to_temp_dir:
+ DoSSHCommand("rm -rf %s" % path, user, host, port=port,
+ ssh_key=ssh_key)
+ if verbose:
+ print "Upload complete"
+
+if __name__ == '__main__':
+ host = RequireEnvironmentVariable('UPLOAD_HOST')
+ user = RequireEnvironmentVariable('UPLOAD_USER')
+ path = OptionalEnvironmentVariable('UPLOAD_PATH')
+ upload_to_temp_dir = OptionalEnvironmentVariable('UPLOAD_TO_TEMP')
+ port = OptionalEnvironmentVariable('UPLOAD_PORT')
+ if port is not None:
+ port = int(port)
+ key = OptionalEnvironmentVariable('UPLOAD_SSH_KEY')
+ post_upload_command = OptionalEnvironmentVariable('POST_UPLOAD_CMD')
+ if (not path and not upload_to_temp_dir) or (path and upload_to_temp_dir):
+ print "One (and only one of UPLOAD_PATH or UPLOAD_TO_TEMP must be " + \
+ "defined."
+ sys.exit(1)
+ if sys.platform == 'win32':
+ if path is not None:
+ path = FixupMsysPath(path)
+ if post_upload_command is not None:
+ post_upload_command = FixupMsysPath(post_upload_command)
+
+ parser = OptionParser(usage="usage: %prog [options] <files>")
+ parser.add_option("-b", "--base-path",
+ action="store", dest="base_path",
+ 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:
+ UploadFiles(user, host, path, args, base_path=options.base_path,
+ port=port, ssh_key=key, upload_to_temp_dir=upload_to_temp_dir,
+ post_upload_command=post_upload_command,
+ verbose=True)
+ except IOError, (strerror):
+ print strerror
+ sys.exit(1)
+ except Exception, (err):
+ print err
+ sys.exit(2)
--- a/build/util.py
+++ b/build/util.py
@@ -1,50 +1,50 @@
-#!/usr/bin/python
-#
-# ***** BEGIN LICENSE BLOCK *****
-# Version: MPL 1.1/GPL 2.0/LGPL 2.1
-#
-# The contents of this file are subject to the Mozilla Public License Version
-# 1.1 (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-# http://www.mozilla.org/MPL/
-#
-# Software distributed under the License is distributed on an "AS IS" basis,
-# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
-# for the specific language governing rights and limitations under the
-# License.
-#
-# The Original Code is mozilla.org code.
-#
-# The Initial Developer of the Original Code is
-# The Mozilla Foundation
-# Portions created by the Initial Developer are Copyright (C) 2008
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-# Ted Mielczarek <ted.mielczarek@gmail.com>
-#
-# Alternatively, the contents of this file may be used under the terms of
-# either the GNU General Public License Version 2 or later (the "GPL"), or
-# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
-# in which case the provisions of the GPL or the LGPL are applicable instead
-# of those above. If you wish to allow use of your version of this file only
-# under the terms of either the GPL or the LGPL, and not to allow others to
-# use your version of this file under the terms of the MPL, indicate your
-# decision by deleting the provisions above and replace them with the notice
-# and other provisions required by the GPL or the LGPL. If you do not delete
-# the provisions above, a recipient may use your version of this file under
-# the terms of any one of the MPL, the GPL or the LGPL.
-#
-# ***** END LICENSE BLOCK *****
-
-try:
- from subprocess import check_call
-except ImportError:
- import subprocess
- def check_call(*popenargs, **kwargs):
- retcode = subprocess.call(*popenargs, **kwargs)
- if retcode:
- cmd = kwargs.get("args")
- if cmd is None:
- cmd = popenargs[0]
- raise Exception("Command '%s' returned non-zero exit status %i" % (cmd, retcode))
+#!/usr/bin/python
+#
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is mozilla.org code.
+#
+# The Initial Developer of the Original Code is
+# The Mozilla Foundation
+# Portions created by the Initial Developer are Copyright (C) 2008
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Ted Mielczarek <ted.mielczarek@gmail.com>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+try:
+ from subprocess import check_call
+except ImportError:
+ import subprocess
+ def check_call(*popenargs, **kwargs):
+ retcode = subprocess.call(*popenargs, **kwargs)
+ if retcode:
+ cmd = kwargs.get("args")
+ if cmd is None:
+ cmd = popenargs[0]
+ raise Exception("Command '%s' returned non-zero exit status %i" % (cmd, retcode))
--- a/js/src/build/cl.py
+++ b/js/src/build/cl.py
@@ -1,96 +1,96 @@
-# ***** BEGIN LICENSE BLOCK *****
-# Version: MPL 1.1/GPL 2.0/LGPL 2.1
-#
-# The contents of this file are subject to the Mozilla Public License Version
-# 1.1 (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-# http://www.mozilla.org/MPL/
-#
-# Software distributed under the License is distributed on an "AS IS" basis,
-# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
-# for the specific language governing rights and limitations under the
-# License.
-#
-# The Original Code is cl.py: a python wrapper for cl to automatically generate
-# dependency information.
-#
-# The Initial Developer of the Original Code is
-# Mozilla Foundation.
-# Portions created by the Initial Developer are Copyright (C) 2010
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-# Kyle Huey <me@kylehuey.com>
-#
-# Alternatively, the contents of this file may be used under the terms of
-# either the GNU General Public License Version 2 or later (the "GPL"), or
-# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
-# in which case the provisions of the GPL or the LGPL are applicable instead
-# of those above. If you wish to allow use of your version of this file only
-# under the terms of either the GPL or the LGPL, and not to allow others to
-# use your version of this file under the terms of the MPL, indicate your
-# decision by deleting the provisions above and replace them with the notice
-# and other provisions required by the GPL or the LGPL. If you do not delete
-# the provisions above, a recipient may use your version of this file under
-# the terms of any one of the MPL, the GPL or the LGPL.
-#
-# ***** END LICENSE BLOCK *****
-
-import os, os.path
-import subprocess
-import sys
-
-CL_INCLUDES_PREFIX = os.environ.get("CL_INCLUDES_PREFIX", "Note: including file:")
-
-def InvokeClWithDependencyGeneration(cmdline):
- target = ""
- # Figure out what the target is
- for arg in cmdline:
- if arg.startswith("-Fo"):
- target = arg[3:]
- break
-
- if target == None:
- print >>sys.stderr, "No target set" and sys.exit(1)
-
- # The deps target lives here
- depstarget = os.path.basename(target) + ".pp"
-
- cmdline += ['-showIncludes']
- cl = subprocess.Popen(cmdline, stdout=subprocess.PIPE)
-
- deps = set()
- for line in cl.stdout:
- # cl -showIncludes prefixes every header with "Note: including file:"
- # and an indentation corresponding to the depth (which we don't need)
- if line.startswith(CL_INCLUDES_PREFIX):
- dep = line[len(CL_INCLUDES_PREFIX):].strip()
- # We can't handle pathes with spaces properly in mddepend.pl, but
- # we can assume that anything in a path with spaces is a system
- # header and throw it away.
- if dep.find(' ') == -1:
- deps.add(dep)
- else:
- sys.stdout.write(line) # Make sure we preserve the relevant output
- # from cl
-
- ret = cl.wait()
- if ret != 0 or target == "":
- sys.exit(ret)
-
- depsdir = os.path.normpath(os.path.join(os.path.dirname(target), ".deps"))
- depstarget = os.path.join(depsdir, depstarget)
- if not os.path.isdir(depsdir):
- try:
- os.makedirs(depsdir)
- except OSError:
- pass # This suppresses the error we get when the dir exists, at the
- # cost of masking failure to create the directory. We'll just
- # die on the next line though, so it's not that much of a loss.
-
- f = open(depstarget, "w")
- for dep in sorted(deps):
- print >>f, "%s: %s" % (target, dep)
-
-if __name__ == "__main__":
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is cl.py: a python wrapper for cl to automatically generate
+# dependency information.
+#
+# The Initial Developer of the Original Code is
+# Mozilla Foundation.
+# Portions created by the Initial Developer are Copyright (C) 2010
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Kyle Huey <me@kylehuey.com>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+import os, os.path
+import subprocess
+import sys
+
+CL_INCLUDES_PREFIX = os.environ.get("CL_INCLUDES_PREFIX", "Note: including file:")
+
+def InvokeClWithDependencyGeneration(cmdline):
+ target = ""
+ # Figure out what the target is
+ for arg in cmdline:
+ if arg.startswith("-Fo"):
+ target = arg[3:]
+ break
+
+ if target == None:
+ print >>sys.stderr, "No target set" and sys.exit(1)
+
+ # The deps target lives here
+ depstarget = os.path.basename(target) + ".pp"
+
+ cmdline += ['-showIncludes']
+ cl = subprocess.Popen(cmdline, stdout=subprocess.PIPE)
+
+ deps = set()
+ for line in cl.stdout:
+ # cl -showIncludes prefixes every header with "Note: including file:"
+ # and an indentation corresponding to the depth (which we don't need)
+ if line.startswith(CL_INCLUDES_PREFIX):
+ dep = line[len(CL_INCLUDES_PREFIX):].strip()
+ # We can't handle pathes with spaces properly in mddepend.pl, but
+ # we can assume that anything in a path with spaces is a system
+ # header and throw it away.
+ if dep.find(' ') == -1:
+ deps.add(dep)
+ else:
+ sys.stdout.write(line) # Make sure we preserve the relevant output
+ # from cl
+
+ ret = cl.wait()
+ if ret != 0 or target == "":
+ sys.exit(ret)
+
+ depsdir = os.path.normpath(os.path.join(os.path.dirname(target), ".deps"))
+ depstarget = os.path.join(depsdir, depstarget)
+ if not os.path.isdir(depsdir):
+ try:
+ os.makedirs(depsdir)
+ except OSError:
+ pass # This suppresses the error we get when the dir exists, at the
+ # cost of masking failure to create the directory. We'll just
+ # die on the next line though, so it's not that much of a loss.
+
+ f = open(depstarget, "w")
+ for dep in sorted(deps):
+ print >>f, "%s: %s" % (target, dep)
+
+if __name__ == "__main__":
InvokeClWithDependencyGeneration(sys.argv[1:])
--- a/tools/update-packaging/generatesnippet.py
+++ b/tools/update-packaging/generatesnippet.py
@@ -1,198 +1,198 @@
-# ***** BEGIN LICENSE BLOCK *****
-# Version: MPL 1.1/GPL 2.0/LGPL 2.1
-#
-# The contents of this file are subject to the Mozilla Public License Version
-# 1.1 (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-# http://www.mozilla.org/MPL/
-#
-# Software distributed under the License is distributed on an "AS IS" basis,
-# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
-# for the specific language governing rights and limitations under the
-# License.
-#
-# The Original Code is the Mozilla build system
-#
-# The Initial Developer of the Original Code is Mozilla.
-# Portions created by the Initial Developer are Copyright (C) 2009
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-# Armen Zambrano Gasparnian <armenzg@mozilla.com>
-#
-# Alternatively, the contents of this file may be used under the terms of
-# either the GNU General Public License Version 2 or later (the "GPL"), or
-# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
-# in which case the provisions of the GPL or the LGPL are applicable instead
-# of those above. If you wish to allow use of your version of this file only
-# under the terms of either the GPL or the LGPL, and not to allow others to
-# use your version of this file under the terms of the MPL, indicate your
-# decision by deleting the provisions above and replace them with the notice
-# and other provisions required by the GPL or the LGPL. If you do not delete
-# the provisions above, a recipient may use your version of this file under
-# the terms of any one of the MPL, the GPL or the LGPL.
-#
-# ***** END LICENSE BLOCK *****
-
-"""
-This script generates the complete snippet for a given locale or en-US
-Most of the parameters received are to generate the MAR's download URL
-and determine the MAR's filename
-"""
-import sys, os, platform, sha
-from optparse import OptionParser
-from ConfigParser import ConfigParser
-from stat import ST_SIZE
-
-def main():
- error = False
- parser = OptionParser(
- usage="%prog [options]")
- parser.add_option("--mar-path",
- action="store",
- dest="marPath",
- help="[Required] Specify the absolute path where the MAR file is found.")
- parser.add_option("--application-ini-file",
- action="store",
- dest="applicationIniFile",
- help="[Required] Specify the absolute path to the application.ini file.")
- parser.add_option("-l",
- "--locale",
- action="store",
- dest="locale",
- help="[Required] Specify which locale we are generating the snippet for.")
- parser.add_option("-p",
- "--product",
- action="store",
- dest="product",
- help="[Required] This option is used to generate the URL to download the MAR file.")
- parser.add_option("--platform",
- action="store",
- dest="platform",
- help="[Required] This option is used to indicate which target platform.")
- parser.add_option("--branch",
- action="store",
- dest="branch",
- help="This option is used to indicate which branch name to use for FTP file names.")
- parser.add_option("--download-base-URL",
- action="store",
- dest="downloadBaseURL",
- help="This option indicates under which.")
- parser.add_option("-v",
- "--verbose",
- action="store_true",
- dest="verbose",
- default=False,
- help="This option increases the output of the script.")
- (options, args) = parser.parse_args()
- for req, msg in (('marPath', "the absolute path to the where the MAR file is"),
- ('applicationIniFile', "the absolute path to the application.ini file."),
- ('locale', "a locale."),
- ('product', "specify a product."),
- ('platform', "specify the platform.")):
- if not hasattr(options, req):
- parser.error('You must specify %s' % msg)
-
- if not options.downloadBaseURL or options.downloadBaseURL == '':
- options.downloadBaseURL = 'http://ftp.mozilla.org/pub/mozilla.org/%s/nightly' % options.product
-
- if not options.branch or options.branch == '':
- options.branch = None
-
- snippet = generateSnippet(options.marPath,
- options.applicationIniFile,
- options.locale,
- options.downloadBaseURL,
- options.product,
- options.platform,
- options.branch)
- f = open(os.path.join(options.marPath, 'complete.update.snippet'), 'wb')
- f.write(snippet)
- f.close()
-
- if options.verbose:
- # Show in our logs what the contents of the snippet are
- print snippet
-
-def generateSnippet(abstDistDir, applicationIniFile, locale,
- downloadBaseURL, product, platform, branch):
- # Let's extract information from application.ini
- c = ConfigParser()
- try:
- c.readfp(open(applicationIniFile))
- except IOError, (stderror):
- sys.exit(stderror)
- buildid = c.get("App", "BuildID")
- appVersion = c.get("App", "Version")
- branchName = branch or c.get("App", "SourceRepository").split('/')[-1]
-
- marFileName = '%s-%s.%s.%s.complete.mar' % (
- product,
- appVersion,
- locale,
- platform)
- # Let's determine the hash and the size of the MAR file
- # This function exits the script if the file does not exist
- (completeMarHash, completeMarSize) = getFileHashAndSize(
- os.path.join(abstDistDir, marFileName))
- # Construct the URL to where the MAR file will exist
- interfix = ''
- if locale == 'en-US':
- interfix = ''
- else:
- interfix = '-l10n'
- marDownloadURL = "%s/%s%s/%s" % (downloadBaseURL,
- datedDirPath(buildid, branchName),
- interfix,
- marFileName)
-
- snippet = """complete
-%(marDownloadURL)s
-sha1
-%(completeMarHash)s
-%(completeMarSize)s
-%(buildid)s
-%(appVersion)s
-%(appVersion)s
-""" % dict( marDownloadURL=marDownloadURL,
- completeMarHash=completeMarHash,
- completeMarSize=completeMarSize,
- buildid=buildid,
- appVersion=appVersion)
-
- return snippet
-
-def getFileHashAndSize(filepath):
- sha1Hash = 'UNKNOWN'
- size = 'UNKNOWN'
-
- try:
- # open in binary mode to make sure we get consistent results
- # across all platforms
- f = open(filepath, "rb")
- shaObj = sha.new(f.read())
- sha1Hash = shaObj.hexdigest()
- size = os.stat(filepath)[ST_SIZE]
- except IOError, (stderror):
- sys.exit(stderror)
-
- return (sha1Hash, size)
-
-def datedDirPath(buildid, milestone):
- """
- Returns a string that will look like:
- 2009/12/2009-12-31-09-mozilla-central
- """
- year = buildid[0:4]
- month = buildid[4:6]
- day = buildid[6:8]
- hour = buildid[8:10]
- datedDir = "%s-%s-%s-%s-%s" % (year,
- month,
- day,
- hour,
- milestone)
- return "%s/%s/%s" % (year, month, datedDir)
-
-if __name__ == '__main__':
- main()
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Mozilla build system
+#
+# The Initial Developer of the Original Code is Mozilla.
+# Portions created by the Initial Developer are Copyright (C) 2009
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Armen Zambrano Gasparnian <armenzg@mozilla.com>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+"""
+This script generates the complete snippet for a given locale or en-US
+Most of the parameters received are to generate the MAR's download URL
+and determine the MAR's filename
+"""
+import sys, os, platform, sha
+from optparse import OptionParser
+from ConfigParser import ConfigParser
+from stat import ST_SIZE
+
+def main():
+ error = False
+ parser = OptionParser(
+ usage="%prog [options]")
+ parser.add_option("--mar-path",
+ action="store",
+ dest="marPath",
+ help="[Required] Specify the absolute path where the MAR file is found.")
+ parser.add_option("--application-ini-file",
+ action="store",
+ dest="applicationIniFile",
+ help="[Required] Specify the absolute path to the application.ini file.")
+ parser.add_option("-l",
+ "--locale",
+ action="store",
+ dest="locale",
+ help="[Required] Specify which locale we are generating the snippet for.")
+ parser.add_option("-p",
+ "--product",
+ action="store",
+ dest="product",
+ help="[Required] This option is used to generate the URL to download the MAR file.")
+ parser.add_option("--platform",
+ action="store",
+ dest="platform",
+ help="[Required] This option is used to indicate which target platform.")
+ parser.add_option("--branch",
+ action="store",
+ dest="branch",
+ help="This option is used to indicate which branch name to use for FTP file names.")
+ parser.add_option("--download-base-URL",
+ action="store",
+ dest="downloadBaseURL",
+ help="This option indicates under which.")
+ parser.add_option("-v",
+ "--verbose",
+ action="store_true",
+ dest="verbose",
+ default=False,
+ help="This option increases the output of the script.")
+ (options, args) = parser.parse_args()
+ for req, msg in (('marPath', "the absolute path to the where the MAR file is"),
+ ('applicationIniFile', "the absolute path to the application.ini file."),
+ ('locale', "a locale."),
+ ('product', "specify a product."),
+ ('platform', "specify the platform.")):
+ if not hasattr(options, req):
+ parser.error('You must specify %s' % msg)
+
+ if not options.downloadBaseURL or options.downloadBaseURL == '':
+ options.downloadBaseURL = 'http://ftp.mozilla.org/pub/mozilla.org/%s/nightly' % options.product
+
+ if not options.branch or options.branch == '':
+ options.branch = None
+
+ snippet = generateSnippet(options.marPath,
+ options.applicationIniFile,
+ options.locale,
+ options.downloadBaseURL,
+ options.product,
+ options.platform,
+ options.branch)
+ f = open(os.path.join(options.marPath, 'complete.update.snippet'), 'wb')
+ f.write(snippet)
+ f.close()
+
+ if options.verbose:
+ # Show in our logs what the contents of the snippet are
+ print snippet
+
+def generateSnippet(abstDistDir, applicationIniFile, locale,
+ downloadBaseURL, product, platform, branch):
+ # Let's extract information from application.ini
+ c = ConfigParser()
+ try:
+ c.readfp(open(applicationIniFile))
+ except IOError, (stderror):
+ sys.exit(stderror)
+ buildid = c.get("App", "BuildID")
+ appVersion = c.get("App", "Version")
+ branchName = branch or c.get("App", "SourceRepository").split('/')[-1]
+
+ marFileName = '%s-%s.%s.%s.complete.mar' % (
+ product,
+ appVersion,
+ locale,
+ platform)
+ # Let's determine the hash and the size of the MAR file
+ # This function exits the script if the file does not exist
+ (completeMarHash, completeMarSize) = getFileHashAndSize(
+ os.path.join(abstDistDir, marFileName))
+ # Construct the URL to where the MAR file will exist
+ interfix = ''
+ if locale == 'en-US':
+ interfix = ''
+ else:
+ interfix = '-l10n'
+ marDownloadURL = "%s/%s%s/%s" % (downloadBaseURL,
+ datedDirPath(buildid, branchName),
+ interfix,
+ marFileName)
+
+ snippet = """complete
+%(marDownloadURL)s
+sha1
+%(completeMarHash)s
+%(completeMarSize)s
+%(buildid)s
+%(appVersion)s
+%(appVersion)s
+""" % dict( marDownloadURL=marDownloadURL,
+ completeMarHash=completeMarHash,
+ completeMarSize=completeMarSize,
+ buildid=buildid,
+ appVersion=appVersion)
+
+ return snippet
+
+def getFileHashAndSize(filepath):
+ sha1Hash = 'UNKNOWN'
+ size = 'UNKNOWN'
+
+ try:
+ # open in binary mode to make sure we get consistent results
+ # across all platforms
+ f = open(filepath, "rb")
+ shaObj = sha.new(f.read())
+ sha1Hash = shaObj.hexdigest()
+ size = os.stat(filepath)[ST_SIZE]
+ except IOError, (stderror):
+ sys.exit(stderror)
+
+ return (sha1Hash, size)
+
+def datedDirPath(buildid, milestone):
+ """
+ Returns a string that will look like:
+ 2009/12/2009-12-31-09-mozilla-central
+ """
+ year = buildid[0:4]
+ month = buildid[4:6]
+ day = buildid[6:8]
+ hour = buildid[8:10]
+ datedDir = "%s-%s-%s-%s-%s" % (year,
+ month,
+ day,
+ hour,
+ milestone)
+ return "%s/%s/%s" % (year, month, datedDir)
+
+if __name__ == '__main__':
+ main()