2013-07-15 21:27:12 +04:00
|
|
|
#!/usr/bin/python
|
2013-07-31 22:27:13 +04:00
|
|
|
# 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 http://mozilla.org/MPL/2.0/.
|
|
|
|
|
2018-05-22 00:58:19 +03:00
|
|
|
# originally from https://hg.mozilla.org/build/tools/file/4ab9c1a4e05b/scripts/release/compare-mozconfigs.py # NOQA: E501
|
2013-07-31 22:27:13 +04:00
|
|
|
|
|
|
|
from __future__ import unicode_literals
|
|
|
|
|
2013-07-15 21:27:12 +04:00
|
|
|
import logging
|
2017-11-21 01:34:50 +03:00
|
|
|
import os
|
2013-07-31 22:27:13 +04:00
|
|
|
import difflib
|
2018-01-06 01:16:04 +03:00
|
|
|
import unittest
|
|
|
|
|
|
|
|
import buildconfig
|
|
|
|
import mozunit
|
2013-07-15 21:27:12 +04:00
|
|
|
|
|
|
|
FAILURE_CODE = 1
|
|
|
|
SUCCESS_CODE = 0
|
|
|
|
|
2017-11-21 01:47:01 +03:00
|
|
|
PLATFORMS = (
|
|
|
|
'linux32',
|
|
|
|
'linux64',
|
|
|
|
'macosx64',
|
|
|
|
'win32',
|
|
|
|
'win64',
|
2019-01-26 12:50:27 +03:00
|
|
|
'win64-aarch64',
|
2017-11-21 01:47:01 +03:00
|
|
|
)
|
|
|
|
|
2013-07-31 22:27:13 +04:00
|
|
|
log = logging.getLogger(__name__)
|
|
|
|
|
2018-05-22 00:58:19 +03:00
|
|
|
|
2013-07-31 22:27:13 +04:00
|
|
|
class ConfigError(Exception):
|
|
|
|
pass
|
|
|
|
|
2018-05-22 00:58:19 +03:00
|
|
|
|
2017-11-21 01:09:47 +03:00
|
|
|
def readConfig(configfile):
|
2013-07-31 22:27:13 +04:00
|
|
|
c = {}
|
|
|
|
execfile(configfile, c)
|
2017-11-21 01:09:47 +03:00
|
|
|
return c['whitelist']
|
2013-07-31 22:27:13 +04:00
|
|
|
|
2018-05-22 00:58:19 +03:00
|
|
|
|
2013-07-31 22:27:13 +04:00
|
|
|
def verify_mozconfigs(mozconfig_pair, nightly_mozconfig_pair, platform,
|
2017-11-21 01:14:56 +03:00
|
|
|
mozconfigWhitelist):
|
2013-07-31 22:27:13 +04:00
|
|
|
"""Compares mozconfig to nightly_mozconfig and compare to an optional
|
|
|
|
whitelist of known differences. mozconfig_pair and nightly_mozconfig_pair
|
|
|
|
are pairs containing the mozconfig's identifier and the list of lines in
|
|
|
|
the mozconfig."""
|
|
|
|
|
|
|
|
# unpack the pairs to get the names, the names are just for
|
|
|
|
# identifying the mozconfigs when logging the error messages
|
|
|
|
mozconfig_name, mozconfig_lines = mozconfig_pair
|
|
|
|
nightly_mozconfig_name, nightly_mozconfig_lines = nightly_mozconfig_pair
|
|
|
|
|
2017-11-21 01:27:13 +03:00
|
|
|
if not mozconfig_lines or not nightly_mozconfig_lines:
|
2013-07-31 22:27:13 +04:00
|
|
|
log.info("Missing mozconfigs to compare for %s" % platform)
|
|
|
|
return False
|
|
|
|
|
|
|
|
success = True
|
|
|
|
|
|
|
|
diff_instance = difflib.Differ()
|
2018-05-22 00:58:19 +03:00
|
|
|
diff_result = diff_instance.compare(
|
|
|
|
mozconfig_lines, nightly_mozconfig_lines)
|
2013-07-31 22:27:13 +04:00
|
|
|
diff_list = list(diff_result)
|
|
|
|
|
|
|
|
for line in diff_list:
|
|
|
|
clean_line = line[1:].strip()
|
|
|
|
if (line[0] == '-' or line[0] == '+') and len(clean_line) > 1:
|
|
|
|
# skip comment lines
|
|
|
|
if clean_line.startswith('#'):
|
|
|
|
continue
|
|
|
|
# compare to whitelist
|
|
|
|
message = ""
|
|
|
|
if line[0] == '-':
|
2015-10-24 05:59:54 +03:00
|
|
|
# handle lines that move around in diff
|
|
|
|
if '+' + line[1:] in diff_list:
|
|
|
|
continue
|
2013-07-31 22:27:13 +04:00
|
|
|
if platform in mozconfigWhitelist.get('release', {}):
|
|
|
|
if clean_line in \
|
|
|
|
mozconfigWhitelist['release'][platform]:
|
|
|
|
continue
|
|
|
|
elif line[0] == '+':
|
2015-10-24 05:59:54 +03:00
|
|
|
if '-' + line[1:] in diff_list:
|
|
|
|
continue
|
2013-07-31 22:27:13 +04:00
|
|
|
if platform in mozconfigWhitelist.get('nightly', {}):
|
|
|
|
if clean_line in \
|
|
|
|
mozconfigWhitelist['nightly'][platform]:
|
|
|
|
continue
|
|
|
|
else:
|
|
|
|
log.warning("%s not in %s %s!" % (
|
|
|
|
clean_line, platform,
|
|
|
|
mozconfigWhitelist['nightly'][platform]))
|
|
|
|
else:
|
|
|
|
log.error("Skipping line %s!" % line)
|
|
|
|
continue
|
|
|
|
message = "found in %s but not in %s: %s"
|
|
|
|
if line[0] == '-':
|
|
|
|
log.error(message % (mozconfig_name,
|
|
|
|
nightly_mozconfig_name, clean_line))
|
|
|
|
else:
|
|
|
|
log.error(message % (nightly_mozconfig_name,
|
|
|
|
mozconfig_name, clean_line))
|
|
|
|
success = False
|
|
|
|
return success
|
|
|
|
|
2018-05-22 00:58:19 +03:00
|
|
|
|
2017-11-21 01:18:46 +03:00
|
|
|
def get_mozconfig(path):
|
|
|
|
"""Consumes a path and returns a list of lines from the mozconfig file."""
|
|
|
|
with open(path, 'rb') as fh:
|
|
|
|
return fh.readlines()
|
2013-07-15 21:27:12 +04:00
|
|
|
|
|
|
|
|
2017-11-21 01:47:01 +03:00
|
|
|
def compare(topsrcdir):
|
|
|
|
app = os.path.join(topsrcdir, 'browser')
|
|
|
|
whitelist = readConfig(os.path.join(app, 'config', 'mozconfigs',
|
|
|
|
'whitelist'))
|
2017-11-21 01:34:50 +03:00
|
|
|
|
2017-11-21 01:47:01 +03:00
|
|
|
success = True
|
2013-07-15 21:27:12 +04:00
|
|
|
|
2017-11-21 01:55:29 +03:00
|
|
|
def normalize_lines(lines):
|
|
|
|
return {l.strip() for l in lines}
|
|
|
|
|
2017-11-21 01:47:01 +03:00
|
|
|
for platform in PLATFORMS:
|
|
|
|
log.info('Comparing platform %s' % platform)
|
|
|
|
|
|
|
|
mozconfigs_path = os.path.join(app, 'config', 'mozconfigs', platform)
|
2013-07-15 21:27:12 +04:00
|
|
|
|
2017-11-21 01:47:01 +03:00
|
|
|
nightly_path = os.path.join(mozconfigs_path, 'nightly')
|
|
|
|
beta_path = os.path.join(mozconfigs_path, 'beta')
|
|
|
|
release_path = os.path.join(mozconfigs_path, 'release')
|
2017-11-21 01:34:50 +03:00
|
|
|
|
2017-11-21 01:47:01 +03:00
|
|
|
nightly_lines = get_mozconfig(nightly_path)
|
|
|
|
beta_lines = get_mozconfig(beta_path)
|
|
|
|
release_lines = get_mozconfig(release_path)
|
2013-07-15 21:27:12 +04:00
|
|
|
|
2017-11-21 01:55:29 +03:00
|
|
|
# Validate that entries in whitelist['nightly'][platform] are actually
|
|
|
|
# present.
|
|
|
|
whitelist_normalized = normalize_lines(
|
|
|
|
whitelist['nightly'].get(platform, []))
|
|
|
|
nightly_normalized = normalize_lines(nightly_lines)
|
|
|
|
|
|
|
|
for line in sorted(whitelist_normalized - nightly_normalized):
|
|
|
|
log.error('extra line in nightly whitelist: %s' % line)
|
|
|
|
success = False
|
|
|
|
|
2017-11-21 01:47:01 +03:00
|
|
|
log.info('Comparing beta and nightly mozconfigs')
|
|
|
|
passed = verify_mozconfigs((beta_path, beta_lines),
|
|
|
|
(nightly_path, nightly_lines),
|
|
|
|
platform,
|
|
|
|
whitelist)
|
2013-07-15 21:27:12 +04:00
|
|
|
|
2017-11-21 01:47:01 +03:00
|
|
|
if not passed:
|
|
|
|
success = False
|
2013-07-15 21:27:12 +04:00
|
|
|
|
2017-11-21 01:47:01 +03:00
|
|
|
log.info('Comparing release and nightly mozconfigs')
|
|
|
|
passed = verify_mozconfigs((release_path, release_lines),
|
|
|
|
(nightly_path, nightly_lines),
|
|
|
|
platform,
|
|
|
|
whitelist)
|
|
|
|
if not passed:
|
|
|
|
success = False
|
2013-07-15 21:27:12 +04:00
|
|
|
|
2017-11-21 01:47:01 +03:00
|
|
|
return success
|
|
|
|
|
|
|
|
|
2018-01-06 01:16:04 +03:00
|
|
|
class TestCompareMozconfigs(unittest.TestCase):
|
|
|
|
def test_compare_mozconfigs(self):
|
|
|
|
topsrcdir = buildconfig.substs['top_srcdir']
|
|
|
|
self.assertTrue(compare(topsrcdir))
|
2017-11-21 01:47:01 +03:00
|
|
|
|
|
|
|
|
2018-01-06 01:16:04 +03:00
|
|
|
if __name__ == '__main__':
|
2017-11-21 01:47:01 +03:00
|
|
|
logging.basicConfig(level=logging.INFO)
|
2018-01-06 01:16:04 +03:00
|
|
|
mozunit.main()
|