Commit e8fe60af authored by Marshall Greenblatt's avatar Marshall Greenblatt
Browse files

Compute all version numbers using cef_version.py (see issue #2596)

The version format can now be controlled by setting the CEF_OLD_VERSION_FORMAT
environment variable. The old format is currently the default.
parent 819eb61e
......@@ -166,45 +166,14 @@ if (is_mac) {
#
if (is_mac) {
cef_commit_number = exec_script(
"//cef/tools/commit_number.py",
[ rebase_path("//cef", root_build_dir) ],
"trim string", [])
cef_version_file = "//cef/VERSION.in"
# The tweak_info_plist.py script requires a version number with 4 parts. CEF
# uses a version number with 3 parts so just set the last part to 0.
cef_plist_version = exec_script(
"//build/util/version.py",
[
"-f",
rebase_path(cef_version_file, root_build_dir),
"-f",
rebase_path(chrome_version_file, root_build_dir),
"-t",
"@CEF_MAJOR@.@BUILD@.${cef_commit_number}.0",
],
"trim string",
[ cef_version_file, chrome_version_file ])
"//cef/tools/cef_version.py", [ "plist" ], "trim string", [])
# Need to be creative to match dylib version formatting requirements.
cef_dylib_version = exec_script(
"//build/util/version.py",
[
"-f",
rebase_path(cef_version_file, root_build_dir),
"-f",
rebase_path(chrome_version_file, root_build_dir),
"-t",
"@CEF_MAJOR@${cef_commit_number}.@BUILD_HI@.@BUILD_LO@",
"-e",
"BUILD_HI=int(BUILD)/256",
"-e",
"BUILD_LO=int(BUILD)%256",
],
"trim string",
[ cef_version_file, chrome_version_file ])
"//cef/tools/cef_version.py", [ "dylib" ], "trim string", [])
}
# Read file lists from gypi files. The gypi_to_gn.py script does not support
......
......@@ -95,8 +95,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION CEF_VERSION_MAJOR,CHROME_VERSION_BUILD,CEF_COMMIT_NUMBER,0
PRODUCTVERSION CEF_VERSION_MAJOR,CHROME_VERSION_BUILD,CEF_COMMIT_NUMBER,0
FILEVERSION CEF_VERSION_MAJOR,CEF_VERSION_MINOR,CEF_VERSION_PATCH,0
PRODUCTVERSION CEF_VERSION_MAJOR,CEF_VERSION_MINOR,CEF_VERSION_PATCH,0
FILEFLAGSMASK 0x17L
#ifdef _DEBUG
FILEFLAGS 0x1L
......
......@@ -12,14 +12,18 @@ CEF_EXPORT int cef_version_info(int entry) {
case 0:
return CEF_VERSION_MAJOR;
case 1:
return CEF_COMMIT_NUMBER;
return CEF_VERSION_MINOR;
case 2:
return CHROME_VERSION_MAJOR;
return CEF_VERSION_PATCH;
case 3:
return CHROME_VERSION_MINOR;
return CEF_COMMIT_NUMBER;
case 4:
return CHROME_VERSION_BUILD;
return CHROME_VERSION_MAJOR;
case 5:
return CHROME_VERSION_MINOR;
case 6:
return CHROME_VERSION_BUILD;
case 7:
return CHROME_VERSION_PATCH;
default:
return 0;
......
......@@ -144,8 +144,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION CEF_VERSION_MAJOR,CHROME_VERSION_BUILD,CEF_COMMIT_NUMBER,0
PRODUCTVERSION CEF_VERSION_MAJOR,CHROME_VERSION_BUILD,CEF_COMMIT_NUMBER,0
FILEVERSION CEF_VERSION_MAJOR,CEF_VERSION_MINOR,CEF_VERSION_PATCH,0
PRODUCTVERSION CEF_VERSION_MAJOR,CEF_VERSION_MINOR,CEF_VERSION_PATCH,0
FILEFLAGSMASK 0x17L
#ifdef _DEBUG
FILEFLAGS 0x1L
......
......@@ -51,8 +51,8 @@ IDI_SMALL ICON "small.ico"
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION CEF_VERSION_MAJOR,CHROME_VERSION_BUILD,CEF_COMMIT_NUMBER,0
PRODUCTVERSION CEF_VERSION_MAJOR,CHROME_VERSION_BUILD,CEF_COMMIT_NUMBER,0
FILEVERSION CEF_VERSION_MAJOR,CEF_VERSION_MINOR,CEF_VERSION_PATCH,0
PRODUCTVERSION CEF_VERSION_MAJOR,CEF_VERSION_MINOR,CEF_VERSION_PATCH,0
FILEFLAGSMASK 0x17L
#ifdef _DEBUG
FILEFLAGS 0x1L
......
......@@ -8,11 +8,13 @@
TEST(VersionTest, VersionInfo) {
EXPECT_EQ(CEF_VERSION_MAJOR, cef_version_info(0));
EXPECT_EQ(CEF_COMMIT_NUMBER, cef_version_info(1));
EXPECT_EQ(CHROME_VERSION_MAJOR, cef_version_info(2));
EXPECT_EQ(CHROME_VERSION_MINOR, cef_version_info(3));
EXPECT_EQ(CHROME_VERSION_BUILD, cef_version_info(4));
EXPECT_EQ(CHROME_VERSION_PATCH, cef_version_info(5));
EXPECT_EQ(CEF_VERSION_MINOR, cef_version_info(1));
EXPECT_EQ(CEF_VERSION_PATCH, cef_version_info(2));
EXPECT_EQ(CEF_COMMIT_NUMBER, cef_version_info(3));
EXPECT_EQ(CHROME_VERSION_MAJOR, cef_version_info(4));
EXPECT_EQ(CHROME_VERSION_MINOR, cef_version_info(5));
EXPECT_EQ(CHROME_VERSION_BUILD, cef_version_info(6));
EXPECT_EQ(CHROME_VERSION_PATCH, cef_version_info(7));
}
TEST(VersionTest, ApiHash) {
......
# Copyright (c) 2019 The Chromium Embedded Framework Authors. All rights
# reserved. Use of this source code is governed by a BSD-style license that
# can be found in the LICENSE file.
from file_util import *
import git_util as git
import os
class VersionFormatter:
""" Formats CEF version information. """
def __init__(self, chromium_src_path=None):
if chromium_src_path is None:
# Relative to the current directory.
script_path = os.path.abspath(os.path.dirname(__file__))
chromium_src_path = os.path.abspath(
os.path.join(script_path, os.pardir, os.pardir))
self.src_path = chromium_src_path
assert os.path.isdir(self.src_path), self.src_path
self.cef_path = os.path.join(self.src_path, 'cef')
assert os.path.isdir(self.cef_path), self.cef_path
# Whether to use the old version format by default.
self._old_format_default = \
bool(int(os.environ.get('CEF_OLD_VERSION_FORMAT', '1')))
self.reset()
def reset(self):
""" Reset internal state. """
self._chrome_version = {}
self._cef_version = {}
self._cef_commit = {}
self._branch_version = {}
self._old_version_string = None
self._old_version_parts = {}
self._version_string = None
self._version_parts = {}
def get_chrome_version_components(self):
""" Returns Chrome version components. """
if not bool(self._chrome_version):
file_path = os.path.join(self.src_path, 'chrome', 'VERSION')
assert os.path.isfile(file_path), file_path
read_version_file(file_path, self._chrome_version)
return self._chrome_version
def get_cef_version_components(self):
""" Returns CEF version components. """
if not bool(self._cef_version):
file_path = os.path.join(self.cef_path, 'VERSION.in')
assert os.path.isfile(file_path), file_path
read_version_file(file_path, self._cef_version)
return self._cef_version
def get_cef_commit_components(self):
""" Returns CEF commit components. """
if not bool(self._cef_commit):
hash = git.get_hash(self.cef_path)
number = git.get_commit_number(self.cef_path)
self._cef_commit = {'HASH': hash, 'NUMBER': number}
return self._cef_commit
def get_cef_branch_version_components(self):
""" Computes the CEF branch version. """
if not bool(self._branch_version):
minor = 0
bugfix = 0
# Retrieve the list of commits that have been applied on the current
# branch since branching from origin/master.
hashes = git.get_branch_hashes(self.cef_path)
for hash in hashes:
# Determine if the API hash file was modified by the commit.
found = False
files = git.get_changed_files(self.cef_path, hash)
for file in files:
if file.find('cef_api_hash.h') >= 0:
found = True
break
if found:
minor += 1
bugfix = 0
else:
bugfix += 1
self._branch_version = {'MINOR': minor, 'PATCH': bugfix}
return self._branch_version
def get_chromium_version_string(self):
""" Returns the Chromium version number string. """
chrome_version = self.get_chrome_version_components()
return '%s.%s.%s.%s' % (chrome_version['MAJOR'], chrome_version['MINOR'],
chrome_version['BUILD'], chrome_version['PATCH'])
@staticmethod
def _format_commit_hash(hash):
return 'g%s' % hash[:7]
# Computes old version numbers in the format "X.YYYY.A.gHHHHHHH".
#
# Where:
# - "X" is the CEF major version (currently 3).
# - "YYYY" is the Chromium branch.
# - "A" is an incremental number representing the number of commits in the
# current branch. This is roughly equivalent to the SVN revision number but
# on a per-branch basis and assists people in quickly determining the order
# of builds in the same branch (for bug reports, etc).
# - "gHHHHHHH" is the 7-character abbreviation for the Git commit hash. This
# facilitates lookup of the relevant commit history in Git.
#
# Example: "3.3729.1921.g62d140e"
def _compute_old_version(self):
if not self._old_version_string is None:
return
chrome_version = self.get_chrome_version_components()
cef_version = self.get_cef_version_components()
cef_commit = self.get_cef_commit_components()
cef_commit_hash = self._format_commit_hash(cef_commit['HASH'])
self._old_version_parts = {
'MAJOR': int(cef_version['CEF_MAJOR']),
'MINOR': int(chrome_version['BUILD']),
'PATCH': int(cef_commit['NUMBER'])
}
self._old_version_string = \
'%s.%s.%s.%s' % (cef_version['CEF_MAJOR'], chrome_version['BUILD'],
cef_commit['NUMBER'], cef_commit_hash)
def _get_old_version_string(self):
self._compute_old_version()
return self._old_version_string
def _get_old_version_parts(self):
self._compute_old_version()
return self._old_version_parts
# Computes version numbers in the format:
# - "X.Y.Z+gHHHHHHH+chromium-A.B.C.D" for release branch builds.
# - "X.0.0-master.N+gHHHHHHH+chromium-A.B.C.D" for master branch builds.
#
# Where:
# - "X" is the Chromium major version (e.g. 74).
# - "Y" is an incremental number that starts at 0 when a release branch is
# created and changes only when the CEF C/C++ API changes (similar to how
# the CEF_API_HASH_UNIVERSAL value behaves in cef_version.h) (release branch
# only).
# - "Z" is an incremental number that starts at 0 when a release branch is
# created and changes on each commit, with reset to 0 when "Y" changes
# (release branch only).
# - "N" is an incremental number representing the number of commits (master
# branch only).
# - "gHHHHHHH" is the 7-character abbreviation for the Git commit hash. This
# facilitates lookup of the relevant commit history in Git.
# - "A.B.C.D" is the Chromium version (e.g. 74.0.3729.6).
#
# Examples:
# - "74.0.1+g62d140e+chromium-74.0.3729.6" for a release build.
# - "74.0.0-master.1920+g725ed88+chromium-74.0.3729.0" for a master build.
def _compute_version(self):
if not self._version_string is None:
return
chrome_version = self.get_chrome_version_components()
chrome_major = chrome_version['MAJOR']
chrome_version_part = 'chromium-' + self.get_chromium_version_string()
cef_commit = self.get_cef_commit_components()
cef_commit_hash = self._format_commit_hash(cef_commit['HASH'])
# Remove the remote name prefix, if any.
cef_branch_name = git.get_branch_name(self.cef_path).split('/')[-1]
if cef_branch_name != chrome_version['BUILD']:
# Not on an official named release branch.
self._version_parts = {'MAJOR': int(chrome_major), 'MINOR': 0, 'PATCH': 0}
self._version_string = '%s.0.0-%s.%s+%s+%s' % \
(chrome_major, cef_branch_name, cef_commit['NUMBER'],
cef_commit_hash, chrome_version_part)
else:
cef_branch = self.get_cef_branch_version_components()
self._version_parts = {
'MAJOR': int(chrome_major),
'MINOR': cef_branch['MINOR'],
'PATCH': cef_branch['PATCH']
}
self._version_string = '%s.%d.%d+%s+%s' % \
(chrome_major, cef_branch['MINOR'], cef_branch['PATCH'],
cef_commit_hash, chrome_version_part)
def _get_version_string(self):
self._compute_version()
return self._version_string
def _get_version_parts(self):
self._compute_version()
return self._version_parts
def get_version_string(self, oldFormat=None):
""" Returns the CEF version number string based on current checkout state.
"""
if oldFormat is None:
oldFormat = self._old_format_default
if oldFormat:
return self._get_old_version_string()
return self._get_version_string()
def get_version_parts(self, oldFormat=None):
""" Returns the CEF version number parts based on current checkout state.
"""
if oldFormat is None:
oldFormat = self._old_format_default
if oldFormat:
return self._get_old_version_parts()
return self._get_version_parts()
def get_plist_version_string(self, oldFormat=None):
""" Returns the CEF version number string for plist files based on current
checkout state. """
parts = self.get_version_parts(oldFormat=oldFormat)
return "%d.%d.%d.0" % (parts['MAJOR'], parts['MINOR'], parts['PATCH'])
def get_dylib_version_string(self, oldFormat=None):
""" Returns the CEF version number string for dylib files based on current
checkout state. """
parts = self.get_version_parts(oldFormat=oldFormat)
# Dylib format supports a max value of 255 for the 2nd and 3rd components.
return "%d%d.%d.%d" % (parts['MAJOR'], parts['MINOR'], parts['PATCH'] / 255,
parts['PATCH'] % 255)
# Test the module.
if __name__ == "__main__":
import sys
# Optionally specify a format.
formats = ['current', 'old', 'plist', 'dylib']
if len(sys.argv) >= 2:
formats = [sys.argv[1]]
# Optionally specify the path to chromium/src.
chromium_src_path = None
if len(sys.argv) >= 3:
chromium_src_path = sys.argv[2]
formatter = VersionFormatter(chromium_src_path)
for format in formats:
if len(formats) > 1:
print format
if format == 'old':
print formatter.get_version_string(True)
elif format == 'dylib':
print formatter.get_dylib_version_string()
elif format == 'plist':
print formatter.get_plist_version_string()
else:
print formatter.get_version_string(False)
# Copyright (c) 2012 The Chromium Embedded Framework Authors. All rights
# reserved. Use of this source code is governed by a BSD-style license that
# can be found in the LICENSE file.
import git_util as git
import os
import sys
# cannot be loaded as a module
if __name__ != "__main__":
sys.stderr.write('This file cannot be loaded as a module!')
sys.exit()
if len(sys.argv) < 2:
raise Exception('Path expected on command-line')
path = sys.argv[1]
if git.is_checkout(path):
sys.stdout.write(git.get_commit_number(path))
else:
raise Exception('Not a valid checkout: ' + path)
......@@ -28,8 +28,7 @@ else:
print "\nGenerating CEF version header file..."
cmd = [
'python', 'tools/make_version_header.py', '--header',
'include/cef_version.h', '--cef_version', 'VERSION.in', '--chrome_version',
'../chrome/VERSION'
'include/cef_version.h'
]
RunAction(cef_dir, cmd)
......
......@@ -27,6 +27,27 @@ def get_hash(path='.', branch='HEAD'):
return 'Unknown'
def get_branch_name(path='.', branch='HEAD'):
""" Returns the branch name for the specified branch/tag/hash. """
# Returns the branch name if not in detached HEAD state, else an empty string
# or "HEAD".
cmd = "%s rev-parse --abbrev-ref %s" % (git_exe, branch)
result = exec_cmd(cmd, path)
if result['out'] != '':
name = result['out'].strip()
if len(name) > 0 and name != 'HEAD':
return name
# Returns a value like "(HEAD, origin/3729, 3729)".
# Ubuntu 14.04 uses Git version 1.9.1 which does not support %D (which
# provides the same output but without the parentheses).
cmd = "%s log -n 1 --pretty=%%d %s" % (git_exe, branch)
result = exec_cmd(cmd, path)
if result['out'] != '':
return result['out'].strip()[1:-1].split(', ')[-1]
return 'Unknown'
def get_url(path='.'):
""" Returns the origin url for the specified path. """
cmd = "%s config --get remote.origin.url" % git_exe
......@@ -63,6 +84,21 @@ def get_changed_files(path, hash):
return []
def get_branch_hashes(path='.', branch='HEAD', ref='origin/master'):
""" Returns an ordered list of hashes for commits that have been applied since
branching from ref. """
cmd = "%s cherry %s %s" % (git_exe, ref, branch)
result = exec_cmd(cmd, path)
if result['out'] != '':
hashes = result['out']
if sys.platform == 'win32':
# Convert to Unix line endings.
hashes = hashes.replace('\r\n', '\n')
# Remove the "+ " or "- " prefix.
return [line[2:] for line in hashes.strip().split('\n')]
return []
def write_indented_output(output):
""" Apply a fixed amount of intent to lines before printing. """
if output == '':
......
......@@ -2,6 +2,7 @@
# reserved. Use of this source code is governed by a BSD-style license that
# can be found in the LICENSE file.
from cef_version import VersionFormatter
from date_util import *
from exec_util import exec_cmd
from file_util import *
......@@ -536,14 +537,10 @@ chromium_rev = git.get_hash(src_dir)
date = get_date()
# Read and parse the version file (key=value pairs, one per line)
args = {}
read_version_file(os.path.join(cef_dir, 'VERSION.in'), args)
read_version_file(os.path.join(cef_dir, '../chrome/VERSION'), args)
cef_ver = '%s.%s.%s.g%s' % (args['CEF_MAJOR'], args['BUILD'], cef_commit_number,
cef_rev[:7])
chromium_ver = args['MAJOR'] + '.' + args['MINOR'] + '.' + args['BUILD'] + '.' + args['PATCH']
# format version strings
formatter = VersionFormatter()
cef_ver = formatter.get_version_string()
chromium_ver = formatter.get_chromium_version_string()
# list of output directories to be archived
archive_dirs = []
......
@echo off
python.bat tools\make_version_header.py --header include\cef_version.h --cef_version VERSION.in --chrome_version ../chrome/VERSION --cpp_header_dir include
python.bat tools\make_version_header.py --header include\cef_version.h
......@@ -2,10 +2,12 @@
# reserved. Use of this source code is governed by a BSD-style license that
# can be found in the LICENSE file.
from cef_version import VersionFormatter
from date_util import *
from file_util import *
from optparse import OptionParser
import git_util as git
import os
import sys
# cannot be loaded as a module
......@@ -24,16 +26,6 @@ parser.add_option(
dest='header',
metavar='FILE',
help='output version header file [required]')
parser.add_option(
'--cef_version',
dest='cef_version',
metavar='FILE',
help='input CEF version config file [required]')
parser.add_option(
'--chrome_version',
dest='chrome_version',
metavar='FILE',
help='input Chrome version config file [required]')
parser.add_option(
'-q',
'--quiet',
......@@ -44,24 +36,17 @@ parser.add_option(
(options, args) = parser.parse_args()
# the header option is required
if options.header is None or options.cef_version is None or options.chrome_version is None:
if options.header is None:
parser.print_help(sys.stdout)
sys.exit()
def write_version_header(header, chrome_version, cef_version):
def write_version_header(header):
""" Creates the header file for the current revision and Chrome version information
if the information has changed or if the file doesn't already exist. """
if not path_exists(chrome_version):
raise Exception('Chrome version file ' + chrome_version +
' does not exist.')
if not path_exists(cef_version):
raise Exception('CEF version file ' + cef_version + ' does not exist.')
args = {}
read_version_file(chrome_version, args)
read_version_file(cef_version, args)
if not git.is_checkout('.'):
raise Exception('Not a valid checkout')
if path_exists(header):
oldcontents = read_file(header)
......@@ -69,14 +54,16 @@ def write_version_header(header, chrome_version, cef_version):
oldcontents = ''
year = get_year()
formatter = VersionFormatter()
commit_hash = formatter.get_cef_commit_components()['HASH']
commit_number = formatter.get_cef_commit_components()['NUMBER']
version = formatter.get_version_string()
version_parts = formatter.get_version_parts()
chrome = formatter.get_chrome_version_components()
if not git.is_checkout('.'):
raise Exception('Not a valid checkout')
commit_number = git.get_commit_number()
commit_hash = git.get_hash()
version = '%s.%s.%s.g%s' % (args['CEF_MAJOR'], args['BUILD'], commit_number,
commit_hash[:7])
version_defines = '#define CEF_VERSION "%s"\n' % version
for key in ('MAJOR', 'MINOR', 'PATCH'):
version_defines += '#define CEF_VERSION_%s %d\n' % (key, version_parts[key])
newcontents = '// Copyright (c) '+year+' Marshall A. Greenblatt. All rights reserved.\n'+\
'//\n'+\
......@@ -113,15 +100,14 @@ def write_version_header(header, chrome_version, cef_version):
'//\n\n'+\
'#ifndef CEF_INCLUDE_CEF_VERSION_H_\n'+\
'#define CEF_INCLUDE_CEF_VERSION_H_\n\n'+\
'#define CEF_VERSION "' + version + '"\n'+\
'#define CEF_VERSION_MAJOR ' + args['CEF_MAJOR'] + '\n'+\
version_defines+\
'#define CEF_COMMIT_NUMBER ' + commit_number + '\n'+\
'#define CEF_COMMIT_HASH "' + commit_hash + '"\n'+\
'#define COPYRIGHT_YEAR ' + year + '\n\n'+\
'#define CHROME_VERSION_MAJOR ' + args['MAJOR'] + '\n'+\
'#define CHROME_VERSION_MINOR ' + args['MINOR'] + '\n'+\
'#define CHROME_VERSION_BUILD ' + args['BUILD'] + '\n'+\
'#define CHROME_VERSION_PATCH ' + args['PATCH'] + '\n\n'+\
'#define CHROME_VERSION_MAJOR ' + chrome['MAJOR'] + '\n'+\
'#define CHROME_VERSION_MINOR ' + chrome['MINOR'] + '\n'+\
'#define CHROME_VERSION_BUILD ' + chrome['BUILD'] + '\n'+\
'#define CHROME_VERSION_PATCH ' + chrome['PATCH'] + '\n\n'+\
'#define DO_MAKE_STRING(p) #p\n'+\
'#define MAKE_STRING(p) DO_MAKE_STRING(p)\n\n'+\
'#ifndef APSTUDIO_HIDDEN_SYMBOLS\n\n'\
......@@ -132,11 +118,13 @@ def write_version_header(header, chrome_version, cef_version):
'// Returns CEF version information for the libcef library. The |entry|\n'+\
'// parameter describes which version component will be returned:\n'+\
'// 0 - CEF_VERSION_MAJOR\n'+\
'// 1 - CEF_COMMIT_NUMBER\n'+\
'// 2 - CHROME_VERSION_MAJOR\n'+\
'// 3 - CHROME_VERSION_MINOR\n'+\
'// 4 - CHROME_VERSION_BUILD\n'+\
'// 5 - CHROME_VERSION_PATCH\n'+\