mirror of
https://github.com/clearlinux/autospec.git
synced 2026-08-21 06:26:18 +00:00
Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e822d6e48d | |||
| 9bfe801c96 | |||
| 412ce5ee2e | |||
| 1fa3bdd6e0 | |||
| 4ea76c998e | |||
| b2d28bb55a | |||
| 4d029647d7 | |||
| 5279a11b53 | |||
| a19cdc79b4 | |||
| 185099bba8 | |||
| 7b01f0ba82 | |||
| 6a4b23bb3e | |||
| c6d7bdb41c | |||
| a16ede7440 |
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|
||||||
|
|||||||
+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 . " \
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -320,6 +321,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),
|
||||||
@@ -995,6 +997,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:
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
+1
-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
|
||||||
|
|||||||
+27
-10
@@ -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"
|
||||||
|
|
||||||
@@ -96,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 = 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 +109,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 +142,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):
|
||||||
@@ -166,8 +181,9 @@ def scan_for_licenses(srcdir, config, pkg_name):
|
|||||||
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 +195,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)))
|
||||||
|
|||||||
+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
|
||||||
|
|||||||
+10
-2
@@ -1345,6 +1345,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 +1355,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 +1434,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 +1467,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")
|
||||||
@@ -1825,6 +1830,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:
|
||||||
|
|||||||
+2
-2
@@ -125,7 +125,7 @@ class Source():
|
|||||||
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 +144,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):
|
||||||
|
|||||||
@@ -274,3 +274,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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
+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