cef/tools/cef_version.py

299 lines
11 KiB
Python
Raw Permalink Normal View History

# 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 __future__ import absolute_import
from __future__ import print_function
from file_util import *
import git_util as git
import os
Add initial support for API versioning (see #3836) - Generated files are now created when running cef_create_projects or the new version_manager.py tool. These files are still created in the cef/ source tree (same location as before) but Git ignores them due to the generated .gitignore file. - API hashes are committed to Git as a new cef_api_versions.json file. This file is used for both code generation and CEF version calculation (replacing the previous usage of cef_api_hash.h for this purpose). It will be updated by the CEF admin before merging breaking API changes upstream. - As an added benefit to the above, contributor PRs will no longer contain generated code that is susceptible to frequent merge conflicts. - From a code generation perspective, the main difference is that we now use versioned structs (e.g. cef_browser_0_t instead of cef_browser_t) on the libcef (dll/framework) side. Most of the make_*.py tool changes are related to supporting this. - From the client perspective, you can now define CEF_API_VERSION in the project configuration (or get CEF_EXPERIMENTAL by default). This define will change the API exposed in CEF’s include/ and include/capi header files. All client-side targets including libcef_dll_wrapper will need be recompiled when changing this define. - Examples of the new API-related define usage are provided in cef_api_version_test.h, api_version_test_impl.cc and api_version_unittest.cc. To test: - Run `ceftests --gtest_filter=ApiVersionTest.*` - Add `cef_api_version=13300` to GN_DEFINES. Re-run configure, build and ceftests steps. - Repeat with 13301, 13302, 13303 (all supported test versions).
2024-12-09 15:20:44 -05:00
from version_util import read_version_last, version_parse, VERSIONS_JSON_FILE
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', '0')))
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
Add initial support for API versioning (see #3836) - Generated files are now created when running cef_create_projects or the new version_manager.py tool. These files are still created in the cef/ source tree (same location as before) but Git ignores them due to the generated .gitignore file. - API hashes are committed to Git as a new cef_api_versions.json file. This file is used for both code generation and CEF version calculation (replacing the previous usage of cef_api_hash.h for this purpose). It will be updated by the CEF admin before merging breaking API changes upstream. - As an added benefit to the above, contributor PRs will no longer contain generated code that is susceptible to frequent merge conflicts. - From a code generation perspective, the main difference is that we now use versioned structs (e.g. cef_browser_0_t instead of cef_browser_t) on the libcef (dll/framework) side. Most of the make_*.py tool changes are related to supporting this. - From the client perspective, you can now define CEF_API_VERSION in the project configuration (or get CEF_EXPERIMENTAL by default). This define will change the API exposed in CEF’s include/ and include/capi header files. All client-side targets including libcef_dll_wrapper will need be recompiled when changing this define. - Examples of the new API-related define usage are provided in cef_api_version_test.h, api_version_test_impl.cc and api_version_unittest.cc. To test: - Run `ceftests --gtest_filter=ApiVersionTest.*` - Add `cef_api_version=13300` to GN_DEFINES. Re-run configure, build and ceftests steps. - Repeat with 13301, 13302, 13303 (all supported test versions).
2024-12-09 15:20:44 -05:00
assert read_version_file(file_path, self._chrome_version), file_path
return self._chrome_version
Add initial support for API versioning (see #3836) - Generated files are now created when running cef_create_projects or the new version_manager.py tool. These files are still created in the cef/ source tree (same location as before) but Git ignores them due to the generated .gitignore file. - API hashes are committed to Git as a new cef_api_versions.json file. This file is used for both code generation and CEF version calculation (replacing the previous usage of cef_api_hash.h for this purpose). It will be updated by the CEF admin before merging breaking API changes upstream. - As an added benefit to the above, contributor PRs will no longer contain generated code that is susceptible to frequent merge conflicts. - From a code generation perspective, the main difference is that we now use versioned structs (e.g. cef_browser_0_t instead of cef_browser_t) on the libcef (dll/framework) side. Most of the make_*.py tool changes are related to supporting this. - From the client perspective, you can now define CEF_API_VERSION in the project configuration (or get CEF_EXPERIMENTAL by default). This define will change the API exposed in CEF’s include/ and include/capi header files. All client-side targets including libcef_dll_wrapper will need be recompiled when changing this define. - Examples of the new API-related define usage are provided in cef_api_version_test.h, api_version_test_impl.cc and api_version_unittest.cc. To test: - Run `ceftests --gtest_filter=ApiVersionTest.*` - Add `cef_api_version=13300` to GN_DEFINES. Re-run configure, build and ceftests steps. - Repeat with 13301, 13302, 13303 (all supported test versions).
2024-12-09 15:20:44 -05:00
def get_chrome_major_version(self):
return self.get_chrome_version_components()['MAJOR']
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
Add initial support for API versioning (see #3836) - Generated files are now created when running cef_create_projects or the new version_manager.py tool. These files are still created in the cef/ source tree (same location as before) but Git ignores them due to the generated .gitignore file. - API hashes are committed to Git as a new cef_api_versions.json file. This file is used for both code generation and CEF version calculation (replacing the previous usage of cef_api_hash.h for this purpose). It will be updated by the CEF admin before merging breaking API changes upstream. - As an added benefit to the above, contributor PRs will no longer contain generated code that is susceptible to frequent merge conflicts. - From a code generation perspective, the main difference is that we now use versioned structs (e.g. cef_browser_0_t instead of cef_browser_t) on the libcef (dll/framework) side. Most of the make_*.py tool changes are related to supporting this. - From the client perspective, you can now define CEF_API_VERSION in the project configuration (or get CEF_EXPERIMENTAL by default). This define will change the API exposed in CEF’s include/ and include/capi header files. All client-side targets including libcef_dll_wrapper will need be recompiled when changing this define. - Examples of the new API-related define usage are provided in cef_api_version_test.h, api_version_test_impl.cc and api_version_unittest.cc. To test: - Run `ceftests --gtest_filter=ApiVersionTest.*` - Add `cef_api_version=13300` to GN_DEFINES. Re-run configure, build and ceftests steps. - Repeat with 13301, 13302, 13303 (all supported test versions).
2024-12-09 15:20:44 -05:00
assert read_version_file(file_path, self._cef_version), file_path
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:
Add initial support for API versioning (see #3836) - Generated files are now created when running cef_create_projects or the new version_manager.py tool. These files are still created in the cef/ source tree (same location as before) but Git ignores them due to the generated .gitignore file. - API hashes are committed to Git as a new cef_api_versions.json file. This file is used for both code generation and CEF version calculation (replacing the previous usage of cef_api_hash.h for this purpose). It will be updated by the CEF admin before merging breaking API changes upstream. - As an added benefit to the above, contributor PRs will no longer contain generated code that is susceptible to frequent merge conflicts. - From a code generation perspective, the main difference is that we now use versioned structs (e.g. cef_browser_0_t instead of cef_browser_t) on the libcef (dll/framework) side. Most of the make_*.py tool changes are related to supporting this. - From the client perspective, you can now define CEF_API_VERSION in the project configuration (or get CEF_EXPERIMENTAL by default). This define will change the API exposed in CEF’s include/ and include/capi header files. All client-side targets including libcef_dll_wrapper will need be recompiled when changing this define. - Examples of the new API-related define usage are provided in cef_api_version_test.h, api_version_test_impl.cc and api_version_unittest.cc. To test: - Run `ceftests --gtest_filter=ApiVersionTest.*` - Add `cef_api_version=13300` to GN_DEFINES. Re-run configure, build and ceftests steps. - Repeat with 13301, 13302, 13303 (all supported test versions).
2024-12-09 15:20:44 -05:00
# Determine if the API versions file was modified by the commit.
found = False
files = git.get_changed_files(self.cef_path, hash)
for file in files:
Add initial support for API versioning (see #3836) - Generated files are now created when running cef_create_projects or the new version_manager.py tool. These files are still created in the cef/ source tree (same location as before) but Git ignores them due to the generated .gitignore file. - API hashes are committed to Git as a new cef_api_versions.json file. This file is used for both code generation and CEF version calculation (replacing the previous usage of cef_api_hash.h for this purpose). It will be updated by the CEF admin before merging breaking API changes upstream. - As an added benefit to the above, contributor PRs will no longer contain generated code that is susceptible to frequent merge conflicts. - From a code generation perspective, the main difference is that we now use versioned structs (e.g. cef_browser_0_t instead of cef_browser_t) on the libcef (dll/framework) side. Most of the make_*.py tool changes are related to supporting this. - From the client perspective, you can now define CEF_API_VERSION in the project configuration (or get CEF_EXPERIMENTAL by default). This define will change the API exposed in CEF’s include/ and include/capi header files. All client-side targets including libcef_dll_wrapper will need be recompiled when changing this define. - Examples of the new API-related define usage are provided in cef_api_version_test.h, api_version_test_impl.cc and api_version_unittest.cc. To test: - Run `ceftests --gtest_filter=ApiVersionTest.*` - Add `cef_api_version=13300` to GN_DEFINES. Re-run configure, build and ceftests steps. - Repeat with 13301, 13302, 13303 (all supported test versions).
2024-12-09 15:20:44 -05:00
if file.find(VERSIONS_JSON_FILE) >= 0:
found = True
break
if found:
minor += 1
bugfix = 0
else:
bugfix += 1
Add initial support for API versioning (see #3836) - Generated files are now created when running cef_create_projects or the new version_manager.py tool. These files are still created in the cef/ source tree (same location as before) but Git ignores them due to the generated .gitignore file. - API hashes are committed to Git as a new cef_api_versions.json file. This file is used for both code generation and CEF version calculation (replacing the previous usage of cef_api_hash.h for this purpose). It will be updated by the CEF admin before merging breaking API changes upstream. - As an added benefit to the above, contributor PRs will no longer contain generated code that is susceptible to frequent merge conflicts. - From a code generation perspective, the main difference is that we now use versioned structs (e.g. cef_browser_0_t instead of cef_browser_t) on the libcef (dll/framework) side. Most of the make_*.py tool changes are related to supporting this. - From the client perspective, you can now define CEF_API_VERSION in the project configuration (or get CEF_EXPERIMENTAL by default). This define will change the API exposed in CEF’s include/ and include/capi header files. All client-side targets including libcef_dll_wrapper will need be recompiled when changing this define. - Examples of the new API-related define usage are provided in cef_api_version_test.h, api_version_test_impl.cc and api_version_unittest.cc. To test: - Run `ceftests --gtest_filter=ApiVersionTest.*` - Add `cef_api_version=13300` to GN_DEFINES. Re-run configure, build and ceftests steps. - Repeat with 13301, 13302, 13303 (all supported test versions).
2024-12-09 15:20:44 -05:00
last_version = read_version_last(
os.path.join(self.cef_path, VERSIONS_JSON_FILE))
if not last_version is None:
major, revision = version_parse(last_version)
if major == int(self.get_chrome_major_version()) and revision > minor:
# Override the computed minor version with the last specified API version.
minor = revision
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
Add initial support for API versioning (see #3836) - Generated files are now created when running cef_create_projects or the new version_manager.py tool. These files are still created in the cef/ source tree (same location as before) but Git ignores them due to the generated .gitignore file. - API hashes are committed to Git as a new cef_api_versions.json file. This file is used for both code generation and CEF version calculation (replacing the previous usage of cef_api_hash.h for this purpose). It will be updated by the CEF admin before merging breaking API changes upstream. - As an added benefit to the above, contributor PRs will no longer contain generated code that is susceptible to frequent merge conflicts. - From a code generation perspective, the main difference is that we now use versioned structs (e.g. cef_browser_0_t instead of cef_browser_t) on the libcef (dll/framework) side. Most of the make_*.py tool changes are related to supporting this. - From the client perspective, you can now define CEF_API_VERSION in the project configuration (or get CEF_EXPERIMENTAL by default). This define will change the API exposed in CEF’s include/ and include/capi header files. All client-side targets including libcef_dll_wrapper will need be recompiled when changing this define. - Examples of the new API-related define usage are provided in cef_api_version_test.h, api_version_test_impl.cc and api_version_unittest.cc. To test: - Run `ceftests --gtest_filter=ApiVersionTest.*` - Add `cef_api_version=13300` to GN_DEFINES. Re-run configure, build and ceftests steps. - Repeat with 13301, 13302, 13303 (all supported test versions).
2024-12-09 15:20:44 -05:00
# the CEF_API_HASH_UNIVERSAL value behaves in cef_api_hash.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'])
# Determine whether the current commit is on a release branch. For example,
# if using Chrome build 3683, are we on CEF branch "3683" or "origin/3683"?
release_branch = chrome_version['BUILD']
on_release_branch = (
git.is_ancestor(self.cef_path, 'HEAD', release_branch) or
git.is_ancestor(self.cef_path, 'HEAD', 'origin/' + release_branch))
if not on_release_branch:
# Not on a commit that is part of an official named release branch. See
# if we can get the name of the branch we are on (may be just "HEAD").
cef_branch_name = git.get_branch_name(self.cef_path).split('/')[-1]
Add initial support for API versioning (see #3836) - Generated files are now created when running cef_create_projects or the new version_manager.py tool. These files are still created in the cef/ source tree (same location as before) but Git ignores them due to the generated .gitignore file. - API hashes are committed to Git as a new cef_api_versions.json file. This file is used for both code generation and CEF version calculation (replacing the previous usage of cef_api_hash.h for this purpose). It will be updated by the CEF admin before merging breaking API changes upstream. - As an added benefit to the above, contributor PRs will no longer contain generated code that is susceptible to frequent merge conflicts. - From a code generation perspective, the main difference is that we now use versioned structs (e.g. cef_browser_0_t instead of cef_browser_t) on the libcef (dll/framework) side. Most of the make_*.py tool changes are related to supporting this. - From the client perspective, you can now define CEF_API_VERSION in the project configuration (or get CEF_EXPERIMENTAL by default). This define will change the API exposed in CEF’s include/ and include/capi header files. All client-side targets including libcef_dll_wrapper will need be recompiled when changing this define. - Examples of the new API-related define usage are provided in cef_api_version_test.h, api_version_test_impl.cc and api_version_unittest.cc. To test: - Run `ceftests --gtest_filter=ApiVersionTest.*` - Add `cef_api_version=13300` to GN_DEFINES. Re-run configure, build and ceftests steps. - Repeat with 13301, 13302, 13303 (all supported test versions).
2024-12-09 15:20:44 -05:00
cef_minor = cef_patch = 0
if cef_branch_name != 'HEAD' and cef_branch_name != 'master':
cef_branch = self.get_cef_branch_version_components()
cef_minor = cef_branch['MINOR']
cef_patch = cef_branch['PATCH']
self._version_parts = {'MAJOR': int(chrome_major), 'MINOR': 0, 'PATCH': 0}
Add initial support for API versioning (see #3836) - Generated files are now created when running cef_create_projects or the new version_manager.py tool. These files are still created in the cef/ source tree (same location as before) but Git ignores them due to the generated .gitignore file. - API hashes are committed to Git as a new cef_api_versions.json file. This file is used for both code generation and CEF version calculation (replacing the previous usage of cef_api_hash.h for this purpose). It will be updated by the CEF admin before merging breaking API changes upstream. - As an added benefit to the above, contributor PRs will no longer contain generated code that is susceptible to frequent merge conflicts. - From a code generation perspective, the main difference is that we now use versioned structs (e.g. cef_browser_0_t instead of cef_browser_t) on the libcef (dll/framework) side. Most of the make_*.py tool changes are related to supporting this. - From the client perspective, you can now define CEF_API_VERSION in the project configuration (or get CEF_EXPERIMENTAL by default). This define will change the API exposed in CEF’s include/ and include/capi header files. All client-side targets including libcef_dll_wrapper will need be recompiled when changing this define. - Examples of the new API-related define usage are provided in cef_api_version_test.h, api_version_test_impl.cc and api_version_unittest.cc. To test: - Run `ceftests --gtest_filter=ApiVersionTest.*` - Add `cef_api_version=13300` to GN_DEFINES. Re-run configure, build and ceftests steps. - Repeat with 13301, 13302, 13303 (all supported test versions).
2024-12-09 15:20:44 -05:00
self._version_string = '%s.%d.%d-%s.%s+%s+%s' % \
(chrome_major, cef_minor, cef_patch, 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_short_version_string(self, oldFormat=None):
""" Returns the short CEF version number string based on current checkout
state. """
parts = self.get_version_parts(oldFormat=oldFormat)
return "%d.%d.%d" % (parts['MAJOR'], parts['MINOR'], parts['PATCH'])
def get_plist_version_string(self, oldFormat=None):
""" Returns the CEF version number string for plist files based on current
checkout state. """
return self.get_short_version_string() + ".0"
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))