Compare commits

..

6 Commits

Author SHA1 Message Date
Brett T. Warden 239d8cd618 Limit diff to ~10 lines
Also include content of added files.
2024-04-15 17:13:34 -07:00
Brett T. Warden 16ee88cb20 Don't write source archive comparison tarball to upstreams file
We only use this for source tree comparison, not part of the build, so
don't add it to the upstreams file.
2024-04-15 16:59:57 -07:00
Brett T. Warden 617c67c388 Make flake8 happy 2024-04-15 16:00:38 -07:00
Brett T. Warden 2cf51ddfb9 Move autogenerated source tree to a versionless directory 2024-04-15 15:54:30 -07:00
Brett T. Warden 6174188098 Fix failure on packages that don't have an autogenerated source tarball 2024-04-15 15:25:16 -07:00
Brett T. Warden 61e16733c8 Capture diffs of dist tarballs vs auto-generated source archives from GitHub 2024-04-15 15:12:17 -07:00
29 changed files with 284 additions and 881 deletions
-7
View File
@@ -1,7 +0,0 @@
## DISCONTINUATION OF PROJECT.
This project will no longer be maintained by Intel.
Intel will not provide or guarantee development of or support for this project, including but not limited to, maintenance, bug fixes, new releases or updates. Patches to this project are no longer accepted by Intel. If you have an ongoing need to use this project, are interested in independently developing it, or would like to maintain patches for the community, please create your own fork of the project.
Contact: webadmin@linux.intel.com
-20
View File
@@ -128,14 +128,6 @@ release
``.spec``. This is also bumped and generated on existing and new packages, ``.spec``. This is also bumped and generated on existing and new packages,
respectively. This results in less manual work via automatic management. respectively. This results in less manual work via automatic management.
license_skips
Each line in the file should be the path to a license file. That path needs
to account for the package tarfile prefix. Likely requires using '*' to be
effective (e.g. ``pkgname-*/path/to/license`` where ``*`` handles the version).
Files paths can contain a single '*' per directory such that
a line of ``/foo*/bar*`` is allowed but ``/foo*bar*`` is not.
$package.license $package.license
In certain cases, the package license may not be automatically discovered. In In certain cases, the package license may not be automatically discovered. In
this instance, ``autospec`` will exit with an error. Update this file to this instance, ``autospec`` will exit with an error. Update this file to
@@ -212,12 +204,6 @@ ${custom}_provides_ban
Controlling the build process Controlling the build process
------------------------------ ------------------------------
invalid_release_sig
This file contains the current version that will **not** have its package
file be processed for signature verification (overriding the config_opt).
This file will be automatically deleted after a new release and is intended
to override a single bad signed release.
extra_sources extra_sources
This file contains a list of extra files to be added to the ``.spec`` and This file contains a list of extra files to be added to the ``.spec`` and
optionally installed as well. Each non-blank and non-comment line should start optionally installed as well. Each non-blank and non-comment line should start
@@ -282,12 +268,6 @@ prep_prepend
resulting ``.spec``, and is used for situations where fine-grained resulting ``.spec``, and is used for situations where fine-grained
control is required. control is required.
copy_prepend
Additional actions that should take place directly before the source
directory is copied for other builds (32bit, avx2, etc). This will be
placed in the resulting ``.spec``, and is used for situations where
fine-grained control is required.
build_prepend build_prepend
Additional actions that should take place after ``%build`` and before Additional actions that should take place after ``%build`` and before
the ``%configure`` macro or equivalent (``%cmake``, etc.). If autospec the ``%configure`` macro or equivalent (``%cmake``, etc.). If autospec
+2 -4
View File
@@ -155,7 +155,7 @@ def is_file_valid(path):
def dump_symbols(path): def dump_symbols(path):
"""Get symbols from a file.""" """Get symbols from a file."""
cmd = "nm --defined-only -g --dynamic \"{}\" | c++filt".format(path) cmd = "nm --defined-only -g --dynamic \"{}\"".format(path)
lines = None lines = None
ret = set() ret = set()
@@ -163,7 +163,7 @@ def dump_symbols(path):
try: try:
lines = get_output(cmd) lines = get_output(cmd)
except Exception as e: except Exception as e:
util.print_fatal("Fatal error inspecting {}: {}".format(path, e)) print("Fatal error inspecting {}: {}".format(path, e))
sys.exit(1) sys.exit(1)
for line in lines.split("\n"): for line in lines.split("\n"):
line = line.strip() line = line.strip()
@@ -236,7 +236,6 @@ def examine_abi_host(download_path, results_dir, name):
cwd=download_path) cwd=download_path)
except Exception as e: except Exception as e:
util.print_fatal("Error invoking abireport: {}".format(e)) util.print_fatal("Error invoking abireport: {}".format(e))
sys.exit(1)
def examine_abi_fallback(download_path, results_dir, name): def examine_abi_fallback(download_path, results_dir, name):
@@ -273,7 +272,6 @@ def examine_abi_fallback(download_path, results_dir, name):
subprocess.check_call(cmd, shell=True) subprocess.check_call(cmd, shell=True)
except Exception as e: except Exception as e:
util.print_fatal("Error extracting RPMS: {}".format(e)) util.print_fatal("Error extracting RPMS: {}".format(e))
sys.exit(1)
os.chdir(download_path) os.chdir(download_path)
collected_files = set() collected_files = set()
+4 -16
View File
@@ -38,7 +38,7 @@ import specfiles
import tarball import tarball
from abireport import examine_abi from abireport import examine_abi
from logcheck import logcheck from logcheck import logcheck
from util import binary_in_path, print_build_failed, print_fatal, write_out from util import binary_in_path, print_fatal, write_out
sys.path.append(os.path.dirname(__file__)) sys.path.append(os.path.dirname(__file__))
@@ -269,17 +269,10 @@ def package(args, url, name, archives, workingdir):
pkg_integrity.check(url, conf, interactive=interactive_mode) pkg_integrity.check(url, conf, interactive=interactive_mode)
pkg_integrity.load_specfile(specfile) pkg_integrity.load_specfile(specfile)
spec_type = specfile.write_spec() specfile.write_spec()
while 1: while 1:
package.package(filemanager, args.mock_config, args.mock_opts, conf, requirements, content, args.cleanup) package.package(filemanager, args.mock_config, args.mock_opts, conf, requirements, content, args.cleanup)
if spec_type == "template":
# specfile template is assumed "correct" and any failures need to be manually addressed
break
filemanager.load_specfile(specfile) filemanager.load_specfile(specfile)
if 'license' in specfile.packages and not conf.config_opts['has_license']:
conf.config_opts['has_license'] = True
conf.rewrite_config_opts()
specfile.write_spec() specfile.write_spec()
filemanager.newfiles_printed = 0 filemanager.newfiles_printed = 0
mock_chroot = "/var/lib/mock/clear-{}/root/builddir/build/BUILDROOT/" \ mock_chroot = "/var/lib/mock/clear-{}/root/builddir/build/BUILDROOT/" \
@@ -298,11 +291,7 @@ def package(args, url, name, archives, workingdir):
if package.success == 0: if package.success == 0:
conf.create_buildreq_cache(content.version, requirements.buildreqs_cache) conf.create_buildreq_cache(content.version, requirements.buildreqs_cache)
print_build_failed() print_fatal("Build failed, aborting")
sys.exit(1)
elif 'license' not in specfile.packages and conf.config_opts['has_license']:
print_fatal("package -license subpackage deleted")
conf.create_buildreq_cache(content.version, requirements.buildreqs_cache)
sys.exit(1) sys.exit(1)
elif os.path.isfile("README.clear"): elif os.path.isfile("README.clear"):
try: try:
@@ -315,8 +304,7 @@ def package(args, url, name, archives, workingdir):
except Exception: except Exception:
pass pass
if spec_type == "generate": check.check_regression(conf.download_path, conf.config_opts['skip_tests'], package.round - 1)
check.check_regression(conf.download_path, conf.config_opts['skip_tests'], package.round - 1)
examine_abi(conf.download_path, content.name) examine_abi(conf.download_path, content.name)
if os.path.exists("/var/lib/rpm"): if os.path.exists("/var/lib/rpm"):
+9 -12
View File
@@ -22,7 +22,6 @@
import os import os
import re import re
import shutil import shutil
import sys
import util import util
@@ -154,7 +153,7 @@ class Build(object):
return True return True
self.must_restart = 0 self.must_restart = 0
self.file_restart = 0 self.file_restart = 0
fatals = [] is_clean = True
util.call("sync") util.call("sync")
with util.open_auto(filename, "r") as rootlog: with util.open_auto(filename, "r") as rootlog:
loglines = rootlog.readlines() loglines = rootlog.readlines()
@@ -162,10 +161,9 @@ class Build(object):
for line in loglines: for line in loglines:
match = missing_pat.match(line) match = missing_pat.match(line)
if match is not None: if match is not None:
fatals.append(f"Cannot resolve dependency name: {match.group(1)}") util.print_fatal("Cannot resolve dependency name: {}".format(match.group(1)))
if fatals: is_clean = False
util.print_fatal('\n'.join(fatals)) return is_clean
sys.exit(1)
def parse_build_results(self, filename, returncode, filemanager, config, requirements, content): def parse_build_results(self, filename, returncode, filemanager, config, requirements, content):
"""Handle build log contents.""" """Handle build log contents."""
@@ -215,8 +213,6 @@ class Build(object):
elif infiles == 1 and "not matching the package arch" not in line: elif infiles == 1 and "not matching the package arch" not in line:
# exclude blank lines from consideration... # exclude blank lines from consideration...
file = line.strip() file = line.strip()
if file in ("/usr", "/usr/"):
self.must_restart += 1
if file and file[0] == "/": if file and file[0] == "/":
filemanager.push_file(file, content.name) filemanager.push_file(file, content.name)
@@ -287,7 +283,7 @@ class Build(object):
mockopts, mockopts,
] ]
if config.config_opts.get('avoid_rebuild') and not cleanup and self.must_restart == 0 and self.file_restart > 0 and set(filemanager.excludes) == set(filemanager.manual_excludes): if not cleanup and self.must_restart == 0 and self.file_restart > 0 and set(filemanager.excludes) == set(filemanager.manual_excludes):
cmd_args.append("--no-clean") cmd_args.append("--no-clean")
cmd_args.append("--short-circuit=binary") cmd_args.append("--short-circuit=binary")
@@ -299,11 +295,12 @@ class Build(object):
# sanity check the build log # sanity check the build log
if not os.path.exists(config.download_path + "/results/build.log"): if not os.path.exists(config.download_path + "/results/build.log"):
util.print_fatal("Mock command failed, results log does not exist. User may not have correct permissions.") util.print_fatal("Mock command failed, results log does not exist. User may not have correct permissions.")
sys.exit(1) exit(1)
self.parse_buildroot_log(config.download_path + "/results/root.log", ret) if not self.parse_buildroot_log(config.download_path + "/results/root.log", ret):
return
self.parse_build_results(config.download_path + "/results/build.log", ret, filemanager, config, requirements, content) self.parse_build_results(config.download_path + "/results/build.log", ret, filemanager, config, requirements, content)
if filemanager.has_banned: if filemanager.has_banned:
util.print_fatal("Content in banned paths found, aborting build") util.print_fatal("Content in banned paths found, aborting build")
sys.exit(1) exit(1)
+9 -23
View File
@@ -147,7 +147,7 @@ def parse_modules_list(modules_string, is_cmake=False):
modules = [m for m in re.split(r'\s*([><]?=|\${?[^}]*}?)\s*', modules_string)] modules = [m for m in re.split(r'\s*([><]?=|\${?[^}]*}?)\s*', modules_string)]
modules = filter(None, modules) modules = filter(None, modules)
else: else:
modules = [m.strip('[]').strip('"') for m in modules_string.split()] modules = [m.strip('[]') for m in modules_string.split()]
res = [] res = []
next_is_ver = False next_is_ver = False
for mod in modules: for mod in modules:
@@ -508,7 +508,7 @@ class Requirements(object):
"""Scan a .cmake or CMakeLists.txt file for what's it's actually looking for.""" """Scan a .cmake or CMakeLists.txt file for what's it's actually looking for."""
findpackage = re.compile(r"^[^#]*find_package\((\w+)\b.*\)", re.I) findpackage = re.compile(r"^[^#]*find_package\((\w+)\b.*\)", re.I)
findpackage_multiline = re.compile(r"^[^#]*find_package\((\w+)\b.*", re.I) findpackage_multiline = re.compile(r"^[^#]*find_package\((\w+)\b.*", re.I)
pkgconfig = re.compile(r"^[^#]*pkg_check_modules\s*\([\w\-]+ (.*)\)", re.I) pkgconfig = re.compile(r"^[^#]*pkg_check_modules\s*\(\w+ (.*)\)", re.I)
pkg_search_modifiers = {'REQUIRED', 'QUIET', 'NO_CMAKE_PATH', pkg_search_modifiers = {'REQUIRED', 'QUIET', 'NO_CMAKE_PATH',
'NO_CMAKE_ENVIRONMENT_PATH', 'IMPORTED_TARGET'} 'NO_CMAKE_ENVIRONMENT_PATH', 'IMPORTED_TARGET'}
extractword = re.compile(r'(?:"([^"]+)"|(\S+))(.*)') extractword = re.compile(r'(?:"([^"]+)"|(\S+))(.*)')
@@ -518,13 +518,8 @@ class Requirements(object):
for line in lines: for line in lines:
if match := findpackage.search(line): if match := findpackage.search(line):
module = match.group(1) module = match.group(1)
if pkgs := cmake_modules.get(module): if pkg := cmake_modules.get(module):
# Some of the entries in cmake_modules list multiple packages, space-separated, so we need to split. self.add_buildreq(pkg)
# Otherwise, anything in buildreq_ban would have to match the entire string, not just a single package name.
# For example: Png2Ico, extra-cmake-modules png2ico
# buildreq_ban would have to contain "extra-cmake-modules png2ico" to match, instead of just "png2ico"
for pkg in pkgs.split():
self.add_buildreq(pkg)
elif findpackage_multiline.search(line): elif findpackage_multiline.search(line):
self.findpackage_parse_lines(line, lines, cmake_modules) self.findpackage_parse_lines(line, lines, cmake_modules)
@@ -709,7 +704,6 @@ class Requirements(object):
"""Use pypi for getting package requires and metadata.""" """Use pypi for getting package requires and metadata."""
# First look for a local override # First look for a local override
pypi_json = "" pypi_json = ""
pypi_name = pypidata.get_pypi_name(name)
pypi_file = os.path.join(config.download_path, "pypi.json") pypi_file = os.path.join(config.download_path, "pypi.json")
if os.path.isfile(pypi_file): if os.path.isfile(pypi_file):
with open(pypi_file, "r") as pfile: with open(pypi_file, "r") as pfile:
@@ -717,20 +711,16 @@ class Requirements(object):
else: else:
# Try and grab the pypi details for the package # Try and grab the pypi details for the package
if config.alias: if config.alias:
pypi_name = config.alias name = config.alias
pypi_name = pypidata.get_pypi_name(pypi_name) pypi_name = pypidata.get_pypi_name(name)
pypi_json = pypidata.get_pypi_metadata(pypi_name) pypi_json = pypidata.get_pypi_metadata(pypi_name)
if not pypi_json: if pypi_json:
self.pypi_provides = pypi_name
else:
try: try:
package_pypi = json.loads(pypi_json) package_pypi = json.loads(pypi_json)
except json.JSONDecodeError: except json.JSONDecodeError:
package_pypi = {"name": pypi_name} package_pypi = {}
if package_pypi.get("name"): if package_pypi.get("name"):
self.pypi_provides = package_pypi["name"] self.pypi_provides = package_pypi["name"]
else:
self.pypi_provides = pypi_name
if package_pypi.get("requires"): if package_pypi.get("requires"):
for pkg in package_pypi["requires"]: for pkg in package_pypi["requires"]:
self.add_requires(f"pypi({pkg})", config.os_packages, override=True, subpkg="python3") self.add_requires(f"pypi({pkg})", config.os_packages, override=True, subpkg="python3")
@@ -761,14 +751,10 @@ class Requirements(object):
configure_ac_files = [] configure_ac_files = []
qmake_profiles = [] qmake_profiles = []
cmake_files = [] cmake_files = []
if config.config_opts['use_ninja']:
self.add_buildreq('ninja')
for dirpath, _, files in os.walk(dirn): for dirpath, _, files in os.walk(dirn):
default_score = 2 if dirpath == dirn else 1 default_score = 2 if dirpath == dirn else 1
if "Cargo.toml" in files and 'Makefile' not in files: if "Cargo.toml" in files:
config.set_build_pattern('cargo', default_score) config.set_build_pattern('cargo', default_score)
if "CMakeLists.txt" in files and "configure.ac" not in files: if "CMakeLists.txt" in files and "configure.ac" not in files:
+21 -18
View File
@@ -64,54 +64,50 @@ def scan_for_tests(src_dir, config, requirements, content):
if config.config_opts.get('skip_tests') or tests_config: if config.config_opts.get('skip_tests') or tests_config:
return return
make_command = "ninja" if config.config_opts.get('use_ninja') else "make"
makeflags = "%{?_smp_mflags} " if config.parallel_build else "" makeflags = "%{?_smp_mflags} " if config.parallel_build else ""
make_check = "{} {}check".format(make_command, makeflags) make_check = "make {}check".format(makeflags)
cmake_check = "{} test".format(make_command) cmake_check = "make test"
make_check_openmpi = "module load openmpi\nexport OMPI_MCA_rmaps_base_oversubscribe=1\n" \ make_check_openmpi = "module load openmpi\nexport OMPI_MCA_rmaps_base_oversubscribe=1\n" \
"{} {}check\nmodule unload openmpi".format(make_command, makeflags) "make {}check\nmodule unload openmpi".format(makeflags)
cmake_check_openmpi = "module load openmpi\nexport OMPI_MCA_rmaps_base_oversubscribe=1\n" \ cmake_check_openmpi = "module load openmpi\nexport OMPI_MCA_rmaps_base_oversubscribe=1\n" \
"{} test\nmodule unload openmpi".format(make_command) "make test\nmodule unload openmpi"
if config.config_opts.get('allow_test_failures'): if config.config_opts.get('allow_test_failures'):
make_check_openmpi = "module load openmpi\nexport OMPI_MCA_rmaps_base_oversubscribe=1\n" \ make_check_openmpi = "module load openmpi\nexport OMPI_MCA_rmaps_base_oversubscribe=1\n" \
"{} {}check || :\nmodule unload openmpi".format(make_command, makeflags) "make {}check || :\nmodule unload openmpi".format(makeflags)
cmake_check_openmpi = "module load openmpi\nexport OMPI_MCA_rmaps_base_oversubscribe=1\n" \ cmake_check_openmpi = "module load openmpi\nexport OMPI_MCA_rmaps_base_oversubscribe=1\n" \
"{} test || :\nmodule unload openmpi".format(make_command) "make test || :\nmodule unload openmpi"
perl_check = "{} TEST_VERBOSE=1 test".format(make_command) perl_check = "make TEST_VERBOSE=1 test"
setup_check = """PYTHONPATH=%{buildroot}$(python -c "import sys; print(sys.path[-1])") python setup.py test"""
meson_check = "meson test -C builddir --print-errorlogs" meson_check = "meson test -C builddir --print-errorlogs"
if config.config_opts.get('allow_test_failures'): if config.config_opts.get('allow_test_failures'):
make_check += " || :" make_check += " || :"
cmake_check += " || :" cmake_check += " || :"
perl_check += " || :" perl_check += " || :"
setup_check += " || :"
meson_check += " || :" meson_check += " || :"
testsuites = { testsuites = {
"makecheck": make_check, "makecheck": make_check,
"perlcheck": perl_check, "perlcheck": perl_check,
"setup.py": setup_check,
"cmake": "cd clr-build; " + cmake_check, "cmake": "cd clr-build; " + cmake_check,
"meson": meson_check, "meson": meson_check,
} }
if config.config_opts.get('32bit'): if config.config_opts.get('32bit'):
testsuites["makecheck"] += "\ncd ../build32;\n" + make_check + " || :" testsuites["makecheck"] += "\ncd ../build32;\n" + make_check + " || :"
testsuites["cmake"] += "\ncd ../../build32/clr-build32;\n" + cmake_check + " || :" testsuites["cmake"] += "\ncd ../clr-build32;\n" + cmake_check + " || :"
testsuites["meson"] += "\ncd ../build32;\n" + meson_check + " || :" testsuites["meson"] += "\ncd ../build32;\n" + meson_check + " || :"
if config.config_opts.get('use_avx2'): if config.config_opts.get('use_avx2'):
testsuites["makecheck"] += "\ncd ../buildavx2;\n" + make_check + " || :" testsuites["makecheck"] += "\ncd ../buildavx2;\n" + make_check + " || :"
testsuites["cmake"] += "\ncd ../../buildavx2/clr-build-avx2;\n" + cmake_check + " || :" testsuites["cmake"] += "\ncd ../clr-build-avx2;\n" + cmake_check + " || :"
testsuites["meson"] += "\ncd ../buildavx2;\n" + meson_check + " || :"
if config.config_opts.get('use_avx512'): if config.config_opts.get('use_avx512'):
testsuites["makecheck"] += "\ncd ../buildavx512;\n" + make_check + " || :" testsuites["makecheck"] += "\ncd ../buildavx512;\n" + make_check + " || :"
testsuites["cmake"] += "\ncd ../../buildavx512/clr-build-avx512;\n" + cmake_check + " || :" testsuites["cmake"] += "\ncd ../clr-build-avx512;\n" + cmake_check + " || :"
testsuites["meson"] += "\ncd ../buildavx512;\n" + meson_check + " || :"
if config.config_opts.get('use_apx'):
testsuites["makecheck"] += "\ncd ../buildapx;\n" + make_check + " || :"
testsuites["cmake"] += "\ncd ../../buildapx/clr-build-apx;\n" + cmake_check + " || :"
testsuites["meson"] += "\ncd ../buildapx;\n" + meson_check + " || :"
if config.config_opts.get('openmpi'): if config.config_opts.get('openmpi'):
testsuites["makecheck"] += "\ncd ../build-openmpi;\n" + make_check_openmpi testsuites["makecheck"] += "\ncd ../build-openmpi;\n" + make_check_openmpi
testsuites["cmake"] += "\ncd ../../build-openmpi/clr-build-openmpi;\n" + cmake_check_openmpi testsuites["cmake"] += "\ncd ../clr-build-openmpi;\n" + cmake_check_openmpi
files = os.listdir(src_dir) files = os.listdir(src_dir)
@@ -142,6 +138,13 @@ def scan_for_tests(src_dir, config, requirements, content):
elif config.default_pattern in ["cpan"] and "Makefile.PL" in files: elif config.default_pattern in ["cpan"] and "Makefile.PL" in files:
tests_config = testsuites["perlcheck"] tests_config = testsuites["perlcheck"]
elif config.default_pattern == "distutils3" and "setup.py" in files:
with util.open_auto(os.path.join(src_dir, "setup.py"), 'r') as setup_fp:
setup_contents = setup_fp.read()
if "test_suite" in setup_contents or "pbr=True" in setup_contents:
tests_config = testsuites["setup.py"]
elif config.default_pattern == "R": elif config.default_pattern == "R":
tests_config = "export _R_CHECK_FORCE_SUGGESTS_=false\n" \ tests_config = "export _R_CHECK_FORCE_SUGGESTS_=false\n" \
"R CMD check --no-manual --no-examples --no-codoc . " \ "R CMD check --no-manual --no-examples --no-codoc . " \
+1 -1
View File
@@ -49,7 +49,7 @@ def scan_for_changes(download_path, directory, transforms):
shutil.copy(source, target) shutil.copy(source, target)
os.chmod(target, 0o644) os.chmod(target, 0o644)
except Exception as e: except Exception as e:
util.print_fatal("Error copying file: {}".format(e)) print("Error copying file: {}".format(e))
sys.exit(1) sys.exit(1)
found.append(item) found.append(item)
+8 -45
View File
@@ -28,8 +28,7 @@ from collections import OrderedDict
import check import check
import license import license
from util import (call, open_auto, print_fatal, print_info, print_warning, from util import call, open_auto, print_info, print_warning, write_out
write_out)
def read_pattern_conf(filename, dest, list_format=False, path=None): def read_pattern_conf(filename, dest, list_format=False, path=None):
@@ -69,7 +68,6 @@ class Config(object):
def __init__(self, download_path): def __init__(self, download_path):
"""Initialize Default configuration settings.""" """Initialize Default configuration settings."""
self.cargo_vendors = ""
self.content = None # hack to avoid circular init dependency self.content = None # hack to avoid circular init dependency
self.extra_configure = "" self.extra_configure = ""
self.extra_configure32 = "" self.extra_configure32 = ""
@@ -93,7 +91,6 @@ class Config(object):
self.install_macro = "%make_install" self.install_macro = "%make_install"
self.disable_static = "--disable-static" self.disable_static = "--disable-static"
self.prep_prepend = [] self.prep_prepend = []
self.copy_prepend = []
self.build_prepend = [] self.build_prepend = []
self.build_prepend_once = [] self.build_prepend_once = []
self.build_append = [] self.build_append = []
@@ -110,7 +107,6 @@ class Config(object):
self.custom_summ = "" self.custom_summ = ""
self.license_fetch = None self.license_fetch = None
self.license_show = None self.license_show = None
self.license_skips = []
self.git_uri = None self.git_uri = None
self.os_packages = set() self.os_packages = set()
self.config_file = None self.config_file = None
@@ -158,7 +154,6 @@ class Config(object):
} }
self.config_opts = {} self.config_opts = {}
self.config_options = { self.config_options = {
"avoid_rebuild": "Try to use mock short circuit to avoid full rebuilds",
"broken_c++": "extend flags with '-std=gnu++98", "broken_c++": "extend flags with '-std=gnu++98",
"cargo_vendor": "create vendor archive with cargo", "cargo_vendor": "create vendor archive with cargo",
"use_lto": "configure build for lto", "use_lto": "configure build for lto",
@@ -192,8 +187,6 @@ class Config(object):
"server": "Package is only used by servers", "server": "Package is only used by servers",
"no_glob": "Do not use the replacement pattern for file matching", "no_glob": "Do not use the replacement pattern for file matching",
"allow_exe": "Allow Windows executables (*.exe, *.dll) to be packaged", "allow_exe": "Allow Windows executables (*.exe, *.dll) to be packaged",
"use_ninja": "Use ninja build files",
"has_license": "Require license subpackage for successful build",
} }
# simple_pattern_pkgconfig patterns # simple_pattern_pkgconfig patterns
# contains patterns for parsing build.log for missing dependencies # contains patterns for parsing build.log for missing dependencies
@@ -273,7 +266,6 @@ class Config(object):
(r"Can't locate [a-zA-Z0-9_\-\/\.]+ in @INC \(you may need to install the ([a-zA-Z0-9_\-:]+) module\)", 0, 'perl'), (r"Can't locate [a-zA-Z0-9_\-\/\.]+ in @INC \(you may need to install the ([a-zA-Z0-9_\-:]+) module\)", 0, 'perl'),
(r"Cannot find ([a-zA-Z0-9\-_\.]*)", 1, None), (r"Cannot find ([a-zA-Z0-9\-_\.]*)", 1, None),
(r"Checking for (.*?)\.\.\.no", 0, None), (r"Checking for (.*?)\.\.\.no", 0, None),
(r"checking for (.*?) \(using pkg-config\)\.\.\. no", 0, None),
(r"Checking for (.*?)\s*: not found", 0, None), (r"Checking for (.*?)\s*: not found", 0, None),
(r"Checking for (.*?)\s>=.*\s*: not found", 0, None), (r"Checking for (.*?)\s>=.*\s*: not found", 0, None),
(r"Could not find suitable distribution for Requirement.parse\('([a-zA-Z\-\.]*)", 0, None), (r"Could not find suitable distribution for Requirement.parse\('([a-zA-Z\-\.]*)", 0, None),
@@ -296,12 +288,10 @@ class Config(object):
(r"No rule to make target `(.*)',", 0, None), (r"No rule to make target `(.*)',", 0, None),
(r"Package (.*) was not found in the pkg-config search path.", 0, 'pkgconfig'), (r"Package (.*) was not found in the pkg-config search path.", 0, 'pkgconfig'),
(r"Package '([a-zA-Z0-9\-:]*)', required by '.*', not found", 0, 'pkgconfig'), (r"Package '([a-zA-Z0-9\-:]*)', required by '.*', not found", 0, 'pkgconfig'),
(r"The file `([a-zA-Z0-9\-:]*)\.pc` needs to be installed and the PKG_CONFIG_PATH environment variable must contain its parent directory\.", 0, 'pkgconfig'),
(r"Package which this enhances but not available for checking: [']([a-zA-Z0-9\-]*)[']", 0, 'R'), (r"Package which this enhances but not available for checking: [']([a-zA-Z0-9\-]*)[']", 0, 'R'),
(r"Perhaps you should add the directory containing `([a-zA-Z0-9\-:]*)\.pc'", 0, 'pkgconfig'), (r"Perhaps you should add the directory containing `([a-zA-Z0-9\-:]*)\.pc'", 0, 'pkgconfig'),
(r"Program (.*) found: NO", 0, None), (r"Program (.*) found: NO", 0, None),
(r"Target '[a-zA-Z0-9\-]' can't be generated as '(.*)' could not be found", 0, None), (r"Target '[a-zA-Z0-9\-]' can't be generated as '(.*)' could not be found", 0, None),
(r"The missing Perl modules are:\s*(\S+)", 0, 'perl'),
(r"Unable to `import (.*)`", 0, None), (r"Unable to `import (.*)`", 0, None),
(r"Unable to find '(.*)'", 0, None), (r"Unable to find '(.*)'", 0, None),
(r"Warning: prerequisite ([a-zA-Z:]+) [0-9\.]+ not found.", 0, 'perl'), (r"Warning: prerequisite ([a-zA-Z:]+) [0-9\.]+ not found.", 0, 'perl'),
@@ -322,7 +312,6 @@ class Config(object):
(r"checking for [a-zA-Z0-9\_\-]+ in (.*?)\.\.\. no", 0, None), (r"checking for [a-zA-Z0-9\_\-]+ in (.*?)\.\.\. no", 0, None),
(r"checking for library containing (.*)... no", 0, None), (r"checking for library containing (.*)... no", 0, None),
(r"checking for perl module ([a-zA-Z:]+) [0-9\.]+... no", 0, 'perl'), (r"checking for perl module ([a-zA-Z:]+) [0-9\.]+... no", 0, 'perl'),
("checking if (.*) is available...", 0, None),
(r"configure: error: (?:pkg-config missing|Unable to locate) (.*)", 0, None), (r"configure: error: (?:pkg-config missing|Unable to locate) (.*)", 0, None),
(r"configure: error: ([a-zA-Z0-9]+) (?:is required to build|not found)", 0, None), (r"configure: error: ([a-zA-Z0-9]+) (?:is required to build|not found)", 0, None),
(r"configure: error: Cannot find (.*)\. Make sure", 0, None), (r"configure: error: Cannot find (.*)\. Make sure", 0, None),
@@ -348,7 +337,7 @@ class Config(object):
def detect_build_from_url(self, url): def detect_build_from_url(self, url):
"""Detect build patterns and build requirements from the patterns detected in the url.""" """Detect build patterns and build requirements from the patterns detected in the url."""
# R package # R package
if "cran.r-project.org" in url or "cran.rstudio.com" in url or "/pub/cran/" in url: if "cran.r-project.org" in url or "cran.rstudio.com" in url:
self.set_build_pattern("R", 10) self.set_build_pattern("R", 10)
# python # python
@@ -445,24 +434,20 @@ class Config(object):
# next the options # next the options
config_f['autospec'] = {} config_f['autospec'] = {}
for fname, comment in sorted(self.config_options.items()): for fname, comment in sorted(self.config_options.items()):
fpath = os.path.join(self.download_path, fname)
config_f.set('autospec', '# {}'.format(comment)) config_f.set('autospec', '# {}'.format(comment))
if os.path.isfile(fpath): if os.path.exists(fname):
config_f['autospec'][fname] = 'true' config_f['autospec'][fname] = 'true'
os.remove(fpath) os.remove(fname)
else: else:
config_f['autospec'][fname] = 'false' config_f['autospec'][fname] = 'false'
# default lto to true for new things # default lto to true for new things
config_f['autospec']['use_lto'] = 'true' config_f['autospec']['use_lto'] = 'true'
# default autoupdate to true for new things
config_f['autospec']['autoupdate'] = 'true'
# renamed options need special care # renamed options need special care
skip_path = os.path.join(self.download_path, "skip_test_suite") if os.path.exists("skip_test_suite"):
if os.path.exists(skip_path):
config_f['autospec']['skip_tests'] = 'true' config_f['autospec']['skip_tests'] = 'true'
os.remove(skip_path) os.remove("skip_test_suite")
self.write_config(config_f) self.write_config(config_f)
def create_buildreq_cache(self, version, buildreqs_cache): def create_buildreq_cache(self, version, buildreqs_cache):
@@ -493,7 +478,7 @@ class Config(object):
config_f = configparser.ConfigParser(interpolation=None) config_f = configparser.ConfigParser(interpolation=None)
config_f.read(opts_path) config_f.read(opts_path)
if "autospec" not in config_f.sections(): if "autospec" not in config_f.sections():
print_fatal("Missing autospec section in options.conf") print("Missing autospec section in options.conf")
sys.exit(1) sys.exit(1)
if 'package' in config_f.sections() and config_f['package'].get('alias'): if 'package' in config_f.sections() and config_f['package'].get('alias'):
@@ -715,7 +700,7 @@ class Config(object):
config.read(self.config_file) config.read(self.config_file)
if "autospec" not in config.sections(): if "autospec" not in config.sections():
print_fatal("Missing autospec section..") print("Missing autospec section..")
sys.exit(1) sys.exit(1)
self.git_uri = config['autospec'].get('git', None) self.git_uri = config['autospec'].get('git', None)
@@ -838,18 +823,6 @@ class Config(object):
except Exception as e: except Exception as e:
print_warning(f"Unable to remove buildreq_cache file: {e}") print_warning(f"Unable to remove buildreq_cache file: {e}")
invalid_release_sig_file = os.path.join(self.download_path, "invalid_release_sig")
content = self.read_conf_file(invalid_release_sig_file)
if content and content[0] == version:
self.config_opts['verify_required'] = False
else:
try:
os.unlink(invalid_release_sig_file)
except FileNotFoundError:
pass
except Exception as e:
print_warning(f"Unable to remove invalid_release_sig file: {e}")
content = self.read_conf_file(os.path.join(self.download_path, "pkgconfig_add")) content = self.read_conf_file(os.path.join(self.download_path, "pkgconfig_add"))
for extra in content: for extra in content:
extra = pkgconfig_re.sub(r'\1', extra) extra = pkgconfig_re.sub(r'\1', extra)
@@ -1010,15 +983,6 @@ class Config(object):
if not license.add_license(word, self.license_translations, self.license_blacklist): if not license.add_license(word, self.license_translations, self.license_blacklist):
print_warning("{}: blacklisted license {} ignored.".format(self.content.name + ".license", word)) print_warning("{}: blacklisted license {} ignored.".format(self.content.name + ".license", word))
content = self.read_conf_file(os.path.join(self.download_path, "license_skips"))
if content:
self.license_skips = self.validate_extras_content(content, "license_skips")
# cargo_vendors is the output of 'cargo vendor' and should be read as is
content = self.read_file(os.path.join(self.download_path, "cargo_vendors"), track=True)
if content:
self.cargo_vendors = "".join(content)
if self.config_opts['use_clang']: if self.config_opts['use_clang']:
self.config_opts['funroll-loops'] = False self.config_opts['funroll-loops'] = False
requirements.add_buildreq("llvm") requirements.add_buildreq("llvm")
@@ -1037,7 +1001,6 @@ class Config(object):
requirements.add_buildreq("openssh") requirements.add_buildreq("openssh")
self.prep_prepend = self.read_script_file(os.path.join(self.download_path, "prep_prepend")) self.prep_prepend = self.read_script_file(os.path.join(self.download_path, "prep_prepend"))
self.copy_prepend = self.read_script_file(os.path.join(self.download_path, "copy_prepend"))
if os.path.isfile(os.path.join(self.download_path, "prep_append")): if os.path.isfile(os.path.join(self.download_path, "prep_append")):
os.rename(os.path.join(self.download_path, "prep_append"), os.path.join(self.download_path, "build_prepend")) os.rename(os.path.join(self.download_path, "prep_append"), os.path.join(self.download_path, "build_prepend"))
self.make_prepend = self.read_script_file(os.path.join(self.download_path, "make_prepend")) self.make_prepend = self.read_script_file(os.path.join(self.download_path, "make_prepend"))
+7
View File
@@ -71,8 +71,14 @@ def sanitize_counts():
"""Validate test counts are within sane bounds.""" """Validate test counts are within sane bounds."""
global total_tests global total_tests
global total_pass global total_pass
global total_fail
global total_xfail
global total_skip
global counted_tests global counted_tests
global counted_pass global counted_pass
global counted_fail
global counted_xfail
global counted_skip
if total_tests > 0 and total_pass == 0: if total_tests > 0 and total_pass == 0:
total_pass = total_tests - total_fail - total_skip - total_xfail total_pass = total_tests - total_fail - total_skip - total_xfail
@@ -164,6 +170,7 @@ def parse_log(log, pkgname=''):
global total_fail global total_fail
global total_xfail global total_xfail
global total_skip global total_skip
global counted_tests
global counted_pass global counted_pass
global counted_fail global counted_fail
global counted_xfail global counted_xfail
-12
View File
@@ -124,9 +124,7 @@ ACL_TYPE_EXTENDED, acl-dev
ALSA, alsa-lib-dev ALSA, alsa-lib-dev
APR, apr-dev APR, apr-dev
APR-util, apr-util-dev APR-util, apr-util-dev
ARPACK-NG, arpack-ng-dev
ASSIMP, assimp-dev ASSIMP, assimp-dev
Adwaita, libadwaita-dev
Analitza, analitza-dev Analitza, analitza-dev
Analitza5, analitza-dev Analitza5, analitza-dev
BABL, babl-dev BABL, babl-dev
@@ -177,7 +175,6 @@ EXPAT, expat-dev
Eet.h, eet-dev Eet.h, eet-dev
Eigen/Core, eigen-dev Eigen/Core, eigen-dev
Eigen/Dense, eigen-dev Eigen/Dense, eigen-dev
Eigen/Sparse, eigen-dev
Eigen3, eigen-dev Eigen3, eigen-dev
Epoxy, pkgconfig(epoxy) Epoxy, pkgconfig(epoxy)
Exiv2, exiv2-dev Exiv2, exiv2-dev
@@ -287,7 +284,6 @@ GSTREAMER, gstreamer-dev
GSettingSchemas, gsettings-desktop-schemas GSettingSchemas, gsettings-desktop-schemas
GSettingSchemas, gsettings-desktop-schemas-dev GSettingSchemas, gsettings-desktop-schemas-dev
GTK, gtk+-dev GTK, gtk+-dev
GTK4, gtk4-dev
GnuTLS, gnutls-dev GnuTLS, gnutls-dev
GooglePerftools, gperftools-dev GooglePerftools, gperftools-dev
Gperf, gperf Gperf, gperf
@@ -463,7 +459,6 @@ KF6NewStuff, knewstuff-def
KF6Notifications, knotifications-dev KF6Notifications, knotifications-dev
KF6NotifyConfig, knotifyconfig-dev KF6NotifyConfig, knotifyconfig-dev
KF6Package, kpackage-dev KF6Package, kpackage-dev
KF6Prison, kprison-dev
KF6Purpose, purpose-dev KF6Purpose, purpose-dev
KF6QuickCharts, kquickcharts-dev KF6QuickCharts, kquickcharts-dev
KF6Runner, krunner-dev KF6Runner, krunner-dev
@@ -553,7 +548,6 @@ NETTLE, nettle-dev
NUMA, numactl-dev NUMA, numactl-dev
Nepomuk, nepomuk-core-dev Nepomuk, nepomuk-core-dev
NetworkManager, NetworkManager-dev NetworkManager, NetworkManager-dev
Nice, libnice-dev
NumPy, pypi-numpy NumPy, pypi-numpy
Numa, numactl-dev Numa, numactl-dev
OPENEXR, openexr-dev OPENEXR, openexr-dev
@@ -627,7 +621,6 @@ Qt5Xdg, libqtxdg-dev
Qt5XdgIconLoader, libqtxdg-dev Qt5XdgIconLoader, libqtxdg-dev
Qt5XmlPatterns, qtxmlpatterns-dev Qt5XmlPatterns, qtxmlpatterns-dev
Qt6Positioning, qt6positioning-dev Qt6Positioning, qt6positioning-dev
Qt6Qml, qt6declarative-dev
Qt6Quick, qt6declarative-dev Qt6Quick, qt6declarative-dev
Qt6QuickTimeline, qt6quicktimeline-dev Qt6QuickTimeline, qt6quicktimeline-dev
Qt6ShaderTools, qt6shadertools-dev Qt6ShaderTools, qt6shadertools-dev
@@ -657,7 +650,6 @@ Soprano, soprano-dev
SpatialIndex, libspatialindex-dev SpatialIndex, libspatialindex-dev
Sphinx, pypi-sphinx Sphinx, pypi-sphinx
Sqlite, sqlite-autoconf-dev Sqlite, sqlite-autoconf-dev
Srtp2, libsrtp-dev
Startup notification library, libnotify-dev Startup notification library, libnotify-dev
TBB, tbb-dev TBB, tbb-dev
TIFF, tiff-dev TIFF, tiff-dev
@@ -1132,7 +1124,6 @@ libsecret-unstable, libsecret-dev
libsoup-2.4, libsoup-dev libsoup-2.4, libsoup-dev
libssh, libssh-dev libssh, libssh-dev
libssh2.h, libssh2-dev libssh2.h, libssh2-dev
libssl, openssl-dev
libsystemd, pkgconfig(systemd) libsystemd, pkgconfig(systemd)
libtirpc (via pkg-config), pkgconfig(libtirpc) libtirpc (via pkg-config), pkgconfig(libtirpc)
libudev.h, systemd-dev libudev.h, systemd-dev
@@ -1307,8 +1298,6 @@ pycparser, pypi(pycparser)
pycurl, pypi(pycurl) pycurl, pypi(pycurl)
pylint, pypi(pylint) pylint, pypi(pylint)
pyperclip, pypi(pyperclip) pyperclip, pypi(pyperclip)
pypi(openvino), openvino-python3
pypi(pytorch), pytorch-python3
pytest, pypi-pytest pytest, pypi-pytest
pytest-cov, pypi(pytest_cov) pytest-cov, pypi(pytest_cov)
python lxml, pypi(lxml) python lxml, pypi(lxml)
@@ -1503,7 +1492,6 @@ yaml-cpp, yaml-cpp-dev
yarg, pypi-yarg yarg, pypi-yarg
yasm, yasm yasm, yasm
yytext is a pointer, flex yytext is a pointer, flex
zconf.h, zlib-dev
zenity, zenity zenity, zenity
zip, zip zip, zip
zlib, zlib-dev zlib, zlib-dev
+28 -2
View File
@@ -197,6 +197,33 @@ class FileManager(object):
return removed return removed
def globlike_match(self, filename, match_name):
"""Compare the filename to the match_name in a way that simulates the shell glob '*'."""
fsplit = filename.split('/')
if len(fsplit) != len(match_name):
return False
match = True
for fpart, mpart in zip(fsplit, match_name):
if fpart != mpart:
if '*' not in mpart:
match = False
break
if len(mpart) > len(fpart) + 1:
match = False
break
mpl, mpr = mpart.split('*')
try:
if fpart.index(mpl) != 0:
match = False
break
if fpart.rindex(mpr) != len(fpart) - len(mpr):
match = False
break
except ValueError:
match = False
break
return match
def push_file(self, filename, pkg_name): def push_file(self, filename, pkg_name):
"""Perform a number of checks against the filename and push the filename if appropriate.""" """Perform a number of checks against the filename and push the filename if appropriate."""
if filename in self.files or filename in self.files_blacklist: if filename in self.files or filename in self.files_blacklist:
@@ -218,7 +245,7 @@ class FileManager(object):
elif len('/'.join(match_name)) <= (len(norm_filename) + 1): elif len('/'.join(match_name)) <= (len(norm_filename) + 1):
# the match name may be 1 longer due to a glob # the match name may be 1 longer due to a glob
# being able to match an empty string # being able to match an empty string
if util.globlike_match(norm_filename, match_name): if self.globlike_match(norm_filename, match_name):
path_prefix = '/' if not match else match.group() path_prefix = '/' if not match else match.group()
self.push_package_file(os.path.join(path_prefix, *match_name), k) self.push_package_file(os.path.join(path_prefix, *match_name), k)
return return
@@ -377,7 +404,6 @@ class FileManager(object):
(r"^/lib/systemd/user/", "services"), (r"^/lib/systemd/user/", "services"),
(r"^/usr/lib/systemd/system/", "services"), (r"^/usr/lib/systemd/system/", "services"),
(r"^/usr/lib/systemd/user/", "services"), (r"^/usr/lib/systemd/user/", "services"),
(r"^/usr/lib/udev/hwdb.d", "config"),
(r"^/usr/lib/udev/rules.d", "config"), (r"^/usr/lib/udev/rules.d", "config"),
(r"^/usr/lib/modules-load.d", "config"), (r"^/usr/lib/modules-load.d", "config"),
(r"^/usr/lib/tmpfiles.d", "config"), (r"^/usr/lib/tmpfiles.d", "config"),
+1
View File
@@ -113,6 +113,7 @@ def commit_to_git(config, name, success):
call("git add whatrequires", check=False, stderr=subprocess.DEVNULL, cwd=path) call("git add whatrequires", check=False, stderr=subprocess.DEVNULL, cwd=path)
call("git add description", check=False, stderr=subprocess.DEVNULL, cwd=path) call("git add description", check=False, stderr=subprocess.DEVNULL, cwd=path)
call("git add attrs", check=False, stderr=subprocess.DEVNULL, cwd=path) call("git add attrs", check=False, stderr=subprocess.DEVNULL, cwd=path)
call("git add archive.diff", check=False, stderr=subprocess.DEVNULL, cwd=path)
# remove deprecated config files # remove deprecated config files
call("git rm make_install_append", check=False, stderr=subprocess.DEVNULL, cwd=path) call("git rm make_install_append", check=False, stderr=subprocess.DEVNULL, cwd=path)
+17 -29
View File
@@ -29,7 +29,7 @@ import urllib.parse
import chardet import chardet
import download import download
import util from util import get_contents, get_sha1sum, print_fatal, print_warning
default_license = "TO BE DETERMINED" default_license = "TO BE DETERMINED"
@@ -55,6 +55,8 @@ def add_license(lic, translations, blacklist):
presence in the blacklist. Returns False if no license were added, True presence in the blacklist. Returns False if no license were added, True
otherwise. otherwise.
""" """
global licenses
global license_files
lic = lic.strip().strip(',') lic = lic.strip().strip(',')
result = False result = False
@@ -94,7 +96,7 @@ def decode_license(license):
def license_from_copying_hash(copying, srcdir, config, name): def license_from_copying_hash(copying, srcdir, config, name):
"""Add licenses based on the hash of the copying file.""" """Add licenses based on the hash of the copying file."""
try: try:
data = util.get_contents(copying) data = get_contents(copying)
except FileNotFoundError: except FileNotFoundError:
# LICENSE file is a bad symlink (qemu-4.2.0!) # LICENSE file is a bad symlink (qemu-4.2.0!)
return return
@@ -107,7 +109,7 @@ def license_from_copying_hash(copying, srcdir, config, name):
if not data: if not data:
return return
hash_sum = util.get_sha1sum(copying) hash_sum = get_sha1sum(copying)
if config.license_fetch: if config.license_fetch:
values = {'hash': hash_sum, 'text': data, 'package': name} values = {'hash': hash_sum, 'text': data, 'package': name}
@@ -140,24 +142,9 @@ def license_from_copying_hash(copying, srcdir, config, name):
else: else:
if not config.license_show: if not config.license_show:
return return
util.print_warning("Unknown license {0} with hash {1}".format(copying, hash_sum)) print_warning("Unknown license {0} with hash {1}".format(copying, hash_sum))
hash_url = config.license_show % {'HASH': hash_sum} hash_url = config.license_show % {'HASH': hash_sum}
util.print_warning("Visit {0} to enter".format(hash_url)) print_warning("Visit {0} to enter".format(hash_url))
def skip_license(license_path, config):
"""Check if a given license file path should be skipped."""
skip_name = False
for skip in config.license_skips:
# handle the common tempfile prefix and normalize for
# skip lines without a starting '/'
skip = skip if skip[0] != '' else skip[1:]
skip_path = ['', 'tmp', '*'] + skip
if util.globlike_match(license_path, skip_path):
util.print_warning(f"Skip license detected for file at {license_path}")
skip_name = True
break
return skip_name
def scan_for_licenses(srcdir, config, pkg_name): def scan_for_licenses(srcdir, config, pkg_name):
@@ -175,13 +162,12 @@ def scan_for_licenses(srcdir, config, pkg_name):
"about_bsd.txt"] "about_bsd.txt"]
# look for files that start with copying or licen[cs]e (but are # look for files that start with copying or licen[cs]e (but are
# not likely scripts) or end with licen[cs]e # not likely scripts) or end with licen[cs]e
target_pat = re.compile(r"^((copying)|(licen[cs]e)|(e[dp]l-v\d+))|(licen[cs]e)(\.(txt|xml))?|(intel simplified software license.*\.txt)$") target_pat = re.compile(r"^((copying)|(licen[cs]e)|(e[dp]l-v\d+))|(licen[cs]e)(\.(txt|xml))?$")
for dirpath, dirnames, files in os.walk(srcdir): for dirpath, dirnames, files in os.walk(srcdir):
for name in files: for name in files:
if name.lower() in targets or target_pat.search(name.lower()): if name.lower() in targets or target_pat.search(name.lower()):
license_path = os.path.join(dirpath, name) license_from_copying_hash(os.path.join(dirpath, name),
if not skip_license(license_path, config): srcdir, config, pkg_name)
license_from_copying_hash(license_path, srcdir, config, pkg_name)
# Also search for license texts in project trees that are # Also search for license texts in project trees that are
# REUSE-compliant, or are in process of adopting this standard (for # REUSE-compliant, or are in process of adopting this standard (for
# example, KDE ecosystem packages). See https://reuse.software for # example, KDE ecosystem packages). See https://reuse.software for
@@ -192,13 +178,12 @@ def scan_for_licenses(srcdir, config, pkg_name):
# seen in the DPDK 20.11.3 tree, where the `LICENSES` directory is # seen in the DPDK 20.11.3 tree, where the `LICENSES` directory is
# named `license` instead. # named `license` instead.
dirbase = os.path.basename(dirpath) dirbase = os.path.basename(dirpath)
if re.search(r'^(LICENSES|licenses?|licensing)$', dirbase) and re.search(r'\.txt$', name): if re.search(r'^(LICENSES|licenses?)$', dirbase) and re.search(r'\.txt$', name):
license_path = os.path.join(dirpath, name) license_from_copying_hash(os.path.join(dirpath, name),
if not skip_license(license_path, config): srcdir, config, pkg_name)
license_from_copying_hash(license_path, srcdir, config, pkg_name)
if not licenses: if not licenses:
util.print_fatal(" Cannot find any license or a valid {}.license file!\n".format(pkg_name)) print_fatal(" Cannot find any license or a valid {}.license file!\n".format(pkg_name))
sys.exit(1) sys.exit(1)
print("Licenses : ", " ".join(sorted(licenses))) print("Licenses : ", " ".join(sorted(licenses)))
@@ -206,6 +191,9 @@ def scan_for_licenses(srcdir, config, pkg_name):
def load_specfile(specfile): def load_specfile(specfile):
"""Get licenses from the specfile content.""" """Get licenses from the specfile content."""
global licenses
global license_files
global hashes
specfile.licenses = licenses if licenses else [default_license] specfile.licenses = licenses if licenses else [default_license]
specfile.license_files = sorted(license_files) specfile.license_files = sorted(license_files)
specfile.hashes = hashes specfile.hashes = hashes
+11 -43
View File
@@ -3,12 +3,12 @@
# This file is sorted with LC_COLLATE=C # This file is sorted with LC_COLLATE=C
# Lines beginning with '#' are ignored. # Lines beginning with '#' are ignored.
# For strings that start with '#', escape the '#' as '\#'. # For strings that start with '#', escape the '#' as '\#'.
=========================
% %
%license %license
(LGPL) (LGPL)
(new) (new)
(specified (specified
*
+ +
- -
-MIT -MIT
@@ -26,8 +26,6 @@
3-Clause 3-Clause
3-clause 3-clause
3BSD 3BSD
=========================
>=-2
@CPACK_RPM_PACKAGE_LICENSE@ @CPACK_RPM_PACKAGE_LICENSE@
AGPLv3+ AGPLv3+
ALv2 ALv2
@@ -37,12 +35,7 @@ APPLICATION__TYPE
ASL ASL
Artistic Artistic
BSD BSD
BSD(2
BSD(3 BSD(3
BSD-2-Clause-Views
BSD-3
BSD-compatible
BSD-derived(Repoze)
BSD-like BSD-like
BSD-style BSD-style
BSDL BSDL
@@ -50,7 +43,6 @@ BSD_3_clause
BSDish BSDish
BSL BSL
CC-BY CC-BY
Clause
Commercial Commercial
Corp. Corp.
Distribution Distribution
@@ -61,7 +53,6 @@ EPL
Eclipse Eclipse
Expat(MIT/X11) Expat(MIT/X11)
Expat/MIT Expat/MIT
FOUNDATION
Foundation Foundation
FreeBSD FreeBSD
GENERAL GENERAL
@@ -69,39 +60,30 @@ GFDL
GNU GNU
GPL GPL
GPL+ GPL+
GPL-1.0-only
GPL/BSD GPL/BSD
GPL/BSD/CPL GPL/BSD/CPL
GPLv2.1 GPLv2.1
General General
IBM IBM
Jupyter
LESSER LESSER
LGPL LGPL
LGPL+BSD LGPL+BSD
LGPL/MIT LGPL/MIT
LICENCE LICENCE
Lesser Lesser
Library
Licences Licences
License License
License(2.0) License(2.0)
License(==-2.0) License(==-2.0)
License(>=-2)
License(>=-2.0) License(>=-2.0)
License(LGPL)
License(MIT)
License, License,
License-2 License-2
License-2.0 License-2.0
License-2.0(MPL-2.0) License-2.0(MPL-2.0)
License-3(GPLv3)
Licensing Licensing
Lucent Lucent
MIT-0
MIT/Expat MIT/Expat
MPL MPL
Minpack
Modified Modified
Mozilla Mozilla
Muddy-MIT Muddy-MIT
@@ -113,13 +95,9 @@ Open
PIL PIL
PSF-2+ PSF-2+
PUBLIC PUBLIC
PYTHON
Permission
Public Public
Revised Revised
SIL SIL
SIP
SOFTWARE
See See
Set Set
Software Software
@@ -133,46 +111,31 @@ UNKNOWN
Unknown Unknown
Unkown Unkown
Unlimited Unlimited
VERSION-2
Version Version
Version-2.0 Version-2.0
Version-3
WITH
What What
\# \#
a
advertising advertising
and and
any any
bsd bsd
charge
classifiers) classifiers)
clause) clause)
copy
cryptsetup-OpenSSL-exception
details details
domain domain
domain.
dual dual
exceptions exceptions
for for
free
gpl gpl
granted
hereby
http://nmap.org/man/man-legal.html http://nmap.org/man/man-legal.html
into
is is
it it
later later
later(LGPLv2+) later(LGPLv2+)
license license
licensing
ndg/httpsclient/LICENCE ndg/httpsclient/LICENCE
new new
none none
obtaining
of
on on
open_source open_source
option option
@@ -180,16 +143,11 @@ option)
or or
or(at or(at
others others
person
public public
released
software
style style
terms terms
the the
to
under? under?
unencumbered
unknown unknown
unrestricted unrestricted
uses uses
@@ -202,3 +160,13 @@ with
your your
| |
~ ~
Permission
a
charge
copy
granted
hereby
obtaining
of
person
to
-2
View File
@@ -16,11 +16,9 @@ Apache License 2.0, Apache-2.0
Apache License, Version 2.0, Apache-2.0 Apache License, Version 2.0, Apache-2.0
Apache, Apache-2.0 Apache, Apache-2.0
Apache-2, Apache-2.0 Apache-2, Apache-2.0
Apache2, Apache-2.0
Apache2.0, Apache-2.0 Apache2.0, Apache-2.0
Apachev2, Apache-2.0 Apachev2, Apache-2.0
Artistic-1.0+GPL-1.0, Artistic-1.0 GPL-1.0 Artistic-1.0+GPL-1.0, Artistic-1.0 GPL-1.0
Artistic/GPL, Artistic-1.0-Perl GPL-1.0-or-later
Artistic_2, Artistic-2.0 Artistic_2, Artistic-2.0
BSD(3-clause), BSD-3-Clause BSD(3-clause), BSD-3-Clause
BSD-2-clause, BSD-2-Clause BSD-2-clause, BSD-2-Clause
+10 -9
View File
@@ -42,7 +42,7 @@ KEYID_TRY = ""
KEYID = "" KEYID = ""
IMPORTED = "" IMPORTED = ""
EMAIL = "" EMAIL = ""
GNUPGCONF = """keyserver keyserver.ubuntu.com""" GNUPGCONF = """keyserver keys.gnupg.net"""
CMD_TIMEOUT = 20 CMD_TIMEOUT = 20
ENV = os.environ ENV = os.environ
INPUT_GETTER_TIMEOUT = 60 INPUT_GETTER_TIMEOUT = 60
@@ -96,7 +96,7 @@ class GPGCli(object):
util.write_out(os.path.join(_gpghome, 'gpg.conf'), GNUPGCONF) util.write_out(os.path.join(_gpghome, 'gpg.conf'), GNUPGCONF)
if pubkey is not None: if pubkey is not None:
args = self.args + ['--import', pubkey] args = self.args + ['--import', pubkey]
_, err, code = self.exec_cmd(args) output, err, code = self.exec_cmd(args)
if code == -9: if code == -9:
raise Exception('Command {} timeout after {} seconds'.format(' '.join(args), CMD_TIMEOUT)) raise Exception('Command {} timeout after {} seconds'.format(' '.join(args), CMD_TIMEOUT))
elif code != 0: elif code != 0:
@@ -205,22 +205,23 @@ class Verifier(object):
@staticmethod @staticmethod
def quit(): def quit():
"""Stop verification.""" """Stop verification."""
util.print_fatal("Verification required for build (verify_required option set)") print('Critical error quitting...')
print(SEPT) print(SEPT)
sys.exit(1) exit(1)
@staticmethod @staticmethod
def calc_sum(filepath, digest_algo): def calc_sum(filepath, digest_algo):
"""Use digest_algo to calculate block sum of a file.""" """Use digest_algo to calculate block sum of a file."""
block_size = 4096 BLOCK_SIZE = 4096
with open(filepath, 'rb') as fp: with open(filepath, 'rb') as fp:
digest = digest_algo() digest = digest_algo()
for block in iter(lambda: fp.read(block_size), b''): for block in iter(lambda: fp.read(BLOCK_SIZE), b''):
digest.update(block) digest.update(block)
return digest.hexdigest() return digest.hexdigest()
def print_result(self, result, err_msg=''): def print_result(self, result, err_msg=''):
"""Display verification results.""" """Display verification results."""
global EMAIL
package_name = '' package_name = ''
if self.url is not None: if self.url is not None:
package_name = os.path.basename(self.url) package_name = os.path.basename(self.url)
@@ -263,12 +264,12 @@ def get_signature_file(package_url, package_path):
def compare_keys(newkey, oldkey): def compare_keys(newkey, oldkey):
"""Key comparison to check against key tampering.""" """Key comparison to check against key tampering."""
if newkey != oldkey: if newkey != oldkey:
util.print_fatal('Public key has changed:\n' util.print_error('Public key has changed:\n'
' old key: {}\n' ' old key: {}\n'
' new key: {}\n' ' new key: {}\n'
'this is a critical security error, quitting...' 'this is a critical security error, quitting...'
.format(oldkey, newkey)) .format(oldkey, newkey))
sys.exit(1) exit(1)
# sha256sum Verifier # sha256sum Verifier
@@ -520,6 +521,7 @@ class GPGVerifier(Verifier):
def quit_verify(): def quit_verify():
"""Halt build due to verification being required.""" """Halt build due to verification being required."""
util.print_error("Verification required for build (verify_required option set)")
Verifier.quit() Verifier.quit()
@@ -530,7 +532,6 @@ VERIFIER_TYPES = {
'.bz2': GPGVerifier, '.bz2': GPGVerifier,
'.xz': GPGVerifier, '.xz': GPGVerifier,
'.zip': GPGVerifier, '.zip': GPGVerifier,
'.zst': GPGVerifier,
} }
+6 -13
View File
@@ -27,15 +27,6 @@ def pkg_search(name):
return False return False
def fixup_pypi_prefix(name):
"""Try and chop off the 'pypi-' or 'python-' prefix for names."""
name = name.lower().replace('-', '_')
for prefix in ["pypi_", "python_"]:
if name.startswith(prefix):
name = name[len(prefix):]
return name
def get_pypi_name(name, miss=False): def get_pypi_name(name, miss=False):
"""Try and verify the pypi name for a given package name.""" """Try and verify the pypi name for a given package name."""
# normalize the name for matching as pypi is case insensitve for search # normalize the name for matching as pypi is case insensitve for search
@@ -44,9 +35,11 @@ def get_pypi_name(name, miss=False):
if pkg_search(name): if pkg_search(name):
return name return name
# Maybe we have a prefix # Maybe we have a prefix
name = fixup_pypi_prefix(name) for prefix in ["pypi_", "python_"]:
if pkg_search(name): if name.startswith(prefix):
return name name = name[len(prefix):]
if pkg_search(name):
return name
# Some cases where search fails (Sphinx) # Some cases where search fails (Sphinx)
# Just try the name we were given # Just try the name we were given
if miss: if miss:
@@ -117,7 +110,7 @@ def main():
pkg_name = sys.argv[1] pkg_name = sys.argv[1]
pypi_name = get_pypi_name(pkg_name) pypi_name = get_pypi_name(pkg_name)
if not pypi_name: if not pypi_name:
util.print_fatal(f"Couldn't find {pkg_name} in pypi") print(f"Couldn't find {pkg_name} in pypi")
sys.exit(1) sys.exit(1)
pypi_metadata = get_pypi_metadata(pypi_name) pypi_metadata = get_pypi_metadata(pypi_name)
print(pypi_metadata) print(pypi_metadata)
+71 -200
View File
@@ -26,8 +26,6 @@ import types
from collections import OrderedDict from collections import OrderedDict
import git import git
from jinja2 import Environment
from jinja2.loaders import DictLoader
from util import _file_write, open_auto from util import _file_write, open_auto
AVX2_CFLAGS = "-march=x86-64-v3" AVX2_CFLAGS = "-march=x86-64-v3"
@@ -37,9 +35,9 @@ AVX512_CFLAGS = "-march=x86-64-v4 -mprefer-vector-width=512"
AVX512_FCFLAGS = "-march=x86-64-v4 -mprefer-vector-width=256" AVX512_FCFLAGS = "-march=x86-64-v4 -mprefer-vector-width=256"
AVX512_LCFLAGS = "-march=x86-64-v4" AVX512_LCFLAGS = "-march=x86-64-v4"
AVX512_LFLAGS = "-Wl,-z,x86-64-v4" AVX512_LFLAGS = "-Wl,-z,x86-64-v4"
APX_CFLAGS = "-march=x86-64-v4 -mapxf" APX_CFLAGS = "-march=x86-64-v3 -mapxf -mavx10.1"
APX_LCFLAGS = "-march=x86-64-v4" APX_LCFLAGS = "-march=x86-64-v3"
APX_LFLAGS = "-Wl,-z,x86-64-v4" APX_LFLAGS = "-Wl,-z,x86-64-v3"
class Specfile(object): class Specfile(object):
@@ -75,42 +73,12 @@ class Specfile(object):
def write_spec(self): def write_spec(self):
"""Write spec file.""" """Write spec file."""
spec_path = f"{os.path.join(self.config.download_path, self.name)}.spec" self.specfile = open_auto("{}/{}.spec".format(self.config.download_path, self.name), "w")
self.specfile = open_auto(spec_path, "w")
self.specfile.write_strip = types.MethodType(_file_write, self.specfile) self.specfile.write_strip = types.MethodType(_file_write, self.specfile)
# last chance to sanitize url for template and build types
if self.config.urlban:
clean_url = re.sub(self.config.urlban, "localhost", self.url)
# Duplicate prefixes entry before we change the url
self.content.prefixes[clean_url] = self.content.prefixes.get(self.url)
self.url = clean_url
template_path = f"{spec_path}.template"
if os.path.isfile(template_path):
# make templates have a template build pattern
self.config.default_pattern = "template"
# spec file comment header # spec file comment header
self.write_comment_header() self.write_comment_header()
if os.path.isfile(template_path):
with open_auto(template_path) as tfile:
template_content = tfile.read()
template = Environment(loader=DictLoader({'spec': template_content})).get_template('spec')
kw = {
'package_name': self.name,
'package_version': self.version,
'package_url': self.url,
'package_release': self.release,
}
self.specfile.write(template.render(**kw))
self.specfile.write_strip('\n')
self.specfile.close()
# return specfile type built so autospec knows how to
# handle build results (template should only builds once)
return "template"
if self.config.config_opts.get('keepstatic'): if self.config.config_opts.get('keepstatic'):
self._write("%define keepstatic 1\n") self._write("%define keepstatic 1\n")
@@ -142,10 +110,6 @@ class Specfile(object):
self.specfile.close() self.specfile.close()
# return specfile type built so autospec knows how to
# handle build results (generate has multiple builds)
return "generate"
def write_comment_header(self): def write_comment_header(self):
"""Write comment header to spec file.""" """Write comment header to spec file."""
self._write("#\n") self._write("#\n")
@@ -168,6 +132,11 @@ class Specfile(object):
def write_nvr(self): def write_nvr(self):
"""Write name, version, and release information.""" """Write name, version, and release information."""
if self.config.urlban:
clean_url = re.sub(self.config.urlban, "localhost", self.url)
# Duplicate prefixes entry before we change the url
self.content.prefixes[clean_url] = self.content.prefixes.get(self.url)
self.url = clean_url
self._write("Name : {}\n".format(self.name)) self._write("Name : {}\n".format(self.name))
self._write("Version : {}\n".format(self.version)) self._write("Version : {}\n".format(self.version))
self._write("Release : {}\n".format(str(self.release))) self._write("Release : {}\n".format(str(self.release)))
@@ -326,9 +295,6 @@ class Specfile(object):
self._write("Group: Default\n") self._write("Group: Default\n")
for dep in deps.get(pkg, []): for dep in deps.get(pkg, []):
# honor requires_ban for manual overrides
if f"{self.name}-{dep}" in self.requirements.banned_requires.get(pkg, []):
continue
if dep in self.packages: if dep in self.packages:
self._write("Requires: {}-{} = %{{version}}-%{{release}}\n".format(self.name, dep)) self._write("Requires: {}-{} = %{{version}}-%{{release}}\n".format(self.name, dep))
@@ -448,8 +414,6 @@ class Specfile(object):
self._write_strip("## make_prepend end") self._write_strip("## make_prepend end")
if self.config.make_command: if self.config.make_command:
make = self.config.make_command make = self.config.make_command
elif self.config.config_opts['use_ninja']:
make = "ninja"
else: else:
make = "make" make = "make"
if build32: if build32:
@@ -466,11 +430,7 @@ class Specfile(object):
def write_cmake_line_openmpi(self): def write_cmake_line_openmpi(self):
"""Write cmake line (openmpi) to spec file.""" """Write cmake line (openmpi) to spec file."""
if self.config.config_opts['use_ninja']: cmake_string = 'cmake -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX=$MPI_ROOT -DCMAKE_INSTALL_SBINDIR=$MPI_BIN \\\n' \
cmake_type = "Ninja"
else:
cmake_type = "Unix Makefiles"
cmake_string = f"cmake -G '{cmake_type}' -DCMAKE_INSTALL_PREFIX=$MPI_ROOT -DCMAKE_INSTALL_SBINDIR=$MPI_BIN \\\n" \
'-DCMAKE_INSTALL_LIBDIR=$MPI_LIB -DCMAKE_INSTALL_INCLUDEDIR=$MPI_INCLUDE -DLIB_INSTALL_DIR=$MPI_LIB \\\n' \ '-DCMAKE_INSTALL_LIBDIR=$MPI_LIB -DCMAKE_INSTALL_INCLUDEDIR=$MPI_INCLUDE -DLIB_INSTALL_DIR=$MPI_LIB \\\n' \
'-DBUILD_SHARED_LIBS:BOOL=ON -DLIB_SUFFIX=64 \\\n' \ '-DBUILD_SHARED_LIBS:BOOL=ON -DLIB_SUFFIX=64 \\\n' \
'-DCMAKE_AR=/usr/bin/gcc-ar -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_RANLIB=/usr/bin/gcc-ranlib \\\n' '-DCMAKE_AR=/usr/bin/gcc-ar -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_RANLIB=/usr/bin/gcc-ranlib \\\n'
@@ -486,16 +446,12 @@ class Specfile(object):
self._write_strip(f"gpg --homedir .gnupg --status-fd 1 --verify {self.config.signature_macro} %{{SOURCE0}} > gpg.status") self._write_strip(f"gpg --homedir .gnupg --status-fd 1 --verify {self.config.signature_macro} %{{SOURCE0}} > gpg.status")
self._write_strip(f"grep -E '^\\[GNUPG:\\] (GOODSIG|EXPKEYSIG) {self.keyid}' gpg.status") self._write_strip(f"grep -E '^\\[GNUPG:\\] (GOODSIG|EXPKEYSIG) {self.keyid}' gpg.status")
self.write_prep_prepend() self.write_prep_prepend()
prefix = self.content.prefixes[self.url]
if self.config.default_pattern == 'R': if self.config.default_pattern == 'R':
prefix = self.content.tarball_prefix prefix = self.content.tarball_prefix
self._write_strip("%setup -q -n " + prefix) self._write_strip("%setup -q -n " + prefix)
else: else:
prefix = self.content.prefixes[self.url] self._write_strip("%setup -q -n " + prefix)
if not prefix:
prefix = os.path.splitext(os.path.basename(self.url))[0]
self._write_strip("%setup -q -c -n " + prefix)
else:
self._write_strip("%setup -q -n " + prefix)
for archive in self.config.sources["archive"]: for archive in self.config.sources["archive"]:
# Handle various archive types # Handle various archive types
extract_cmd = 'tar xf {}' extract_cmd = 'tar xf {}'
@@ -503,11 +459,6 @@ class Specfile(object):
extract_cmd = 'unzip -q {}' extract_cmd = 'unzip -q {}'
if archive.endswith('.bz2') and not archive.endswith('.tar.bz2'): if archive.endswith('.bz2') and not archive.endswith('.tar.bz2'):
extract_cmd = 'bzcat {0} > $(basename "{0}" .bz2)' extract_cmd = 'bzcat {0} > $(basename "{0}" .bz2)'
if archive.endswith('.zst'):
if archive.endswith('.tar.zst'):
extract_cmd = 'tar -I zstd xf {}'
else:
extract_cmd = 'zstd -dqc {0} > $(basename "{0}" .zst)'
self._write_strip('cd %{_builddir}') self._write_strip('cd %{_builddir}')
archive_file = os.path.basename(archive) archive_file = os.path.basename(archive)
if self.config.archive_details.get(archive + "prefix"): if self.config.archive_details.get(archive + "prefix"):
@@ -540,43 +491,45 @@ class Specfile(object):
if not archive_prefix: if not archive_prefix:
# Make it up # Make it up
archive_prefix = os.path.splitext(os.path.basename(archive))[0] archive_prefix = os.path.splitext(os.path.basename(archive))[0]
self._write_strip("cp -r %{{_builddir}}/{0}/. %{{_builddir}}/{1}/{2}" self._write_strip("cp -r %{{_builddir}}/{0}/* %{{_builddir}}/{1}/{2}"
.format(archive_prefix, .format(archive_prefix,
self.content.tarball_prefix, self.content.tarball_prefix,
destination)) destination))
self.apply_patches() self.apply_patches()
# setup cargo.toml vendoring if needed # setup cargo.toml vendoring if needed
if self.config.cargo_vendors: if self.config.config_opts['cargo_vendor']:
if self.config.subdir: if self.config.subdir:
self._write_strip("pushd " + self.config.subdir) self._write_strip("pushd " + self.config.subdir)
self._write_strip("mkdir -p .cargo") self._write_strip("mkdir -p .cargo")
self._write_strip(f"echo '\n{self.config.cargo_vendors}' >> .cargo/config.toml") self._write_strip("echo '[source.crates-io]' >> .cargo/config.toml")
self._write_strip("""echo 'replace-with = "vendored-sources"' >> .cargo/config.toml""")
self._write_strip("echo '[source.vendored-sources]' >> .cargo/config.toml")
self._write_strip("""echo 'directory = "vendor"' >> .cargo/config.toml""")
if self.config.subdir: if self.config.subdir:
self._write_strip("popd") self._write_strip("popd")
self.write_copy_prepend() if self.config.default_pattern != 'cmake':
if self.config.config_opts['32bit']:
if self.config.config_opts['32bit']: self._write_strip("pushd ..")
self._write_strip("pushd ..") self._write_strip("cp -a {} build32".format(self.content.tarball_prefix))
self._write_strip("cp -a {} build32".format(self.content.tarball_prefix)) self._write_strip("popd")
self._write_strip("popd") if self.config.config_opts['use_avx2']:
if self.config.config_opts['use_avx2']: self._write_strip("pushd ..")
self._write_strip("pushd ..") self._write_strip("cp -a {} buildavx2".format(self.content.tarball_prefix))
self._write_strip("cp -a {} buildavx2".format(self.content.tarball_prefix)) self._write_strip("popd")
self._write_strip("popd") if self.config.config_opts['use_avx512']:
if self.config.config_opts['use_avx512']: self._write_strip("pushd ..")
self._write_strip("pushd ..") self._write_strip("cp -a {} buildavx512".format(self.content.tarball_prefix))
self._write_strip("cp -a {} buildavx512".format(self.content.tarball_prefix)) self._write_strip("popd")
self._write_strip("popd") if self.config.config_opts['use_apx']:
if self.config.config_opts['use_apx']: self._write_strip("pushd ..")
self._write_strip("pushd ..") self._write_strip("cp -a {} buildapx".format(self.content.tarball_prefix))
self._write_strip("cp -a {} buildapx".format(self.content.tarball_prefix)) self._write_strip("popd")
self._write_strip("popd") if self.config.config_opts['openmpi']:
if self.config.config_opts['openmpi']: self._write_strip("pushd ..")
self._write_strip("pushd ..") self._write_strip("cp -a {} build-openmpi".format(self.content.tarball_prefix))
self._write_strip("cp -a {} build-openmpi".format(self.content.tarball_prefix)) self._write_strip("popd")
self._write_strip("popd")
self._write_strip("\n") self._write_strip("\n")
def write_32bit_exports(self): def write_32bit_exports(self):
@@ -638,7 +591,7 @@ class Specfile(object):
if self.config.config_opts['use_clang']: if self.config.config_opts['use_clang']:
flags.extend(["-O3"]) flags.extend(["-O3"])
else: else:
flags.extend(["-fno-semantic-interposition", "-falign-functions=32"]) flags.extend(["-Ofast", "-fno-semantic-interposition", "-falign-functions=32"])
if not self.config.config_opts['full-debug-info'] and not self.config.config_opts['use_clang']: if not self.config.config_opts['full-debug-info'] and not self.config.config_opts['use_clang']:
flags.extend(["-gno-variable-location-views", "-gno-column-info", "-femit-struct-debug-baseonly", "-fdebug-types-section", "-gz=zstd", "-g1"]) flags.extend(["-gno-variable-location-views", "-gno-column-info", "-femit-struct-debug-baseonly", "-fdebug-types-section", "-gz=zstd", "-g1"])
if self.config.default_pattern != 'qmake' or self.config.default_pattern != 'qmake6': if self.config.default_pattern != 'qmake' or self.config.default_pattern != 'qmake6':
@@ -836,14 +789,6 @@ class Specfile(object):
self._write_strip("{}\n".format(line)) self._write_strip("{}\n".format(line))
self._write_strip("## prep_prepend end") self._write_strip("## prep_prepend end")
def write_copy_prepend(self):
"""Write out any custom supplied commands prior to creating source copies for avx, etc builds."""
if self.config.copy_prepend:
self._write_strip("## copy_prepend content")
for line in self.config.copy_prepend:
self._write_strip("{}\n".format(line))
self._write_strip("## copy_prepend end")
def write_build_prepend(self): def write_build_prepend(self):
"""Write out any custom supplied commands at the start of the %build section and every build type.""" """Write out any custom supplied commands at the start of the %build section and every build type."""
if self.config.build_prepend: if self.config.build_prepend:
@@ -959,11 +904,10 @@ class Specfile(object):
self._write_strip("export GOAMD64=v2") self._write_strip("export GOAMD64=v2")
if self.config.config_opts['use_ninja'] and self.config.install_macro == '%make_install': if self.config.subdir:
self.config.install_macro = '%ninja_install' self._write_strip("pushd " + self.config.subdir)
if self.config.config_opts['32bit']: if self.config.config_opts['32bit']:
self._write_strip("pushd ../build32/" + self.config.subdir)
self._write_strip("pushd clr-build32") self._write_strip("pushd clr-build32")
self._write_strip("{}32 {} {}".format(self.config.install_macro, self._write_strip("{}32 {} {}".format(self.config.install_macro,
self.config.extra_make_install, self.config.extra_make_install,
@@ -981,42 +925,30 @@ class Specfile(object):
self._write_strip(" popd") self._write_strip(" popd")
self._write_strip("fi") self._write_strip("fi")
self._write_strip("popd") self._write_strip("popd")
self._write_strip("popd")
if self.config.config_opts['use_avx2']: if self.config.config_opts['use_avx2']:
self._write_strip("pushd ../buildavx2/" + self.config.subdir)
self._write_strip("GOAMD64=v3") self._write_strip("GOAMD64=v3")
self._write_strip("pushd clr-build-avx2") self._write_strip("pushd clr-build-avx2")
self._write_strip("%s_v3 %s || :\n" % (self.config.install_macro, self.config.extra_make_install)) self._write_strip("%s_v3 %s || :\n" % (self.config.install_macro, self.config.extra_make_install))
self._write_strip("popd") self._write_strip("popd")
self._write_strip("popd")
if self.config.config_opts['use_avx512']: if self.config.config_opts['use_avx512']:
self._write_strip("pushd ../buildavx512/" + self.config.subdir)
self._write_strip("GOAMD64=v4") self._write_strip("GOAMD64=v4")
self._write_strip("pushd clr-build-avx512") self._write_strip("pushd clr-build-avx512")
self._write_strip("%s_v4 %s || :\n" % (self.config.install_macro, self.config.extra_make_install)) self._write_strip("%s_v4 %s || :\n" % (self.config.install_macro, self.config.extra_make_install))
self._write_strip("popd") self._write_strip("popd")
self._write_strip("popd")
if self.config.config_opts['use_apx']: if self.config.config_opts['use_apx']:
self._write_strip("pushd ../buildapx/" + self.config.subdir)
self._write_strip("GOAMD64=v3") self._write_strip("GOAMD64=v3")
self._write_strip("pushd clr-build-apx") self._write_strip("pushd clr-build-apx")
self._write_strip("%s_va %s || :\n" % (self.config.install_macro, self.config.extra_make_install)) self._write_strip("%s_va %s || :\n" % (self.config.install_macro, self.config.extra_make_install))
self._write_strip("popd") self._write_strip("popd")
self._write_strip("popd")
if self.config.config_opts['openmpi']: if self.config.config_opts['openmpi']:
self._write_strip("pushd ../build-openmpi/" + self.config.subdir)
self._write_strip("GOAMD64=v3") self._write_strip("GOAMD64=v3")
self._write_strip("pushd clr-build-openmpi") self._write_strip("pushd clr-build-openmpi")
self.write_install_openmpi() self.write_install_openmpi()
self._write_strip("popd") self._write_strip("popd")
self._write_strip("popd")
if self.config.subdir:
self._write_strip("pushd " + self.config.subdir)
self._write_strip("GOAMD64=v2") self._write_strip("GOAMD64=v2")
self._write_strip("pushd clr-build") self._write_strip("pushd clr-build")
@@ -1165,8 +1097,9 @@ class Specfile(object):
self._write_strip("pushd ../buildapx/" + self.config.subdir) self._write_strip("pushd ../buildapx/" + self.config.subdir)
self.write_build_prepend() self.write_build_prepend()
self._write_strip("GOAMD64=v3") self._write_strip("GOAMD64=v3")
self._write_strip('CC="gcc-14"')
self._write_strip(f'CFLAGS="$CLEAR_INTERMEDIATE_CFLAGS {APX_CFLAGS} {APX_LFLAGS} "') self._write_strip(f'CFLAGS="$CLEAR_INTERMEDIATE_CFLAGS {APX_CFLAGS} {APX_LFLAGS} "')
self._write_strip(f'CXXFLAGS="$CLEAR_INTERMEDIATE_CXXFLAGS {APX_CFLAGS} {APX_LFLAGS} "') self._write_strip(f'CXXFLAGS="$CLEAR_INTERMEDIATE_CXXFLAGS {AVX2_CFLAGS} {AVX2_LFLAGS} "')
self._write_strip(f'FFLAGS="$CLEAR_INTERMEDIATE_FFLAGS {APX_CFLAGS} {APX_LFLAGS} "') self._write_strip(f'FFLAGS="$CLEAR_INTERMEDIATE_FFLAGS {APX_CFLAGS} {APX_LFLAGS} "')
self._write_strip(f'FCFLAGS="$CLEAR_INTERMEDIATE_FCFLAGS {APX_CFLAGS} "') self._write_strip(f'FCFLAGS="$CLEAR_INTERMEDIATE_FCFLAGS {APX_CFLAGS} "')
self._write_strip(f'LDFLAGS="$CLEAR_INTERMEDIATE_LDFLAGS {APX_LCFLAGS} "') self._write_strip(f'LDFLAGS="$CLEAR_INTERMEDIATE_LDFLAGS {APX_LCFLAGS} "')
@@ -1270,6 +1203,7 @@ class Specfile(object):
self._write_strip("pushd ../buildapx/" + self.config.subdir) self._write_strip("pushd ../buildapx/" + self.config.subdir)
self.write_build_prepend() self.write_build_prepend()
self._write_strip("GOAMD64=v3") self._write_strip("GOAMD64=v3")
self._write_strip('CC="gcc-14"')
self._write_strip(f'CFLAGS="$CLEAR_INTERMEDIATE_CFLAGS {APX_CFLAGS} {APX_LFLAGS} "') self._write_strip(f'CFLAGS="$CLEAR_INTERMEDIATE_CFLAGS {APX_CFLAGS} {APX_LFLAGS} "')
self._write_strip(f'CXXFLAGS="$CLEAR_INTERMEDIATE_CXXFLAGS {AVX2_CFLAGS} {AVX2_LFLAGS} "') self._write_strip(f'CXXFLAGS="$CLEAR_INTERMEDIATE_CXXFLAGS {AVX2_CFLAGS} {AVX2_LFLAGS} "')
self._write_strip(f'FFLAGS="$CLEAR_INTERMEDIATE_FFLAGS {APX_CFLAGS} {APX_LFLAGS} "') self._write_strip(f'FFLAGS="$CLEAR_INTERMEDIATE_FFLAGS {APX_CFLAGS} {APX_LFLAGS} "')
@@ -1330,6 +1264,7 @@ class Specfile(object):
self._write_strip("pushd ../buildapx" + self.config.subdir) self._write_strip("pushd ../buildapx" + self.config.subdir)
self.write_build_prepend() self.write_build_prepend()
self._write_strip("GOAMD64=v3") self._write_strip("GOAMD64=v3")
self._write_strip('CC=gcc-14')
self._write_strip(f'CFLAGS="$CLEAR_INTERMEDIATE_CFLAGS {APX_CFLAGS} {APX_LFLAGS} "') self._write_strip(f'CFLAGS="$CLEAR_INTERMEDIATE_CFLAGS {APX_CFLAGS} {APX_LFLAGS} "')
self._write_strip(f'CXXFLAGS="$CLEAR_INTERMEDIATE_CXXFLAGS {AVX2_CFLAGS} {AVX2_LFLAGS} "') self._write_strip(f'CXXFLAGS="$CLEAR_INTERMEDIATE_CXXFLAGS {AVX2_CFLAGS} {AVX2_LFLAGS} "')
self._write_strip(f'FFLAGS="$CLEAR_INTERMEDIATE_FFLAGS {APX_CFLAGS} {APX_LFLAGS} "') self._write_strip(f'FFLAGS="$CLEAR_INTERMEDIATE_FFLAGS {APX_CFLAGS} {APX_LFLAGS} "')
@@ -1348,8 +1283,6 @@ class Specfile(object):
self.write_lang_c(export_epoch=True) self.write_lang_c(export_epoch=True)
self.write_variables() self.write_variables()
self.write_profile_payload("autogen") self.write_profile_payload("autogen")
if self.config.subdir:
self._write_strip("pushd " + self.config.subdir)
self._write_strip("export GOAMD64=v2") self._write_strip("export GOAMD64=v2")
self._write_strip("{0}%autogen {1} {2} {3}" self._write_strip("{0}%autogen {1} {2} {3}"
.format(self.get_profile_use_flags(), .format(self.get_profile_use_flags(),
@@ -1358,8 +1291,6 @@ class Specfile(object):
self.config.extra_configure64)) self.config.extra_configure64))
self.write_make_line() self.write_make_line()
self._write_strip("\n") self._write_strip("\n")
if self.config.subdir:
self._write_strip("popd")
if self.config.config_opts['32bit']: if self.config.config_opts['32bit']:
self._write_strip("pushd ../build32/" + self.config.subdir) self._write_strip("pushd ../build32/" + self.config.subdir)
self.write_build_prepend() self.write_build_prepend()
@@ -1411,6 +1342,7 @@ class Specfile(object):
self._write_strip("pushd ../buildapx/" + self.config.subdir) self._write_strip("pushd ../buildapx/" + self.config.subdir)
self.write_build_prepend() self.write_build_prepend()
self._write_strip("GOAMD64=v3") self._write_strip("GOAMD64=v3")
self._write_strip('CC=gcc-14')
self._write_strip(f'CFLAGS="$CLEAR_INTERMEDIATE_CFLAGS {APX_CFLAGS} {APX_LFLAGS} "') self._write_strip(f'CFLAGS="$CLEAR_INTERMEDIATE_CFLAGS {APX_CFLAGS} {APX_LFLAGS} "')
self._write_strip(f'CXXFLAGS="$CLEAR_INTERMEDIATE_CXXFLAGS {AVX2_CFLAGS} {AVX2_LFLAGS} "') self._write_strip(f'CXXFLAGS="$CLEAR_INTERMEDIATE_CXXFLAGS {AVX2_CFLAGS} {AVX2_LFLAGS} "')
self._write_strip(f'FFLAGS="$CLEAR_INTERMEDIATE_FFLAGS {APX_CFLAGS} {APX_LFLAGS} "') self._write_strip(f'FFLAGS="$CLEAR_INTERMEDIATE_FFLAGS {APX_CFLAGS} {APX_LFLAGS} "')
@@ -1437,9 +1369,6 @@ class Specfile(object):
for module in self.config.pypi_overrides: for module in self.config.pypi_overrides:
self._write_strip(f"pypi-dep-fix.py . {module}") self._write_strip(f"pypi-dep-fix.py . {module}")
self._write_strip("python3 -m build --wheel --skip-dependency-check --no-isolation " + self.config.extra_configure) self._write_strip("python3 -m build --wheel --skip-dependency-check --no-isolation " + self.config.extra_configure)
self._write_strip("\n")
if self.config.subdir:
self._write_strip("popd")
if self.config.config_opts['use_avx2']: if self.config.config_opts['use_avx2']:
self._write_strip("pushd ../buildavx2/" + self.config.subdir) self._write_strip("pushd ../buildavx2/" + self.config.subdir)
@@ -1458,6 +1387,7 @@ class Specfile(object):
if self.config.config_opts['use_apx'] and not self.config.config_opts['use_clang']: if self.config.config_opts['use_apx'] and not self.config.config_opts['use_clang']:
self._write_strip("pushd ../buildapx/" + self.config.subdir) self._write_strip("pushd ../buildapx/" + self.config.subdir)
self.write_build_prepend() self.write_build_prepend()
self._write_strip('CC=gcc-14')
self._write_strip(f'CFLAGS="$CLEAR_INTERMEDIATE_CFLAGS {APX_CFLAGS} {APX_LFLAGS} "') self._write_strip(f'CFLAGS="$CLEAR_INTERMEDIATE_CFLAGS {APX_CFLAGS} {APX_LFLAGS} "')
self._write_strip(f'CXXFLAGS="$CLEAR_INTERMEDIATE_CXXFLAGS {AVX2_CFLAGS} {AVX2_LFLAGS} "') self._write_strip(f'CXXFLAGS="$CLEAR_INTERMEDIATE_CXXFLAGS {AVX2_CFLAGS} {AVX2_LFLAGS} "')
self._write_strip(f'FFLAGS="$CLEAR_INTERMEDIATE_FFLAGS {APX_CFLAGS} {APX_LFLAGS} "') self._write_strip(f'FFLAGS="$CLEAR_INTERMEDIATE_FFLAGS {APX_CFLAGS} {APX_LFLAGS} "')
@@ -1470,6 +1400,8 @@ class Specfile(object):
self._write_strip("popd") self._write_strip("popd")
self._write_strip("\n") self._write_strip("\n")
if self.config.subdir:
self._write_strip("popd")
self.write_build_append() self.write_build_append()
self.write_check() self.write_check()
self._write_strip("%install") self._write_strip("%install")
@@ -1503,6 +1435,7 @@ class Specfile(object):
if self.config.config_opts['use_apx'] and not self.config.config_opts['use_clang']: if self.config.config_opts['use_apx'] and not self.config.config_opts['use_clang']:
self._write_strip("pushd ../buildapx/" + self.config.subdir) self._write_strip("pushd ../buildapx/" + self.config.subdir)
self._write_strip('CC=gcc-14')
self._write_strip(f'CFLAGS="$CLEAR_INTERMEDIATE_CFLAGS {APX_CFLAGS} {APX_LFLAGS} "') self._write_strip(f'CFLAGS="$CLEAR_INTERMEDIATE_CFLAGS {APX_CFLAGS} {APX_LFLAGS} "')
self._write_strip(f'CXXFLAGS="$CLEAR_INTERMEDIATE_CXXFLAGS {AVX2_CFLAGS} {AVX2_LFLAGS} "') self._write_strip(f'CXXFLAGS="$CLEAR_INTERMEDIATE_CXXFLAGS {AVX2_CFLAGS} {AVX2_LFLAGS} "')
self._write_strip(f'FFLAGS="$CLEAR_INTERMEDIATE_FFLAGS {APX_CFLAGS} {APX_LFLAGS} "') self._write_strip(f'FFLAGS="$CLEAR_INTERMEDIATE_FFLAGS {APX_CFLAGS} {APX_LFLAGS} "')
@@ -1545,6 +1478,7 @@ class Specfile(object):
if self.config.config_opts['use_apx'] and not self.config.config_opts['use_clang']: if self.config.config_opts['use_apx'] and not self.config.config_opts['use_clang']:
self._write_strip("pushd ../buildapx/" + self.config.subdir) self._write_strip("pushd ../buildapx/" + self.config.subdir)
self.write_build_prepend() self.write_build_prepend()
self._write_strip('CC=gcc-14')
self._write_strip(f'CFLAGS="$CLEAR_INTERMEDIATE_CFLAGS {APX_CFLAGS} {APX_LFLAGS} "') self._write_strip(f'CFLAGS="$CLEAR_INTERMEDIATE_CFLAGS {APX_CFLAGS} {APX_LFLAGS} "')
self._write_strip(f'CXXFLAGS="$CLEAR_INTERMEDIATE_CXXFLAGS {AVX2_CFLAGS} {AVX2_LFLAGS} "') self._write_strip(f'CXXFLAGS="$CLEAR_INTERMEDIATE_CXXFLAGS {AVX2_CFLAGS} {AVX2_LFLAGS} "')
self._write_strip(f'FFLAGS="$CLEAR_INTERMEDIATE_FFLAGS {APX_CFLAGS} {APX_LFLAGS} "') self._write_strip(f'FFLAGS="$CLEAR_INTERMEDIATE_FFLAGS {APX_CFLAGS} {APX_LFLAGS} "')
@@ -1589,6 +1523,7 @@ class Specfile(object):
if self.config.config_opts['use_apx'] and not self.config.config_opts['use_clang']: if self.config.config_opts['use_apx'] and not self.config.config_opts['use_clang']:
self._write_strip("pushd ../buildapx/" + self.config.subdir) self._write_strip("pushd ../buildapx/" + self.config.subdir)
self._write_strip('CC=gcc-14')
self._write_strip(f'CFLAGS="$CLEAR_INTERMEDIATE_CFLAGS {APX_CFLAGS} {APX_LFLAGS} "') self._write_strip(f'CFLAGS="$CLEAR_INTERMEDIATE_CFLAGS {APX_CFLAGS} {APX_LFLAGS} "')
self._write_strip(f'CXXFLAGS="$CLEAR_INTERMEDIATE_CXXFLAGS {AVX2_CFLAGS} {AVX2_LFLAGS} "') self._write_strip(f'CXXFLAGS="$CLEAR_INTERMEDIATE_CXXFLAGS {AVX2_CFLAGS} {AVX2_LFLAGS} "')
self._write_strip(f'FFLAGS="$CLEAR_INTERMEDIATE_FFLAGS {APX_CFLAGS} {APX_LFLAGS} "') self._write_strip(f'FFLAGS="$CLEAR_INTERMEDIATE_FFLAGS {APX_CFLAGS} {APX_LFLAGS} "')
@@ -1704,22 +1639,14 @@ class Specfile(object):
self._write_strip("pushd clr-build") self._write_strip("pushd clr-build")
self.write_variables() self.write_variables()
self._write_strip("export GOAMD64=v2") self._write_strip("export GOAMD64=v2")
if self.config.config_opts['use_ninja']: self._write_strip("%cmake {} {}".format(self.config.cmake_srcdir, self.extra_cmake))
cmake_type = "-G Ninja"
else:
cmake_type = "-G 'Unix Makefiles'"
self._write_strip(f"%cmake {self.config.cmake_srcdir} {self.extra_cmake} {cmake_type}")
self.write_profile_payload("cmake") self.write_profile_payload("cmake")
self.write_make_line() self.write_make_line()
self._write_strip("popd") self._write_strip("popd")
if self.config.subdir:
self._write_strip("popd")
if self.config.config_opts['use_avx2']: if self.config.config_opts['use_avx2']:
self._write_strip("pushd ../buildavx2/" + self.config.subdir)
self._write_strip("mkdir -p clr-build-avx2") self._write_strip("mkdir -p clr-build-avx2")
self._write_strip("pushd clr-build-avx2") self._write_strip("pushd clr-build-avx2")
self.write_build_prepend() self.write_build_prepend()
@@ -1729,13 +1656,11 @@ class Specfile(object):
self._write_strip(f'CXXFLAGS="$CLEAR_INTERMEDIATE_CXXFLAGS {AVX2_CFLAGS} {AVX2_LFLAGS} "') self._write_strip(f'CXXFLAGS="$CLEAR_INTERMEDIATE_CXXFLAGS {AVX2_CFLAGS} {AVX2_LFLAGS} "')
self._write_strip(f'FFLAGS="$CLEAR_INTERMEDIATE_FFLAGS {AVX2_CFLAGS} {AVX2_LFLAGS} "') self._write_strip(f'FFLAGS="$CLEAR_INTERMEDIATE_FFLAGS {AVX2_CFLAGS} {AVX2_LFLAGS} "')
self._write_strip(f'FCFLAGS="$CLEAR_INTERMEDIATE_FCFLAGS {AVX2_CFLAGS} "') self._write_strip(f'FCFLAGS="$CLEAR_INTERMEDIATE_FCFLAGS {AVX2_CFLAGS} "')
self._write_strip(f"%cmake {self.config.cmake_srcdir} {self.extra_cmake} {cmake_type}") self._write_strip("%cmake {} {}".format(self.config.cmake_srcdir, self.extra_cmake))
self.write_make_line() self.write_make_line()
self._write_strip("popd") self._write_strip("popd")
self._write_strip("popd")
if self.config.config_opts['use_avx512']: if self.config.config_opts['use_avx512']:
self._write_strip("pushd ../buildavx512/" + self.config.subdir)
self._write_strip("mkdir -p clr-build-avx512") self._write_strip("mkdir -p clr-build-avx512")
self._write_strip("pushd clr-build-avx512") self._write_strip("pushd clr-build-avx512")
self.write_build_prepend() self.write_build_prepend()
@@ -1745,29 +1670,26 @@ class Specfile(object):
self._write_strip(f'CXXFLAGS="$CLEAR_INTERMEDIATE_CXXFLAGS {AVX512_CFLAGS} {AVX512_LFLAGS} "') self._write_strip(f'CXXFLAGS="$CLEAR_INTERMEDIATE_CXXFLAGS {AVX512_CFLAGS} {AVX512_LFLAGS} "')
self._write_strip(f'FFLAGS="$CLEAR_INTERMEDIATE_FFLAGS {AVX512_CFLAGS} {AVX512_LFLAGS} "') self._write_strip(f'FFLAGS="$CLEAR_INTERMEDIATE_FFLAGS {AVX512_CFLAGS} {AVX512_LFLAGS} "')
self._write_strip(f'FCFLAGS="$CLEAR_INTERMEDIATE_FCFLAGS {AVX512_CFLAGS} "') self._write_strip(f'FCFLAGS="$CLEAR_INTERMEDIATE_FCFLAGS {AVX512_CFLAGS} "')
self._write_strip(f"%cmake {self.config.cmake_srcdir} {self.extra_cmake} {cmake_type}") self._write_strip("%cmake {} {}".format(self.config.cmake_srcdir, self.extra_cmake))
self.write_make_line() self.write_make_line()
self._write_strip("popd") self._write_strip("popd")
self._write_strip("popd")
if self.config.config_opts['use_apx'] and not self.config.config_opts['use_clang']: if self.config.config_opts['use_apx'] and not self.config.config_opts['use_clang']:
self._write_strip("pushd ../buildapx/" + self.config.subdir)
self._write_strip("mkdir -p clr-build-apx") self._write_strip("mkdir -p clr-build-apx")
self._write_strip("pushd clr-build-apx") self._write_strip("pushd clr-build-apx")
self.write_build_prepend() self.write_build_prepend()
self.write_variables() self.write_variables()
self._write_strip("GOAMD64=v3") self._write_strip("GOAMD64=v3")
self._write_strip('CC=gcc-14')
self._write_strip(f'CFLAGS="$CLEAR_INTERMEDIATE_CFLAGS {APX_CFLAGS} {APX_LFLAGS} "') self._write_strip(f'CFLAGS="$CLEAR_INTERMEDIATE_CFLAGS {APX_CFLAGS} {APX_LFLAGS} "')
self._write_strip(f'CXXFLAGS="$CLEAR_INTERMEDIATE_CXXFLAGS {AVX2_CFLAGS} {AVX2_LFLAGS} "') self._write_strip(f'CXXFLAGS="$CLEAR_INTERMEDIATE_CXXFLAGS {AVX2_CFLAGS} {AVX2_LFLAGS} "')
self._write_strip(f'FFLAGS="$CLEAR_INTERMEDIATE_FFLAGS {APX_CFLAGS} {APX_LFLAGS} "') self._write_strip(f'FFLAGS="$CLEAR_INTERMEDIATE_FFLAGS {APX_CFLAGS} {APX_LFLAGS} "')
self._write_strip(f'FCFLAGS="$CLEAR_INTERMEDIATE_FCFLAGS {APX_CFLAGS} "') self._write_strip(f'FCFLAGS="$CLEAR_INTERMEDIATE_FCFLAGS {APX_CFLAGS} "')
self._write_strip(f"%cmake {self.config.cmake_srcdir} {self.extra_cmake} {cmake_type}") self._write_strip("%cmake {} {}".format(self.config.cmake_srcdir, self.extra_cmake))
self.write_make_line() self.write_make_line()
self._write_strip("popd") self._write_strip("popd")
self._write_strip("popd")
if self.config.config_opts['32bit']: if self.config.config_opts['32bit']:
self._write_strip("pushd ../build32/" + self.config.subdir)
self._write_strip("mkdir -p clr-build32") self._write_strip("mkdir -p clr-build32")
self._write_strip("pushd clr-build32") self._write_strip("pushd clr-build32")
self.write_build_prepend() self.write_build_prepend()
@@ -1776,14 +1698,12 @@ class Specfile(object):
self._write_strip("%cmake -DLIB_INSTALL_DIR:PATH=/usr/lib32 " self._write_strip("%cmake -DLIB_INSTALL_DIR:PATH=/usr/lib32 "
"-DCMAKE_INSTALL_LIBDIR=/usr/lib32 " "-DCMAKE_INSTALL_LIBDIR=/usr/lib32 "
"-DLIB_SUFFIX=32 " "-DLIB_SUFFIX=32 "
f"{self.config.cmake_srcdir} {self.extra_cmake} {cmake_type}") "{} {} ".format(self.config.cmake_srcdir, self.extra_cmake))
self.write_make_line() self.write_make_line()
self._write_strip("unset PKG_CONFIG_PATH") self._write_strip("unset PKG_CONFIG_PATH")
self._write_strip("popd") self._write_strip("popd")
self._write_strip("popd")
if self.config.config_opts['openmpi']: if self.config.config_opts['openmpi']:
self._write_strip("pushd ../build-openmpi/" + self.config.subdir)
self._write_strip("mkdir -p clr-build-openmpi") self._write_strip("mkdir -p clr-build-openmpi")
self._write_strip("pushd clr-build-openmpi") self._write_strip("pushd clr-build-openmpi")
self._write_strip(". /usr/share/defaults/etc/profile.d/modules.sh") self._write_strip(". /usr/share/defaults/etc/profile.d/modules.sh")
@@ -1799,6 +1719,8 @@ class Specfile(object):
self.write_make_line() self.write_make_line()
self._write_strip("module unload openmpi") self._write_strip("module unload openmpi")
self._write_strip("popd") self._write_strip("popd")
if self.config.subdir:
self._write_strip("popd") self._write_strip("popd")
self._write_strip("\n") self._write_strip("\n")
@@ -1806,59 +1728,6 @@ class Specfile(object):
self.write_cmake_install() self.write_cmake_install()
def write_qmake5_pattern(self):
"""Write qmake5 build pattern to spec file."""
extra_qmake_args = ""
if self.config.config_opts['use_clang']:
extra_qmake_args = "-spec linux-clang "
if self.config.config_opts['use_lto']:
extra_qmake_args += "-config ltcg -config fat-static-lto "
else:
extra_qmake_args += "QMAKE_CFLAGS+=-fno-lto QMAKE_CXXFLAGS+=-fno-lto "
self.write_prep()
self._write_strip("%build")
self.write_build_prepend()
self.write_proxy_exports()
self._write_strip("export LANG=C.UTF-8")
self.write_variables()
if self.config.subdir:
self._write_strip("pushd " + self.config.subdir)
self._write_strip('export QMAKE_CFLAGS="$CFLAGS"')
self._write_strip('export QMAKE_CXXFLAGS="$CXXFLAGS"')
self._write_strip('export QMAKE_LFLAGS="$LDFLAGS"')
self._write_strip('export QMAKE_LIBDIR=/usr/lib64')
self._write_strip('export QMAKE_CFLAGS_RELEASE=')
self._write_strip('export QMAKE_CXXFLAGS_RELEASE=')
# Add the qtbase tools to the path
self._write_strip('export PATH=/usr/lib64/qt5/bin:$PATH')
if self.config.make_command:
qmake = self.config.make_command
else:
qmake = "qmake"
self._write_strip(f"{qmake} {extra_qmake_args} {self.config.extra_configure}")
self._write_strip("test -r config.log && cat config.log")
self.write_make_line()
if self.config.subdir:
self._write_strip("popd")
if self.config.config_opts['use_avx2']:
self._write_strip("pushd ../buildavx2/" + self.config.subdir)
self._write(f"{qmake} 'QT_CPU_FEATURES.x86_64 += avx avx2 bmi bmi2 f16c fma lzcnt popcnt'\\\n")
self._write(f' QMAKE_CFLAGS+="{AVX2_CFLAGS} {AVX2_LFLAGS}" QMAKE_CXXFLAGS+="{AVX2_CFLAGS} {AVX2_LFLAGS}" \\\n')
self._write(f' QMAKE_LFLAGS+="{AVX2_LCFLAGS}" {extra_qmake_args} {self.config.extra_configure}\n')
self.write_make_line()
self._write_strip("popd")
self.write_build_append()
self._write_strip("\n")
self.write_make_install()
def write_qmake_pattern(self): def write_qmake_pattern(self):
"""Write qmake build pattern to spec file.""" """Write qmake build pattern to spec file."""
extra_qmake_args = "" extra_qmake_args = ""
@@ -1886,9 +1755,6 @@ class Specfile(object):
self._write_strip('export QMAKE_CFLAGS_RELEASE=') self._write_strip('export QMAKE_CFLAGS_RELEASE=')
self._write_strip('export QMAKE_CXXFLAGS_RELEASE=') self._write_strip('export QMAKE_CXXFLAGS_RELEASE=')
# Add the qt6base tools to the path
self._write_strip('export PATH=/usr/lib64/qt6/bin:$PATH')
if self.config.make_command: if self.config.make_command:
qmake = self.config.make_command qmake = self.config.make_command
else: else:
@@ -2020,6 +1886,7 @@ class Specfile(object):
self._write_strip('ninja -v -C builddiravx512') self._write_strip('ninja -v -C builddiravx512')
if self.config.config_opts['use_apx'] and not self.config.config_opts['use_clang']: if self.config.config_opts['use_apx'] and not self.config.config_opts['use_clang']:
self._write_strip("GOAMD64=v3") self._write_strip("GOAMD64=v3")
self._write_strip('CC=gcc-14')
if self.config.config_opts['pgo'] and self.config.profile_payload != "": if self.config.config_opts['pgo'] and self.config.profile_payload != "":
self._write_strip(f'CFLAGS="$CFLAGS_GENERATE {APX_CFLAGS} {APX_LFLAGS} "' self._write_strip(f'CFLAGS="$CFLAGS_GENERATE {APX_CFLAGS} {APX_LFLAGS} "'
f' CXXFLAGS="$CXXFLAGS_GENERATE {AVX2_CFLAGS} {AVX2_LFLAGS} "' f' CXXFLAGS="$CXXFLAGS_GENERATE {AVX2_CFLAGS} {AVX2_LFLAGS} "'
@@ -2090,6 +1957,7 @@ class Specfile(object):
self._write_strip('DESTDIR=%{buildroot}-v4 ninja -C builddiravx512 install') self._write_strip('DESTDIR=%{buildroot}-v4 ninja -C builddiravx512 install')
if self.config.config_opts['use_apx'] and not self.config.config_opts['use_clang']: if self.config.config_opts['use_apx'] and not self.config.config_opts['use_clang']:
self._write_strip("GOAMD64=v3") self._write_strip("GOAMD64=v3")
self._write_strip('CC=gcc-14')
self._write_strip('DESTDIR=%{buildroot}-va ninja -C builddirapx install') self._write_strip('DESTDIR=%{buildroot}-va ninja -C builddirapx install')
self._write_strip("GOAMD64=v2") self._write_strip("GOAMD64=v2")
@@ -2123,11 +1991,14 @@ class Specfile(object):
self.write_license_files() self.write_license_files()
if self.config.subdir: if self.config.subdir:
self._write_strip("pushd " + self.config.subdir) self._write_strip("pushd " + self.config.subdir)
self._write_strip("cargo install --path .") if self.config.install_macro:
self._write_strip("mkdir -p %{buildroot}/usr/bin") self._write_strip(self.config.install_macro)
self._write_strip('pushd "${HOME}/.cargo/bin/"') else:
self._write_strip("mv * %{buildroot}/usr/bin/") self._write_strip("cargo install --path .")
self._write_strip("popd") self._write_strip("mkdir -p %{buildroot}/usr/bin")
self._write_strip('pushd "${HOME}/.cargo/bin/"')
self._write_strip("mv * %{buildroot}/usr/bin/")
self._write_strip("popd")
if self.config.subdir: if self.config.subdir:
self._write_strip("popd") self._write_strip("popd")
self.write_install_append() self.write_install_append()
+30 -28
View File
@@ -26,8 +26,7 @@ import tarfile
import zipfile import zipfile
import download import download
import zstandard as zstd from util import call, do_regex, get_sha1sum, print_fatal, write_out
from util import do_regex, get_sha1sum, print_fatal, write_out
class Source(): class Source():
@@ -54,8 +53,6 @@ class Source():
self.type = 'zip' self.type = 'zip'
elif self.url.lower().endswith(('.bz2')) and not self.url.lower().endswith(('.tar.bz2')): elif self.url.lower().endswith(('.bz2')) and not self.url.lower().endswith(('.tar.bz2')):
self.type = 'bz2' self.type = 'bz2'
elif self.url.lower().endswith('.zst'):
self.type = 'zst'
else: else:
self.type = 'tar' self.type = 'tar'
@@ -84,16 +81,6 @@ class Source():
print_fatal("Not a valid tar file.") print_fatal("Not a valid tar file.")
sys.exit(1) sys.exit(1)
def set_zst_prefix(self):
"""Determine prefix folder name of tar.zst file."""
with tarfile.open(fileobj=zstd.open(self.path, 'rb'), mode='r|') as content:
lines = content.getnames()
if len(lines) == 0:
print_fatal("Zstd compressed tar file doesn't appear to have any content")
sys.exit(1)
elif len(lines) > 1:
self.prefix = os.path.commonpath(lines)
def set_bz2_prefix(self): def set_bz2_prefix(self):
"""No prefix for plain bz2 archives.""" """No prefix for plain bz2 archives."""
@@ -120,15 +107,12 @@ class Source():
extraction_path = base_path extraction_path = base_path
extract_method = getattr(self, 'extract_{}'.format(self.type)) extract_method = getattr(self, 'extract_{}'.format(self.type))
try: extract_method(extraction_path)
extract_method(extraction_path)
except tarfile.AbsoluteLinkError:
pass
def extract_tar(self, extraction_path): def extract_tar(self, extraction_path):
"""Extract tar in path.""" """Extract tar in path."""
with tarfile.open(self.path) as content: with tarfile.open(self.path) as content:
content.extractall(path=extraction_path, filter='data') content.extractall(path=extraction_path)
def extract_bz2(self, extraction_path): def extract_bz2(self, extraction_path):
"""Extract plain bz2 file in path.""" """Extract plain bz2 file in path."""
@@ -144,11 +128,6 @@ class Source():
with zipfile.ZipFile(self.path, 'r') as content: with zipfile.ZipFile(self.path, 'r') as content:
content.extractall(path=extraction_path) content.extractall(path=extraction_path)
def extract_zst(self, extraction_path):
"""Extract zst in path."""
with tarfile.open(fileobj=zstd.open(self.path, 'rb'), mode='r|') as content:
content.extractall(path=extraction_path, filter='data')
def convert_version(ver_str, name): def convert_version(ver_str, name):
"""Remove disallowed characters from the version.""" """Remove disallowed characters from the version."""
@@ -156,7 +135,7 @@ def convert_version(ver_str, name):
# them out with expensive regular expressions # them out with expensive regular expressions
banned_subs = ["x86.64", "source", "src", "all", "bin", "release", "rh", banned_subs = ["x86.64", "source", "src", "all", "bin", "release", "rh",
"ga", ".ce", "lcms", "onig", "linux", "gc", "sdk", "orig", "ga", ".ce", "lcms", "onig", "linux", "gc", "sdk", "orig",
"jurko", "%2f", "%2F", "%20", "x265", "autotools"] "jurko", "%2f", "%2F", "%20", "x265"]
# package names may be modified in the version string by adding "lib" for # package names may be modified in the version string by adding "lib" for
# example. Remove these from the name before trying to remove the name from # example. Remove these from the name before trying to remove the name from
@@ -172,7 +151,7 @@ def convert_version(ver_str, name):
ver_str = ver_str.replace(name.replace(mod, ""), "") ver_str = ver_str.replace(name.replace(mod, ""), "")
# replace illegal characters # replace illegal characters
ver_str = ver_str.strip().replace('-', '.').replace('_', '.').replace('+', '.') ver_str = ver_str.strip().replace('-', '.').replace('_', '.')
# remove banned substrings # remove banned substrings
for sub in banned_subs: for sub in banned_subs:
@@ -205,6 +184,7 @@ class Content():
self.prefixes = dict() self.prefixes = dict()
self.config = config self.config = config
self.base_path = base_path self.base_path = base_path
self.autogenerated_tarball = None
def write_upstream(self, sha, tarfile, mode="w"): def write_upstream(self, sha, tarfile, mode="w"):
"""Write the upstream hash to the upstream file.""" """Write the upstream hash to the upstream file."""
@@ -234,6 +214,14 @@ class Content():
main_src = Source(url, '', src_path, self.config.default_pattern) main_src = Source(url, '', src_path, self.config.default_pattern)
return main_src return main_src
def process_autogenerated_source(self, url):
"""Download any autogenerated source tarball for comparison."""
autogenerated_src = None
if url:
src_path = self.check_or_get_file(url, os.path.basename(url), mode="")
autogenerated_src = Source(url, '../autogenerated-tmp', src_path, self.config.default_pattern)
return autogenerated_src
def print_header(self): def print_header(self):
"""Print header for autospec run.""" """Print header for autospec run."""
print("\n") print("\n")
@@ -298,8 +286,7 @@ class Content():
if "github.com" in self.url: if "github.com" in self.url:
# define regex accepted for valid packages, important for specific # define regex accepted for valid packages, important for specific
# patterns to come before general ones # patterns to come before general ones
github_patterns = [r"https?://github.com/(.*)/(.*?)/archive/refs/tags/.*/(.*).tar", github_patterns = [r"https?://github.com/(.*)/(.*?)/archive/refs/tags/[vVrR]?(.*)\.tar",
r"https?://github.com/(.*)/(.*?)/archive/refs/tags/[vVrR]?(.*)\.tar",
r"https?://github.com/(.*)/(.*?)/archive/[v|r]?.*/(.*).tar", r"https?://github.com/(.*)/(.*?)/archive/[v|r]?.*/(.*).tar",
r"https?://github.com/(.*)/(.*?)/archive/[-a-zA-Z_]*-(.*).tar", r"https?://github.com/(.*)/(.*?)/archive/[-a-zA-Z_]*-(.*).tar",
r"https?://github.com/(.*)/(.*?)/archive/[vVrR]?(.*).tar", r"https?://github.com/(.*)/(.*?)/archive/[vVrR]?(.*).tar",
@@ -317,6 +304,9 @@ class Content():
name = re.sub(r"release-", '', name) name = re.sub(r"release-", '', name)
name = re.sub(r"\d*$", '', name) name = re.sub(r"\d*$", '', name)
self.rawname = name self.rawname = name
# Identify the auto-generated tarball URL for comparison
if "/releases/download/" in self.url:
self.autogenerated_tarball = "https://github.com/" + match.group(1).strip() + "/" + self.repo + "/archive/refs/tags/" + match.group(3).strip() + ".tar.gz"
version = match.group(3).replace(name, '') version = match.group(3).replace(name, '')
if "/archive/" not in self.url: if "/archive/" not in self.url:
version = re.sub(r"^[-_.a-zA-Z]+", "", version) version = re.sub(r"^[-_.a-zA-Z]+", "", version)
@@ -449,3 +439,15 @@ class Content():
archives_src = self.process_archives() archives_src = self.process_archives()
# Extract all sources # Extract all sources
self.extract_sources(main_src, archives_src) self.extract_sources(main_src, archives_src)
# Download and process any auto-generated source-tree archive for comparison
autogenerated_src = self.process_autogenerated_source(self.autogenerated_tarball)
# Extract autogenerated source for comparison
if autogenerated_src:
autogenerated_src.extract(os.path.join(self.base_path, 'autogenerated-tmp'))
# Move the autogenerated source to a non-version-named directory for consistent diffs
call(f"mv autogenerated-tmp/{autogenerated_src.prefix} autogenerated", check=True, cwd=self.base_path)
call("diff -u -r --unidirectional-new-file ../autogenerated ./",
logfile="archive.diff.in", check=False, cwd=os.path.join(self.base_path, main_src.prefix))
call("grep -A14 -E '^(diff|Only in)' archive.diff.in",
logfile="archive.diff", check=False, cwd=os.getcwd())
call("rm archive.diff.in", check=False, cwd=os.getcwd())
+4 -138
View File
@@ -27,101 +27,6 @@ import sys
dictionary_filename = os.path.dirname(__file__) + "/translate.dic" dictionary_filename = os.path.dirname(__file__) + "/translate.dic"
dictionary = [line.strip() for line in open(dictionary_filename, 'r')] dictionary = [line.strip() for line in open(dictionary_filename, 'r')]
os_paths = None os_paths = None
ERROR_FILE = 'pumpAutospec'
ERROR_ENV = 'AUTOSPEC_UPDATE'
def _log_error(error):
write_out(ERROR_FILE, f"{error}\n", mode='a')
def _commit_result():
if not os.path.isfile(ERROR_FILE):
return
call(f"git add {ERROR_FILE}", check=False, stderr=subprocess.DEVNULL)
call(f"git commit {ERROR_FILE} -m 'Notes update'", check=False, stderr=subprocess.DEVNULL)
call("git push", check=False, stderr=subprocess.DEVNULL)
def _process_line(line, prev_line, current_patch, reported_patches, error):
if m := re.match('^Patch #[0-9]+ .(?P<patch>.*).:', line):
current_patch[0] = m.group('patch')
if m := re.match('Hunk #[0-9]+ FAILED at [0-9]+', line):
if current_patch[0] not in reported_patches:
_log_error("Patch " + current_patch[0] + " does not apply")
reported_patches[current_patch[0]] = True
return True
if m := re.match(".*can't find file to patch at input line ", line):
if current_patch[0] not in reported_patches:
_log_error("Patch " + current_patch[0] + " does not apply")
reported_patches[current_patch[0]] = True
return True
if m := re.match('.*meson.build:[0-9]+:[0-9]+: ERROR: Unknown options: "(?P<option>.*)"', line):
_log_error("Unknown meson option: " + m.group('option'))
return True
if m := re.match('Error: package (?P<module>.*) .* was found, but', line):
_log_error("R package " + m.group('module') + " not found")
return True
if m := re.match('.*CMake Error at .*/CMake', prev_line):
if m := re.match('(?P<module>.*) not found', line):
_log_error("CMake module " + m.group('module') + "not found")
return True
if m := re.match(r'go: download.*connect: connection refused', line):
_log_error("Go online update")
return True
if 'Updating crates.io index' in line:
_log_error("Rust crates.io online update")
return True
if "error: '__builtin_ctzs' needs isa option -mbmi" in line:
_log_error(" error: '__builtin_ctzs' needs isa option -mbmi")
return True
if "error:" in line and 'Bad exit status from' not in line:
m = re.match('.*error:(?P<error>.*)', line)
if m and not error:
_log_error("Compiler: " + m.group('error'))
return True
if m := re.match(r'Could NOT find (?P<package>.*) .missing', line):
_log_error("CMake module " + m.group('package') + " not found")
return True
if m := re.match(r'Could not find a package configuration file provided by (?P<package>.*) with', line):
_log_error("CMake module " + m.group('package') + " not found")
return True
# Unable to find program 'gperf'
if m := re.match(r"Failed to find program (?P<module>.*)", line):
_log_error("Failed to find " + m.group('module'))
return True
if m := re.match(r"Failed to find (?P<module>.*)", line):
_log_error("Failed to find " + m.group('module'))
return True
return False
def _process_build_log(filename):
with open_auto(filename, "r") as lfile:
lines = lfile.readlines()
prev_line = ''
current_patch = ['']
reported_patches = {}
error = False
for line in lines:
if _process_line(line, prev_line, current_patch, reported_patches, error):
error = True
prev_line = line
if error:
_commit_result()
def call(command, logfile=None, check=True, **kwargs): def call(command, logfile=None, check=True, **kwargs):
@@ -156,6 +61,7 @@ def _file_write(self, s):
def translate(package): def translate(package):
"""Convert terms to their alternate definition.""" """Convert terms to their alternate definition."""
global dictionary
for item in dictionary: for item in dictionary:
if item.startswith(package + "="): if item.startswith(package + "="):
return item.split("=")[1] return item.split("=")[1]
@@ -210,22 +116,9 @@ def print_error(message):
_print_message(message, 'ERROR', 'red') _print_message(message, 'ERROR', 'red')
def print_build_failed():
"""Print final fatal error, color coded for TTYs."""
_print_message('Build failed, aborting', 'FATAL', 'red')
try:
if os.environ.get(ERROR_ENV):
_process_build_log('results/build.log')
except Exception:
pass
def print_fatal(message): def print_fatal(message):
"""Print fatal error, color coded for TTYs.""" """Print fatal error, color coded for TTYs."""
_print_message(message, 'FATAL', 'red') _print_message(message, 'FATAL', 'red')
if os.environ.get(ERROR_ENV):
write_out(ERROR_FILE, f"{message}\n", mode='a')
_commit_result()
def print_warning(message): def print_warning(message):
@@ -257,8 +150,9 @@ def binary_in_path(binary):
def write_out(filename, content, mode="w"): def write_out(filename, content, mode="w"):
"""File.write convenience wrapper.""" """File.write convenience wrapper."""
with open_auto(filename, mode) as require_f: if mode:
require_f.write(content) with open_auto(filename, mode) as require_f:
require_f.write(content)
def open_auto(*args, **kwargs): def open_auto(*args, **kwargs):
@@ -273,31 +167,3 @@ def open_auto(*args, **kwargs):
assert 'encoding' not in kwargs assert 'encoding' not in kwargs
assert 'errors' not in kwargs assert 'errors' not in kwargs
return open(*args, encoding="utf-8", errors="surrogateescape", **kwargs) return open(*args, encoding="utf-8", errors="surrogateescape", **kwargs)
def globlike_match(filename, match_name):
"""Compare the filename to the match_name in a way that simulates the shell glob '*'."""
fsplit = filename.split('/')
if len(fsplit) != len(match_name):
return False
match = True
for fpart, mpart in zip(fsplit, match_name):
if fpart != mpart:
if '*' not in mpart:
match = False
break
if len(mpart) > len(fpart) + 1:
match = False
break
mpl, mpr = mpart.split('*')
try:
if fpart.index(mpl) != 0:
match = False
break
if fpart.rindex(mpr) != len(fpart) - len(mpr):
match = False
break
except ValueError:
match = False
break
return match
-2
View File
@@ -1612,5 +1612,3 @@ http://sourceforge.net/projects/zsh/files/zsh/5.4.2/zsh-5.4.2.tar.gz,zsh,5.4.2
https://pigeonhole.dovecot.org/releases/2.3/dovecot-2.3.11-pigeonhole-0.5.11.tar.gz,pigeonhole,0.5.11 https://pigeonhole.dovecot.org/releases/2.3/dovecot-2.3.11-pigeonhole-0.5.11.tar.gz,pigeonhole,0.5.11
https://pigeonhole.dovecot.org/releases/2.3/dovecot-2.3-pigeonhole-0.5.20.tar.gz,pigeonhole,0.5.20 https://pigeonhole.dovecot.org/releases/2.3/dovecot-2.3-pigeonhole-0.5.20.tar.gz,pigeonhole,0.5.20
https://www.ezix.org/software/files/lshw-B.02.19.2.tar.gz,lshw,02.19.2 https://www.ezix.org/software/files/lshw-B.02.19.2.tar.gz,lshw,02.19.2
https://github.com/VectorCamp/vectorscan/archive/refs/tags/vectorscan/5.4.11.tar.gz,vectorscan,5.4.11
https://lib.openmpt.org/files/libopenmpt/src/libopenmpt-0.7.13+release.autotools.tar.gz,libopenmpt,0.7.13
+9 -19
View File
@@ -190,36 +190,25 @@ class TestBuildpattern(unittest.TestCase):
def mock_util_call(cmd): def mock_util_call(cmd):
del cmd del cmd
def mock_wrap_fatal():
output = ['']
def mock_print_fatal(msg):
output[0] = msg
return output, mock_print_fatal
result, mock_print_fatal = mock_wrap_fatal()
exit_backup = build.sys.exit
call_backup = build.util.call call_backup = build.util.call
print_backup = build.util.print_fatal
build.sys.exit = MagicMock()
build.util.call = mock_util_call build.util.call = mock_util_call
build.util.print_fatal = mock_print_fatal
open_name = 'build.util.open_auto' open_name = 'build.util.open_auto'
content = "line1\nDEBUG util.py:399: No matching package to install: 'foobar'\nDEBUG util.py:399: No matching package to install: 'foobarbaz'\nline 4" content = "line1\nDEBUG util.py:399: No matching package to install: 'foobar'\nDEBUG util.py:399: No matching package to install: 'foobarbaz'\nline 4"
m_open = mock_open(read_data=content) m_open = mock_open(read_data=content)
pkg = build.Build() pkg = build.Build()
pkg.must_restart = 1
pkg.file_restart = 1
result = True
with patch(open_name, m_open, create=True): with patch(open_name, m_open, create=True):
pkg.parse_buildroot_log('testname', 1) result = pkg.parse_buildroot_log('testname', 1)
build.util.print_fatal = print_backup
build.util.call = call_backup build.util.call = call_backup
mock_exit = build.sys.exit
build.sys.exit = exit_backup
self.assertEqual(result[0], 'Cannot resolve dependency name: foobar\nCannot resolve dependency name: foobarbaz') self.assertFalse(result)
mock_exit.assert_called_once() self.assertEqual(pkg.must_restart, 0)
self.assertEqual(pkg.file_restart, 0)
def test_parse_buildroot_log_pass(self): def test_parse_buildroot_log_pass(self):
""" """
@@ -238,10 +227,11 @@ class TestBuildpattern(unittest.TestCase):
result = True result = True
with patch(open_name, m_open, create=True): with patch(open_name, m_open, create=True):
pkg.parse_buildroot_log('testname', 1) result = pkg.parse_buildroot_log('testname', 1)
build.util.call = call_backup build.util.call = call_backup
self.assertTrue(result)
self.assertEqual(pkg.must_restart, 0) self.assertEqual(pkg.must_restart, 0)
def test_parse_buildroot_log_noop(self): def test_parse_buildroot_log_noop(self):
-111
View File
@@ -402,7 +402,6 @@ class TestBuildreq(unittest.TestCase):
should be sufficient. should be sufficient.
""" """
conf = config.Config("") conf = config.Config("")
conf.config_opts['use_ninja'] = False
with tempfile.TemporaryDirectory() as tmpd: with tempfile.TemporaryDirectory() as tmpd:
os.mkdir(os.path.join(tmpd, 'subdir')) os.mkdir(os.path.join(tmpd, 'subdir'))
open(os.path.join(tmpd, 'setup.py'), 'w').close() open(os.path.join(tmpd, 'setup.py'), 'w').close()
@@ -419,7 +418,6 @@ class TestBuildreq(unittest.TestCase):
should be sufficient. should be sufficient.
""" """
conf = config.Config("") conf = config.Config("")
conf.config_opts['use_ninja'] = False
with tempfile.TemporaryDirectory() as tmpd: with tempfile.TemporaryDirectory() as tmpd:
os.mkdir(os.path.join(tmpd, 'subdir')) os.mkdir(os.path.join(tmpd, 'subdir'))
open(os.path.join(tmpd, 'CMakeLists.txt'), 'w').close() open(os.path.join(tmpd, 'CMakeLists.txt'), 'w').close()
@@ -436,7 +434,6 @@ class TestBuildreq(unittest.TestCase):
should be sufficient. should be sufficient.
""" """
conf = config.Config("") conf = config.Config("")
conf.config_opts['use_ninja'] = False
with tempfile.TemporaryDirectory() as tmpd: with tempfile.TemporaryDirectory() as tmpd:
os.mkdir(os.path.join(tmpd, 'subdir')) os.mkdir(os.path.join(tmpd, 'subdir'))
open(os.path.join(tmpd, 'SConstruct'), 'w').close() open(os.path.join(tmpd, 'SConstruct'), 'w').close()
@@ -453,7 +450,6 @@ class TestBuildreq(unittest.TestCase):
should be sufficient. should be sufficient.
""" """
conf = config.Config("") conf = config.Config("")
conf.config_opts['use_ninja'] = False
with tempfile.TemporaryDirectory() as tmpd: with tempfile.TemporaryDirectory() as tmpd:
os.mkdir(os.path.join(tmpd, 'subdir')) os.mkdir(os.path.join(tmpd, 'subdir'))
open(os.path.join(tmpd, 'meson.build'), 'w').close() open(os.path.join(tmpd, 'meson.build'), 'w').close()
@@ -484,7 +480,6 @@ class TestBuildreq(unittest.TestCase):
buildreq.pypidata.get_pypi_metadata = MagicMock(return_value=content) buildreq.pypidata.get_pypi_metadata = MagicMock(return_value=content)
with tempfile.TemporaryDirectory() as tmpd: with tempfile.TemporaryDirectory() as tmpd:
conf = config.Config(tmpd) conf = config.Config(tmpd)
conf.config_opts['use_ninja'] = False
os.mkdir(os.path.join(tmpd, 'subdir')) os.mkdir(os.path.join(tmpd, 'subdir'))
open(os.path.join(tmpd, 'subdir', 'pyproject.toml'), 'w').close() open(os.path.join(tmpd, 'subdir', 'pyproject.toml'), 'w').close()
self.reqs.scan_for_configure(os.path.join(tmpd, 'subdir'), "", conf) self.reqs.scan_for_configure(os.path.join(tmpd, 'subdir'), "", conf)
@@ -499,95 +494,6 @@ class TestBuildreq(unittest.TestCase):
self.assertEqual(self.reqs.requires['python3'], pypi_requires) self.assertEqual(self.reqs.requires['python3'], pypi_requires)
self.assertEqual(ssummary, summary) self.assertEqual(ssummary, summary)
def test_scan_for_configure_pypi_no_name_in_json(self):
"""
Test scan_for_configure when distutils is being used for the build
pattern to test connecting to pypi but not getting a name back.
"""
orig_summary = buildreq.specdescription.default_summary
orig_sscore = buildreq.specdescription.default_summary_score
orig_pypi_name = buildreq.pypidata.get_pypi_name
orig_pypi_meta = buildreq.pypidata.get_pypi_metadata
name = "pypi-name"
content = json.dumps({})
buildreq.pypidata.pkg_search = MagicMock(return_value=False)
buildreq.pypidata.get_pypi_metadata = MagicMock(return_value=content)
with tempfile.TemporaryDirectory() as tmpd:
conf = config.Config(tmpd)
conf.config_opts['use_ninja'] = False
os.mkdir(os.path.join(tmpd, 'subdir'))
open(os.path.join(tmpd, 'subdir', 'pyproject.toml'), 'w').close()
self.reqs.scan_for_configure(os.path.join(tmpd, 'subdir'), name, conf)
post_summary = buildreq.specdescription.default_summary
buildreq.specdescription.default_summary = orig_summary
buildreq.specdescription.default_summary_score = orig_sscore
buildreq.pypidata.get_pypi_name = orig_pypi_name
buildreq.pypidata.get_pypi_metadata = orig_pypi_meta
self.assertEqual(self.reqs.pypi_provides, "name")
self.assertEqual(post_summary, orig_summary)
def test_scan_for_configure_pypi_no_json(self):
"""
Test scan_for_configure when distutils is being used for the build
pattern to test being unable to connect to pypi.
"""
orig_summary = buildreq.specdescription.default_summary
orig_sscore = buildreq.specdescription.default_summary_score
orig_pypi_name = buildreq.pypidata.get_pypi_name
orig_pypi_meta = buildreq.pypidata.get_pypi_metadata
name = "pypi-name"
buildreq.pypidata.pkg_search = MagicMock(return_value=False)
buildreq.pypidata.get_pypi_metadata = MagicMock(return_value="")
with tempfile.TemporaryDirectory() as tmpd:
conf = config.Config(tmpd)
conf.config_opts['use_ninja'] = False
os.mkdir(os.path.join(tmpd, 'subdir'))
open(os.path.join(tmpd, 'subdir', 'pyproject.toml'), 'w').close()
self.reqs.scan_for_configure(os.path.join(tmpd, 'subdir'), name, conf)
post_summary = buildreq.specdescription.default_summary
buildreq.specdescription.default_summary = orig_summary
buildreq.specdescription.default_summary_score = orig_sscore
buildreq.pypidata.get_pypi_name = orig_pypi_name
buildreq.pypidata.get_pypi_metadata = orig_pypi_meta
self.assertEqual(self.reqs.pypi_provides, "name")
self.assertEqual(post_summary, orig_summary)
def test_scan_for_configure_pypi_bad_json(self):
"""
Test scan_for_configure when distutils is being used for the build
pattern to test being given bad json data.
"""
orig_summary = buildreq.specdescription.default_summary
orig_sscore = buildreq.specdescription.default_summary_score
orig_pypi_name = buildreq.pypidata.get_pypi_name
orig_pypi_meta = buildreq.pypidata.get_pypi_metadata
orig_json_loads = buildreq.json.loads
name = "pypi-name"
content = json.dumps({})
buildreq.pypidata.pkg_search = MagicMock(return_value=False)
buildreq.pypidata.get_pypi_metadata = MagicMock(return_value=content)
buildreq.json.loads = MagicMock(side_effect=json.JSONDecodeError("", "", 0))
with tempfile.TemporaryDirectory() as tmpd:
conf = config.Config(tmpd)
conf.config_opts['use_ninja'] = False
os.mkdir(os.path.join(tmpd, 'subdir'))
open(os.path.join(tmpd, 'subdir', 'pyproject.toml'), 'w').close()
self.reqs.scan_for_configure(os.path.join(tmpd, 'subdir'), name, conf)
post_summary = buildreq.specdescription.default_summary
buildreq.specdescription.default_summary = orig_summary
buildreq.specdescription.default_summary_score = orig_sscore
buildreq.pypidata.get_pypi_name = orig_pypi_name
buildreq.pypidata.get_pypi_metadata = orig_pypi_meta
buildreq.json.loads = orig_json_loads
self.assertEqual(self.reqs.pypi_provides, "name")
self.assertEqual(post_summary, orig_summary)
def test_scan_for_configure_pypi_override(self): def test_scan_for_configure_pypi_override(self):
""" """
Test scan_for_configure when distutils is being used for the build Test scan_for_configure when distutils is being used for the build
@@ -606,7 +512,6 @@ class TestBuildreq(unittest.TestCase):
m_open = mock_open(read_data=content) m_open = mock_open(read_data=content)
with tempfile.TemporaryDirectory() as tmpd: with tempfile.TemporaryDirectory() as tmpd:
conf = config.Config(tmpd) conf = config.Config(tmpd)
conf.config_opts['use_ninja'] = False
os.mkdir(os.path.join(tmpd, 'subdir')) os.mkdir(os.path.join(tmpd, 'subdir'))
open(os.path.join(tmpd, 'subdir', 'pyproject.toml'), 'w').close() open(os.path.join(tmpd, 'subdir', 'pyproject.toml'), 'w').close()
open(os.path.join(tmpd, 'pypi.json'), 'w').close() open(os.path.join(tmpd, 'pypi.json'), 'w').close()
@@ -632,7 +537,6 @@ class TestBuildreq(unittest.TestCase):
with tempfile.TemporaryDirectory() as tmpd: with tempfile.TemporaryDirectory() as tmpd:
conf = config.Config(tmpd) conf = config.Config(tmpd)
conf.config_opts['use_ninja'] = False
os.mkdir(os.path.join(tmpd, 'subdir')) os.mkdir(os.path.join(tmpd, 'subdir'))
open(os.path.join(tmpd, 'subdir', 'setup.py'), 'w').close() open(os.path.join(tmpd, 'subdir', 'setup.py'), 'w').close()
open(os.path.join(tmpd, 'subdir', 'requires.txt'), 'w').close() open(os.path.join(tmpd, 'subdir', 'requires.txt'), 'w').close()
@@ -642,21 +546,6 @@ class TestBuildreq(unittest.TestCase):
self.reqs.add_setup_py_requires.assert_called_once() self.reqs.add_setup_py_requires.assert_called_once()
self.reqs.grab_python_requirements.assert_called_once() self.reqs.grab_python_requirements.assert_called_once()
def test_scan_for_configure_ninja(self):
"""
Test scan_for_configure when ninja is enabled.
"""
conf = config.Config("")
conf.config_opts['use_ninja'] = True
with tempfile.TemporaryDirectory() as tmpd:
os.mkdir(os.path.join(tmpd, 'subdir'))
open(os.path.join(tmpd, 'setup.py'), 'w').close()
self.reqs.scan_for_configure(tmpd, "", conf)
self.assertEqual(self.reqs.buildreqs,
set(['buildreq-distutils3', 'ninja']))
def test_parse_cmake_pkg_check_modules(self): def test_parse_cmake_pkg_check_modules(self):
""" """
Test parse_cmake to ensure accurate detection of versioned and Test parse_cmake to ensure accurate detection of versioned and
+20
View File
@@ -152,6 +152,26 @@ class TestTest(unittest.TestCase):
check.os.listdir = listdir_backup check.os.listdir = listdir_backup
self.assertEqual(check.tests_config, 'make TEST_VERBOSE=1 test') self.assertEqual(check.tests_config, 'make TEST_VERBOSE=1 test')
def test_scan_for_tests_setup(self):
"""
Test scan_for_tests with setup.py suite
"""
reqs = buildreq.Requirements("")
conf = config.Config("")
tcontent = tarball.Content("", "", "", [], conf, "")
listdir_backup = os.listdir
check.os.listdir = mock_generator(['setup.py'])
content = 'test_suite'
m_open = mock_open(read_data=content)
with patch(self.open_name, m_open, create=True):
conf.default_pattern = "distutils3"
check.scan_for_tests('pkgdir', conf, reqs, tcontent)
check.os.listdir = listdir_backup
self.assertEqual(check.tests_config,
'PYTHONPATH=%{buildroot}$(python -c "import sys; print(sys.path[-1])") '
'python setup.py test')
def test_scan_for_tests_cmake(self): def test_scan_for_tests_cmake(self):
""" """
Test scan_for_tests with cmake suite Test scan_for_tests with cmake suite
-1
View File
@@ -6,7 +6,6 @@ import config
# Structure: (url, build_pattern) # Structure: (url, build_pattern)
BUILD_PAT_URL = [ BUILD_PAT_URL = [
("https://cran.r-project.org/src/contrib/raster_3.0-12.tar.gz", "R"), ("https://cran.r-project.org/src/contrib/raster_3.0-12.tar.gz", "R"),
("https://ftp.osuosl.org/pub/cran/src/contrib/hexbin_1.28.5.tar.gz", "R"),
("http://pypi.debian.net/argparse/argparse-1.4.0.tar.gz", "distutils3"), ("http://pypi.debian.net/argparse/argparse-1.4.0.tar.gz", "distutils3"),
("https://pypi.python.org/packages/source/T/Tempita/Tempita-0.5.2.tar.gz", "distutils3"), ("https://pypi.python.org/packages/source/T/Tempita/Tempita-0.5.2.tar.gz", "distutils3"),
("https://cpan.metacpan.org/authors/id/T/TO/TODDR/IO-Tty-1.14.tar.gz", "cpan"), ("https://cpan.metacpan.org/authors/id/T/TO/TODDR/IO-Tty-1.14.tar.gz", "cpan"),
+1 -57
View File
@@ -71,7 +71,7 @@ class TestLicense(unittest.TestCase):
conf = config.Config("") conf = config.Config("")
conf.setup_patterns() conf.setup_patterns()
# remove the hash from license_hashes # remove the hash from license_hashes
del(conf.license_hashes[license.util.get_sha1sum('tests/COPYING_TEST')]) del(conf.license_hashes[license.get_sha1sum('tests/COPYING_TEST')])
conf.license_show = "license.show.url" conf.license_show = "license.show.url"
license.license_from_copying_hash('tests/COPYING_TEST', '', conf, '') license.license_from_copying_hash('tests/COPYING_TEST', '', conf, '')
@@ -233,62 +233,6 @@ class TestLicense(unittest.TestCase):
self.assertIn("Cannot find any license", out.getvalue()) self.assertIn("Cannot find any license", out.getvalue())
self.assertEqual(license.licenses, []) self.assertEqual(license.licenses, [])
def test_scan_for_licenses_skip(self):
"""
Test scan_for_licenses in temporary directory with licenses to skip
"""
conf = config.Config("")
conf.setup_patterns()
conf.license_skips = [['COPYING']]
with open('tests/COPYING_TEST', 'rb') as copyingf:
content = copyingf.read()
with tempfile.TemporaryDirectory() as tmpd:
# create the copying file
with open(os.path.join(tmpd, 'COPYING'), 'w') as newcopyingf:
newcopyingf.write(content.decode('utf-8'))
# create some cruft for testing
for testf in ['testlib.c', 'testmain.c', 'testheader.h']:
with open(os.path.join(tmpd, testf), 'w') as newtestf:
newtestf.write('test content')
# let's check that the proper thing is being printed as well
out = StringIO()
with redirect_stdout(out):
with self.assertRaises(SystemExit) as thread:
license.scan_for_licenses(tmpd, conf, '')
self.assertEqual(thread.exception.code, 1)
self.assertIn("Cannot find any license", out.getvalue())
self.assertEqual(license.licenses, [])
def test_scan_for_licenses_skip_prefix_slash(self):
"""
Test scan_for_licenses in temporary directory with licenses to skip
"""
conf = config.Config("")
conf.setup_patterns()
conf.license_skips = [['', 'COPYING']]
with open('tests/COPYING_TEST', 'rb') as copyingf:
content = copyingf.read()
with tempfile.TemporaryDirectory() as tmpd:
# create the copying file
with open(os.path.join(tmpd, 'COPYING'), 'w') as newcopyingf:
newcopyingf.write(content.decode('utf-8'))
# create some cruft for testing
for testf in ['testlib.c', 'testmain.c', 'testheader.h']:
with open(os.path.join(tmpd, testf), 'w') as newtestf:
newtestf.write('test content')
# let's check that the proper thing is being printed as well
out = StringIO()
with redirect_stdout(out):
with self.assertRaises(SystemExit) as thread:
license.scan_for_licenses(tmpd, conf, '')
self.assertEqual(thread.exception.code, 1)
self.assertIn("Cannot find any license", out.getvalue())
self.assertEqual(license.licenses, [])
def test_load_specfile(self): def test_load_specfile(self):
""" """
Test load_specfile with populated license list. This method is not Test load_specfile with populated license list. This method is not
+14 -1
View File
@@ -47,7 +47,7 @@ class TestSpecfileWrite(unittest.TestCase):
self.WRITES = self.WRITES[:4] + self.WRITES[6:] self.WRITES = self.WRITES[:4] + self.WRITES[6:]
self.assertEqual(expect, self.WRITES) self.assertEqual(expect, self.WRITES)
def test_write_nvr(self): def test_write_nvr_no_urlban(self):
""" """
test Specfile.write_nvr with no urlban set test Specfile.write_nvr with no urlban set
""" """
@@ -59,6 +59,19 @@ class TestSpecfileWrite(unittest.TestCase):
"Source0 : http://www.testpkg.com/testpkg/pkg-1.0.tar.gz\n"] "Source0 : http://www.testpkg.com/testpkg/pkg-1.0.tar.gz\n"]
self.assertEqual(expect, self.WRITES) self.assertEqual(expect, self.WRITES)
def test_write_nvr_urlban(self):
"""
test Specfile.write_nvr with urlban set
"""
self.specfile.config.urlban = "www.testpkg.com"
self.specfile.write_nvr()
expect = ["Name : pkg\n",
"Version : 1.0\n",
"Release : 2\n",
"URL : http://localhost/testpkg/pkg-1.0.tar.gz\n",
"Source0 : http://localhost/testpkg/pkg-1.0.tar.gz\n"]
self.assertEqual(expect, self.WRITES)
def test_write_sources(self): def test_write_sources(self):
""" """
test write_sources with all Specfile.sources set. test write_sources with all Specfile.sources set.
+1 -68
View File
@@ -2,8 +2,7 @@ import subprocess
import os import os
import tempfile import tempfile
import unittest import unittest
from unittest.mock import MagicMock, mock_open, patch import unittest.mock
import util import util
@@ -65,71 +64,5 @@ class TestUtil(unittest.TestCase):
self.assertTrue(util.binary_in_path('testbin')) self.assertTrue(util.binary_in_path('testbin'))
self.assertEqual(util.os_paths, [tmpd]) self.assertEqual(util.os_paths, [tmpd])
def test__process_build_log_bad_patch(self):
"""
Test _process_build_log with a bad patch
"""
def isfile_mock(_):
return True
isfile_backup = util.os.path.isfile
util.os.path.isfile = isfile_mock
call_backup = util.call
util.call = MagicMock()
open_name = 'util.open_auto'
content = "Patch #1 (bad.patch):\nHunk #1 FAILED at 1."
m_open = mock_open(read_data=content)
with patch(open_name, m_open, create=True):
util._process_build_log('filename')
util.os.path.isfile = isfile_backup
mock_call = util.call
util.call = call_backup
self.assertTrue(len(mock_call.mock_calls) == 3)
def test_globlike_match(self):
"""
Test globlike_match
"""
match_name = ['a', 'b', 'c']
file_path = 'a/b'
self.assertFalse(util.globlike_match(file_path, match_name))
match_name = ['a', 'c']
file_path = 'a/b'
self.assertFalse(util.globlike_match(file_path, match_name))
match_name = ['a', 'bb*']
file_path = 'a/b'
self.assertFalse(util.globlike_match(file_path, match_name))
match_name = ['a', 'b*']
file_path = 'a/ab'
self.assertFalse(util.globlike_match(file_path, match_name))
match_name = ['a', '*a']
file_path = 'a/ab'
self.assertFalse(util.globlike_match(file_path, match_name))
match_name = ['a', 'c*']
file_path = 'a/b'
self.assertFalse(util.globlike_match(file_path, match_name))
match_name = ['a', '*c']
file_path = 'a/b'
self.assertFalse(util.globlike_match(file_path, match_name))
match_name = ['a', 'b*']
file_path = 'a/b'
self.assertTrue(util.globlike_match(file_path, match_name))
match_name = ['a', '*b']
file_path = 'a/b'
self.assertTrue(util.globlike_match(file_path, match_name))
match_name = ['a', 'b']
file_path = 'a/b'
self.assertTrue(util.globlike_match(file_path, match_name))
if __name__ == '__main__': if __name__ == '__main__':
unittest.main(buffer=True) unittest.main(buffer=True)