cefbuilds: Remove html generation and add beta channel support

This commit is contained in:
Marshall Greenblatt
2020-10-24 13:13:43 -04:00
parent c3aa36323b
commit 6a525748c4
5 changed files with 47 additions and 521 deletions

View File

@ -1,323 +0,0 @@
# Copyright (c) 2016 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 cef_json_builder import cef_json_builder
import datetime
import math
import os
import sys
# Class used to build the cefbuilds HTML file. Generate an index.json file using
# the cef_json_builder_example.py tool (or some other means) and then run:
# > python cef_html_builder.py index.json index.html.in index.html
#
# Expected HTML template format is:
#
# Header
# <section:platform_link>
# $platform_name$
# </section:platform_link>
# <section:platform>
# $platform_name$ Builds:
# <section:version>
# CEF version $cef_version$ Files:
# <section:file>
# File $file$ size $size$ sha1 $sha1$
# </section:file>
# </section:version>
# </section:platform>
# Footer
#
# Notes:
# - The variables ("$key$") available in each section generally match the key
# names that exist in the JSON file for that section. Additional variables are
# exposed where needed.
# - Some global variables like "$year$" will be replaced in the whole template
# before further parsing occurs.
class cef_html_builder:
""" Class used to build the cefbuilds HTML file. """
def __init__(self, branding=''):
""" Create a new cef_html_builder object. """
self.clear()
self._branding = branding
def clear(self):
""" Clear the contents of this object. """
self._parts = {}
return
@staticmethod
def _token(key):
# Returns the token representation of |key|
return '$' + key + '$'
@staticmethod
def _section_tags(section):
# Returns the start and end tags for |section|
return ('<section:' + section + '>', '</section:' + section + '>')
@staticmethod
def _section_key(section):
# Returns the replacement key for |section|
return section + '_section'
@staticmethod
def _replace(str, key, value):
# Replaces all instances of |key| with |value| in |str|.
return str.replace(cef_html_builder._token(key), value)
@staticmethod
def _replace_all(str, dict):
for (key, value) in dict.items():
str = cef_html_builder._replace(str, key, value)
return str
@staticmethod
def _extract(str, section):
# Extracts the |section| region and replaces it with a token named
# "<section>_section".
(start_tag, end_tag) = cef_html_builder._section_tags(section)
start_pos = str.find(start_tag)
end_pos = str.rfind(end_tag)
if start_pos < 0 or end_pos < 0:
raise Exception('Failed to find section %s' % section)
top = str[:start_pos]
middle = str[start_pos + len(start_tag):end_pos]
bottom = str[end_pos + len(end_tag):]
return (
top + cef_html_builder._token(cef_html_builder._section_key(section)) +
bottom, middle)
def load(self, html_template):
""" Load the specified |html_template| string. """
self.clear()
root = html_template
# Extract the platform link section from root.
(root, platform_link) = self._extract(root, 'platform_link')
# Extract platform section from root.
(root, platform) = self._extract(root, 'platform')
# Extract version section from platform.
(platform, version) = self._extract(platform, 'version')
# Extract file section from version.
(version, file) = self._extract(version, 'file')
self._parts = {
'root': root,
'platform_link': platform_link,
'platform': platform,
'version': version,
'file': file
}
@staticmethod
def _get_platform_name(platform):
return {
'linux32': 'Linux 32-bit',
'linux64': 'Linux 64-bit',
'linuxarm': 'Linux ARM',
'linuxarm64': 'Linux ARM64',
'macosx64': 'MacOS 64-bit',
'windows32': 'Windows 32-bit',
'windows64': 'Windows 64-bit'
}[platform]
@staticmethod
def _get_type_name(type):
return {
'standard': 'Standard Distribution',
'minimal': 'Minimal Distribution',
'client': 'Sample Application',
'debug_symbols': 'Debug Symbols',
'release_symbols': 'Release Symbols'
}[type]
@staticmethod
def _get_date(date):
return date.strftime('%m/%d/%Y')
@staticmethod
def _get_file_size(size):
if (size == 0):
return '0B'
size_name = ('B', 'KB', 'MB', 'GB')
i = int(math.floor(math.log(size, 1024)))
p = math.pow(1024, i)
s = round(size / p, 2)
return '%.2f %s' % (s, size_name[i])
@staticmethod
def _get_cef_source_url(cef_version):
if cef_version.find('+chromium') > 0:
# New-style CEF version numbers include the Chromium version number.
# Example: 74.0.1+g62d140e+chromium-74.0.3729.6
chromium_version = cef_version[cef_version.rfind('-') + 1:]
branch = chromium_version.split('.')[2]
else:
branch = cef_version.split('.')[1]
return 'https://bitbucket.org/chromiumembedded/cef/get/%s.tar.bz2' % branch
@staticmethod
def _get_chromium_source_url(chromium_version):
if chromium_version == 'master':
return 'https://chromium.googlesource.com/chromium/src.git'
return 'https://gsdview.appspot.com/chromium-browser-official/chromium-%s.tar.xz' % chromium_version
@staticmethod
def _get_file_url(platform, cef_version, file):
return file['name'].replace('+', '%2B')
@staticmethod
def _get_sha1_url(platform, cef_version, file):
return cef_html_builder._get_file_url(platform, cef_version, file) + '.sha1'
@staticmethod
def _get_tooltip_text(platform, cef_version, file):
if platform.startswith('linux'):
sample_app = 'cefsimple'
else:
sample_app = 'cefclient'
return {
'standard':
'Standard binary distribution. Includes header files, libcef_dll_wrapper source code, binary files, CMake configuration files and source code for the cefclient and cefsimple sample applications. See the included README.txt file for usage and build requirements.',
'minimal':
'Minimal binary distribution. Includes header files, libcef_dll_wrapper source code, Release build binary files and CMake configuration files. Does not include Debug build binary files or sample application source code. See the included README.txt file for usage and build requirements.',
'client':
'Release build of the ' + sample_app +
' sample application. See the included README.txt file for usage requirements.',
'debug_symbols':
'Debug build symbols. Must be extracted and placed next to the CEF Debug binary file with the same name and version.',
'release_symbols':
'Release build symbols. Must be extracted and placed next to the CEF Release binary file with the same name and version.'
}[file['type']]
def generate(self, json_builder):
""" Generate HTML output based on the contents of |json_builder|. """
if not isinstance(json_builder, cef_json_builder):
raise Exception('Invalid argument')
# Substitution values are augmented at each nesting level.
subs = {
'year': '2016',
'branding': self._branding,
}
# Substitute variables.
root_str = self._replace_all(self._parts['root'], subs)
platform_link_strs = []
platform_strs = []
for platform in json_builder.get_platforms():
subs['platform'] = platform
subs['platform_name'] = self._get_platform_name(platform)
# Substitute variables.
platform_link_str = self._replace_all(self._parts['platform_link'], subs)
platform_str = self._replace_all(self._parts['platform'], subs)
version_strs = []
for version in json_builder.get_versions(platform):
subs['cef_version'] = version['cef_version']
subs['chromium_version'] = version['chromium_version']
subs['last_modified'] = self._get_date(
version['files'][0]['last_modified'])
subs['cef_source_url'] = self._get_cef_source_url(
version['cef_version'])
subs['chromium_source_url'] = self._get_chromium_source_url(
version['chromium_version'])
# Substitute variables.
version_str = self._replace_all(self._parts['version'], subs)
file_strs = {}
for file in version['files']:
subs['last_modified'] = self._get_date(file['last_modified'])
subs['name'] = file['name']
subs['sha1'] = file['sha1']
subs['size'] = self._get_file_size(file['size'])
subs['type'] = file['type']
subs['type_name'] = self._get_type_name(file['type'])
subs['file_url'] = self._get_file_url(platform,
version['cef_version'], file)
subs['sha1_url'] = self._get_sha1_url(platform,
version['cef_version'], file)
subs['tooltip_text'] = self._get_tooltip_text(
platform, version['cef_version'], file)
# Substitute variables.
file_str = self._replace_all(self._parts['file'], subs)
file_strs[file['type']] = file_str
if len(file_strs) > 0:
# Always output file types in the same order.
file_out = ''
type_order = [
'standard', 'minimal', 'client', 'debug_symbols',
'release_symbols'
]
for type in type_order:
if type in file_strs:
file_out = file_out + file_strs[type]
# Insert files.
version_str = self._replace(version_str,
self._section_key('file'), file_out)
version_strs.append(version_str)
if len(version_strs) > 0:
# Insert versions.
platform_str = self._replace(platform_str,
self._section_key('version'),
"".join(version_strs))
platform_strs.append(platform_str)
platform_link_strs.append(platform_link_str)
if len(platform_strs) > 0:
# Insert platforms.
root_str = self._replace(root_str,
self._section_key('platform_link'),
"".join(platform_link_strs))
root_str = self._replace(root_str,
self._section_key('platform'),
"".join(platform_strs))
return root_str
# Program entry point.
if __name__ == '__main__':
# Verify command-line arguments.
if len(sys.argv) < 4:
sys.stderr.write('Usage: %s <json_file_in> <html_file_in> <html_file_out>\n'
% sys.argv[0])
sys.exit()
json_file_in = sys.argv[1]
html_file_in = sys.argv[2]
html_file_out = sys.argv[3]
# Create the HTML builder and load the HTML template.
print('--> Reading %s' % html_file_in)
html_builder = cef_html_builder()
with open(html_file_in, 'r') as f:
html_builder.load(f.read())
# Create the JSON builder and load the JSON file.
print('--> Reading %s' % json_file_in)
json_builder = cef_json_builder(silent=False)
with open(json_file_in, 'r') as f:
json_builder.load(f.read())
# Write the HTML output file.
print('--> Writing %s' % html_file_out)
with open(html_file_out, 'w') as f:
f.write(html_builder.generate(json_builder))

View File

@ -125,14 +125,12 @@ class cef_json_builder:
bool(re.compile('^' + _chromium_version_regex + '$').match(version)) bool(re.compile('^' + _chromium_version_regex + '$').match(version))
@staticmethod @staticmethod
def get_file_name(version, platform, type): def get_file_name(version, platform, type, channel='stable'):
""" Returns the expected distribution file name excluding extension based on """ Returns the expected distribution file name excluding extension based on
the input parameters. """ the input parameters. """
if type != 'standard': type_str = '_' + type if type != 'standard' else ''
type_str = '_' + type channel_str = '_' + channel if channel != 'stable' else ''
else: return 'cef_binary_%s_%s%s%s' % (version, platform, channel_str, type_str)
type_str = ''
return 'cef_binary_%s_%s%s' % (version, platform, type_str)
def clear(self): def clear(self):
""" Clear the contents of this object. """ """ Clear the contents of this object. """
@ -246,7 +244,8 @@ class cef_json_builder:
# Validate the new data's structure. # Validate the new data's structure.
for platform in self._data.keys(): for platform in self._data.keys():
if not platform in new_data: if not platform in new_data:
self._print('load: Platform %s not found' % platform) if not self._silent:
print('load: Platform %s not found' % platform)
continue continue
if not 'versions' in new_data[platform]: if not 'versions' in new_data[platform]:
self._print('load: Missing platform key(s) for %s' % platform) self._print('load: Missing platform key(s) for %s' % platform)
@ -271,8 +270,8 @@ class cef_json_builder:
self._print('load: Missing file key(s) for %s %s' % self._print('load: Missing file key(s) for %s %s' %
(platform, version['cef_version'])) (platform, version['cef_version']))
continue continue
(expected_platform, expected_version, (expected_platform, expected_version, expected_type,
expected_type) = self._parse_name(file['name']) expected_channel) = self._parse_name(file['name'])
if expected_platform != platform or \ if expected_platform != platform or \
expected_version != version['cef_version'] or \ expected_version != version['cef_version'] or \
expected_type != file['type']: expected_type != file['type']:
@ -301,6 +300,8 @@ class cef_json_builder:
'chromium_version': 'chromium_version':
self.set_chromium_version(version['cef_version'], self.set_chromium_version(version['cef_version'],
version['chromium_version']), version['chromium_version']),
'channel':
version.get('channel', 'stable'),
'files': 'files':
self._sort_files(valid_files) self._sort_files(valid_files)
}) })
@ -340,6 +341,7 @@ class cef_json_builder:
del name_parts[0] del name_parts[0]
type = None type = None
channel = 'stable'
# Might be '<version>_<platform>_[debug|release]_symbols'. # Might be '<version>_<platform>_[debug|release]_symbols'.
if name_parts[-1] == 'symbols': if name_parts[-1] == 'symbols':
@ -358,6 +360,11 @@ class cef_json_builder:
type = 'client' type = 'client'
del name_parts[-1] del name_parts[-1]
# Might be '<version>_<platform>_beta'.
if name_parts[-1] == 'beta':
del name_parts[-1]
channel = 'beta'
# Remainder must be '<version>_<platform>'. # Remainder must be '<version>_<platform>'.
if len(name_parts) != 2: if len(name_parts) != 2:
raise Exception('Invalid filename: %s' % name) raise Exception('Invalid filename: %s' % name)
@ -368,7 +375,7 @@ class cef_json_builder:
version = name_parts[0] version = name_parts[0]
platform = name_parts[1] platform = name_parts[1]
return [platform, version, type] return [platform, version, type, channel]
@staticmethod @staticmethod
def _validate_args(platform, version, type, size, last_modified, sha1): def _validate_args(platform, version, type, size, last_modified, sha1):
@ -397,7 +404,7 @@ class cef_json_builder:
file is added or False if a file with the same |name| and |sha1| file is added or False if a file with the same |name| and |sha1|
already exists. """ already exists. """
# Parse the file name. # Parse the file name.
(platform, version, type) = self._parse_name(name) (platform, version, type, channel) = self._parse_name(name)
if not isinstance(size, int): if not isinstance(size, int):
size = int(size) size = int(size)
@ -418,10 +425,11 @@ class cef_json_builder:
if version_idx == -1: if version_idx == -1:
# Add a new version record. # Add a new version record.
self._print('add_file: Add %s %s' % (platform, version)) self._print('add_file: Add %s %s %s' % (platform, version, channel))
self._data[platform]['versions'].append({ self._data[platform]['versions'].append({
'cef_version': version, 'cef_version': version,
'chromium_version': self.get_chromium_version(version), 'chromium_version': self.get_chromium_version(version),
'channel': channel,
'files': [] 'files': []
}) })
version_idx = len(self._data[platform]['versions']) - 1 version_idx = len(self._data[platform]['versions']) - 1
@ -480,6 +488,7 @@ class cef_json_builder:
result_obj['platform'] = platform result_obj['platform'] = platform
result_obj['cef_version'] = version_obj['cef_version'] result_obj['cef_version'] = version_obj['cef_version']
result_obj['chromium_version'] = version_obj['chromium_version'] result_obj['chromium_version'] = version_obj['chromium_version']
result_obj['channel'] = version_obj['channel']
results.append(result_obj) results.append(result_obj)
return results return results

View File

@ -12,9 +12,6 @@
# > python cef_json_builder_example.py add all 3.2704.1416.g185cd6c 51.0.2704.47 # > python cef_json_builder_example.py add all 3.2704.1416.g185cd6c 51.0.2704.47
# #
# See cef_json_builder.get_platforms() for the list of supported platforms. # See cef_json_builder.get_platforms() for the list of supported platforms.
#
# After creating an index.json file you can use the cef_html_builder.py tool to
# create an HTML file.
from __future__ import absolute_import from __future__ import absolute_import
from __future__ import print_function from __future__ import print_function

View File

@ -76,9 +76,11 @@ class TestCefJSONBuilder(unittest.TestCase):
platform='linux32', platform='linux32',
version='3.2704.1414.g185cd6c', version='3.2704.1414.g185cd6c',
type='standard', type='standard',
channel='stable',
attrib_idx=0, attrib_idx=0,
shouldfail=False): shouldfail=False):
name = cef_json_builder.get_file_name(version, platform, type) + '.tar.gz' name = cef_json_builder.get_file_name(version, platform, type,
channel) + '.tar.gz'
# Some random attribute information. sha1 must be different to trigger replacement. # Some random attribute information. sha1 must be different to trigger replacement.
attribs = [{ attribs = [{
@ -113,6 +115,7 @@ class TestCefJSONBuilder(unittest.TestCase):
'platform': platform, 'platform': platform,
'last_modified': attribs[attrib_idx]['date_val'], 'last_modified': attribs[attrib_idx]['date_val'],
'cef_version': version, 'cef_version': version,
'channel': channel,
'type': type, 'type': type,
'size': attribs[attrib_idx]['size'] 'size': attribs[attrib_idx]['size']
} }
@ -127,10 +130,10 @@ class TestCefJSONBuilder(unittest.TestCase):
self.assertEqual(len(files), 0) self.assertEqual(len(files), 0)
# Test add/get of a single file with the specified type. # Test add/get of a single file with the specified type.
def _test_add_file(self, type): def _test_add_file(self, type, channel='stable'):
builder = cef_json_builder() builder = cef_json_builder()
expected = self._add_test_file(builder, type=type) expected = self._add_test_file(builder, type=type, channel=channel)
self._verify_write_read(builder) self._verify_write_read(builder)
files = builder.get_files() files = builder.get_files()
@ -157,6 +160,26 @@ class TestCefJSONBuilder(unittest.TestCase):
def test_add_release_symbols_file(self): def test_add_release_symbols_file(self):
self._test_add_file('release_symbols') self._test_add_file('release_symbols')
# Test add/get of a standard type file in beta channel.
def test_add_standard_file_beta(self):
self._test_add_file('standard', channel='beta')
# Test add/get of a minimal type file in beta channel.
def test_add_minimal_file_beta(self):
self._test_add_file('minimal', channel='beta')
# Test add/get of a client type file in beta channel.
def test_add_client_file_beta(self):
self._test_add_file('client', channel='beta')
# Test add/get of a debug_symbols type file in beta channel.
def test_add_debug_symbols_file_beta(self):
self._test_add_file('debug_symbols', channel='beta')
# Test add/get of a release_symbols type file in beta channel.
def test_add_release_symbols_file_beta(self):
self._test_add_file('release_symbols', channel='beta')
# Test get_files() behavior with a single file. # Test get_files() behavior with a single file.
def test_get_files_single(self): def test_get_files_single(self):
# yapf: disable # yapf: disable

File diff suppressed because one or more lines are too long