blob: b0307e3b5924e2136440cb0d8714d875ab298f76 [file] [log] [blame]
# Copyright 2012 The Cobalt Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Utilities for use by gyp_cobalt and other build tools."""
import json
import logging
import os
import subprocess
from six.moves import urllib
from cobalt.tools import paths
_SUBREPO_PATHS = ['starboard/keyboxes']
_VERSION_SERVER_URL = 'https://carbon-airlock-95823.appspot.com/build_version/generate' # pylint:disable=line-too-long
_XSSI_PREFIX = ")]}'\n"
# The path to the build.id file that preserves a build ID.
BUILD_ID_PATH = os.path.join(paths.BUILD_ROOT, 'build.id')
def CheckRevInfo(key, cwd=None):
git_get_remote_args = ['git', 'config', '--get', 'remote.origin.url']
remote = subprocess.check_output(
git_get_remote_args, cwd=cwd).strip().decode('utf-8')
if remote.endswith('.git'):
remote = remote[:-len('.git')]
git_get_revision_args = ['git', 'rev-parse', 'HEAD']
revision = subprocess.check_output(
git_get_revision_args, cwd=cwd).strip().decode('utf-8')
return {key: '{}@{}'.format(remote, revision)}
def GetRevinfo():
"""Get absolute state of all git repos."""
try:
repo_root = subprocess.check_output(['git', 'rev-parse', '--show-toplevel'
]).strip().decode('utf-8')
except subprocess.CalledProcessError:
logging.info('Could not get repo root. Trying again in src/')
try:
repo_root = subprocess.check_output(
['git', '-C', 'src', 'rev-parse',
'--show-toplevel']).strip().decode('utf-8')
except subprocess.CalledProcessError as e:
logging.warning('Failed to get revision information: %s', e)
return {}
# First make sure we can add the cobalt_src repo.
try:
repos = CheckRevInfo('.', cwd=repo_root)
except subprocess.CalledProcessError as e:
logging.warning('Failed to get revision information: %s', e)
return {}
for rel_path in _SUBREPO_PATHS:
path = os.path.join(repo_root, rel_path)
try:
repos.update(CheckRevInfo(rel_path, cwd=path))
except subprocess.CalledProcessError as e:
logging.warning('Failed to get revision information for subrepo %s: %s',
rel_path, e)
continue
except OSError as e:
logging.info('%s. Subrepository %s not found.', e, rel_path)
continue
return repos
# We leave this function in for backwards compatibility.
# New callers should use GetOrGenerateNewBuildNumber.
def GetBuildNumber(version_server=_VERSION_SERVER_URL):
return GetOrGenerateNewBuildNumber(version_server)
def GetOrGenerateNewBuildNumber(version_server=_VERSION_SERVER_URL):
"""Send a request to the build version server for a build number."""
if os.path.isfile(BUILD_ID_PATH):
with open(BUILD_ID_PATH, 'r') as build_id_file:
build_number = int(build_id_file.read().replace('\n', ''))
logging.info('Retrieving build number from %s', BUILD_ID_PATH)
return build_number
revinfo = GetRevinfo()
json_deps = json.dumps(revinfo)
username = os.environ.get('USERNAME', os.environ.get('USER'))
post_data = {'deps': json_deps}
if username:
post_data['user'] = username
logging.debug('Post data is %s', post_data)
request = urllib.request.Request(version_server)
# TODO: retry on timeout.
try:
response = urllib.request.urlopen( # pylint: disable=consider-using-with
request,
data=urllib.parse.urlencode(post_data).encode('utf-8'))
data = response.read().decode('utf-8')
if data.find(_XSSI_PREFIX) == 0:
data = data[len(_XSSI_PREFIX):]
results = json.loads(data)
build_number = results.get('build_number', 0)
return build_number
except urllib.error.HTTPError as e:
logging.warning('Failed to retrieve build number: %s', e)
return 0
except urllib.error.URLError as e:
logging.warning('Could not connect to %s: %s', version_server, e)
return 0