From f90b6f7fb581978759330589a8b5d525f24a88aa Mon Sep 17 00:00:00 2001 From: Daniel Garcia Moreno Date: Mon, 3 Feb 2025 11:09:12 +0100 Subject: [PATCH] Add declarative build support to SpecCheck Fix https://github.com/rpm-software-management/rpmlint/issues/1311 --- rpmlint/checks/SpecCheck.py | 15 +++++- test/spec/libspelling.spec | 103 ++++++++++++++++++++++++++++++++++++ test/test_speccheck.py | 17 ++++++ 3 files changed, 134 insertions(+), 1 deletion(-) create mode 100644 test/spec/libspelling.spec diff --git a/rpmlint/checks/SpecCheck.py b/rpmlint/checks/SpecCheck.py index 6f1f15e8d..135669041 100644 --- a/rpmlint/checks/SpecCheck.py +++ b/rpmlint/checks/SpecCheck.py @@ -66,6 +66,8 @@ def re_tag_compile(tag): obsoletes_regex = re.compile(r'^Obsoletes:\s*(.*)', re.IGNORECASE) conflicts_regex = re.compile(r'^(?:Build)?Conflicts:\s*(.*)', re.IGNORECASE) +declarative_regex = re.compile(r'^BuildSystem:\s*(.*)', re.IGNORECASE) + compop_regex = re.compile(r'[<>=]') setup_regex = re.compile(r'%setup\b') # intentionally no whitespace before! @@ -143,6 +145,7 @@ def _default_state(self): self.indent_spaces = 0 self.indent_tabs = 0 self.section = {} + self.declarative = False self.current_section = 'package' # None == main package @@ -198,7 +201,10 @@ def check_spec(self, pkg): # Run checks for whole package self._check_no_buildroot_tag(pkg, self.buildroot) - self._check_no_s_section(pkg, self.section) + + if not self.declarative: + self._check_no_s_section(pkg, self.section) + self._check_superfluous_clean_section(pkg, self.section) self._check_more_than_one_changelog_section(pkg, self.section) self._check_lib_package_without_mklibname(pkg, self.is_lib_pkg, self.mklibname) @@ -360,6 +366,7 @@ def _check_line(self, line): Run check methods for this line. """ + self._checkline_declarative(line) self._checkline_break_space(line) if self._checkline_section(line): return @@ -398,6 +405,12 @@ def _check_line(self, line): # line checks methods + def _checkline_declarative(self, line): + # Do not override if we found the regex in previous lines + if self.declarative: + return + self.declarative = bool(declarative_regex.search(line)) + def _checkline_break_space(self, line): char = line.find(UNICODE_NBSP) if char != -1: diff --git a/test/spec/libspelling.spec b/test/spec/libspelling.spec new file mode 100644 index 000000000..517897c54 --- /dev/null +++ b/test/spec/libspelling.spec @@ -0,0 +1,103 @@ +# +# spec file for package libspelling +# +# Copyright (c) 2025 SUSE LLC +# +# All modifications and additions to the file contributed by third parties +# remain the property of their copyright owners, unless otherwise agreed +# upon. The license for this file, and modifications and additions to the +# file, is the same license as for the pristine package itself (unless the +# license for the pristine package is not an Open Source License, in which +# case the license is the MIT License). An "Open Source License" is a +# license that conforms to the Open Source Definition (Version 1.9) +# published by the Open Source Initiative. + +# Please submit bugfixes or comments via https://bugs.opensuse.org/ +# + + +%define so_ver 1-2 +%define api_ver 1 + +Name: libspelling +Version: 0.4.6 +Release: 0 +Summary: A spellcheck library for GTK 4 +License: LGPL-2.1-or-later +URL: https://gitlab.gnome.org/chergert/libspelling +Source: %{name}-%{version}.tar.zst + +BuildRequires: c_compiler +BuildRequires: meson +BuildRequires: pkgconfig +BuildRequires: pkgconfig(enchant-2) +BuildRequires: pkgconfig(gi-docgen) +BuildRequires: pkgconfig(gio-2.0) +BuildRequires: pkgconfig(gobject-introspection-1.0) +BuildRequires: pkgconfig(gtk4) >= 4.15.5 +BuildRequires: pkgconfig(gtksourceview-5) +BuildRequires: pkgconfig(icu-uc) +BuildRequires: pkgconfig(vapigen) +# For tests +BuildRequires: myspell-en_US + +BuildSystem: meson +BuildOption: -Dsysprof=false + +%description +A spellcheck library for GTK 4. +This library is heavily based upon GNOME Text Editor and GNOME +Builder's spellcheck implementation. However, it is licensed +LGPL-2.1-or-later + +%package -n libspelling%{so_ver} +Summary: Shared libraries for %{name} +Provides: %{name} = %{version} + +%description -n libspelling%{so_ver} +Shared libraries for %{name}. + +%package -n typelib-1_0-Spelling-%{api_ver} +Summary: Introspection file for %{name} + +%description -n typelib-1_0-Spelling-1 +Introspection file for %{name}. + +%package devel +Summary: Development files for %{name} +Requires: libspelling%{so_ver} = %{version} +Requires: typelib-1_0-Spelling-%{api_ver} = %{version} + +%description devel +The %{name}-devel package contains libraries and header files for +developing applications that use %{name}. + +%lang_package + +%install -a +%find_lang %{name} %{?no_lang_C} + +%ldconfig_scriptlets -n libspelling%{so_ver} + +%files -n libspelling%{so_ver} +%license COPYING +%doc NEWS README.md +%{_libdir}/libspelling-%{api_ver}.so.* + +%files -n typelib-1_0-Spelling-%{api_ver} +%{_libdir}/girepository-1.0/Spelling-%{api_ver}.typelib + +%files devel +%doc %{_datadir}/doc/libspelling-%{api_ver}/ +%{_includedir}/libspelling-%{api_ver} +%{_libdir}/libspelling-%{api_ver}.so +%{_libdir}/pkgconfig/libspelling-%{api_ver}.pc +%{_datadir}/gir-1.0/Spelling-%{api_ver}.gir +%dir %{_datadir}/vala +%dir %{_datadir}/vala/vapi +%{_datadir}/vala/vapi/libspelling-%{api_ver}.deps +%{_datadir}/vala/vapi/libspelling-%{api_ver}.vapi + +%files lang -f %{name}.lang + +%changelog diff --git a/test/test_speccheck.py b/test/test_speccheck.py index ef905804c..cf3d979f5 100644 --- a/test/test_speccheck.py +++ b/test/test_speccheck.py @@ -899,6 +899,23 @@ def test_check_no_essential_section(package, speccheck): assert 'W: no-%check-section' in out +@pytest.mark.parametrize('package', ['spec/libspelling']) +def test_check_no_essential_section_declarative(package, speccheck): + """Test for declarative build check + Test if specfile does not have essential section tag but uses declarative + build. + https://github.com/rpm-software-management/rpmlint/issues/1311 + """ + output, test = speccheck + pkg = get_tested_spec_package(package) + test.check_spec(pkg) + out = output.print_results(output.results) + assert 'W: no-%prep-section' not in out + assert 'W: no-%install-section' not in out + assert 'W: no-%build-section' not in out + assert 'W: no-%check-section' not in out + + @pytest.mark.parametrize('package', ['spec/SpecCheck2']) def test_check_no_essential_section_not_applied(package, speccheck): """Test for no-%%%s-section check