mirror of
https://github.com/clearlinux/autospec.git
synced 2026-08-20 22:17:57 +00:00
Compare commits
33 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b5d8cf5341 | |||
| cd8d0065aa | |||
| 6aaa12ff76 | |||
| 65cf152900 | |||
| 99a7985f29 | |||
| 9594167cc7 | |||
| c62c42a21d | |||
| a88ffdc2a7 | |||
| 936534a889 | |||
| d73a1e70d8 | |||
| f07e061437 | |||
| d4144f5efd | |||
| 07a959cc83 | |||
| e36a856c50 | |||
| 2618dc3eb1 | |||
| 8b9384758b | |||
| 94c6be068b | |||
| f4a13a5a93 | |||
| 5424026110 | |||
| e822d6e48d | |||
| 9bfe801c96 | |||
| 412ce5ee2e | |||
| 1fa3bdd6e0 | |||
| 4ea76c998e | |||
| b2d28bb55a | |||
| 4d029647d7 | |||
| 5279a11b53 | |||
| a19cdc79b4 | |||
| 185099bba8 | |||
| 7b01f0ba82 | |||
| 6a4b23bb3e | |||
| c6d7bdb41c | |||
| a16ede7440 |
@@ -0,0 +1,7 @@
|
|||||||
|
## 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
|
||||||
+14
@@ -128,6 +128,14 @@ 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
|
||||||
@@ -204,6 +212,12 @@ ${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
|
||||||
|
|||||||
@@ -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 \"{}\"".format(path)
|
cmd = "nm --defined-only -g --dynamic \"{}\" | c++filt".format(path)
|
||||||
lines = None
|
lines = None
|
||||||
|
|
||||||
ret = set()
|
ret = set()
|
||||||
|
|||||||
@@ -277,6 +277,9 @@ def package(args, url, name, archives, workingdir):
|
|||||||
# specfile template is assumed "correct" and any failures need to be manually addressed
|
# specfile template is assumed "correct" and any failures need to be manually addressed
|
||||||
break
|
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/" \
|
||||||
@@ -297,6 +300,10 @@ def package(args, url, name, archives, workingdir):
|
|||||||
conf.create_buildreq_cache(content.version, requirements.buildreqs_cache)
|
conf.create_buildreq_cache(content.version, requirements.buildreqs_cache)
|
||||||
print_build_failed()
|
print_build_failed()
|
||||||
sys.exit(1)
|
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)
|
||||||
elif os.path.isfile("README.clear"):
|
elif os.path.isfile("README.clear"):
|
||||||
try:
|
try:
|
||||||
print("\nREADME.clear CONTENTS")
|
print("\nREADME.clear CONTENTS")
|
||||||
|
|||||||
@@ -215,6 +215,8 @@ 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)
|
||||||
|
|
||||||
|
|||||||
+18
-8
@@ -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,8 +518,13 @@ 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 pkg := cmake_modules.get(module):
|
if pkgs := cmake_modules.get(module):
|
||||||
self.add_buildreq(pkg)
|
# Some of the entries in cmake_modules list multiple packages, space-separated, so we need to split.
|
||||||
|
# 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)
|
||||||
|
|
||||||
@@ -704,6 +709,7 @@ 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:
|
||||||
@@ -711,16 +717,20 @@ 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:
|
||||||
name = config.alias
|
pypi_name = config.alias
|
||||||
pypi_name = pypidata.get_pypi_name(name)
|
pypi_name = pypidata.get_pypi_name(pypi_name)
|
||||||
pypi_json = pypidata.get_pypi_metadata(pypi_name)
|
pypi_json = pypidata.get_pypi_metadata(pypi_name)
|
||||||
if pypi_json:
|
if not 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 = {}
|
package_pypi = {"name": pypi_name}
|
||||||
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")
|
||||||
@@ -758,7 +768,7 @@ class Requirements(object):
|
|||||||
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:
|
if "Cargo.toml" in files and 'Makefile' not 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:
|
||||||
|
|||||||
+8
-17
@@ -64,34 +64,32 @@ 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 = "make {}check".format(makeflags)
|
make_check = "{} {}check".format(make_command, makeflags)
|
||||||
cmake_check = "make test"
|
cmake_check = "{} test".format(make_command)
|
||||||
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" \
|
||||||
"make {}check\nmodule unload openmpi".format(makeflags)
|
"{} {}check\nmodule unload openmpi".format(make_command, 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" \
|
||||||
"make test\nmodule unload openmpi"
|
"{} test\nmodule unload openmpi".format(make_command)
|
||||||
|
|
||||||
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" \
|
||||||
"make {}check || :\nmodule unload openmpi".format(makeflags)
|
"{} {}check || :\nmodule unload openmpi".format(make_command, 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" \
|
||||||
"make test || :\nmodule unload openmpi"
|
"{} test || :\nmodule unload openmpi".format(make_command)
|
||||||
|
|
||||||
perl_check = "make TEST_VERBOSE=1 test"
|
perl_check = "{} TEST_VERBOSE=1 test".format(make_command)
|
||||||
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,
|
||||||
}
|
}
|
||||||
@@ -144,13 +142,6 @@ 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 . " \
|
||||||
|
|||||||
+20
-1
@@ -110,6 +110,7 @@ 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
|
||||||
@@ -192,6 +193,7 @@ class Config(object):
|
|||||||
"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",
|
"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
|
||||||
@@ -320,6 +322,7 @@ 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),
|
||||||
@@ -345,7 +348,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:
|
if "cran.r-project.org" in url or "cran.rstudio.com" in url or "/pub/cran/" in url:
|
||||||
self.set_build_pattern("R", 10)
|
self.set_build_pattern("R", 10)
|
||||||
|
|
||||||
# python
|
# python
|
||||||
@@ -835,6 +838,18 @@ 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)
|
||||||
@@ -995,6 +1010,10 @@ 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
|
# 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)
|
content = self.read_file(os.path.join(self.download_path, "cargo_vendors"), track=True)
|
||||||
if content:
|
if content:
|
||||||
|
|||||||
@@ -71,14 +71,8 @@ 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
|
||||||
|
|
||||||
@@ -170,7 +164,6 @@ 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
|
||||||
|
|||||||
@@ -124,7 +124,9 @@ 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
|
||||||
@@ -175,6 +177,7 @@ 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
|
||||||
@@ -284,6 +287,7 @@ 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
|
||||||
@@ -459,6 +463,7 @@ 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
|
||||||
@@ -548,6 +553,7 @@ 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
|
||||||
@@ -621,6 +627,7 @@ 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
|
||||||
@@ -650,6 +657,7 @@ 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
|
||||||
@@ -1124,6 +1132,7 @@ 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
|
||||||
@@ -1298,6 +1307,8 @@ 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)
|
||||||
@@ -1492,6 +1503,7 @@ 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
|
||||||
|
|||||||
+2
-28
@@ -197,33 +197,6 @@ 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:
|
||||||
@@ -245,7 +218,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 self.globlike_match(norm_filename, match_name):
|
if util.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
|
||||||
@@ -404,6 +377,7 @@ 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"),
|
||||||
|
|||||||
+28
-16
@@ -29,7 +29,7 @@ import urllib.parse
|
|||||||
|
|
||||||
import chardet
|
import chardet
|
||||||
import download
|
import download
|
||||||
from util import get_contents, get_sha1sum, print_fatal, print_warning
|
import util
|
||||||
|
|
||||||
default_license = "TO BE DETERMINED"
|
default_license = "TO BE DETERMINED"
|
||||||
|
|
||||||
@@ -55,8 +55,6 @@ 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
|
||||||
|
|
||||||
@@ -96,7 +94,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 = get_contents(copying)
|
data = util.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
|
||||||
@@ -109,7 +107,7 @@ def license_from_copying_hash(copying, srcdir, config, name):
|
|||||||
if not data:
|
if not data:
|
||||||
return
|
return
|
||||||
|
|
||||||
hash_sum = get_sha1sum(copying)
|
hash_sum = util.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}
|
||||||
@@ -142,9 +140,24 @@ def license_from_copying_hash(copying, srcdir, config, name):
|
|||||||
else:
|
else:
|
||||||
if not config.license_show:
|
if not config.license_show:
|
||||||
return
|
return
|
||||||
print_warning("Unknown license {0} with hash {1}".format(copying, hash_sum))
|
util.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}
|
||||||
print_warning("Visit {0} to enter".format(hash_url))
|
util.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):
|
||||||
@@ -162,12 +175,13 @@ 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))?$")
|
target_pat = re.compile(r"^((copying)|(licen[cs]e)|(e[dp]l-v\d+))|(licen[cs]e)(\.(txt|xml))?|(intel simplified software license.*\.txt)$")
|
||||||
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_from_copying_hash(os.path.join(dirpath, name),
|
license_path = os.path.join(dirpath, name)
|
||||||
srcdir, config, pkg_name)
|
if not skip_license(license_path, config):
|
||||||
|
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
|
||||||
@@ -179,11 +193,12 @@ def scan_for_licenses(srcdir, config, pkg_name):
|
|||||||
# 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?|licensing)$', dirbase) and re.search(r'\.txt$', name):
|
||||||
license_from_copying_hash(os.path.join(dirpath, name),
|
license_path = os.path.join(dirpath, name)
|
||||||
srcdir, config, pkg_name)
|
if not skip_license(license_path, config):
|
||||||
|
license_from_copying_hash(license_path, srcdir, config, pkg_name)
|
||||||
|
|
||||||
if not licenses:
|
if not licenses:
|
||||||
print_fatal(" Cannot find any license or a valid {}.license file!\n".format(pkg_name))
|
util.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)))
|
||||||
@@ -191,9 +206,6 @@ 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
|
||||||
|
|||||||
+43
-11
@@ -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,6 +26,8 @@
|
|||||||
3-Clause
|
3-Clause
|
||||||
3-clause
|
3-clause
|
||||||
3BSD
|
3BSD
|
||||||
|
=========================
|
||||||
|
>=-2
|
||||||
@CPACK_RPM_PACKAGE_LICENSE@
|
@CPACK_RPM_PACKAGE_LICENSE@
|
||||||
AGPLv3+
|
AGPLv3+
|
||||||
ALv2
|
ALv2
|
||||||
@@ -35,7 +37,12 @@ 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
|
||||||
@@ -43,6 +50,7 @@ BSD_3_clause
|
|||||||
BSDish
|
BSDish
|
||||||
BSL
|
BSL
|
||||||
CC-BY
|
CC-BY
|
||||||
|
Clause
|
||||||
Commercial
|
Commercial
|
||||||
Corp.
|
Corp.
|
||||||
Distribution
|
Distribution
|
||||||
@@ -53,6 +61,7 @@ EPL
|
|||||||
Eclipse
|
Eclipse
|
||||||
Expat(MIT/X11)
|
Expat(MIT/X11)
|
||||||
Expat/MIT
|
Expat/MIT
|
||||||
|
FOUNDATION
|
||||||
Foundation
|
Foundation
|
||||||
FreeBSD
|
FreeBSD
|
||||||
GENERAL
|
GENERAL
|
||||||
@@ -60,30 +69,39 @@ 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
|
||||||
@@ -95,9 +113,13 @@ 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
|
||||||
@@ -111,31 +133,46 @@ 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
|
||||||
@@ -143,11 +180,16 @@ 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
|
||||||
@@ -160,13 +202,3 @@ with
|
|||||||
your
|
your
|
||||||
|
|
|
|
||||||
~
|
~
|
||||||
Permission
|
|
||||||
a
|
|
||||||
charge
|
|
||||||
copy
|
|
||||||
granted
|
|
||||||
hereby
|
|
||||||
obtaining
|
|
||||||
of
|
|
||||||
person
|
|
||||||
to
|
|
||||||
|
|||||||
@@ -16,9 +16,11 @@ 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
|
||||||
|
|||||||
@@ -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]
|
||||||
output, err, code = self.exec_cmd(args)
|
_, 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:
|
||||||
@@ -212,16 +212,15 @@ class Verifier(object):
|
|||||||
@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)
|
||||||
|
|||||||
+12
-5
@@ -27,6 +27,15 @@ 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
|
||||||
@@ -35,11 +44,9 @@ 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
|
||||||
for prefix in ["pypi_", "python_"]:
|
name = fixup_pypi_prefix(name)
|
||||||
if name.startswith(prefix):
|
if pkg_search(name):
|
||||||
name = name[len(prefix):]
|
return name
|
||||||
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:
|
||||||
|
|||||||
+77
-16
@@ -37,9 +37,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-v3 -mapxf -mavx10.1"
|
APX_CFLAGS = "-march=x86-64-v4 -mapxf"
|
||||||
APX_LCFLAGS = "-march=x86-64-v3"
|
APX_LCFLAGS = "-march=x86-64-v4"
|
||||||
APX_LFLAGS = "-Wl,-z,x86-64-v3"
|
APX_LFLAGS = "-Wl,-z,x86-64-v4"
|
||||||
|
|
||||||
|
|
||||||
class Specfile(object):
|
class Specfile(object):
|
||||||
@@ -326,6 +326,9 @@ 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))
|
||||||
|
|
||||||
@@ -537,7 +540,7 @@ 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))
|
||||||
@@ -548,7 +551,7 @@ class Specfile(object):
|
|||||||
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 '{self.config.cargo_vendors}' >> .cargo/config.toml")
|
self._write_strip(f"echo '\n{self.config.cargo_vendors}' >> .cargo/config.toml")
|
||||||
if self.config.subdir:
|
if self.config.subdir:
|
||||||
self._write_strip("popd")
|
self._write_strip("popd")
|
||||||
|
|
||||||
@@ -1163,7 +1166,7 @@ class Specfile(object):
|
|||||||
self.write_build_prepend()
|
self.write_build_prepend()
|
||||||
self._write_strip("GOAMD64=v3")
|
self._write_strip("GOAMD64=v3")
|
||||||
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 {APX_CFLAGS} {APX_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} "')
|
||||||
@@ -1345,6 +1348,8 @@ 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(),
|
||||||
@@ -1353,6 +1358,8 @@ 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()
|
||||||
@@ -1430,6 +1437,9 @@ 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)
|
||||||
@@ -1460,8 +1470,6 @@ 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")
|
||||||
@@ -1798,6 +1806,59 @@ 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 = ""
|
||||||
@@ -1825,6 +1886,9 @@ 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:
|
||||||
@@ -2059,14 +2123,11 @@ 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)
|
||||||
if self.config.install_macro:
|
self._write_strip("cargo install --path .")
|
||||||
self._write_strip(self.config.install_macro)
|
self._write_strip("mkdir -p %{buildroot}/usr/bin")
|
||||||
else:
|
self._write_strip('pushd "${HOME}/.cargo/bin/"')
|
||||||
self._write_strip("cargo install --path .")
|
self._write_strip("mv * %{buildroot}/usr/bin/")
|
||||||
self._write_strip("mkdir -p %{buildroot}/usr/bin")
|
self._write_strip("popd")
|
||||||
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()
|
||||||
|
|||||||
+8
-5
@@ -120,12 +120,15 @@ 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))
|
||||||
extract_method(extraction_path)
|
try:
|
||||||
|
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)
|
content.extractall(path=extraction_path, filter='data')
|
||||||
|
|
||||||
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,7 +147,7 @@ class Source():
|
|||||||
def extract_zst(self, extraction_path):
|
def extract_zst(self, extraction_path):
|
||||||
"""Extract zst in path."""
|
"""Extract zst in path."""
|
||||||
with tarfile.open(fileobj=zstd.open(self.path, 'rb'), mode='r|') as content:
|
with tarfile.open(fileobj=zstd.open(self.path, 'rb'), mode='r|') as content:
|
||||||
content.extractall(path=extraction_path)
|
content.extractall(path=extraction_path, filter='data')
|
||||||
|
|
||||||
|
|
||||||
def convert_version(ver_str, name):
|
def convert_version(ver_str, name):
|
||||||
@@ -153,7 +156,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"]
|
"jurko", "%2f", "%2F", "%20", "x265", "autotools"]
|
||||||
|
|
||||||
# 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
|
||||||
@@ -169,7 +172,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('_', '.')
|
ver_str = ver_str.strip().replace('-', '.').replace('_', '.').replace('+', '.')
|
||||||
|
|
||||||
# remove banned substrings
|
# remove banned substrings
|
||||||
for sub in banned_subs:
|
for sub in banned_subs:
|
||||||
|
|||||||
+28
-1
@@ -156,7 +156,6 @@ 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]
|
||||||
@@ -274,3 +273,31 @@ 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
|
||||||
|
|||||||
@@ -1613,3 +1613,4 @@ https://pigeonhole.dovecot.org/releases/2.3/dovecot-2.3.11-pigeonhole-0.5.11.tar
|
|||||||
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://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
|
||||||
|
|||||||
@@ -499,6 +499,95 @@ 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
|
||||||
|
|||||||
@@ -152,26 +152,6 @@ 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
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ 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"),
|
||||||
|
|||||||
+57
-1
@@ -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.get_sha1sum('tests/COPYING_TEST')])
|
del(conf.license_hashes[license.util.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,6 +233,62 @@ 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
|
||||||
|
|||||||
+68
-1
@@ -2,7 +2,8 @@ import subprocess
|
|||||||
import os
|
import os
|
||||||
import tempfile
|
import tempfile
|
||||||
import unittest
|
import unittest
|
||||||
import unittest.mock
|
from unittest.mock import MagicMock, mock_open, patch
|
||||||
|
|
||||||
import util
|
import util
|
||||||
|
|
||||||
|
|
||||||
@@ -64,5 +65,71 @@ 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)
|
||||||
|
|||||||
Reference in New Issue
Block a user