author Gregory Szorc <>
Tue, 24 May 2016 11:35:44 -0700
changeset 337832 32886f06e0fb2a5c2b58d49500b3baee59e970d4
parent 320382 51029f4d82d3dcb3ca3aa8cab60bf1ed29152846
child 357039 3648a587a3d9e5072064f0d8df1b31763aa5f188
permissions -rw-r--r--
Bug 1274655 - Resolve changeset when only repo is defined; r=mshal Previously, we required both or none of MOZ_SOURCE_REPO and MOZ_SOURCE_CHANGESET to be defined. This logic was established in 51029f4d82d3 (bug 1247162). There appears to be no good reason why we require MOZ_SOURCE_CHANGESET if MOZ_SOURCE_REPO is defined. After all, if we have a checkout we should be able to resolve the revision. This commit changes the logic to resolve the changeset when not defined. We still error if MOZ_SOURCE_REPO is defined but we can't resolve the changeset. I can't imagine this breaking anything. This change will be necessary to appease TaskCluster tasks once mozharness is changed in a subsequent commit to define MOZ_SOURCE_REPO. Buildbot and TC each have their own way of specifying the source revision. Rather than change mozharness, it feels easier to just have the build system derive things. This decision is further justified by the fact there is a chicken and egg problem in mozharness: the environment variable dict is resolved before source directory population. So, we'd need to teach mozharness about TC's VCS mechanism, which it currently has no knowledge of. I'd rather not do that. MozReview-Commit-ID: ANaoGbPGWj2

# 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

from __future__ import print_function, unicode_literals

import os
import subprocess
import sys
from datetime import datetime

def buildid_header(output):
    buildid = os.environ.get('MOZ_BUILD_DATE')
    if buildid and len(buildid) != 14:
        print('Ignoring invalid MOZ_BUILD_DATE: %s' % buildid, file=sys.stderr)
        buildid = None
    if not buildid:
        buildid ='%Y%m%d%H%M%S')
    output.write("#define MOZ_BUILDID %s\n" % buildid)

def get_program_output(*command):
        with open(os.devnull) as stderr:
            return subprocess.check_output(command, stderr=stderr)
        return ''

def get_hg_info(workdir):
    repo = get_program_output('hg', '-R', workdir, 'path', 'default')
    if repo:
        repo = repo.strip()
        if repo.startswith('ssh://'):
            repo = 'https://' + repo[6:]
        repo = repo.rstrip('/')

    changeset = get_hg_changeset(workdir)

    return repo, changeset

def get_hg_changeset(path):
    return get_program_output('hg', '-R', path, 'parent', '--template={node}')

def source_repo_header(output):
    # We allow the source repo and changeset to be specified via the
    # environment (see configure)
    import buildconfig
    repo = buildconfig.substs.get('MOZ_SOURCE_REPO')
    changeset = buildconfig.substs.get('MOZ_SOURCE_CHANGESET')
    source = ''

    if not repo:
        if os.path.exists(os.path.join(buildconfig.topsrcdir, '.hg')):
            repo, changeset = get_hg_info(buildconfig.topsrcdir)
    elif not changeset:
        changeset = get_hg_changeset(buildconfig.topsrcdir)
        if not changeset:
            raise Exception('could not resolve changeset; '
                            'try setting MOZ_SOURCE_CHANGESET')

    if changeset:
        output.write('#define MOZ_SOURCE_STAMP %s\n' % changeset)

    if repo and buildconfig.substs.get('MOZ_INCLUDE_SOURCE_INFO'):
        source = '%s/rev/%s' % (repo, changeset)
        output.write('#define MOZ_SOURCE_REPO %s\n' % repo)
        output.write('#define MOZ_SOURCE_URL %s\n' % source)

def main(args):
    if (len(args)):
        func = globals().get(args[0])
        if func:
            return func(sys.stdout, *args[1:])

if __name__ == '__main__':