summaryrefslogtreecommitdiffstats
path: root/comm/build/moz.configure/gecko_source.configure
diff options
context:
space:
mode:
Diffstat (limited to 'comm/build/moz.configure/gecko_source.configure')
-rw-r--r--comm/build/moz.configure/gecko_source.configure261
1 files changed, 261 insertions, 0 deletions
diff --git a/comm/build/moz.configure/gecko_source.configure b/comm/build/moz.configure/gecko_source.configure
new file mode 100644
index 0000000000..319150c81a
--- /dev/null
+++ b/comm/build/moz.configure/gecko_source.configure
@@ -0,0 +1,261 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=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/.
+
+# Attempt to ascertain the Gecko source repository information.
+# We need to have accurate source repository information for MPL compliance.
+
+
+def get_fail_msg(source_name, repo_name, rev_name):
+ return """Unable to determine {} source repository.
+Try setting {} and {}
+environment variables or build from a Mercurial checkout.""".format(
+ source_name, repo_name, rev_name
+ )
+
+
+# Wrap check_cmd_output so that it does not fatally end configure on command
+# failure.
+def hg_cmd_output(*args, **kwargs):
+ def hg_error():
+ return None
+
+ kwargs["onerror"] = hg_error
+
+ return check_cmd_output(*args, **kwargs)
+
+
+@template
+def read_sourcestamp(repository):
+ """
+ Last resort, look for the revision data in the sourcestamp file.
+ This file only exists in release tar files created in CI.
+ repository must be one of "GECKO" or "COMM".
+ """
+ log.info("Determining %s source information from sourcestamp.txt..." % repository)
+
+ line2read = {"COMM": 1, "GECKO": 2}[repository]
+
+ @depends(build_environment)
+ @imports(_from="os.path", _import="exists")
+ @imports(_from="os.path", _import="join")
+ @imports(_from="__builtin__", _import="open")
+ def get_sourcestamp(build_env):
+ sourcestamp_file = join(build_env.topsrcdir, "sourcestamp.txt")
+ if exists(sourcestamp_file):
+ try:
+ lines = open(sourcestamp_file).readlines()
+ except:
+ pass
+
+ if len(lines) != 3:
+ log.warn("sourcestamp.txt is corrupt!")
+ return
+
+ if lines and lines[line2read].startswith("http"):
+ repo_line = lines[line2read]
+ repo_url = repo_line.split("/rev/")
+ return namespace(repo_url=repo_url[0], repo_rev=repo_url[1])
+
+ return get_sourcestamp
+
+
+@template
+def read_gecko_rev_yml():
+ def get_value(x):
+ return x.split()[1]
+
+ @depends(commtopsrcdir)
+ @imports(_from="os.path", _import="exists")
+ @imports(_from="os.path", _import="join")
+ @imports(_from="__builtin__", _import="open")
+ def wrapped(commtopsrcdir):
+ log.info("Determining GECKO source information from .gecko_rev.yml")
+ rev_file = join(commtopsrcdir, ".gecko_rev.yml")
+ if not exists(rev_file):
+ return
+
+ repo = rev = ref = None
+
+ for line in open(rev_file).readlines():
+ if line.startswith("GECKO_HEAD_REPOSITORY:"):
+ repo = get_value(line)
+ elif line.startswith("GECKO_HEAD_REV:"):
+ rev = get_value(line)
+ elif line.startswith("GECKO_HEAD_REF:"):
+ ref = get_value(line)
+ else:
+ pass
+
+ return namespace(repo=repo, rev=rev, ref=ref)
+
+ return wrapped
+
+
+@depends(application)
+@imports(_from="os", _import="environ")
+def comm_repo_from_environ(app):
+ """
+ Read the Thunderbird source repository information from the environment.
+
+ Taskcluster builds set COMM_HEAD_REPOSITORY and COMM_HEAD_REV pointing
+ to the comm-* repository.
+ """
+ log.info("Determining COMM source information from environment...")
+ comm_repo = environ.get("COMM_HEAD_REPOSITORY", None)
+ comm_rev = environ.get("COMM_HEAD_REV", None)
+
+ if all([comm_repo, comm_rev]):
+ log.info("{}/rev/{}".format(comm_repo, comm_rev))
+ return namespace(comm_repo=comm_repo, comm_rev=comm_rev)
+
+
+# Read sourcestamp.txt and return the Thunderbird source URL (with changeset).
+# Silent fail if the file cannot be read.
+comm_sourcestamp = read_sourcestamp("COMM")
+
+
+@depends(comm_repo_from_environ, commtopsrcdir, hg, comm_sourcestamp)
+@imports(_from="os", _import="environ")
+def comm_repo_heuristics(comm_environ, commtopsrcdir, hg, sourcestamp):
+ """
+ Determine the Thunderbird Mercurial repository and revision from Mercurial
+ or sourcestamp.txt when COMM_HEAD_REPOSITORY and COMM_HEAD_REV are unset
+ (local developer builds).
+ """
+ if not comm_environ:
+ comm_repo = comm_rev = None
+ if hg:
+ log.info("Determining COMM source information from Mercurial...")
+ comm_rev = hg_cmd_output(hg, "-R", commtopsrcdir, "parent", "--template={node}")
+ comm_repo = hg_cmd_output(hg, "-R", commtopsrcdir, "path", "default")
+ if comm_repo:
+ comm_repo = comm_repo.strip()
+ if comm_repo.startswith("ssh://"):
+ comm_repo = "https://" + comm_repo[6:]
+ comm_repo = comm_repo.rstrip("/")
+ # TODO: git-cinnabar support?
+
+ if not comm_repo or not comm_rev:
+ try:
+ comm_repo, comm_rev = sourcestamp.repo_url, sourcestamp.repo_rev
+ except:
+ pass
+
+ if comm_repo and comm_rev:
+ return namespace(comm_repo=comm_repo, comm_rev=comm_rev)
+
+
+@depends(comm_repo_from_environ, comm_repo_heuristics, "MOZ_AUTOMATION")
+@imports(_from="os", _import="environ")
+def comm_source_repo(from_environ, from_config, automation):
+ rv = None
+ if from_environ:
+ rv = from_environ
+ elif from_config:
+ rv = from_config
+ elif automation:
+ die(get_fail_msg("COMM", "COMM_HEAD_REPOSITORY", "COMM_HEAD_REV"))
+ else:
+ log.info(get_fail_msg("COMM", "COMM_HEAD_REPOSITORY", "COMM_HEAD_REV"))
+ rv = namespace(comm_repo="unknown", comm_rev="unknown")
+
+ log.info("COMM_SOURCE_REPOSITORY: {}".format(rv.comm_repo))
+ log.info("COMM_SOURCE_CHANGESET: {}".format(rv.comm_rev))
+
+ # Used by old-configure to set in buildconfig. This is configure's environment
+ # not the same as used by the build itself.
+ environ["MOZ_SOURCE_REPO"] = rv.comm_repo
+ environ["MOZ_SOURCE_CHANGESET"] = rv.comm_rev
+
+ return rv
+
+
+@depends(application)
+@imports(_from="os", _import="environ")
+def gecko_repo_from_environ(app):
+ """
+ Same as above, but this time checking for the mozilla- repository.
+ """
+ log.info("Determining GECKO source information from environment...")
+ gecko_repo = environ.get("GECKO_HEAD_REPOSITORY", None)
+ gecko_rev = environ.get("GECKO_HEAD_REV", None)
+ if all([gecko_repo, gecko_rev]):
+ log.info("{}/rev/{}".format(gecko_repo, gecko_rev))
+ return namespace(gecko_repo=gecko_repo, gecko_rev=gecko_rev)
+
+
+# Read sourcestamp.txt, this time returning the mozilla- data
+gecko_sourcestamp = read_sourcestamp("GECKO")
+# Look in comm/.gecko_rev.yml fpr repository information
+gecko_yml = read_gecko_rev_yml()
+
+
+@depends(gecko_repo_from_environ, build_environment, hg, gecko_sourcestamp, gecko_yml)
+@imports(_from="os.path", _import="join")
+@imports(_from="os.path", _import="exists")
+def gecko_repo_heuristics(gecko_environ, build_env, hg, sourcestamp, gecko_yml):
+ """
+ Look for the source repository and changeset for the mozilla- repository
+ when the Taskcluster environment variables are not set, checking
+ .gecko_rev.yml before falling back to Mercurial and sourcestamp.txt.
+ """
+ if not gecko_environ:
+ gecko_repo = gecko_rev = gecko_ref = None
+
+ try:
+ gecko_repo = gecko_yml.repo
+ gecko_rev = gecko_yml.rev
+ gecko_ref = gecko_yml.ref
+ except:
+ pass
+
+ if gecko_repo:
+ if not gecko_rev and gecko_ref:
+ # gecko_repo is known, but we have a branch ref like
+ # "default" when a revision hash is needed. Try to query
+ # Mercurial first.
+ if hg:
+ log.info("Determining GECKO source information from Mercurial...")
+ gecko_rev = hg_cmd_output(
+ hg, "-R", build_env.topsrcdir, "parent", "--template={node}"
+ )
+ # TODO: git-cinnabar support?
+
+ if not gecko_repo or not gecko_rev:
+ # See if we have a sourcestamp file. Last ditch effort!
+ try:
+ gecko_repo, gecko_rev = sourcestamp.repo_url, sourcestamp.repo_rev
+ except:
+ pass
+
+ # Check one last time to see if both gecko_repo and gecko_rev
+ # are set
+ if gecko_repo and gecko_rev:
+ return namespace(gecko_repo=gecko_repo, gecko_rev=gecko_rev)
+
+
+@depends(gecko_repo_from_environ, gecko_repo_heuristics, "MOZ_AUTOMATION")
+def gecko_source_repo(from_environ, from_heuristics, automation):
+ rv = None
+ if from_environ:
+ rv = from_environ
+ elif from_heuristics:
+ rv = from_heuristics
+ elif automation:
+ die(get_fail_msg("GECKO", "GECKO_HEAD_REPOSITORY", "GECKO_HEAD_REV"))
+ else:
+ log.info(get_fail_msg("GECKO", "GECKO_HEAD_REPOSITORY", "GECKO_HEAD_REV"))
+ rv = namespace(gecko_repo="unknown", gecko_rev="unknown")
+
+ log.info("GECKO_SOURCE_REPOSITORY: {}".format(rv.gecko_repo))
+ log.info("GECKO_SOURCE_CHANGESET: {}".format(rv.gecko_rev))
+ return rv
+
+
+set_config("MOZ_COMM_SOURCE_REPO", comm_source_repo.comm_repo)
+set_config("MOZ_COMM_SOURCE_CHANGESET", comm_source_repo.comm_rev)
+set_config("MOZ_GECKO_SOURCE_REPO", gecko_source_repo.gecko_repo)
+set_config("MOZ_GECKO_SOURCE_CHANGESET", gecko_source_repo.gecko_rev)