diff -Nru libmodulemd-2.12.0/bindings/python/meson.build libmodulemd-2.13.0/bindings/python/meson.build --- libmodulemd-2.12.0/bindings/python/meson.build 2021-01-15 02:04:56.000000000 +0000 +++ libmodulemd-2.13.0/bindings/python/meson.build 2021-07-09 09:29:23.324000000 +0000 @@ -2,17 +2,19 @@ gobject_overrides_dir_py2 = get_option('gobject_overrides_dir_py2') # Python 3 -if gobject_overrides_dir_py3 == '' - ret = run_command([python3, '-c', 'import gi; print(gi._overridesdir)']) +if with_py3 + if gobject_overrides_dir_py3 == '' + ret = run_command([python3, '-c', 'import gi; print(gi._overridesdir)']) - if ret.returncode() != 0 - error('Failed to determine Python 3 pygobject overridedir') - else - gobject_overrides_dir_py3 = ret.stdout().strip() + if ret.returncode() != 0 + error('Failed to determine Python 3 pygobject overridedir') + else + gobject_overrides_dir_py3 = ret.stdout().strip() + endif endif -endif -install_data('gi/overrides/Modulemd.py', install_dir: gobject_overrides_dir_py3) + install_data('gi/overrides/Modulemd.py', install_dir: gobject_overrides_dir_py3) +endif # Python 2 if with_py2 diff -Nru libmodulemd-2.12.0/.ci/ci-mageia.sh libmodulemd-2.13.0/.ci/ci-mageia.sh --- libmodulemd-2.12.0/.ci/ci-mageia.sh 2021-01-15 02:04:56.000000000 +0000 +++ libmodulemd-2.13.0/.ci/ci-mageia.sh 2021-07-09 09:29:23.319000000 +0000 @@ -8,7 +8,7 @@ set -e set -x -release=${1:-7} +release=${1:-8} mmd_run_docker_tests \ os=mageia \ diff -Nru libmodulemd-2.12.0/.ci/fedora/ci-tasks.sh libmodulemd-2.13.0/.ci/fedora/ci-tasks.sh --- libmodulemd-2.12.0/.ci/fedora/ci-tasks.sh 2021-01-15 02:04:56.000000000 +0000 +++ libmodulemd-2.13.0/.ci/fedora/ci-tasks.sh 2021-07-09 09:29:23.320000000 +0000 @@ -55,6 +55,7 @@ set -e meson --buildtype=debug \ -Dskip_introspection=true \ + -Dwith_py3=false \ ci_scanbuild pushd ci_scanbuild diff -Nru libmodulemd-2.12.0/.ci/mageia/ci-tasks.sh libmodulemd-2.13.0/.ci/mageia/ci-tasks.sh --- libmodulemd-2.12.0/.ci/mageia/ci-tasks.sh 2021-01-15 02:04:56.000000000 +0000 +++ libmodulemd-2.13.0/.ci/mageia/ci-tasks.sh 2021-07-09 09:29:23.321000000 +0000 @@ -41,6 +41,7 @@ set -e meson --buildtype=debug \ -Dskip_introspection=true \ + -Dwith_py3=false \ $COMMON_MESON_ARGS \ ci_scanbuild diff -Nru libmodulemd-2.12.0/.ci/mageia/Dockerfile.deps.tmpl libmodulemd-2.13.0/.ci/mageia/Dockerfile.deps.tmpl --- libmodulemd-2.12.0/.ci/mageia/Dockerfile.deps.tmpl 2021-01-15 02:04:56.000000000 +0000 +++ libmodulemd-2.13.0/.ci/mageia/Dockerfile.deps.tmpl 2021-07-09 09:29:23.321000000 +0000 @@ -24,7 +24,7 @@ openssl \ pkgconf \ popt-devel \ - python2-six \ + python3-six \ python3-autopep8 \ python3-devel \ python3-gitpython \ diff -Nru libmodulemd-2.12.0/.ci/openmandriva/ci-tasks.sh libmodulemd-2.13.0/.ci/openmandriva/ci-tasks.sh --- libmodulemd-2.12.0/.ci/openmandriva/ci-tasks.sh 2021-01-15 02:04:56.000000000 +0000 +++ libmodulemd-2.13.0/.ci/openmandriva/ci-tasks.sh 2021-07-09 09:29:23.321000000 +0000 @@ -45,6 +45,7 @@ set -e CC=clang CXX=clang++ meson --buildtype=debug \ -Dskip_introspection=true \ + -Dwith_py3=false \ $COMMON_MESON_ARGS \ ci_scanbuild diff -Nru libmodulemd-2.12.0/debian/changelog libmodulemd-2.13.0/debian/changelog --- libmodulemd-2.12.0/debian/changelog 2021-02-11 15:23:55.000000000 +0000 +++ libmodulemd-2.13.0/debian/changelog 2021-10-28 22:30:29.000000000 +0000 @@ -1,3 +1,18 @@ +libmodulemd (2.13.0-1) unstable; urgency=medium + + * Declare compliance with Policy 4.6.0 with no changes. + * autopkgtest: fix the test with meson 0.60 by not passing + the obsolete "developer_build" meson option. Closes: #998026 + * Move the Python gir override to the gir-* package, drop the Python + handling and runtime dependency, and add python3-six as a dependency in + the autopkgtest environment. Closes: #996113 + * Adapt the watch file for modulemd-*.tar.xz releases. + * New upstream release: + - update the library symbols file + - update the upstream copyright years + + -- Peter Pentchev Fri, 29 Oct 2021 01:30:29 +0300 + libmodulemd (2.12.0-1) unstable; urgency=medium * Declare compliance with Policy 4.5.1 with no changes. diff -Nru libmodulemd-2.12.0/debian/control libmodulemd-2.13.0/debian/control --- libmodulemd-2.12.0/debian/control 2021-02-11 15:23:55.000000000 +0000 +++ libmodulemd-2.13.0/debian/control 2021-10-28 22:17:54.000000000 +0000 @@ -6,7 +6,6 @@ Build-Depends: debhelper-compat (= 13), dh-sequence-gir, - dh-sequence-python3, help2man, libgirepository1.0-dev, libglib2.0-dev, @@ -16,7 +15,7 @@ meson, pkg-config, python3-gi, -Standards-Version: 4.5.1 +Standards-Version: 4.6.0 Vcs-Git: https://salsa.debian.org/pkg-rpm-team/libmodulemd.git Vcs-Browser: https://salsa.debian.org/pkg-rpm-team/libmodulemd Homepage: https://github.com/fedora-modularity/libmodulemd @@ -39,7 +38,6 @@ Multi-Arch: same Depends: ${misc:Depends}, - ${python3:Depends}, ${shlibs:Depends}, gir1.2-modulemd-2.0 (= ${binary:Version}), libglib2.0-dev, @@ -81,4 +79,7 @@ files describing the modular repositories introduced in the Fedora project and RedHat Enterprise Linux. . - This package contains the gobject-introspection definitions. + This package contains the gobject-introspection definitions. Note that + there is an override written in Python, so any packages that use + the GObject introspection definitions with the libmodulemd Python + bindings must also depend on python3:any and python3-six. diff -Nru libmodulemd-2.12.0/debian/copyright libmodulemd-2.13.0/debian/copyright --- libmodulemd-2.12.0/debian/copyright 2021-02-11 15:23:55.000000000 +0000 +++ libmodulemd-2.13.0/debian/copyright 2021-10-28 22:25:14.000000000 +0000 @@ -7,7 +7,7 @@ Files: * Copyright: 2017 - 2020 Stephen Gallagher - 2016 - 2020 Red Hat, Inc. + 2016 - 2021 Red Hat, Inc. License: Expat Files: diff -Nru libmodulemd-2.12.0/debian/gir1.2-modulemd-2.0.install libmodulemd-2.13.0/debian/gir1.2-modulemd-2.0.install --- libmodulemd-2.12.0/debian/gir1.2-modulemd-2.0.install 2021-02-11 15:23:55.000000000 +0000 +++ libmodulemd-2.13.0/debian/gir1.2-modulemd-2.0.install 2021-10-28 22:17:54.000000000 +0000 @@ -1 +1,2 @@ usr/lib/*/girepository-1.0/Modulemd-2.0.typelib +usr/lib/python3/dist-packages/gi/overrides/Modulemd.py diff -Nru libmodulemd-2.12.0/debian/gir1.2-modulemd-2.0.lintian-overrides libmodulemd-2.13.0/debian/gir1.2-modulemd-2.0.lintian-overrides --- libmodulemd-2.12.0/debian/gir1.2-modulemd-2.0.lintian-overrides 1970-01-01 00:00:00.000000000 +0000 +++ libmodulemd-2.13.0/debian/gir1.2-modulemd-2.0.lintian-overrides 2021-10-28 22:17:54.000000000 +0000 @@ -0,0 +1,5 @@ +# The GObject introspection definitions may be consumed by tools +# written in languages other than Python; there is no need to +# pull the Python dependency in for everyone. See #996113 for +# the rationale. +gir1.2-modulemd-2.0: python-package-missing-depends-on-python diff -Nru libmodulemd-2.12.0/debian/libmodulemd2.symbols libmodulemd-2.13.0/debian/libmodulemd2.symbols --- libmodulemd-2.12.0/debian/libmodulemd2.symbols 2021-02-11 15:23:55.000000000 +0000 +++ libmodulemd-2.13.0/debian/libmodulemd2.symbols 2021-10-28 22:22:03.000000000 +0000 @@ -346,6 +346,7 @@ modulemd_module_stream_v1_set_xmd@Base 2.9.4 modulemd_module_stream_v2_add_component@Base 2.9.4 modulemd_module_stream_v2_add_content_license@Base 2.9.4 + modulemd_module_stream_v2_add_demodularized_rpm@Base 2.13.0 modulemd_module_stream_v2_add_dependencies@Base 2.9.4 modulemd_module_stream_v2_add_module_license@Base 2.9.4 modulemd_module_stream_v2_add_profile@Base 2.9.4 @@ -355,6 +356,7 @@ modulemd_module_stream_v2_add_servicelevel@Base 2.9.4 modulemd_module_stream_v2_associate_obsoletes@Base 2.10.0 modulemd_module_stream_v2_clear_content_licenses@Base 2.9.4 + modulemd_module_stream_v2_clear_demodularized_rpms@Base 2.13.0 modulemd_module_stream_v2_clear_dependencies@Base 2.9.4 modulemd_module_stream_v2_clear_module_components@Base 2.9.4 modulemd_module_stream_v2_clear_module_licenses@Base 2.9.4 @@ -370,6 +372,7 @@ modulemd_module_stream_v2_get_buildopts@Base 2.9.4 modulemd_module_stream_v2_get_community@Base 2.9.4 modulemd_module_stream_v2_get_content_licenses_as_strv@Base 2.9.4 + modulemd_module_stream_v2_get_demodularized_rpms@Base 2.13.0 modulemd_module_stream_v2_get_dependencies@Base 2.9.4 modulemd_module_stream_v2_get_description@Base 2.9.4 modulemd_module_stream_v2_get_documentation@Base 2.9.4 @@ -397,6 +400,7 @@ modulemd_module_stream_v2_new@Base 2.9.4 modulemd_module_stream_v2_parse_yaml@Base 2.9.4 modulemd_module_stream_v2_remove_content_license@Base 2.9.4 + modulemd_module_stream_v2_remove_demodularized_rpm@Base 2.13.0 modulemd_module_stream_v2_remove_dependencies@Base 2.9.4 modulemd_module_stream_v2_remove_module_component@Base 2.9.4 modulemd_module_stream_v2_remove_module_license@Base 2.9.4 @@ -405,6 +409,7 @@ modulemd_module_stream_v2_remove_rpm_component@Base 2.9.4 modulemd_module_stream_v2_remove_rpm_filter@Base 2.9.4 modulemd_module_stream_v2_replace_content_licenses@Base 2.9.4 + modulemd_module_stream_v2_replace_demodularized_rpms@Base 2.13.0 modulemd_module_stream_v2_replace_dependencies@Base 2.9.4 modulemd_module_stream_v2_replace_module_licenses@Base 2.9.4 modulemd_module_stream_v2_replace_rpm_api@Base 2.9.4 @@ -458,11 +463,13 @@ modulemd_ordered_str_keys_as_strv@Base 2.9.4 modulemd_packager_v3_add_build_config@Base 2.10.0 modulemd_packager_v3_add_component@Base 2.10.0 + modulemd_packager_v3_add_demodularized_rpm@Base 2.13.0 modulemd_packager_v3_add_module_license@Base 2.10.0 modulemd_packager_v3_add_profile@Base 2.10.0 modulemd_packager_v3_add_rpm_api@Base 2.10.0 modulemd_packager_v3_add_rpm_filter@Base 2.10.0 modulemd_packager_v3_clear_build_configs@Base 2.10.0 + modulemd_packager_v3_clear_demodularized_rpms@Base 2.13.0 modulemd_packager_v3_clear_module_components@Base 2.10.0 modulemd_packager_v3_clear_module_licenses@Base 2.10.0 modulemd_packager_v3_clear_profiles@Base 2.10.0 @@ -475,6 +482,7 @@ modulemd_packager_v3_get_build_config@Base 2.10.0 modulemd_packager_v3_get_build_config_contexts_as_strv@Base 2.10.0 modulemd_packager_v3_get_community@Base 2.10.0 + modulemd_packager_v3_get_demodularized_rpms@Base 2.13.0 modulemd_packager_v3_get_description@Base 2.10.0 modulemd_packager_v3_get_documentation@Base 2.10.0 modulemd_packager_v3_get_mdversion@Base 2.11.1 @@ -495,11 +503,13 @@ modulemd_packager_v3_get_xmd@Base 2.10.0 modulemd_packager_v3_new@Base 2.10.0 modulemd_packager_v3_parse_yaml@Base 2.10.0 + modulemd_packager_v3_remove_demodularized_rpm@Base 2.13.0 modulemd_packager_v3_remove_module_component@Base 2.10.0 modulemd_packager_v3_remove_module_license@Base 2.10.0 modulemd_packager_v3_remove_rpm_api@Base 2.10.0 modulemd_packager_v3_remove_rpm_component@Base 2.10.0 modulemd_packager_v3_remove_rpm_filter@Base 2.10.0 + modulemd_packager_v3_replace_demodularized_rpms@Base 2.13.0 modulemd_packager_v3_replace_rpm_api@Base 2.10.0 modulemd_packager_v3_replace_rpm_filters@Base 2.10.0 modulemd_packager_v3_set_community@Base 2.10.0 diff -Nru libmodulemd-2.12.0/debian/libmodulemd-dev.install libmodulemd-2.13.0/debian/libmodulemd-dev.install --- libmodulemd-2.12.0/debian/libmodulemd-dev.install 2021-02-11 15:23:55.000000000 +0000 +++ libmodulemd-2.13.0/debian/libmodulemd-dev.install 2021-10-28 22:17:54.000000000 +0000 @@ -1,5 +1,4 @@ usr/include/modulemd-2.0 usr/lib/*/libmodulemd.so usr/lib/*/pkgconfig/modulemd-2.0.pc -usr/lib/python3/dist-packages/gi/overrides/Modulemd.py usr/share/gir-1.0/Modulemd-2.0.gir diff -Nru libmodulemd-2.12.0/debian/tests/control libmodulemd-2.13.0/debian/tests/control --- libmodulemd-2.12.0/debian/tests/control 2021-02-11 15:23:55.000000000 +0000 +++ libmodulemd-2.13.0/debian/tests/control 2021-10-28 22:17:54.000000000 +0000 @@ -1,2 +1,2 @@ Tests: upstream.sh -Depends: @, build-essential, libmagic-dev, pkg-config, meson, python3-gi +Depends: @, build-essential, libmagic-dev, pkg-config, meson, python3-gi, python3-six diff -Nru libmodulemd-2.12.0/debian/tests/upstream.sh libmodulemd-2.13.0/debian/tests/upstream.sh --- libmodulemd-2.12.0/debian/tests/upstream.sh 2021-02-11 15:23:55.000000000 +0000 +++ libmodulemd-2.13.0/debian/tests/upstream.sh 2021-10-28 22:17:54.000000000 +0000 @@ -8,7 +8,6 @@ -Dwith_manpages=disabled \ -Dpython_name=python3 \ -Dwith_py2=false \ - -Ddeveloper_build=false \ -Dtest_installed_lib=true \ echo '=== Changing into the "build" directory' diff -Nru libmodulemd-2.12.0/debian/watch libmodulemd-2.13.0/debian/watch --- libmodulemd-2.12.0/debian/watch 2021-02-11 15:23:55.000000000 +0000 +++ libmodulemd-2.13.0/debian/watch 2021-10-28 22:17:54.000000000 +0000 @@ -1,2 +1,2 @@ version=4 -https://github.com/fedora-modularity/libmodulemd/releases .*/@PACKAGE@-@ANY_VERSION@@ARCHIVE_EXT@ +https://github.com/fedora-modularity/libmodulemd/releases .*/(?:lib)?modulemd-@ANY_VERSION@@ARCHIVE_EXT@ diff -Nru libmodulemd-2.12.0/fedora/libmodulemd.spec libmodulemd-2.13.0/fedora/libmodulemd.spec --- libmodulemd-2.12.0/fedora/libmodulemd.spec 2021-01-15 02:04:56.000000000 +0000 +++ libmodulemd-2.13.0/fedora/libmodulemd.spec 2021-07-09 09:29:23.325000000 +0000 @@ -135,7 +135,7 @@ %files %license COPYING -%doc README.md +%doc NEWS README.md %{_bindir}/modulemd-validator%{?v2_suffix} %{_mandir}/man1/modulemd-validator%{?v2_suffix}.1* %{_libdir}/%{upstream_name}.so.2* diff -Nru libmodulemd-2.12.0/.github/workflows/ci.yaml libmodulemd-2.13.0/.github/workflows/ci.yaml --- libmodulemd-2.12.0/.github/workflows/ci.yaml 2021-01-15 02:04:56.000000000 +0000 +++ libmodulemd-2.13.0/.github/workflows/ci.yaml 1970-01-01 00:00:00.000000000 +0000 @@ -1,49 +0,0 @@ -name: Continuous Integration - -on: [push, pull_request] - -jobs: - stable_tests: - name: Operating Systems (Stable) - runs-on: ubuntu-20.04 - continue-on-error: false - strategy: - matrix: - distro: - - Fedora 32 - - Fedora 33 - - CentOS 7 - - CentOS 8 - - steps: - - name: Checkout code - uses: actions/checkout@v2 - - - name: Run tests - env: - DISTRO: ${{ matrix.distro }} - run: | - ./.ci/ci-launcher.sh - experimental_tests: - name: Operating Systems (Experimental) - runs-on: ubuntu-20.04 - continue-on-error: true - strategy: - matrix: - distro: - - Fedora rawhide - - Archlinux - - Mageia 7 - # Disabled for now, since it's broken - #- OpenMandriva cooker - - openSUSE tumbleweed - - steps: - - name: Checkout code - uses: actions/checkout@v2 - - - name: Run tests - env: - DISTRO: ${{ matrix.distro }} - run: | - ./.ci/ci-launcher.sh diff -Nru libmodulemd-2.12.0/.github/workflows/formatters.yaml libmodulemd-2.13.0/.github/workflows/formatters.yaml --- libmodulemd-2.12.0/.github/workflows/formatters.yaml 2021-01-15 02:04:56.000000000 +0000 +++ libmodulemd-2.13.0/.github/workflows/formatters.yaml 1970-01-01 00:00:00.000000000 +0000 @@ -1,30 +0,0 @@ -name: Automatic Code Formatters -on: push - -jobs: - autoformat: - name: Auto-format code - runs-on: ubuntu-20.04 - steps: - - name: Checkout code - uses: actions/checkout@v2 - - - name: Install formatters - run: | - sudo apt-get update - sudo apt-get install clang-format black - - - name: Format code - run: | - clang-format -i --verbose $(find . -name "*.[ch]") - black --target-version py36 --verbose --line-length 79 . - - - name: Commit changes - uses: EndBug/add-and-commit@v6 - with: - author_name: Libmodulemd CI - author_email: github-actions@github.com - message: 'Code auto-formatting' - add: -u - signoff: true - push: true diff -Nru libmodulemd-2.12.0/.github/workflows/multiarch.yaml libmodulemd-2.13.0/.github/workflows/multiarch.yaml --- libmodulemd-2.12.0/.github/workflows/multiarch.yaml 2021-01-15 02:04:56.000000000 +0000 +++ libmodulemd-2.13.0/.github/workflows/multiarch.yaml 1970-01-01 00:00:00.000000000 +0000 @@ -1,40 +0,0 @@ -name: Other Architectures -on: [push, pull_request] - -jobs: - multiarch: - runs-on: ubuntu-20.04 - name: ${{ matrix.distro }} on ${{ matrix.arch }} - continue-on-error: true - - # Run steps on a matrix of 3 arch/distro combinations - strategy: - matrix: - include: - - arch: ppc64le - distro: fedora_latest - - arch: s390x - distro: fedora_latest - - steps: - - uses: actions/checkout@v2 - - - uses: uraimo/run-on-arch-action@v2.0.7 - name: Perform upstream tests - - with: - arch: ${{ matrix.arch }} - distro: ${{ matrix.distro }} - - # Not required, but speeds up builds by storing container images in - # a GitHub package registry. - githubToken: ${{ github.token }} - - # Work-around ldd bug in rawhide CIs - run: | - $GITHUB_WORKSPACE/.ci/fedora/get_fedora_deps.sh - sed -i -e 's/test -r/test -f/g' -e 's/test -x/test -f/g' /bin/ldd - meson setup --buildtype=debugoptimized -Dverbose_tests=false /tmp/ci $GITHUB_WORKSPACE - meson test --suite formatters -C /tmp/ci --print-errorlogs -t 5 - meson test --suite ci -C /tmp/ci --print-errorlogs -t 5 - diff -Nru libmodulemd-2.12.0/.github/workflows/release.yaml libmodulemd-2.13.0/.github/workflows/release.yaml --- libmodulemd-2.12.0/.github/workflows/release.yaml 2021-01-15 02:04:56.000000000 +0000 +++ libmodulemd-2.13.0/.github/workflows/release.yaml 1970-01-01 00:00:00.000000000 +0000 @@ -1,43 +0,0 @@ -name: Release Tasks -on: - release: - types: [published] - -jobs: - docs: - name: Publish Documentation - runs-on: ubuntu-20.04 - continue-on-error: false - if: github.repository == 'fedora-modularity/libmodulemd' - steps: - - name: Checkout code repo - uses: actions/checkout@v2 - - - name: Checkout documentation repo - uses: actions/checkout@v2 - with: - repository: fedora-modularity/fedora-modularity.github.io - ref: main - path: fedora-modularity.github.io - token: ${{ secrets.DOC_TOKEN }} - - - name: Get release version - run: | - echo "version=$(./get_version.sh)" >> $GITHUB_ENV - - - name: Generate documentation - run: | - ./.ci/ci-docs.sh $version - - - name: Commit documentation - uses: EndBug/add-and-commit@v6 - with: - branch: main - token: ${{ secrets.DOC_TOKEN }} - cwd: fedora-modularity.github.io - author_name: Libmodulemd CI - author_email: github-actions@github.com - message: libmodulemd docs for ${{ env.version }} - add: libmodulemd/${{ env.version }} - signoff: true - push: true diff -Nru libmodulemd-2.12.0/.github/workflows/upstreamed.yaml libmodulemd-2.13.0/.github/workflows/upstreamed.yaml --- libmodulemd-2.12.0/.github/workflows/upstreamed.yaml 2021-01-15 02:04:56.000000000 +0000 +++ libmodulemd-2.13.0/.github/workflows/upstreamed.yaml 1970-01-01 00:00:00.000000000 +0000 @@ -1,54 +0,0 @@ -name: Upstreamed -on: - push: - branches: - - main -jobs: - static_analysis: - name: Static Analysis - runs-on: ubuntu-20.04 - if: github.repository == 'fedora-modularity/libmodulemd' - steps: - - name: Checkout code - uses: actions/checkout@v2 - - - name: Coverity Scan - env: - COVERITY_SCAN_TOKEN: ${{ secrets.COVERITY_TOKEN }} - run: | - ./.ci/ci-coverity.sh - - docs: - name: Publish Documentation - runs-on: ubuntu-20.04 - continue-on-error: false - if: github.repository == 'fedora-modularity/libmodulemd' - steps: - - name: Checkout code repo - uses: actions/checkout@v2 - - - name: Checkout documentation repo - uses: actions/checkout@v2 - with: - repository: fedora-modularity/fedora-modularity.github.io - ref: main - path: fedora-modularity.github.io - token: ${{ secrets.DOC_TOKEN }} - - - - name: Generate documentation - run: | - ./.ci/ci-docs.sh - - - name: Commit documentation - uses: EndBug/add-and-commit@v6 - with: - branch: main - token: ${{ secrets.DOC_TOKEN }} - cwd: fedora-modularity.github.io - author_name: Libmodulemd CI - author_email: github-actions@github.com - message: Updating libmodulemd docs for ${{ github.sha }} - add: libmodulemd/latest - signoff: true - push: true diff -Nru libmodulemd-2.12.0/.gitignore libmodulemd-2.13.0/.gitignore --- libmodulemd-2.12.0/.gitignore 2021-01-15 02:04:56.000000000 +0000 +++ libmodulemd-2.13.0/.gitignore 1970-01-01 00:00:00.000000000 +0000 @@ -1,87 +0,0 @@ -*.o -*.py[co] -.deps -/**/*.swp -/*.bak -/*.gcda -/*.gcno -/*.o -/*.orig -/*.rej -/*.tab.c -/*~ -__pycache__/ -/.*.sw[nop] -/.dirstamp -/.gitignore -/ChangeLog -/GPATH -/GRTAGS -/GSYMS -/GTAGS -/ID -/INSTALL -/m4 -/Makefile -/Makefile.in -/TAGS -/aclocal.m4 -/autom4te.cache -/build-aux -/config -/config.cache -/config.h -/config.h.in -/config.log -/config.lt -/config.status -/config.status.lineno -/configure -/configure.lineno -/gtk-doc.m4 -/gtk-doc.make -/intltool-extract.in -/intltool-merge.in -/intltool-update.in -/libtool -/po/*.gmo -/po/*.header -/po/*.mo -/po/*.sed -/po/*.sin -/po/.intltool-merge-cache -/po/Makefile -/po/Makefile.in -/po/Makefile.in.in -/po/Makefile.in.in~ -/po/Makevars.template -/po/POTFILES -/po/Rules-quot -/po/modulemd.pot -/po/stamp-it -/so_locations -/stamp-h1 -/tags -# Common config files for IDEs -/.buildconfig -/.project -/.vscode -/settings.json -# Common meson build directories -/build -/debugbuild -/x86_64 -/i*86 -/aarch64 -/armv7hl -/ppc64le -/s390* -/libmodulemd.spec -/fedora/*.patch -/fedora/modulemd-* -/fedora/libmodulemd-* -*.rpm -.travis/.home* -.travis/*/Dockerfile.deps.* -.ci/.home* -.ci/*/Dockerfile.deps.* diff -Nru libmodulemd-2.12.0/meson.build libmodulemd-2.13.0/meson.build --- libmodulemd-2.12.0/meson.build 2021-01-15 02:04:56.000000000 +0000 +++ libmodulemd-2.13.0/meson.build 2021-07-09 09:29:23.326000000 +0000 @@ -12,7 +12,7 @@ project( 'modulemd', 'c', -version : '2.12.0', +version : '2.13.0', default_options : ['buildtype=debugoptimized', 'c_std=c11', 'warning_level=1', 'b_asneeded=true'], license : 'MIT', meson_version : '>=0.47.0' @@ -105,18 +105,29 @@ 'g_ptr_array_extend_and_steal', dependencies : [ glib ]) -python_name = get_option('python_name') +with_py3 = get_option('with_py3') +if with_py3 + if get_option('skip_introspection') + error('A Python3 binding requires a GObject introspection.') + endif -if python_name != '' - # If we've been instructed to use a specific python version - python3 = pymod.find_installation(python_name) + python_name = get_option('python_name') + if python_name != '' + # If we've been instructed to use a specific python version + python3 = pymod.find_installation(python_name) + else + # Use the python installation that is running meson + python3 = pymod.find_installation() + endif else - # Use the python installation that is running meson - python3 = pymod.find_installation() + python3 = disabler() endif with_py2 = get_option('with_py2') if with_py2 + if get_option('skip_introspection') + error('A Python2 binding requires a GObject introspection.') + endif python2 = pymod.find_installation('python2') else python2 = disabler() @@ -193,7 +204,7 @@ 'libdir': get_option('libdir'), 'datadir': get_option('datadir'), 'Python 2 GObject Overrides': gobject_overrides_dir_py2, - 'Python 3 GObject Overrides': gobject_overrides_dir_py3 + 'Python 3 GObject Overrides': gobject_overrides_dir_py3, }, section: 'Directories') summary({'libmagic Support': magic_status, @@ -202,6 +213,7 @@ 'Generate Manpages': manpages_status, 'Generate HTML Documentation': get_option('with_docs'), 'Python 2 Support': get_option('with_py2'), + 'Python 3 Support': get_option('with_py3'), 'Skip Introspection': get_option('skip_introspection'), 'Test Installed Library': get_option('test_installed_lib'), }, section: 'Build Configuration') diff -Nru libmodulemd-2.12.0/meson_options.txt libmodulemd-2.13.0/meson_options.txt --- libmodulemd-2.12.0/meson_options.txt 2021-01-15 02:04:56.000000000 +0000 +++ libmodulemd-2.13.0/meson_options.txt 2021-07-09 09:29:23.326000000 +0000 @@ -38,6 +38,9 @@ option('with_py2', type : 'boolean', value : false, description : 'Build Python 2 language bindings and run Python 2 tests.') +option('with_py3', type : 'boolean', value : true, + description : 'Build Python 3 language bindings and run Python 3 tests.') + option('gobject_overrides_dir_py2', type : 'string', description : 'Path to Python 2 PyGObject overrides directory. Leave empty to determine it automatically.') diff -Nru libmodulemd-2.12.0/modulemd/include/modulemd-2.0/modulemd-module-stream-v2.h libmodulemd-2.13.0/modulemd/include/modulemd-2.0/modulemd-module-stream-v2.h --- libmodulemd-2.12.0/modulemd/include/modulemd-2.0/modulemd-module-stream-v2.h 2021-01-15 02:04:56.000000000 +0000 +++ libmodulemd-2.13.0/modulemd/include/modulemd-2.0/modulemd-module-stream-v2.h 2021-07-09 09:29:23.329000000 +0000 @@ -764,6 +764,61 @@ /** + * modulemd_module_stream_v2_add_demodularized_rpm: + * @self: (in): This #ModulemdModuleStreamV2 object. + * @rpm: (in): A name of a binary RPM package to become non-modular. + * + * Add a binary package name to a list of demodularized packages. + * + * Since: 2.13 + */ +void +modulemd_module_stream_v2_add_demodularized_rpm (ModulemdModuleStreamV2 *self, + const gchar *rpm); + + +/** + * modulemd_module_stream_v2_remove_demodularized_rpm: + * @self: (in): This #ModulemdModuleStreamV2 object. + * @rpm: (in): A binary RPM name to remove from a demodularized list. + * + * Remove a binary package name from a list of demodularized packages. + * + * Since: 2.13 + */ +void +modulemd_module_stream_v2_remove_demodularized_rpm ( + ModulemdModuleStreamV2 *self, const gchar *rpm); + + +/** + * modulemd_module_stream_v2_clear_demodularized_rpms: + * @self: (in): This #ModulemdModuleStreamV2 object. + * + * Remove all RPM packages from a demodularized list of the object. + * + * Since: 2.13 + */ +void +modulemd_module_stream_v2_clear_demodularized_rpms ( + ModulemdModuleStreamV2 *self); + + +/** + * modulemd_module_stream_v2_get_demodularized_rpms: + * @self: (in): This #ModulemdModuleStreamV2 object. + * + * Returns: (transfer full): An ordered #GStrv list of binary RPM package names + * that became non-modular. + * + * Since: 2.13 + */ +GStrv +modulemd_module_stream_v2_get_demodularized_rpms ( + ModulemdModuleStreamV2 *self); + + +/** * modulemd_module_stream_v2_add_servicelevel: * @self: (in): This #ModulemdModuleStreamV2 object. * @servicelevel: (in) (transfer none): A #ModulemdServiceLevel for this module stream. diff -Nru libmodulemd-2.12.0/modulemd/include/modulemd-2.0/modulemd-packager-v3.h libmodulemd-2.13.0/modulemd/include/modulemd-2.0/modulemd-packager-v3.h --- libmodulemd-2.12.0/modulemd/include/modulemd-2.0/modulemd-packager-v3.h 2021-01-15 02:04:56.000000000 +0000 +++ libmodulemd-2.13.0/modulemd/include/modulemd-2.0/modulemd-packager-v3.h 2021-07-09 09:29:23.330000000 +0000 @@ -611,6 +611,74 @@ /** + * modulemd_packager_v3_add_demodularized_rpm: + * @self: (in): This #ModulemdPackagerV3 object. + * @rpm: (in): A name of a binary RPM package to become non-modular. + * + * Add a binary package name to a list of demodularized packages. + * + * Since: 2.13 + */ +void +modulemd_packager_v3_add_demodularized_rpm (ModulemdPackagerV3 *self, + const gchar *rpm); + + +/** + * modulemd_packager_v3_remove_demodularized_rpm: + * @self: (in): This #ModulemdPackagerV3 object. + * @rpm: (in): A binary RPM package name to remove from a demodularized list. + * + * Remove a binary package name from a list of demodularized packages. + * + * Since: 2.13 + */ +void +modulemd_packager_v3_remove_demodularized_rpm (ModulemdPackagerV3 *self, + const gchar *rpm); + + +/** + * modulemd_packager_v3_clear_demodularized_rpms: + * @self: (in): This #ModulemdPackagerV3 object. + * + * Remove all RPM packages from a demodularized list of the object. + * + * Since: 2.13 + */ +void +modulemd_packager_v3_clear_demodularized_rpms (ModulemdPackagerV3 *self); + + +/** + * modulemd_packager_v3_get_demodularized_rpms: + * @self: (in): This #ModulemdPackagerV3 object. + * + * Returns: (transfer full): An ordered #GStrv list of binary RPM package names + * that became non-modular. + * + * Since: 2.13 + */ +GStrv +modulemd_packager_v3_get_demodularized_rpms (ModulemdPackagerV3 *self); + + +/** + * modulemd_packager_v3_replace_demodularized_rpms: + * @self: (in): This #ModulemdPackagerV3 object. + * @set: (in): A #GHashTable set of names of binary RPM packages to demodularize. + * + * Any existing demodularized binary RPM package names associated with module + * stream @self are removed and replaced by @set. + * + * Since: 2.13 + */ +void +modulemd_packager_v3_replace_demodularized_rpms (ModulemdPackagerV3 *self, + GHashTable *set); + + +/** * modulemd_packager_v3_add_component: * @self: (in): This #ModulemdPackagerV3 object. * @component: (in) (transfer none): A #ModulemdComponent to be added to this diff -Nru libmodulemd-2.12.0/modulemd/include/private/modulemd-module-stream-v2-private.h libmodulemd-2.13.0/modulemd/include/private/modulemd-module-stream-v2-private.h --- libmodulemd-2.12.0/modulemd/include/private/modulemd-module-stream-v2-private.h 2021-01-15 02:04:56.000000000 +0000 +++ libmodulemd-2.13.0/modulemd/include/private/modulemd-module-stream-v2-private.h 2021-07-09 09:29:23.333000000 +0000 @@ -13,6 +13,7 @@ #pragma once +#include "modulemd-module-stream.h" #include "modulemd-module-stream-v2.h" #include "modulemd-subdocument-info.h" #include @@ -23,6 +24,17 @@ /** + * MODULEMD_MODULE_STREAM_V2_MAXCONTEXTLEN: + * + * The ModuleStream v3 specification defines the maximum lenth of the context + * field. Just before building, the v3 format is converted to v2 format. But + * if a scratch build was requested, an underscore with a decimal number (e.g. + * "_1") is appended to the v2 context. Allow up to 99 scratch builds here. + */ +#define MODULEMD_MODULE_STREAM_V2_MAXCONTEXTLEN (MMD_MAXCONTEXTLEN + 3) + + +/** * SECTION: modulemd-module-stream-v2-private * @title: Modulemd.ModuleStreamV2 (Private) * @stability: private @@ -61,6 +73,8 @@ GHashTable *rpm_filters; /* string set */ + GHashTable *demodularized_rpms; /* string set */ + GHashTable *servicelevels; /* */ @@ -191,6 +205,20 @@ GHashTable *set); /** + * modulemd_module_stream_v2_replace_demodularized_rpms: + * @self: (in): This #ModulemdModuleStreamV2 object. + * @set: (in): A #GHashTable set of names of binary RPM packages to demodularize. + * + * Any existing demodularized binary RPM package names associated with module + * stream @self are removed and replaced by @set. + * + * Since: 2.13 + */ +void +modulemd_module_stream_v2_replace_demodularized_rpms ( + ModulemdModuleStreamV2 *self, GHashTable *set); + +/** * modulemd_module_stream_v2_replace_dependencies: * @self: (in): This #ModulemdModuleStreamV2 object. * @array: (in): A #GPtrArray of #ModulemdDependencies objects for this module diff -Nru libmodulemd-2.12.0/modulemd/meson.build libmodulemd-2.13.0/modulemd/meson.build --- libmodulemd-2.12.0/modulemd/meson.build 2021-01-15 02:04:56.000000000 +0000 +++ libmodulemd-2.13.0/modulemd/meson.build 2021-07-09 09:29:23.335000000 +0000 @@ -187,19 +187,24 @@ ) endif -modulemd_validator = executable( - 'modulemd-validator', - sources : modulemd_validator_srcs, - include_directories : include_dirs, - dependencies : [ - gobject, - magic, - rpm, - yaml, - modulemd_dep - ], - install : true -) +if test_installed_lib + # Run tests against an installed tool of in-tree + modulemd_validator = find_program('modulemd-validator').full_path() +else + modulemd_validator = executable( + 'modulemd-validator', + sources : modulemd_validator_srcs, + include_directories : include_dirs, + dependencies : [ + gobject, + magic, + rpm, + yaml, + modulemd_dep + ], + install : true + ) +endif header_path = 'modulemd-2.0' @@ -209,6 +214,76 @@ ) +# --- GOBject Introspection -- # + +if skip_introspection +else +girs = gnome.generate_gir( + modulemd_lib, + sources : modulemd_srcs + modulemd_hdrs + ['include/private/gi-binding-renames.h'], + nsversion : '2.0', + namespace : 'Modulemd', + symbol_prefix : 'modulemd_', + identifier_prefix : 'Modulemd', + includes : [ + 'GObject-2.0', + ], + extra_args : [ '--accept-unprefixed' ], + install : true, + fatal_warnings : true, + ) +endif + +pkg.generate( + libraries : modulemd_lib, + subdirs : header_path, + version : libmodulemd_version, + name : 'modulemd-2.0', + filebase : 'modulemd-2.0', + description : 'Module metadata manipulation library', + requires: [ 'glib-2.0', 'gobject-2.0' ], +) + +xcdata = configuration_data() +xcdata.set('VERSION', meson.project_version()) +configure_file( + input : 'version.xml.in', + output : 'version.xml', + configuration : xcdata +) + +if with_docs + gnome.gtkdoc( + 'modulemd-2.0', + install_dir: 'modulemd-2.0', + src_dir : './modulemd', + main_xml : 'modulemd-docs.xml', + gobject_typesfile : join_paths(meson.current_build_dir(), 'modulemd-2.0.types'), + dependencies : [ + modulemd_dep, + ], + fixxref_args: [ + '--extra-dir=@0@'.format(join_paths(glib_docpath, 'glib')), + '--extra-dir=@0@'.format(join_paths(glib_docpath, 'gobject')), + ], + install : true, + ) +endif + +help2man_opts = [ + '--no-info', + '--section=1', +] +custom_target( + 'modulemd-validator.1', + output: 'modulemd-validator.1', + command: [ + help2man, help2man_opts, '--output=@OUTPUT@', modulemd_validator, + ], + install: true, + install_dir: join_paths(get_option('mandir'), 'man1')) + + # --- TESTS --- # # Test env with release values @@ -271,6 +346,7 @@ 'component_module' : [ 'tests/test-modulemd-component-module.c' ], 'component_rpm' : [ 'tests/test-modulemd-component-rpm.c' ], 'compression' : [ 'tests/test-modulemd-compression.c' ], +'context' : [ 'tests/test-modulemd-context.c' ], 'defaults' : [ 'tests/test-modulemd-defaults.c' ], 'defaultsv1' : [ 'tests/test-modulemd-defaults-v1.c' ], 'dependencies' : [ 'tests/test-modulemd-dependencies.c' ], @@ -279,6 +355,7 @@ 'module_index_merger' : [ 'tests/test-modulemd-merger.c' ], 'modulestream' : [ 'tests/test-modulemd-modulestream.c' ], 'packagerv3' : [ 'tests/test-modulemd-packager-v3.c' ], +'parse_int64' : [ 'tests/test-modulemd-parse_int64.c' ], 'profile' : [ 'tests/test-modulemd-profile.c' ], 'rpm_map' : [ 'tests/test-modulemd-rpmmap.c' ], 'service_level' : [ 'tests/test-modulemd-service-level.c' ], @@ -331,33 +408,145 @@ } foreach name, script : python_tests - test_python_scripts += files(script) - test (name + '_python3_debug', python3, - env : py_test_env, - timeout : 60, - args : files(script), - suite : ['ci', 'py3', 'py3_debug']) - test (name + '_python3_release', python3, - env : py_test_release_env, - timeout : 60, - args : files(script), - suite : ['ci', 'py3', 'py3_release']) + if with_py3 + test_python_scripts += files(script) + test (name + '_python3_debug', python3, + env : py_test_env, + timeout : 60, + args : files(script), + depends : girs, + suite : ['ci', 'py3', 'py3_debug']) + test (name + '_python3_release', python3, + env : py_test_release_env, + timeout : 60, + args : files(script), + depends : girs, + suite : ['ci', 'py3', 'py3_release']) + endif if with_py2 test (name + '_python2_debug', python2, env : py_test_env, timeout : 60, args : files(script), + depends : girs, suite : ['ci', 'py2', 'py2_debug']) test (name + '_python2_release', python2, env : py_test_release_env, timeout : 60, args : files(script), + depends : girs, suite : ['ci', 'py2', 'py2_release']) endif #with_py2 endforeach +# Tests for modulemd-validator tool +modulemd_validator_tests = { +'help' : [['--code', '0'], ['--help']], +'version' : [['--code', '0'], ['--version']], +'valid' : [['--code', '0'], + [files('tests/test_data/static_context.yaml')]], +'invalid' : [['--code', '1', '--stdout', 'No data section provided'], + [files('tests/test_data/good_and_bad.yaml')]], +'stream_packagerv3_invalid_mix_as_index': + [['--code', '1'], + [files('tests/test_data/stream_packager_mix.yaml')]], +'valid_defaultsv1.yaml': + [['--code', '0'], + [files('../yaml_specs/modulemd_defaults_v1.yaml')]], +'invalid_defaultsv1.yaml': + [['--code', '1'], + [files('tests/test_data/invalid_defaults.yaml')]], +'valid_defaultsv1_as_defaultsv1': + [['--code', '0'], + ['--type', 'modulemd-defaults-v1', files('../yaml_specs/modulemd_defaults_v1.yaml')]], +'invalid_defaultsv1_as_defaultsv1': + [['--code', '1'], + ['--type', 'modulemd-defaults-v1', files('tests/test_data/invalid_defaults.yaml')]], +'valid_defaultsv1_with_garbage_as_defaultsv1': + [['--code', '1'], + ['--type', 'modulemd-defaults-v1', files('tests/test_data/valid_defaults_with_garbage.yaml')]], +'valid_defaultsv1_with_unexpected_document_as_defaultsv1': + [['--code', '1'], + ['--type', 'modulemd-defaults-v1', files('tests/test_data/valid_defaults_with_unexpected_document.yaml')]], +'valid_modulemdv1_as_modulemdv1': + [['--code', '0'], + ['--type', 'modulemd-v1', files('../yaml_specs/modulemd_stream_v1.yaml')]], +'invalid_modulemdv1_as_modulemdv1': + [['--code', '1', '--stderr', 'not in valid N-E:V-R.A format'], + ['--type', 'modulemd-v1', files('tests/test_data/bad_stream_v1.yaml')]], +'valid_modulemdv2_as_modulemdv1': + [['--code', '1'], + ['--type', 'modulemd-v1', files('../yaml_specs/modulemd_stream_v2.yaml')]], +'valid_modulemdv2_as_modulemdv2': + [['--code', '0'], + ['--type', 'modulemd-v2', files('../yaml_specs/modulemd_stream_v2.yaml')]], +'invalid_modulemdv2_as_modulemdv2': + [['--code', '1', '--stderr', 'Stream context'], + ['--type', 'modulemd-v2', files('tests/test_data/bad_stream_v2.yaml')]], +'valid_packagerv3_as_modulemdv2': + [['--code', '1'], + ['--type', 'modulemd-v2', files('../yaml_specs/modulemd_packager_v3.yaml')]], +'valid_obsoletesv1.yaml': + [['--code', '0'], + [files('../yaml_specs/modulemd_obsoletes_v1.yaml')]], +'invalid_obsoletesv1.yaml': + [['--code', '1'], + [files('tests/test_data/invalid_obsoletes_v1.yaml')]], +'valid_obsoletesv1_as_obsoletesv1.yaml': + [['--code', '0'], + ['--type', 'modulemd-obsoletes-v1', files('../yaml_specs/modulemd_obsoletes_v1.yaml')]], +'invalid_obsoletesv1_as_obseletesv1.yaml': + [['--code', '1'], + ['--type', 'modulemd-obsoletes-v1', files('tests/test_data/invalid_obsoletes_v1.yaml')]], +'modulemdv2_as_defaultsv1': + [['--code', '1'], + ['--type', 'defaults-v1', files('../yaml_specs/modulemd_stream_v2.yaml')]], +'valid_packagerv2_as_packagerv2': + [['--code', '0'], + ['--type', 'modulemd-packager-v2', files('../yaml_specs/modulemd_packager_v2.yaml')]], +'invalid_packagerv2_as_packagerv2': + [['--code', '1', '--stderr', 'license is missing'], + ['--type', 'modulemd-packager-v2', files('tests/test_data/bad_packager_v2.yaml')]], +'valid_modulemdv2_as_packagerv2': + [['--code', '1'], + ['--type', 'modulemd-packager-v2', files('../yaml_specs/modulemd_stream_v2.yaml')]], +'valid_packagerv3_as_packagerv3': + [['--code', '0'], + ['--type', 'modulemd-packager-v3', files('../yaml_specs/modulemd_packager_v3.yaml')]], +'invalid_packagerv3_as_packagerv3': + [['--code', '1', '--stderr', 'context exceeds'], + ['--type', 'modulemd-packager-v3', files('tests/test_data/bad_packager_v3.yaml')]], +'valid_modulemdv2_as_packagerv3': + [['--code', '1'], + ['--type', 'modulemd-packager-v3', files('../yaml_specs/modulemd_stream_v2.yaml')]], +'valid_translationsv1_as_translationsv1': + [['--code', '0'], + ['--type', 'modulemd-translations-v1', files('../yaml_specs/modulemd_translations_v1.yaml')]], +'invalid_translationsv1_as_translationsv1': + [['--code', '1', '--stderr', 'not a valid integer'], + ['--type', 'modulemd-translations-v1', files('tests/test_data/bad_translations_v1.yaml')]], +'valid_modulemdv2_as_translationsv1': + [['--code', '1'], + ['--type', 'modulemd-translations-v1', files('../yaml_specs/modulemd_stream_v2.yaml')]], +} +test_modulemd_validator = executable( + 'test-modulemd-validator', + files('tests/test-modulemd-validator.c'), + dependencies : [ glib ], + install : false, +) + +foreach name, arguments : modulemd_validator_tests + test(name, test_modulemd_validator, + args : [arguments[0], '--', modulemd_validator, arguments[1]], + env : test_env, + timeout : 60, + suite : ['ci', 'modulemd_validator']) +endforeach + + # -- C/C++ Header test -- # # Ensures that all public headers can be imported by consumers # This test takes a while, so run it near the end so that the functional test @@ -370,71 +559,3 @@ suite : ['smoketest', 'ci']) -# --- GOBject Introspection -- # - -if skip_introspection -else - gnome.generate_gir( - modulemd_lib, - sources : modulemd_srcs + modulemd_hdrs + ['include/private/gi-binding-renames.h'], - nsversion : '2.0', - namespace : 'Modulemd', - symbol_prefix : 'modulemd_', - identifier_prefix : 'Modulemd', - includes : [ - 'GObject-2.0', - ], - extra_args : [ '--accept-unprefixed' ], - install : true, - fatal_warnings : true, - ) -endif - -pkg.generate( - libraries : modulemd_lib, - subdirs : header_path, - version : libmodulemd_version, - name : 'modulemd-2.0', - filebase : 'modulemd-2.0', - description : 'Module metadata manipulation library', - requires: [ 'glib-2.0', 'gobject-2.0' ], -) - -xcdata = configuration_data() -xcdata.set('VERSION', meson.project_version()) -configure_file( - input : 'version.xml.in', - output : 'version.xml', - configuration : xcdata -) - -if with_docs - gnome.gtkdoc( - 'modulemd-2.0', - install_dir: 'modulemd-2.0', - src_dir : './modulemd', - main_xml : 'modulemd-docs.xml', - gobject_typesfile : join_paths(meson.current_build_dir(), 'modulemd-2.0.types'), - dependencies : [ - modulemd_dep, - ], - fixxref_args: [ - '--extra-dir=@0@'.format(join_paths(glib_docpath, 'glib')), - '--extra-dir=@0@'.format(join_paths(glib_docpath, 'gobject')), - ], - install : true, - ) -endif - -help2man_opts = [ - '--no-info', - '--section=1', -] -custom_target( - 'modulemd-validator.1', - output: 'modulemd-validator.1', - command: [ - help2man, help2man_opts, '--output=@OUTPUT@', modulemd_validator, - ], - install: true, - install_dir: join_paths(get_option('mandir'), 'man1')) diff -Nru libmodulemd-2.12.0/modulemd/modulemd-module-stream.c libmodulemd-2.13.0/modulemd/modulemd-module-stream.c --- libmodulemd-2.12.0/modulemd/modulemd-module-stream.c 2021-01-15 02:04:56.000000000 +0000 +++ libmodulemd-2.13.0/modulemd/modulemd-module-stream.c 2021-07-09 09:29:23.340000000 +0000 @@ -502,9 +502,10 @@ g_autoptr (ModulemdModuleStream) current_stream = NULL; g_autoptr (ModulemdModuleStream) updated_stream = NULL; g_autoptr (GError) nested_error = NULL; - guint64 current_mdversion = modulemd_module_stream_get_mdversion (self); + guint64 current_mdversion; g_return_val_if_fail (MODULEMD_IS_MODULE_STREAM (self), NULL); + current_mdversion = modulemd_module_stream_get_mdversion (self); if (!mdversion) { @@ -581,9 +582,10 @@ g_autoptr (ModulemdModule) current_module = NULL; g_autoptr (ModulemdModule) updated_module = NULL; g_autoptr (GError) nested_error = NULL; - guint64 current_mdversion = modulemd_module_stream_get_mdversion (self); + guint64 current_mdversion; g_return_val_if_fail (MODULEMD_IS_MODULE_STREAM (self), NULL); + current_mdversion = modulemd_module_stream_get_mdversion (self); if (!mdversion) { diff -Nru libmodulemd-2.12.0/modulemd/modulemd-module-stream-v2.c libmodulemd-2.13.0/modulemd/modulemd-module-stream-v2.c --- libmodulemd-2.12.0/modulemd/modulemd-module-stream-v2.c 2021-01-15 02:04:56.000000000 +0000 +++ libmodulemd-2.13.0/modulemd/modulemd-module-stream-v2.c 2021-07-09 09:29:23.340000000 +0000 @@ -98,6 +98,8 @@ g_clear_pointer (&self->rpm_filters, g_hash_table_unref); + g_clear_pointer (&self->demodularized_rpms, g_hash_table_unref); + g_clear_pointer (&self->servicelevels, g_hash_table_unref); g_clear_pointer (&self->dependencies, g_ptr_array_unref); @@ -218,6 +220,12 @@ return FALSE; } + if (!modulemd_hash_table_sets_are_equal (v2_self_1->demodularized_rpms, + v2_self_2->demodularized_rpms)) + { + return FALSE; + } + if (!modulemd_hash_table_equals (v2_self_1->servicelevels, v2_self_2->servicelevels, modulemd_service_level_equals_wrapper)) @@ -1061,6 +1069,65 @@ void +modulemd_module_stream_v2_add_demodularized_rpm (ModulemdModuleStreamV2 *self, + const gchar *rpm) +{ + if (!rpm) + { + return; + } + + g_return_if_fail (MODULEMD_IS_MODULE_STREAM_V2 (self)); + + g_hash_table_add (self->demodularized_rpms, g_strdup (rpm)); +} + + +void +modulemd_module_stream_v2_replace_demodularized_rpms ( + ModulemdModuleStreamV2 *self, GHashTable *set) +{ + g_return_if_fail (MODULEMD_IS_MODULE_STREAM_V2 (self)); + + MODULEMD_REPLACE_SET (self->demodularized_rpms, set); +} + + +void +modulemd_module_stream_v2_remove_demodularized_rpm ( + ModulemdModuleStreamV2 *self, const gchar *rpm) +{ + if (!rpm) + { + return; + } + + g_return_if_fail (MODULEMD_IS_MODULE_STREAM_V2 (self)); + + g_hash_table_remove (self->demodularized_rpms, rpm); +} + + +void +modulemd_module_stream_v2_clear_demodularized_rpms ( + ModulemdModuleStreamV2 *self) +{ + g_return_if_fail (MODULEMD_IS_MODULE_STREAM_V2 (self)); + + g_hash_table_remove_all (self->demodularized_rpms); +} + + +GStrv +modulemd_module_stream_v2_get_demodularized_rpms (ModulemdModuleStreamV2 *self) +{ + g_return_val_if_fail (MODULEMD_IS_MODULE_STREAM_V2 (self), NULL); + + return modulemd_ordered_str_keys_as_strv (self->demodularized_rpms); +} + + +void modulemd_module_stream_v2_add_servicelevel (ModulemdModuleStreamV2 *self, ModulemdServiceLevel *servicelevel) { @@ -1237,7 +1304,7 @@ modulemd_module_stream_v2_validate_context (const gchar *context, GError **error) { - /* must be string of up to MMD_MAXCONTEXTLEN [a-zA-Z0-9] */ + /* must be string of up to MODULEMD_MODULE_STREAM_V2_MAXCONTEXTLEN [a-zA-Z0-9_] */ if (context == NULL || *context == '\0') { @@ -1246,26 +1313,27 @@ return FALSE; } - if (strlen (context) > MMD_MAXCONTEXTLEN) + if (strlen (context) > MODULEMD_MODULE_STREAM_V2_MAXCONTEXTLEN) { g_set_error (error, MODULEMD_ERROR, MMD_ERROR_VALIDATE, "Stream context '%s' exceeds maximum length (%d)", context, - MMD_MAXCONTEXTLEN); + MODULEMD_MODULE_STREAM_V2_MAXCONTEXTLEN); return FALSE; } for (const gchar *i = context; *i != '\0'; i++) { - if (!g_ascii_isalnum (*i)) + if (!g_ascii_isalnum (*i) && *i != '_') { - g_set_error (error, - MODULEMD_ERROR, - MMD_ERROR_VALIDATE, - "Non-alphanumeric character in stream context '%s'", - context); + g_set_error ( + error, + MODULEMD_ERROR, + MMD_ERROR_VALIDATE, + "Stream context '%s' can only contain [a-zA-Z0-9_] characters", + context); return FALSE; } } @@ -1550,6 +1618,7 @@ STREAM_REPLACE_HASHTABLE (v2, copy, v2_self, rpm_api); STREAM_REPLACE_HASHTABLE (v2, copy, v2_self, rpm_artifacts); STREAM_REPLACE_HASHTABLE (v2, copy, v2_self, rpm_filters); + STREAM_REPLACE_HASHTABLE (v2, copy, v2_self, demodularized_rpms); /* Internal Data Structures: With add on value */ COPY_HASHTABLE_BY_VALUE_ADDER ( @@ -1731,6 +1800,9 @@ self->rpm_filters = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + self->demodularized_rpms = + g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + self->servicelevels = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); @@ -2041,6 +2113,17 @@ g_clear_pointer (&set, g_hash_table_unref); } + /* Demodularized Packages */ + else if (g_str_equal ((const gchar *)event.data.scalar.value, + "demodularized")) + { + set = modulemd_yaml_parse_string_set_from_map ( + &parser, "rpms", strict, &nested_error); + modulemd_module_stream_v2_replace_demodularized_rpms ( + modulestream, set); + g_clear_pointer (&set, g_hash_table_unref); + } + /* Build Options */ else if (g_str_equal ((const gchar *)event.data.scalar.value, "buildopts") && @@ -3067,6 +3150,14 @@ EMIT_MAPPING_END (emitter, error); } + if (NON_EMPTY_TABLE (self->demodularized_rpms)) + { + EMIT_SCALAR (emitter, error, "demodularized"); + EMIT_MAPPING_START (emitter, error); + EMIT_STRING_SET (emitter, error, "rpms", self->demodularized_rpms); + EMIT_MAPPING_END (emitter, error); + } + if (self->buildopts != NULL) { EMIT_SCALAR (emitter, error, "buildopts"); diff -Nru libmodulemd-2.12.0/modulemd/modulemd-packager-v3.c libmodulemd-2.13.0/modulemd/modulemd-packager-v3.c --- libmodulemd-2.12.0/modulemd/modulemd-packager-v3.c 2021-01-15 02:04:56.000000000 +0000 +++ libmodulemd-2.13.0/modulemd/modulemd-packager-v3.c 2021-07-09 09:29:23.342000000 +0000 @@ -40,6 +40,7 @@ GHashTable *profiles; /* */ GHashTable *rpm_api; /* string set */ GHashTable *rpm_filters; /* string set */ + GHashTable *demodularized_rpms; /* string set */ GHashTable *rpm_components; /* */ GHashTable *module_components; /* profiles, g_hash_table_unref); g_clear_pointer (&self->rpm_api, g_hash_table_unref); g_clear_pointer (&self->rpm_filters, g_hash_table_unref); + g_clear_pointer (&self->demodularized_rpms, g_hash_table_unref); g_clear_pointer (&self->rpm_components, g_hash_table_unref); g_clear_pointer (&self->module_components, g_hash_table_unref); @@ -102,6 +104,9 @@ self->rpm_filters = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + self->demodularized_rpms = + g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + self->rpm_components = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); @@ -150,6 +155,9 @@ modulemd_packager_v3_replace_rpm_filters (copy, self->rpm_filters); + modulemd_packager_v3_replace_demodularized_rpms (copy, + self->demodularized_rpms); + COPY_HASHTABLE_BY_VALUE_ADDER ( copy, self, rpm_components, modulemd_packager_v3_add_component); @@ -612,6 +620,64 @@ void +modulemd_packager_v3_add_demodularized_rpm (ModulemdPackagerV3 *self, + const gchar *rpm) +{ + if (!rpm) + { + return; + } + + g_return_if_fail (MODULEMD_IS_PACKAGER_V3 (self)); + + g_hash_table_add (self->demodularized_rpms, g_strdup (rpm)); +} + + +void +modulemd_packager_v3_replace_demodularized_rpms (ModulemdPackagerV3 *self, + GHashTable *set) +{ + g_return_if_fail (MODULEMD_IS_PACKAGER_V3 (self)); + + MODULEMD_REPLACE_SET (self->demodularized_rpms, set); +} + + +void +modulemd_packager_v3_remove_demodularized_rpm (ModulemdPackagerV3 *self, + const gchar *rpm) +{ + if (!rpm) + { + return; + } + + g_return_if_fail (MODULEMD_IS_PACKAGER_V3 (self)); + + g_hash_table_remove (self->demodularized_rpms, rpm); +} + + +void +modulemd_packager_v3_clear_demodularized_rpms (ModulemdPackagerV3 *self) +{ + g_return_if_fail (MODULEMD_IS_PACKAGER_V3 (self)); + + g_hash_table_remove_all (self->demodularized_rpms); +} + + +GStrv +modulemd_packager_v3_get_demodularized_rpms (ModulemdPackagerV3 *self) +{ + g_return_val_if_fail (MODULEMD_IS_PACKAGER_V3 (self), NULL); + + return modulemd_ordered_str_keys_as_strv (self->demodularized_rpms); +} + + +void modulemd_packager_v3_add_component (ModulemdPackagerV3 *self, ModulemdComponent *component) { @@ -842,6 +908,9 @@ modulemd_module_stream_v2_replace_rpm_filters (stream_v2, packager_v3->rpm_filters); + modulemd_module_stream_v2_replace_demodularized_rpms ( + stream_v2, packager_v3->demodularized_rpms); + COPY_HASHTABLE_BY_VALUE_ADDER (stream_v2, packager_v3, rpm_components, @@ -1279,6 +1348,15 @@ } else if (g_str_equal ((const gchar *)event.data.scalar.value, + "demodularized")) + { + set = modulemd_yaml_parse_string_set_from_map ( + &parser, "rpms", strict, &nested_error); + modulemd_packager_v3_replace_demodularized_rpms (packager, set); + g_clear_pointer (&set, g_hash_table_unref); + } + + else if (g_str_equal ((const gchar *)event.data.scalar.value, "components")) { if (!modulemd_packager_v3_parse_components ( @@ -1863,6 +1941,14 @@ EMIT_MAPPING_END (emitter, error); } + if (NON_EMPTY_TABLE (self->demodularized_rpms)) + { + EMIT_SCALAR (emitter, error, "demodularized"); + EMIT_MAPPING_START (emitter, error); + EMIT_STRING_SET (emitter, error, "rpms", self->demodularized_rpms); + EMIT_MAPPING_END (emitter, error); + } + if (NON_EMPTY_TABLE (self->rpm_components) || NON_EMPTY_TABLE (self->module_components)) { diff -Nru libmodulemd-2.12.0/modulemd/modulemd-subdocument-info.c libmodulemd-2.13.0/modulemd/modulemd-subdocument-info.c --- libmodulemd-2.12.0/modulemd/modulemd-subdocument-info.c 2021-01-15 02:04:56.000000000 +0000 +++ libmodulemd-2.13.0/modulemd/modulemd-subdocument-info.c 2021-07-09 09:29:23.343000000 +0000 @@ -329,17 +329,51 @@ void modulemd_subdocument_info_debug_dump_failures (GPtrArray *failures) { - ModulemdSubdocumentInfo *doc = NULL; - if (failures && failures->len) { - g_debug ("%u YAML subdocuments were invalid", failures->len); - for (gsize i = 0; i < failures->len; i++) + if (failures->len == 1) + { + g_debug ("%u YAML subdocument was invalid:", failures->len); + } + else { + g_debug ("%u YAML subdocuments were invalid:", failures->len); + } + for (guint i = 0; i < failures->len; i++) + { + ModulemdSubdocumentInfo *doc = NULL; + const GError *error = NULL; + const gchar *message = NULL; + const gchar *yaml = NULL; + doc = MODULEMD_SUBDOCUMENT_INFO (g_ptr_array_index (failures, i)); - g_debug ("\nFailed subdocument (%s): \n%s\n", - modulemd_subdocument_info_get_gerror (doc)->message, - modulemd_subdocument_info_get_yaml (doc)); + if (doc) + { + error = modulemd_subdocument_info_get_gerror (doc); + if (error && error->message) + { + message = error->message; + } + else + { + message = "unknown reason"; + } + yaml = modulemd_subdocument_info_get_yaml (doc); + } + else + { + message = "undefined document"; + } + + if (yaml) + { + g_debug ( + "Failed subdocument #%u (%s):\n%s", i + 1, message, yaml); + } + else + { + g_debug ("Failed subdocument #%u (%s).", i + 1, message); + } } } } diff -Nru libmodulemd-2.12.0/modulemd/modulemd-validator.c libmodulemd-2.13.0/modulemd/modulemd-validator.c --- libmodulemd-2.12.0/modulemd/modulemd-validator.c 2021-01-15 02:04:56.000000000 +0000 +++ libmodulemd-2.13.0/modulemd/modulemd-validator.c 2021-07-09 09:29:23.343000000 +0000 @@ -13,12 +13,22 @@ #include "modulemd.h" +#include "modulemd-errors.h" +#include "private/modulemd-defaults-v1-private.h" #include "private/modulemd-module-index-private.h" +#include "private/modulemd-module-stream-v1-private.h" +#include "private/modulemd-module-stream-v2-private.h" +#include "private/modulemd-obsoletes-private.h" +#include "private/modulemd-subdocument-info-private.h" +#include "private/modulemd-translation-private.h" #include "private/modulemd-yaml.h" #include #include #include +#include +#include +#include enum mmd_verbosity { @@ -28,13 +38,31 @@ MMD_DEBUG }; +/* Identifiers for modulemd type-version documents. + * We cannot use GTypes, e.g. MODULEMD_TYPE_PACKAGER_V3, because + * modulemd-packager-v2 GType does not exist (the format is parsed into + * a modulemd-v2 data structure). Also GTypes are not constants. They are + * a run-time computed value and hence cannot be used in switch-cases. */ +enum mmd_type +{ + MMD_TYPE_INDEX, /* Untyped validation by loading into an index */ + MMD_TYPE_MODULEMD_V1, + MMD_TYPE_MODULEMD_V2, + MMD_TYPE_MODULEMD_DEFAULTS_V1, + MMD_TYPE_MODULEMD_OBSOLETES_V1, + MMD_TYPE_MODULEMD_PACKAGER_V2, + MMD_TYPE_MODULEMD_PACKAGER_V3, + MMD_TYPE_MODULEMD_TRANSLATIONS_V1 +}; + struct validator_options { enum mmd_verbosity verbosity; + GType type; gchar **filenames; }; -struct validator_options options = { 0, NULL }; +struct validator_options options = { 0 }; static gboolean print_version (const gchar *option_name, @@ -43,7 +71,7 @@ GError **error) { g_fprintf (stdout, "modulemd-validator %s\n", modulemd_get_version ()); - exit (1); + exit (EXIT_SUCCESS); } static gboolean @@ -76,7 +104,15 @@ { debugging_env = g_strdup (G_LOG_DOMAIN); } - g_setenv ("G_MESSAGES_DEBUG", debugging_env, TRUE); + if (!g_setenv ("G_MESSAGES_DEBUG", debugging_env, TRUE)) + { + g_set_error ( + error, + G_OPTION_ERROR, + G_OPTION_ERROR_FAILED, + "Could not set G_MESSAGES_DEBUG environment variable"); + return FALSE; + } } } else if (g_strcmp0 ("-q", option_name) == 0 || @@ -97,9 +133,60 @@ return TRUE; } +static gboolean +set_type (const gchar *option_name, + const gchar *value, + gpointer data, + GError **error) +{ + if (!g_strcmp0 (value, "modulemd-v1")) + options.type = MMD_TYPE_MODULEMD_V1; + else if (!g_strcmp0 (value, "modulemd-v2")) + options.type = MMD_TYPE_MODULEMD_V2; + else if (!g_strcmp0 (value, "modulemd-defaults-v1")) + options.type = MMD_TYPE_MODULEMD_DEFAULTS_V1; + else if (!g_strcmp0 (value, "modulemd-obsoletes-v1")) + options.type = MMD_TYPE_MODULEMD_OBSOLETES_V1; + else if (!g_strcmp0 (value, "modulemd-packager-v2")) + options.type = MMD_TYPE_MODULEMD_PACKAGER_V2; + else if (!g_strcmp0 (value, "modulemd-packager-v3")) + options.type = MMD_TYPE_MODULEMD_PACKAGER_V3; + else if (!g_strcmp0 (value, "modulemd-translations-v1")) + options.type = MMD_TYPE_MODULEMD_TRANSLATIONS_V1; + else + { + g_set_error (error, + G_OPTION_ERROR, + G_OPTION_ERROR_FAILED, + "Unknown document type: %s", + value); + return FALSE; + } + return TRUE; +} + +static const gchar * +mmd_type2astring (enum mmd_type type) +{ + switch (type) + { + case MMD_TYPE_INDEX: return "an index"; + case MMD_TYPE_MODULEMD_V1: return "a modulemd-v1"; + case MMD_TYPE_MODULEMD_V2: return "a modulemd-v2"; + case MMD_TYPE_MODULEMD_DEFAULTS_V1: return "a modulemd-defaults-v1"; + case MMD_TYPE_MODULEMD_OBSOLETES_V1: return "a modulemd-obsoletes-v1"; + case MMD_TYPE_MODULEMD_PACKAGER_V2: return "a modulemd-packager-v2"; + case MMD_TYPE_MODULEMD_PACKAGER_V3: return "a modulemd-packager-v3"; + case MMD_TYPE_MODULEMD_TRANSLATIONS_V1: + return "a modulemd-translations-v1"; + } + return "an unknown document type"; +} + // clang-format off static GOptionEntry entries[] = { { "debug", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, set_verbosity, "Output debugging messages", NULL }, + { "type", 0, G_OPTION_FLAG_NONE, G_OPTION_ARG_CALLBACK, set_type, "Constrain a document type (modulemd-v1, modulemd-v2, modulemd-defaults-v1, modulemd-obsoletes-v1, modulemd-packager-v2, modulemd-packager-v3, modulemd-translations-v1); by default any document type loadable into a modulemd index is acceptable; this option only supports single-document files", "TYPE" }, { "quiet", 'q', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, set_verbosity, "Print no output", NULL }, { "verbose", 'v', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, set_verbosity, "Be verbose", NULL }, { "version", 'V', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, print_version, "Print version number, then exit", NULL }, @@ -107,20 +194,246 @@ { NULL } }; // clang-format on +static const gchar * +ModulemdYamlDocumentTypeEnum2string (ModulemdYamlDocumentTypeEnum type) +{ + switch (type) + { + case MODULEMD_YAML_DOC_MODULESTREAM: return "modulemd"; + case MODULEMD_YAML_DOC_DEFAULTS: return "modulemd-defaults"; + case MODULEMD_YAML_DOC_TRANSLATIONS: return "modulemd-translations"; + case MODULEMD_YAML_DOC_PACKAGER: return "modulemd-packager"; + case MODULEMD_YAML_DOC_OBSOLETES: return "modulemd-obsoletes"; + case MODULEMD_YAML_DOC_UNKNOWN: /* fall through */ + default: return "unknown type"; + } +} +/* We cannot load by index as it converts from old versions before + * a return and as it does not provide enumeration functions for + * subdocuments. We will use private modulemd_defaults_v1_parse_yaml() etc. + * parsers. */ static gboolean -parse_file (const gchar *filename, GPtrArray **failures, GError **error) +parse_file_as_subdoc_and_validate (const gchar *filename, + enum mmd_type validation_type, + ModulemdYamlDocumentTypeEnum expected_type, + guint64 expected_version, + GError **error) { - g_autoptr (ModulemdModuleIndex) index = NULL; + g_autoptr (FILE) file = NULL; + MMD_INIT_YAML_PARSER (parser); + MMD_INIT_YAML_EVENT (event); + g_autoptr (ModulemdSubdocumentInfo) subdoc = NULL; + const GError *subdoc_error; + ModulemdYamlDocumentTypeEnum type; + guint64 version; + g_autoptr (GObject) object = NULL; + + /* Open the file and determine a document type */ + file = fopen (filename, "r"); + if (!file) + { + g_set_error (error, + MODULEMD_YAML_ERROR, + MMD_YAML_ERROR_OPEN, + "Could not open %s file: %s", + filename, + strerror (errno)); + return FALSE; + } + yaml_parser_set_input_file (&parser, file); + if (!yaml_parser_parse (&parser, &event)) + { + MMD_YAML_ERROR_EVENT_EXIT_BOOL (error, event, "Invalid YAML"); + } + if (event.type != YAML_STREAM_START_EVENT) + { + { + MMD_YAML_ERROR_EVENT_EXIT_BOOL ( + error, event, "YAML parser could not find a start of a YAML stream"); + } + } + yaml_event_delete (&event); + if (!yaml_parser_parse (&parser, &event)) + { + MMD_YAML_ERROR_EVENT_EXIT_BOOL (error, event, "Invalid YAML"); + } + if (event.type != YAML_DOCUMENT_START_EVENT) + { + { + MMD_YAML_ERROR_EVENT_EXIT_BOOL ( + error, + event, + "YAML parser could not find a start of a YAML document"); + } + } + yaml_event_delete (&event); + subdoc = modulemd_yaml_parse_document_type (&parser); + subdoc_error = modulemd_subdocument_info_get_gerror (subdoc); + if (subdoc_error) + { + *error = g_error_copy (subdoc_error); + return FALSE; + } + type = modulemd_subdocument_info_get_doctype (subdoc); + if (type != expected_type) + { + g_set_error (error, + MODULEMD_ERROR, + 0, + "Not %s document; it is %s", + mmd_type2astring (validation_type), + ModulemdYamlDocumentTypeEnum2string (type)); + return FALSE; + } + version = modulemd_subdocument_info_get_mdversion (subdoc); + if (version != expected_version) + { + g_set_error (error, + MODULEMD_ERROR, + 0, + "Not %s document; it is %" G_GUINT64_FORMAT " version", + mmd_type2astring (validation_type), + version); + return FALSE; + } + /* Parse and validate the document body */ + switch (validation_type) + { + case MMD_TYPE_MODULEMD_V1: + object = + G_OBJECT (modulemd_module_stream_v1_parse_yaml (subdoc, TRUE, error)); + if (object && !modulemd_module_stream_validate ( + MODULEMD_MODULE_STREAM (object), error)) + g_clear_object (&object); + break; + case MMD_TYPE_MODULEMD_DEFAULTS_V1: + object = + G_OBJECT (modulemd_defaults_v1_parse_yaml (subdoc, TRUE, error)); + /* validated implicitly */ + break; + case MMD_TYPE_MODULEMD_OBSOLETES_V1: + object = G_OBJECT (modulemd_obsoletes_parse_yaml (subdoc, TRUE, error)); + /* validated implicitly */ + break; + case MMD_TYPE_MODULEMD_PACKAGER_V2: + object = G_OBJECT ( + modulemd_module_stream_v2_parse_yaml (subdoc, TRUE, TRUE, error)); + if (object && !modulemd_module_stream_validate ( + MODULEMD_MODULE_STREAM (object), error)) + g_clear_object (&object); + break; + case MMD_TYPE_MODULEMD_TRANSLATIONS_V1: + object = + G_OBJECT (modulemd_translation_parse_yaml (subdoc, TRUE, error)); + /* validated implicitly */ + break; + default: + g_set_error (error, + MODULEMD_ERROR, + 0, + "Internal error: %s type is not supported", + mmd_type2astring (validation_type)); + return FALSE; + } + if (!object) + return FALSE; + + /* Check for a garbage past the first document */ + if (!yaml_parser_parse (&parser, &event)) + { + MMD_YAML_ERROR_EVENT_EXIT_BOOL ( + error, event, "Invalid YAML after first document"); + } + if (event.type != YAML_STREAM_END_EVENT) + { + { + MMD_YAML_ERROR_EVENT_EXIT_BOOL ( + error, event, "Another YAML document after the first one"); + return FALSE; + } + } + yaml_event_delete (&event); + return TRUE; +} + +static gboolean +parse_file (const gchar *filename, GPtrArray **failures, GError **error) +{ if (options.verbosity >= MMD_VERBOSE) { g_fprintf (stdout, "Validating %s\n", filename); } - index = modulemd_module_index_new (); - return modulemd_module_index_update_from_file_ext ( - index, filename, TRUE, TRUE, failures, error); + switch (options.type) + { + case MMD_TYPE_INDEX: + { + g_autoptr (ModulemdModuleIndex) index = NULL; + index = modulemd_module_index_new (); + return modulemd_module_index_update_from_file_ext ( + index, filename, TRUE, TRUE, failures, error); + } + case MMD_TYPE_MODULEMD_V1: + return parse_file_as_subdoc_and_validate ( + filename, options.type, MODULEMD_YAML_DOC_MODULESTREAM, 1u, error); + case MMD_TYPE_MODULEMD_V2: + { + GType type; + g_autoptr (GObject) object = NULL; + type = modulemd_read_packager_file (filename, &object, error); + if (type == G_TYPE_INVALID) + return FALSE; + if (type != MODULEMD_TYPE_MODULE_STREAM_V2) + { + g_set_error (error, + MODULEMD_ERROR, + 0, + "Not a modulemd-v2 document; it is %s", + g_type_name (type)); + return FALSE; + } + return modulemd_module_stream_validate ( + MODULEMD_MODULE_STREAM (object), error); + } + case MMD_TYPE_MODULEMD_DEFAULTS_V1: + return parse_file_as_subdoc_and_validate ( + filename, options.type, MODULEMD_YAML_DOC_DEFAULTS, 1u, error); + case MMD_TYPE_MODULEMD_OBSOLETES_V1: + return parse_file_as_subdoc_and_validate ( + filename, options.type, MODULEMD_YAML_DOC_OBSOLETES, 1u, error); + case MMD_TYPE_MODULEMD_PACKAGER_V2: + return parse_file_as_subdoc_and_validate ( + filename, options.type, MODULEMD_YAML_DOC_PACKAGER, 2u, error); + case MMD_TYPE_MODULEMD_PACKAGER_V3: + { + GType type; + g_autoptr (GObject) object = NULL; + type = modulemd_read_packager_file (filename, &object, error); + if (type == G_TYPE_INVALID) + return FALSE; + if (type != MODULEMD_TYPE_PACKAGER_V3) + { + g_set_error (error, + MODULEMD_ERROR, + 0, + "Not a modulemd-packager-v3 document; it is %s", + g_type_name (type)); + return FALSE; + } + /* modulemd_packager_v3 is validated implicitly by + * modulemd_read_packager_file (). */ + return TRUE; + } + case MMD_TYPE_MODULEMD_TRANSLATIONS_V1: + return parse_file_as_subdoc_and_validate ( + filename, options.type, MODULEMD_YAML_DOC_TRANSLATIONS, 1u, error); + } + g_fprintf (stderr, + "Internal error: unsupported document type: %s\n", + mmd_type2astring (options.type)); + exit (EXIT_FAILURE); } @@ -137,19 +450,20 @@ setlocale (LC_ALL, ""); + options.type = MMD_TYPE_INDEX; context = g_option_context_new ("FILES - Simple modulemd YAML validator"); g_option_context_add_main_entries (context, entries, "modulemd-validator"); if (!g_option_context_parse (context, &argc, &argv, &error)) { g_print ("option parsing failed: %s\n", error->message); - exit (1); + exit (EXIT_FAILURE); } if (!(options.filenames && options.filenames[0])) { g_fprintf (stderr, "At least one file must be specified on the command-line\n"); - return EXIT_FAILURE; + exit (EXIT_FAILURE); } for (gsize i = 0; options.filenames[i]; i++) diff -Nru libmodulemd-2.12.0/modulemd/modulemd-yaml-util.c libmodulemd-2.13.0/modulemd/modulemd-yaml-util.c --- libmodulemd-2.12.0/modulemd/modulemd-yaml-util.c 2021-01-15 02:04:56.000000000 +0000 +++ libmodulemd-2.13.0/modulemd/modulemd-yaml-util.c 2021-07-09 09:29:23.344000000 +0000 @@ -15,6 +15,7 @@ #include "private/modulemd-subdocument-info-private.h" #include "private/modulemd-util.h" #include "private/modulemd-yaml.h" +#include #include #include #include @@ -425,6 +426,8 @@ gint64 modulemd_yaml_parse_int64 (yaml_parser_t *parser, GError **error) { + gint64 value; + gchar *endptr; MMD_INIT_YAML_EVENT (event); YAML_PARSER_PARSE_WITH_EXIT_INT (parser, &event, error); @@ -433,13 +436,61 @@ MMD_YAML_ERROR_EVENT_EXIT_INT (error, event, "String was not a scalar"); } - return g_ascii_strtoll ((const gchar *)event.data.scalar.value, NULL, 10); + value = + g_ascii_strtoll ((const gchar *)event.data.scalar.value, &endptr, 10); + + if ((value == G_MAXINT64 && errno == ERANGE)) + { + g_set_error (error, + MODULEMD_YAML_ERROR, + MODULEMD_ERROR_VALIDATE, + "%s: The integer value is larger than %" G_GINT64_FORMAT, + (const gchar *)event.data.scalar.value, + G_MAXINT64); + return 0; + } + + if ((value == G_MININT64 && errno == ERANGE)) + { + g_set_error (error, + MODULEMD_YAML_ERROR, + MODULEMD_ERROR_VALIDATE, + "%s: The integer value is samller than %" G_GINT64_FORMAT, + (const gchar *)event.data.scalar.value, + G_MININT64); + return 0; + } + + if (value == 0 && errno == EINVAL) + { + g_set_error_literal ( + error, + MODULEMD_YAML_ERROR, + MODULEMD_ERROR_NOT_IMPLEMENTED, + "Your GLib library does not support parsing integers in 10 base"); + return 0; + } + + if ((value == 0 && endptr == (gchar *)event.data.scalar.value) || + *endptr != '\0') + { + g_set_error (error, + MODULEMD_YAML_ERROR, + MMD_ERROR_VALIDATE, + "%s: The string is not a valid integer", + (const gchar *)event.data.scalar.value); + return 0; + } + + return value; } guint64 modulemd_yaml_parse_uint64 (yaml_parser_t *parser, GError **error) { + guint64 value; + gchar *endptr; MMD_INIT_YAML_EVENT (event); YAML_PARSER_PARSE_WITH_EXIT_INT (parser, &event, error); @@ -450,7 +501,53 @@ g_debug ("Parsing scalar: %s", (const gchar *)event.data.scalar.value); - return g_ascii_strtoull ((const gchar *)event.data.scalar.value, NULL, 10); + /* g_ascii_strtoull() accepts negative values by definition. */ + if (event.data.scalar.value[0] == '-') + { + g_set_error (error, + MODULEMD_YAML_ERROR, + MODULEMD_ERROR_VALIDATE, + "%s: The integer value is negative", + (const gchar *)event.data.scalar.value); + return 0u; + } + + value = + g_ascii_strtoull ((const gchar *)event.data.scalar.value, &endptr, 10); + + if (value == G_MAXUINT64 && errno == ERANGE) + { + g_set_error (error, + MODULEMD_YAML_ERROR, + MODULEMD_ERROR_VALIDATE, + "%s: The integer value is larger than %" G_GUINT64_FORMAT, + (const gchar *)event.data.scalar.value, + G_MAXUINT64); + return 0u; + } + + if (value == 0u && errno == EINVAL) + { + g_set_error_literal ( + error, + MODULEMD_YAML_ERROR, + MODULEMD_ERROR_NOT_IMPLEMENTED, + "Your GLib library does not support parsing integers in 10 base"); + return 0u; + } + + if ((value == 0u && endptr == (gchar *)event.data.scalar.value) || + *endptr != '\0') + { + g_set_error (error, + MODULEMD_YAML_ERROR, + MMD_ERROR_VALIDATE, + "%s: The string is not a valid integer", + (const gchar *)event.data.scalar.value); + return 0u; + } + + return value; } diff -Nru libmodulemd-2.12.0/modulemd/tests/ModulemdTests/modulestream.py libmodulemd-2.13.0/modulemd/tests/ModulemdTests/modulestream.py --- libmodulemd-2.12.0/modulemd/tests/ModulemdTests/modulestream.py 2021-01-15 02:04:56.000000000 +0000 +++ libmodulemd-2.13.0/modulemd/tests/ModulemdTests/modulestream.py 2021-07-09 09:29:23.346000000 +0000 @@ -20,9 +20,14 @@ import unittest import gi - gi._overridesdir = os.path.join( - os.getenv("MESON_SOURCE_ROOT"), "bindings", "python", "gi", "overrides" - ) + if os.getenv("MMD_TEST_INSTALLED_LIBS") != "TRUE": + gi._overridesdir = os.path.join( + os.getenv("MESON_SOURCE_ROOT"), + "bindings", + "python", + "gi", + "overrides", + ) gi.require_version("Modulemd", "2.0") from gi.repository import GLib @@ -495,6 +500,25 @@ stream.clear_rpm_filters() assert len(stream.get_rpm_filters()) == 0 + def test_demodularized_rpms(self): + for version in modulestream_versions: + stream = Modulemd.ModuleStream.new(version) + # demodularized_rpms are supported since v2 + if version < Modulemd.ModuleStreamVersionEnum.TWO: + continue + stream.add_demodularized_rpm("foo") + stream.add_demodularized_rpm("bar") + assert "foo" in stream.get_demodularized_rpms() + assert "bar" in stream.get_demodularized_rpms() + assert len(stream.get_demodularized_rpms()) == 2 + + stream.remove_demodularized_rpm("bar") + assert "foo" in stream.get_demodularized_rpms() + assert len(stream.get_demodularized_rpms()) == 1 + + stream.clear_demodularized_rpms() + assert len(stream.get_demodularized_rpms()) == 0 + def test_servicelevels(self): for version in modulestream_versions: # servicelevels are not supported after v2 @@ -690,6 +714,10 @@ filter: rpms: rpm_c + demodularized: + rpms: + - rpm_d + artifacts: rpms: - bar-0:1.23-1.module_deadbeef.x86_64 @@ -824,6 +852,8 @@ assert "rpm_c" in stream.get_rpm_filters() + assert "rpm_d" in stream.get_demodularized_rpms() + assert ( "bar-0:1.23-1.module_deadbeef.x86_64" in stream.get_rpm_artifacts() ) diff -Nru libmodulemd-2.12.0/modulemd/tests/test_data/bad_packager_v2.yaml libmodulemd-2.13.0/modulemd/tests/test_data/bad_packager_v2.yaml --- libmodulemd-2.12.0/modulemd/tests/test_data/bad_packager_v2.yaml 1970-01-01 00:00:00.000000000 +0000 +++ libmodulemd-2.13.0/modulemd/tests/test_data/bad_packager_v2.yaml 2021-07-09 09:29:23.353000000 +0000 @@ -0,0 +1,9 @@ +--- +document: modulemd-packager +version: 2 +data: + summary: Trivial Summary + description: >- + Trivial Description + #license: a missing license breaks validity +... diff -Nru libmodulemd-2.12.0/modulemd/tests/test_data/bad_packager_v3.yaml libmodulemd-2.13.0/modulemd/tests/test_data/bad_packager_v3.yaml --- libmodulemd-2.12.0/modulemd/tests/test_data/bad_packager_v3.yaml 1970-01-01 00:00:00.000000000 +0000 +++ libmodulemd-2.13.0/modulemd/tests/test_data/bad_packager_v3.yaml 2021-07-09 09:29:23.353000000 +0000 @@ -0,0 +1,14 @@ +--- +document: modulemd-packager +version: 3 +data: + name: trivialname + stream: trivialstream + summary: Trivial Summary + description: >- + Trivial Description + license: [MIT] + configurations: + - context: a2345678901 + platform: foo +... diff -Nru libmodulemd-2.12.0/modulemd/tests/test_data/bad_stream_v1.yaml libmodulemd-2.13.0/modulemd/tests/test_data/bad_stream_v1.yaml --- libmodulemd-2.12.0/modulemd/tests/test_data/bad_stream_v1.yaml 1970-01-01 00:00:00.000000000 +0000 +++ libmodulemd-2.13.0/modulemd/tests/test_data/bad_stream_v1.yaml 2021-07-09 09:29:23.354000000 +0000 @@ -0,0 +1,15 @@ +--- +document: modulemd +version: 1 +data: + name: trivialname + stream: trivialstream + summary: Trivial Summary + description: >- + Trivial Description + license: + module: [MIT] + artifacts: + rpms: + - "MissingEpoch-0-0.src" +... diff -Nru libmodulemd-2.12.0/modulemd/tests/test_data/bad_stream_v2.yaml libmodulemd-2.13.0/modulemd/tests/test_data/bad_stream_v2.yaml --- libmodulemd-2.12.0/modulemd/tests/test_data/bad_stream_v2.yaml 1970-01-01 00:00:00.000000000 +0000 +++ libmodulemd-2.13.0/modulemd/tests/test_data/bad_stream_v2.yaml 2021-07-09 09:29:23.354000000 +0000 @@ -0,0 +1,14 @@ +--- +document: modulemd +version: 2 +data: + name: trivialname + stream: trivialstream + summary: Trivial Summary + description: >- + Trivial Description + license: + module: [MIT] + static_context: true + context: '-' +... diff -Nru libmodulemd-2.12.0/modulemd/tests/test_data/bad_translations_v1.yaml libmodulemd-2.13.0/modulemd/tests/test_data/bad_translations_v1.yaml --- libmodulemd-2.12.0/modulemd/tests/test_data/bad_translations_v1.yaml 1970-01-01 00:00:00.000000000 +0000 +++ libmodulemd-2.13.0/modulemd/tests/test_data/bad_translations_v1.yaml 2021-07-09 09:29:23.354000000 +0000 @@ -0,0 +1,7 @@ +document: modulemd-translations +version: 1 +data: + module: foo + stream: bar + modified: 42invalid + translations: diff -Nru libmodulemd-2.12.0/modulemd/tests/test_data/good-v2-extra-keys.yaml libmodulemd-2.13.0/modulemd/tests/test_data/good-v2-extra-keys.yaml --- libmodulemd-2.12.0/modulemd/tests/test_data/good-v2-extra-keys.yaml 2021-01-15 02:04:56.000000000 +0000 +++ libmodulemd-2.13.0/modulemd/tests/test_data/good-v2-extra-keys.yaml 2021-07-09 09:29:23.363000000 +0000 @@ -178,6 +178,19 @@ unknown_sequence: - foo - bar + demodularized: + rpms: + - bar-old + + unknown_key: foo + unknown_map: + stuff: [ a, b ] + junk: [ b, c ] + morestuff: + yay: [ d, e ] + unknown_sequence: + - foo + - bar buildopts: rpms: diff -Nru libmodulemd-2.12.0/modulemd/tests/test_data/invalid_defaults.yaml libmodulemd-2.13.0/modulemd/tests/test_data/invalid_defaults.yaml --- libmodulemd-2.12.0/modulemd/tests/test_data/invalid_defaults.yaml 1970-01-01 00:00:00.000000000 +0000 +++ libmodulemd-2.13.0/modulemd/tests/test_data/invalid_defaults.yaml 2021-07-09 09:29:23.364000000 +0000 @@ -0,0 +1,5 @@ +document: modulemd-defaults +version: 1 +data: + module: foo + modified: 42invalid diff -Nru libmodulemd-2.12.0/modulemd/tests/test_data/invalid_obsoletes_v1.yaml libmodulemd-2.13.0/modulemd/tests/test_data/invalid_obsoletes_v1.yaml --- libmodulemd-2.12.0/modulemd/tests/test_data/invalid_obsoletes_v1.yaml 1970-01-01 00:00:00.000000000 +0000 +++ libmodulemd-2.13.0/modulemd/tests/test_data/invalid_obsoletes_v1.yaml 2021-07-09 09:29:23.364000000 +0000 @@ -0,0 +1,8 @@ +--- +document: modulemd-obsoletes +version: 1 +data: + module: foo + stream: '42' + modified: 1970-01-01T00:00Z + # message: a missing message breaks validity diff -Nru libmodulemd-2.12.0/modulemd/tests/test_data/upgrades/packager_v3_to_index.yaml libmodulemd-2.13.0/modulemd/tests/test_data/upgrades/packager_v3_to_index.yaml --- libmodulemd-2.12.0/modulemd/tests/test_data/upgrades/packager_v3_to_index.yaml 2021-01-15 02:04:56.000000000 +0000 +++ libmodulemd-2.13.0/modulemd/tests/test_data/upgrades/packager_v3_to_index.yaml 2021-07-09 09:29:23.366000000 +0000 @@ -58,6 +58,9 @@ filter: rpms: - baz-nonfoo + demodularized: + rpms: + - bar-old buildopts: rpms: macros: > @@ -144,6 +147,9 @@ filter: rpms: - baz-nonfoo + demodularized: + rpms: + - bar-old components: rpms: bar: diff -Nru libmodulemd-2.12.0/modulemd/tests/test_data/upgrades/packager_v3_to_stream_v2.yaml libmodulemd-2.13.0/modulemd/tests/test_data/upgrades/packager_v3_to_stream_v2.yaml --- libmodulemd-2.12.0/modulemd/tests/test_data/upgrades/packager_v3_to_stream_v2.yaml 2021-01-15 02:04:56.000000000 +0000 +++ libmodulemd-2.13.0/modulemd/tests/test_data/upgrades/packager_v3_to_stream_v2.yaml 2021-07-09 09:29:23.367000000 +0000 @@ -61,6 +61,9 @@ filter: rpms: - baz-nonfoo + demodularized: + rpms: + - bar-old buildopts: rpms: macros: > diff -Nru libmodulemd-2.12.0/modulemd/tests/test_data/valid_defaults_with_garbage.yaml libmodulemd-2.13.0/modulemd/tests/test_data/valid_defaults_with_garbage.yaml --- libmodulemd-2.12.0/modulemd/tests/test_data/valid_defaults_with_garbage.yaml 1970-01-01 00:00:00.000000000 +0000 +++ libmodulemd-2.13.0/modulemd/tests/test_data/valid_defaults_with_garbage.yaml 2021-07-09 09:29:23.367000000 +0000 @@ -0,0 +1,7 @@ +document: modulemd-defaults +version: 1 +data: + module: foo + modified: 42 +... +garbage diff -Nru libmodulemd-2.12.0/modulemd/tests/test_data/valid_defaults_with_unexpected_document.yaml libmodulemd-2.13.0/modulemd/tests/test_data/valid_defaults_with_unexpected_document.yaml --- libmodulemd-2.12.0/modulemd/tests/test_data/valid_defaults_with_unexpected_document.yaml 1970-01-01 00:00:00.000000000 +0000 +++ libmodulemd-2.13.0/modulemd/tests/test_data/valid_defaults_with_unexpected_document.yaml 2021-07-09 09:29:23.367000000 +0000 @@ -0,0 +1,7 @@ +document: modulemd-defaults +version: 1 +data: + module: foo + modified: 42 +... +garbage diff -Nru libmodulemd-2.12.0/modulemd/tests/test-modulemd-common.c libmodulemd-2.13.0/modulemd/tests/test-modulemd-common.c --- libmodulemd-2.12.0/modulemd/tests/test-modulemd-common.c 2021-01-15 02:04:56.000000000 +0000 +++ libmodulemd-2.13.0/modulemd/tests/test-modulemd-common.c 2021-07-09 09:29:23.347000000 +0000 @@ -538,6 +538,7 @@ signal (SIGTRAP, modulemd_test_signal_handler); otype = modulemd_read_packager_string (NULL, &object, &error); g_assert_cmpint (modulemd_test_signal, ==, SIGTRAP); + g_assert_cmpint (otype, ==, G_TYPE_INVALID); g_assert_null (object); /* An empty string is not a valid packager format */ diff -Nru libmodulemd-2.12.0/modulemd/tests/test-modulemd-compression.c libmodulemd-2.13.0/modulemd/tests/test-modulemd-compression.c --- libmodulemd-2.12.0/modulemd/tests/test-modulemd-compression.c 2021-01-15 02:04:56.000000000 +0000 +++ libmodulemd-2.13.0/modulemd/tests/test-modulemd-compression.c 2021-07-09 09:29:23.348000000 +0000 @@ -140,13 +140,13 @@ filename = g_strdup_printf ("%s/compression/%s", g_getenv ("TEST_DATA_PATH"), expected_magic[j].filename); + g_debug ("Getting compression type for %s", filename); filestream = g_fopen (filename, "rbe"); g_assert_nonnull (filestream); fd = fileno (filestream); - g_assert_cmpint (modulemd_detect_compression (filename, fd, &error), - ==, - expected_magic[j].type); + result = modulemd_detect_compression (filename, fd, &error); g_assert_no_error (error); + g_assert_cmpint (result, ==, expected_magic[j].type); g_clear_error (&error); g_clear_pointer (&filestream, fclose); g_clear_pointer (&filename, g_free); diff -Nru libmodulemd-2.12.0/modulemd/tests/test-modulemd-context.c libmodulemd-2.13.0/modulemd/tests/test-modulemd-context.c --- libmodulemd-2.12.0/modulemd/tests/test-modulemd-context.c 1970-01-01 00:00:00.000000000 +0000 +++ libmodulemd-2.13.0/modulemd/tests/test-modulemd-context.c 2021-07-09 09:29:23.348000000 +0000 @@ -0,0 +1,226 @@ +/* + * This file is part of libmodulemd + * Copyright (C) 2021 Red Hat, Inc. + * + * Fedora-License-Identifier: MIT + * SPDX-2.0-License-Identifier: MIT + * SPDX-3.0-License-Identifier: MIT + * + * This program is free software. + * For more information on the license, see COPYING. + * For more information on free software, see . + */ + +#include +#include +#include "modulemd.h" +#include "config.h" + +static void +test_modulemd_v3_context_valid (void) +{ + const gchar *yaml_string = NULL; + g_autoptr (GError) error = NULL; + g_autoptr (GObject) object = NULL; + GType type = G_TYPE_INVALID; + + yaml_string = + "---\n" + "document: modulemd-packager\n" + "version: 3\n" + "data:\n" + " name: trivialname\n" + " stream: trivialstream\n" + " summary: Trivial Summary\n" + " description: >-\n" + " Trivial Description\n" + " license: [MIT]\n" + " configurations:\n" + " - context: a234567890\n" + " platform: foo\n" + "...\n"; + type = modulemd_read_packager_string (yaml_string, &object, &error); + g_assert_true (type == MODULEMD_TYPE_PACKAGER_V3); + g_assert_no_error (error); +} + + +static void +test_modulemd_v3_context_overlong (void) +{ + const gchar *yaml_string = NULL; + g_autoptr (GError) error = NULL; + g_autoptr (GObject) object = NULL; + GType type = G_TYPE_INVALID; + + yaml_string = + "---\n" + "document: modulemd-packager\n" + "version: 3\n" + "data:\n" + " name: trivialname\n" + " stream: trivialstream\n" + " summary: Trivial Summary\n" + " description: >-\n" + " Trivial Description\n" + " license: [MIT]\n" + " configurations:\n" + " - context: a2345678901\n" + " platform: foo\n" + "...\n"; + type = modulemd_read_packager_string (yaml_string, &object, &error); + g_assert_true (type == G_TYPE_INVALID); + g_assert_error (error, MODULEMD_ERROR, MMD_ERROR_VALIDATE); +} + + +static void +test_modulemd_v3_context_bad_underscore (void) +{ + const gchar *yaml_string = NULL; + g_autoptr (GError) error = NULL; + g_autoptr (GObject) object = NULL; + GType type = G_TYPE_INVALID; + + yaml_string = + "---\n" + "document: modulemd-packager\n" + "version: 3\n" + "data:\n" + " name: trivialname\n" + " stream: trivialstream\n" + " summary: Trivial Summary\n" + " description: >-\n" + " Trivial Description\n" + " license: [MIT]\n" + " configurations:\n" + " - context: _\n" + " platform: foo\n" + "...\n"; + type = modulemd_read_packager_string (yaml_string, &object, &error); + g_assert_true (type == G_TYPE_INVALID); + g_assert_error (error, MODULEMD_ERROR, MMD_ERROR_VALIDATE); +} + + +static void +test_modulemd_v2_context_valid (void) +{ + const gchar *yaml_string = NULL; + g_autoptr (GError) error = NULL; + g_autoptr (GObject) object = NULL; + GType type = G_TYPE_INVALID; + + yaml_string = + "---\n" + "document: modulemd\n" + "version: 2\n" + "data:\n" + " name: trivialname\n" + " stream: trivialstream\n" + " summary: Trivial Summary\n" + " description: >-\n" + " Trivial Description\n" + " license:\n" + " module: [MIT]\n" + " static_context: true\n" + " context: a234567890_23\n" + "...\n"; + type = modulemd_read_packager_string (yaml_string, &object, &error); + g_assert_true (type == MODULEMD_TYPE_MODULE_STREAM_V2); + g_assert_no_error (error); + /* Reading v2 document does not validate it; validating explictly */ + g_assert_true ( + modulemd_module_stream_validate (MODULEMD_MODULE_STREAM (object), &error)); +} + + +static void +test_modulemd_v2_context_overlong (void) +{ + const gchar *yaml_string = NULL; + g_autoptr (GError) error = NULL; + g_autoptr (GObject) object = NULL; + GType type = G_TYPE_INVALID; + + yaml_string = + "---\n" + "document: modulemd\n" + "version: 2\n" + "data:\n" + " name: trivialname\n" + " stream: trivialstream\n" + " summary: Trivial Summary\n" + " description: >-\n" + " Trivial Description\n" + " license:\n" + " module: [MIT]\n" + " static_context: true\n" + " context: a234567890_234\n" + "...\n"; + type = modulemd_read_packager_string (yaml_string, &object, &error); + g_assert_true (type == MODULEMD_TYPE_MODULE_STREAM_V2); + g_assert_no_error (error); + /* Reading v2 document does not validate it; validating explictly */ + g_assert_false ( + modulemd_module_stream_validate (MODULEMD_MODULE_STREAM (object), &error)); +} + + +static void +test_modulemd_v2_context_bad_character (void) +{ + const gchar *yaml_string = NULL; + g_autoptr (GError) error = NULL; + g_autoptr (GObject) object = NULL; + GType type = G_TYPE_INVALID; + + yaml_string = + "---\n" + "document: modulemd\n" + "version: 2\n" + "data:\n" + " name: trivialname\n" + " stream: trivialstream\n" + " summary: Trivial Summary\n" + " description: >-\n" + " Trivial Description\n" + " license:\n" + " module: [MIT]\n" + " static_context: true\n" + " context: '-'\n" + "...\n"; + type = modulemd_read_packager_string (yaml_string, &object, &error); + g_assert_true (type == MODULEMD_TYPE_MODULE_STREAM_V2); + g_assert_no_error (error); + /* Reading v2 document does not validate it; validating explictly */ + g_assert_false ( + modulemd_module_stream_validate (MODULEMD_MODULE_STREAM (object), &error)); +} + + +int +main (int argc, char *argv[]) +{ + setlocale (LC_ALL, ""); + g_test_init (&argc, &argv, NULL); + g_test_set_nonfatal_assertions (); + g_test_bug_base ("https://github.com/fedora-modularity/libmodulemd/issues/"); + g_test_bug ("549"); + + g_test_add_func ("/modulemd/v3/context/valid", + test_modulemd_v3_context_valid); + g_test_add_func ("/modulemd/v3/context/overlong", + test_modulemd_v3_context_overlong); + g_test_add_func ("/modulemd/v3/context/bad_underscore", + test_modulemd_v3_context_bad_underscore); + + g_test_add_func ("/modulemd/v2/context/valid", + test_modulemd_v2_context_valid); + g_test_add_func ("/modulemd/v2/context/overlong", + test_modulemd_v2_context_overlong); + g_test_add_func ("/modulemd/v2/context/bad_character", + test_modulemd_v2_context_bad_character); + + return g_test_run (); +} diff -Nru libmodulemd-2.12.0/modulemd/tests/test-modulemd-modulestream.c libmodulemd-2.13.0/modulemd/tests/test-modulemd-modulestream.c --- libmodulemd-2.12.0/modulemd/tests/test-modulemd-modulestream.c 2021-01-15 02:04:56.000000000 +0000 +++ libmodulemd-2.13.0/modulemd/tests/test-modulemd-modulestream.c 2021-07-09 09:29:23.351000000 +0000 @@ -536,6 +536,42 @@ static void +module_stream_v2_test_demodularized_rpms (void) +{ + g_autoptr (ModulemdModuleStreamV2) stream = NULL; + g_auto (GStrv) demodularized = NULL; + + stream = modulemd_module_stream_v2_new ("sssd", NULL); + + // Test add_demodularized_rpm + modulemd_module_stream_v2_add_demodularized_rpm (stream, "foo"); + modulemd_module_stream_v2_add_demodularized_rpm (stream, "bar"); + demodularized = modulemd_module_stream_v2_get_demodularized_rpms (stream); + + g_assert_true (g_strv_contains ((const gchar *const *)demodularized, "foo")); + g_assert_true (g_strv_contains ((const gchar *const *)demodularized, "bar")); + g_assert_cmpint (g_strv_length (demodularized), ==, 2); + g_clear_pointer (&demodularized, g_strfreev); + + // Test remove_demodularized_rpm + modulemd_module_stream_v2_remove_demodularized_rpm (stream, "foo"); + demodularized = modulemd_module_stream_v2_get_demodularized_rpms (stream); + + g_assert_true (g_strv_contains ((const gchar *const *)demodularized, "bar")); + g_assert_cmpint (g_strv_length (demodularized), ==, 1); + g_clear_pointer (&demodularized, g_strfreev); + + // Test clear_demodularized_rpms + modulemd_module_stream_v2_clear_demodularized_rpms (stream); + demodularized = modulemd_module_stream_v2_get_demodularized_rpms (stream); + g_assert_cmpint (g_strv_length (demodularized), ==, 0); + + g_clear_pointer (&demodularized, g_strfreev); + g_clear_object (&stream); +} + + +static void module_stream_test_upgrade_v1_to_v2 (void) { gboolean ret; @@ -623,6 +659,7 @@ g_auto (GStrv) rpm_apis = NULL; g_auto (GStrv) rpm_filters = NULL; + g_auto (GStrv) demodularized_rpms = NULL; g_auto (GStrv) rpm_artifacts = NULL; g_auto (GStrv) servicelevel_names = NULL; @@ -673,6 +710,10 @@ " filter:\n" " rpms: rpm_c\n" + " demodularized:\n" + " rpms:\n" + " - rpm_d\n" + " artifacts:\n" " rpms:\n" " - bar-0:1.23-1.module_deadbeef.x86_64\n" @@ -822,6 +863,8 @@ rpm_apis = modulemd_module_stream_v2_get_rpm_api_as_strv (streamV2); rpm_filters = modulemd_module_stream_v2_get_rpm_filters_as_strv (streamV2); + demodularized_rpms = + modulemd_module_stream_v2_get_demodularized_rpms (streamV2); rpm_artifacts = modulemd_module_stream_v2_get_rpm_artifacts_as_strv (streamV2); servicelevel_names = @@ -832,6 +875,9 @@ g_assert_true (g_strv_contains ((const gchar *const *)rpm_filters, "rpm_c")); + g_assert_true ( + g_strv_contains ((const gchar *const *)demodularized_rpms, "rpm_d")); + g_assert_true (g_strv_contains ((const gchar *const *)rpm_artifacts, "bar-0:1.23-1.module_deadbeef.x86_64")); @@ -988,6 +1034,7 @@ g_clear_pointer (&rpm_apis, g_strfreev); g_clear_pointer (&rpm_filters, g_strfreev); + g_clear_pointer (&demodularized_rpms, g_strfreev); g_clear_pointer (&rpm_artifacts, g_strfreev); g_clear_pointer (&servicelevel_names, g_strfreev); @@ -2127,6 +2174,8 @@ modulemd_module_stream_v2_add_rpm_artifact (stream_1, "artifact_b"); modulemd_module_stream_v2_add_rpm_filter (stream_1, "filter_a"); modulemd_module_stream_v2_add_rpm_filter (stream_1, "filter_b"); + modulemd_module_stream_v2_add_demodularized_rpm (stream_1, "rpm_3"); + modulemd_module_stream_v2_add_demodularized_rpm (stream_1, "rpm_4"); stream_2 = modulemd_module_stream_v2_new (NULL, NULL); modulemd_module_stream_v2_add_rpm_api (stream_2, "rpm_1"); @@ -2139,6 +2188,8 @@ modulemd_module_stream_v2_add_rpm_artifact (stream_2, "artifact_b"); modulemd_module_stream_v2_add_rpm_filter (stream_2, "filter_a"); modulemd_module_stream_v2_add_rpm_filter (stream_2, "filter_b"); + modulemd_module_stream_v2_add_demodularized_rpm (stream_2, "rpm_3"); + modulemd_module_stream_v2_add_demodularized_rpm (stream_2, "rpm_4"); g_assert_true (modulemd_module_stream_equals ( (ModulemdModuleStream *)stream_1, (ModulemdModuleStream *)stream_2)); @@ -2158,6 +2209,8 @@ modulemd_module_stream_v2_add_rpm_artifact (stream_1, "artifact_c"); modulemd_module_stream_v2_add_rpm_filter (stream_1, "filter_a"); modulemd_module_stream_v2_add_rpm_filter (stream_1, "filter_b"); + modulemd_module_stream_v2_add_demodularized_rpm (stream_1, "rpm_3"); + modulemd_module_stream_v2_add_demodularized_rpm (stream_1, "rpm_4"); stream_2 = modulemd_module_stream_v2_new (NULL, NULL); modulemd_module_stream_v2_add_rpm_api (stream_2, "rpm_1"); @@ -2169,6 +2222,8 @@ modulemd_module_stream_v2_add_rpm_artifact (stream_2, "artifact_b"); modulemd_module_stream_v2_add_rpm_filter (stream_2, "filter_a"); modulemd_module_stream_v2_add_rpm_filter (stream_2, "filter_b"); + modulemd_module_stream_v2_add_demodularized_rpm (stream_2, "rpm_3"); + modulemd_module_stream_v2_add_demodularized_rpm (stream_2, "rpm_4"); g_assert_false (modulemd_module_stream_equals ( (ModulemdModuleStream *)stream_1, (ModulemdModuleStream *)stream_2)); @@ -2712,6 +2767,9 @@ " filter:\n" " rpms:\n" " - baz-nonfoo\n" + " demodularized:\n" + " rpms:\n" + " - bar-old\n" " buildopts:\n" " rpms:\n" " macros: >\n" @@ -3451,6 +3509,9 @@ g_test_add_func ("/modulemd/v2/modulestream/v2/rpm_filters", module_stream_v2_test_rpm_filters); + g_test_add_func ("/modulemd/v2/modulestream/v2/demodularized_rpms", + module_stream_v2_test_demodularized_rpms); + g_test_add_func ("/modulemd/v2/modulestream/v2_yaml", module_stream_test_v2_yaml); diff -Nru libmodulemd-2.12.0/modulemd/tests/test-modulemd-packager-v3.c libmodulemd-2.13.0/modulemd/tests/test-modulemd-packager-v3.c --- libmodulemd-2.12.0/modulemd/tests/test-modulemd-packager-v3.c 2021-01-15 02:04:56.000000000 +0000 +++ libmodulemd-2.13.0/modulemd/tests/test-modulemd-packager-v3.c 2021-07-09 09:29:23.351000000 +0000 @@ -76,6 +76,11 @@ g_assert_null (list[0]); g_clear_pointer (&list, g_strfreev); + list = modulemd_packager_v3_get_demodularized_rpms (packager); + g_assert_nonnull (list); + g_assert_null (list[0]); + g_clear_pointer (&list, g_strfreev); + list = modulemd_packager_v3_get_rpm_component_names_as_strv (packager); g_assert_nonnull (list); @@ -262,6 +267,13 @@ g_assert_null (strv[1]); g_clear_pointer (&strv, g_strfreev); + strv = modulemd_packager_v3_get_demodularized_rpms (packager); + g_assert_nonnull (strv); + g_assert_nonnull (strv[0]); + g_assert_cmpstr ("bar-old", ==, strv[0]); + g_assert_null (strv[1]); + g_clear_pointer (&strv, g_strfreev); + strv = modulemd_packager_v3_get_rpm_component_names_as_strv (packager); g_assert_nonnull (strv); g_assert_nonnull (strv[0]); @@ -369,6 +381,9 @@ " filter:\n" " rpms:\n" " - baz-nonfoo\n" + " demodularized:\n" + " rpms:\n" + " - bar-old\n" " components:\n" " rpms:\n" " bar:\n" diff -Nru libmodulemd-2.12.0/modulemd/tests/test-modulemd-parse_int64.c libmodulemd-2.13.0/modulemd/tests/test-modulemd-parse_int64.c --- libmodulemd-2.12.0/modulemd/tests/test-modulemd-parse_int64.c 1970-01-01 00:00:00.000000000 +0000 +++ libmodulemd-2.13.0/modulemd/tests/test-modulemd-parse_int64.c 2021-07-09 09:29:23.351000000 +0000 @@ -0,0 +1,158 @@ +/* + * This file is part of libmodulemd + * Copyright (C) 2021 Red Hat, Inc. + * + * Fedora-License-Identifier: MIT + * SPDX-2.0-License-Identifier: MIT + * SPDX-3.0-License-Identifier: MIT + * + * This program is free software. + * For more information on the license, see COPYING. + * For more information on free software, see . + */ + +#include +#include +#include + +#include "private/modulemd-yaml.h" +#include "private/test-utils.h" +#include + +static void +test (const char *input, gint64 expected_value, gboolean expected_error) +{ + gint64 parsed; + g_autoptr (GError) error = NULL; + MMD_INIT_YAML_EVENT (event); + MMD_INIT_YAML_PARSER (parser); + + yaml_parser_set_input_string ( + &parser, (const unsigned char *)input, strlen (input)); + parser_skip_document_start (&parser); + + parsed = modulemd_yaml_parse_int64 (&parser, &error); + if (expected_error) + g_assert_nonnull (error); + else + g_assert_null (error); + g_assert_cmpuint (parsed, ==, expected_value); +} + +static void +test_int64_valid (void) +{ + test ("42", 42, FALSE); +} + +static void +test_int64_invalid_no_digit (void) +{ + test ("foo", 0, TRUE); +} + +static void +test_int64_invalid_incomplete (void) +{ + test ("42foo", 0, TRUE); +} + +static void +test_int64_valid_negative (void) +{ + test ("-42", -42, FALSE); +} + +static void +test_int64_invalid_too_big (void) +{ + test ("9223372036854775808", 0, TRUE); +} + +static void +test_int64_invalid_too_small (void) +{ + test ("-9223372036854775809", 0, TRUE); +} + +static void +utest (const char *input, guint64 expected_value, gboolean expected_error) +{ + guint64 parsed; + g_autoptr (GError) error = NULL; + MMD_INIT_YAML_EVENT (event); + MMD_INIT_YAML_PARSER (parser); + + yaml_parser_set_input_string ( + &parser, (const unsigned char *)input, strlen (input)); + parser_skip_document_start (&parser); + + parsed = modulemd_yaml_parse_uint64 (&parser, &error); + if (expected_error) + g_assert_nonnull (error); + else + g_assert_null (error); + g_assert_cmpuint (parsed, ==, expected_value); +} + +static void +test_uint64_valid (void) +{ + utest ("42", 42u, FALSE); +} + +static void +test_uint64_invalid_no_digit (void) +{ + utest ("foo", 0u, TRUE); +} + +static void +test_uint64_invalid_incomplete (void) +{ + utest ("42foo", 0u, TRUE); +} + +static void +test_uint64_invalid_negative (void) +{ + utest ("-42", 0u, TRUE); +} + +static void +test_uint64_invalid_too_big (void) +{ + utest ("18446744073709551616", 0u, TRUE); +} + + +int +main (int argc, char *argv[]) +{ + setlocale (LC_ALL, ""); + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/modulemd/v2/int64/yaml/parse/valid", test_int64_valid); + g_test_add_func ("/modulemd/v2/int64/yaml/parse/invalid_no_digit", + test_int64_invalid_no_digit); + g_test_add_func ("/modulemd/v2/int64/yaml/parse/invalid_incomplete", + test_int64_invalid_incomplete); + g_test_add_func ("/modulemd/v2/int64/yaml/parse/valid_negative", + test_int64_valid_negative); + g_test_add_func ("/modulemd/v2/int64/yaml/parse/invalid_too_big", + test_int64_invalid_too_big); + g_test_add_func ("/modulemd/v2/int64/yaml/parse/invalid_too_small", + test_int64_invalid_too_small); + + g_test_add_func ("/modulemd/v2/uint64/yaml/parse/valid", test_uint64_valid); + g_test_add_func ("/modulemd/v2/uint64/yaml/parse/invalid_no_digit", + test_uint64_invalid_no_digit); + g_test_add_func ("/modulemd/v2/uint64/yaml/parse/invalid_incomplete", + test_uint64_invalid_incomplete); + g_test_add_func ("/modulemd/v2/uint64/yaml/parse/invalid_negative", + test_uint64_invalid_negative); + g_test_add_func ("/modulemd/v2/uint64/yaml/parse/invalid_too_big", + test_uint64_invalid_too_big); + + return g_test_run (); +} diff -Nru libmodulemd-2.12.0/modulemd/tests/test-modulemd-validator.c libmodulemd-2.13.0/modulemd/tests/test-modulemd-validator.c --- libmodulemd-2.12.0/modulemd/tests/test-modulemd-validator.c 1970-01-01 00:00:00.000000000 +0000 +++ libmodulemd-2.13.0/modulemd/tests/test-modulemd-validator.c 2021-07-09 09:29:23.352000000 +0000 @@ -0,0 +1,218 @@ +/* + * This file is part of libmodulemd + * Copyright (C) 2021 Red Hat, Inc. + * + * Fedora-License-Identifier: MIT + * SPDX-2.0-License-Identifier: MIT + * SPDX-3.0-License-Identifier: MIT + * + * This program is free software. + * For more information on the license, see COPYING. + * For more information on free software, see . + */ + +#include +#include +#include +#include + +gint test_number = 0; +gint failed = 0; + +gchar **validator_argv = NULL; +gchar *validator_stdout = NULL; +gchar *validator_stderr = NULL; +gint validator_exit_status = 0; +gint expected_exit_code = 0; +gchar *expected_stdout = NULL; +gchar *expected_stderr = NULL; + +static void +ok (gboolean value, const gchar *name) +{ + test_number++; + if (value) + { + g_fprintf (stdout, "ok %d - %s\n", test_number, name); + } + else + { + failed++; + g_fprintf (stdout, "not ok %d - %s\n", test_number, name); + } +} + +static void +skip_n (gint tests, const gchar *reason) +{ + while (tests-- > 0) + { + test_number++; + if (!reason) + reason = ""; + g_fprintf (stdout, "ok %d # SKIP %s\n", test_number, reason); + } +} + +static void +skip (const gchar *reason) +{ + test_number++; + if (!reason) + reason = ""; + g_fprintf (stdout, "ok %d # SKIP %s\n", test_number, reason); +} + +static gboolean +test_execute (void) +{ + gboolean executed; + g_autoptr (GError) error = NULL; + g_autofree gchar *command = g_strjoinv (" ", validator_argv); + g_fprintf (stdout, "# Executing: %s\n", command); + executed = g_spawn_sync (NULL, + validator_argv, + NULL, + G_SPAWN_SEARCH_PATH, + NULL, + NULL, + &validator_stdout, + &validator_stderr, + &validator_exit_status, + &error); + ok (executed, "command executed"); + if (error) + { + g_fprintf (stdout, "# Exec failed with: %s\n", error->message); + } + return executed; +} + +static void +test_stdout (void) +{ + if (expected_stdout) + { + const gchar *found = + g_strstr_len (validator_stdout, -1, expected_stdout); + ok (NULL != found, "standard output conforms"); + if (!found) + g_fprintf (stdout, + "# expected: %s\n# got: %s\n", + expected_stdout, + validator_stdout); + } + else + { + skip ("no check for standard output specified"); + } +} + +static void +test_stderr (void) +{ + if (expected_stderr) + { + const gchar *found = + g_strstr_len (validator_stderr, -1, expected_stderr); + ok (NULL != found, "error output conforms"); + if (!found) + g_fprintf (stderr, + "# expected: %s\n# got: %s\n", + expected_stderr, + validator_stderr); + } + else + { + skip ("no check for error output specified"); + } +} + +static void +test_exit_code (void) +{ + g_autoptr (GError) error = NULL; + g_autofree gchar *message = NULL; + g_spawn_check_exit_status (validator_exit_status, &error); + message = g_strdup_printf ("exit code was %d", expected_exit_code); + if (0 == expected_exit_code) + ok (!error, message); + else + ok (error && error->domain == G_SPAWN_EXIT_ERROR && + error->code == expected_exit_code, + message); +} + + +int +main (int argc, char *argv[]) +{ + GOptionEntry entries[] = { + { "code", + '\0', + G_OPTION_FLAG_NONE, + G_OPTION_ARG_INT, + &expected_exit_code, + "Expected exit code (default is 0)", + NULL }, + { "stdout", + '\0', + G_OPTION_FLAG_NONE, + G_OPTION_ARG_STRING, + &expected_stdout, + "Check standard output for a substring (default is no check)", + NULL }, + { "stderr", + '\0', + G_OPTION_FLAG_NONE, + G_OPTION_ARG_STRING, + &expected_stderr, + "Check error output for a substring (default is no check)", + NULL }, + { NULL } + }; + GOptionContext *context; + g_autoptr (GError) error = NULL; + + setlocale (LC_ALL, ""); + + /* "-- --help" is not handled as a non-option if g_test_init() is used. + * Therefore this program does not Glib test frame work. */ + context = g_option_context_new ( + "MODULEMD_VALIDATOR_EXECUTABLE [MODULEMD_VALIDATOR_ARGUMENT...] - " + "test modulemd-validator behavior"); + g_option_context_add_main_entries (context, entries, NULL); + if (!g_option_context_parse (context, &argc, &argv, &error)) + { + g_fprintf (stderr, "Could not parse arguments: %s\n", error->message); + exit (EXIT_FAILURE); + } + g_option_context_free (context); + validator_argv = argv + 1; + if (!g_strcmp0 (validator_argv[0], "--")) + { + validator_argv++; + } + if (!validator_argv[0]) + { + g_fprintf (stderr, "No positional arguments.\n"); + exit (EXIT_FAILURE); + } + + g_fprintf (stdout, "1..4\n"); + if (test_execute ()) + { + test_exit_code (); + test_stdout (); + test_stderr (); + } + else + { + skip_n (3, "program failed to execute"); + } + g_free (expected_stdout); + g_free (expected_stderr); + g_free (validator_stdout); + g_free (validator_stderr); + exit (failed ? EXIT_FAILURE : EXIT_SUCCESS); +} diff -Nru libmodulemd-2.12.0/NEWS libmodulemd-2.13.0/NEWS --- libmodulemd-2.12.0/NEWS 1970-01-01 00:00:00.000000000 +0000 +++ libmodulemd-2.13.0/NEWS 2021-07-09 09:29:23.323000000 +0000 @@ -0,0 +1,59 @@ +Release history for libmodulemd + +2.13.0 2021-07-09 + +This release is fully compatible with the previous 2.12.1 version. + +Enhancements: +- Add /data/demodularized/rpms list to modulemd and modulemd-packager formats. + The listed binary RPM package names will be handled by a package manager as + removed from all previous module versions. This enables moving a package from + a module to a non-modular package set. +- modulemd-validator tool enables you to constrain a document type with a new + "--type" option. Without this option, all document types recognized by + a modulemd index are accepted. To validate version 3 of modulemd-packager + format, use "modulemd-validator --type modulemd-packager-v3 foo.yaml" + command. +- Allow disabling Python 3. You can pass -Dwith_py3=false to a meson setup + command to disable building a binding for Python 3. The binding is enabled + by default. + +Fixes: +- Reject invalid integers. Purely non-numeric values and negative numbers where + an unsigned type is mandated by a specification raise a parser error now. +- Handle a failed g_setenv() call in modulemd-validator. +- Prevent from dereferencing a NULL pointer when reporting invalid + subdocuments. +- A build script now refuses to disable Glib introspection + (-Dskip_introspection=true) while a Python binding is requested + (-Dwith_py3=true). +- "modulemd-validator --version" command returns 0 exit code now. + + +2.12.1 2021-05-03 + +This is a bug-fix release fully compatible with the previous 2.12.0 +version. Notable changes: + +Enhancements: +- Improve diagnostic messages for compression tests. +- Tests performed in a GitHub continues integration are faster. +- Use GitHub actions to perform CI tests also on ArchLinux, Mageia, + Mandriva, and OpenSUSE. + +Fixes: +- Relax context value up to 13 characters including an underscore + character in modulemd v2 format. This reenables scratch-builds in MBS. +- Migrate Packit tests from a deprecated current_version_command to + a newer actions/get-current-version. + + +2.12.0 2021-01-15 + +Enhancements: +- Enable component 'buildorder' for modulemd-packager v2 and v3 documents. + +Fixes: +- When adding obsoletes ensure index has stream mdversion at least 2. +- Add missing @staticmethod for python2. + diff -Nru libmodulemd-2.12.0/.packit.yml libmodulemd-2.13.0/.packit.yml --- libmodulemd-2.12.0/.packit.yml 2021-01-15 02:04:56.000000000 +0000 +++ libmodulemd-2.13.0/.packit.yml 2021-07-09 09:29:23.323000000 +0000 @@ -3,7 +3,8 @@ upstream_project_url: https://github.com/fedora-modularity/libmodulemd downstream_package_name: libmodulemd -current_version_command: [ ./get_version.sh ] +actions: + get-current-version: ./get_version.sh synced_files: - fedora/ @@ -19,3 +20,4 @@ targets: - fedora-all - epel-7 + - epel-8 diff -Nru libmodulemd-2.12.0/spec.v2.yaml libmodulemd-2.13.0/spec.v2.yaml --- libmodulemd-2.12.0/spec.v2.yaml 2021-01-15 02:04:56.000000000 +0000 +++ libmodulemd-2.13.0/spec.v2.yaml 2021-07-09 09:29:23.369000000 +0000 @@ -88,7 +88,7 @@ # Mandatory for module metadata in a yum/dnf repository. # # If 'static_context' is set to True: - # The context flag is a string of up to ten [a-zA-Z0-9] characters + # The context flag is a string of up to thirteen [a-zA-Z0-9_] characters # representing a build and runtime configuration for this stream. This # string is arbitrary but must be unique in this module stream. # @@ -385,6 +385,26 @@ rpms: - baz-nonfoo + # demodularized: + # Artifacts which became non-modular + # Defaults to no demodularization. + # Type: OPTIONAL + demodularized: + # rpms: + # A list of binary RPM package names which where removed from + # a module. This list explains to a package mananger that the packages + # are not part of the module anymore and up-to-now same-named masked + # non-modular packages should become available again. This enables + # moving a package from a module to a set of non-modular packages. The + # exact implementation of the demodularization (e.g. whether it + # applies to all modules or only to this stream) is defined by the + # package manager. + # Defaults to an empty list. + # + # Type: OPTIONAL + rpms: + - bar-old + # buildopts: # Component build options # Additional per component type module-wide build options. diff -Nru libmodulemd-2.12.0/spec.yaml libmodulemd-2.13.0/spec.yaml --- libmodulemd-2.12.0/spec.yaml 2021-01-15 02:04:56.000000000 +0000 +++ libmodulemd-2.13.0/spec.yaml 2021-07-09 09:29:23.369000000 +0000 @@ -88,7 +88,7 @@ # Mandatory for module metadata in a yum/dnf repository. # # If 'static_context' is set to True: - # The context flag is a string of up to ten [a-zA-Z0-9] characters + # The context flag is a string of up to thirteen [a-zA-Z0-9_] characters # representing a build and runtime configuration for this stream. This # string is arbitrary but must be unique in this module stream. # @@ -385,6 +385,26 @@ rpms: - baz-nonfoo + # demodularized: + # Artifacts which became non-modular + # Defaults to no demodularization. + # Type: OPTIONAL + demodularized: + # rpms: + # A list of binary RPM package names which where removed from + # a module. This list explains to a package mananger that the packages + # are not part of the module anymore and up-to-now same-named masked + # non-modular packages should become available again. This enables + # moving a package from a module to a set of non-modular packages. The + # exact implementation of the demodularization (e.g. whether it + # applies to all modules or only to this stream) is defined by the + # package manager. + # Defaults to an empty list. + # + # Type: OPTIONAL + rpms: + - bar-old + # buildopts: # Component build options # Additional per component type module-wide build options. diff -Nru libmodulemd-2.12.0/yaml_specs/modulemd_packager_v2.yaml libmodulemd-2.13.0/yaml_specs/modulemd_packager_v2.yaml --- libmodulemd-2.12.0/yaml_specs/modulemd_packager_v2.yaml 2021-01-15 02:04:56.000000000 +0000 +++ libmodulemd-2.13.0/yaml_specs/modulemd_packager_v2.yaml 2021-07-09 09:29:23.368000000 +0000 @@ -275,6 +275,26 @@ rpms: - baz-nonfoo + # demodularized: + # Artifacts which became non-modular + # Defaults to no demodularization. + # Type: OPTIONAL + demodularized: + # rpms: + # A list of binary RPM package names which where removed from + # a module. This list explains to a package mananger that the packages + # are not part of the module anymore and up-to-now same-named masked + # non-modular packages should become available again. This enables + # moving a package from a module to a set of non-modular packages. The + # exact implementation of the demodularization (e.g. whether it + # applies to all modules or only to this stream) is defined by the + # package manager. + # Defaults to an empty list. + # + # Type: OPTIONAL + rpms: + - bar-old + # components: # Functional components of the module # diff -Nru libmodulemd-2.12.0/yaml_specs/modulemd_packager_v3.yaml libmodulemd-2.13.0/yaml_specs/modulemd_packager_v3.yaml --- libmodulemd-2.12.0/yaml_specs/modulemd_packager_v3.yaml 2021-01-15 02:04:56.000000000 +0000 +++ libmodulemd-2.13.0/yaml_specs/modulemd_packager_v3.yaml 2021-07-09 09:29:23.368000000 +0000 @@ -335,6 +335,26 @@ rpms: - baz-nonfoo + # demodularized: + # Artifacts which became non-modular + # Defaults to no demodularization. + # Type: OPTIONAL + demodularized: + # rpms: + # A list of binary RPM package names which where removed from + # a module. This list explains to a package mananger that the packages + # are not part of the module anymore and up-to-now same-named masked + # non-modular packages should become available again. This enables + # moving a package from a module to a set of non-modular packages. The + # exact implementation of the demodularization (e.g. whether it + # applies to all modules or only to this stream) is defined by the + # package manager. + # Defaults to an empty list. + # + # Type: OPTIONAL + rpms: + - bar-old + # components: # Functional components of the module # diff -Nru libmodulemd-2.12.0/yaml_specs/modulemd_stream_v2.yaml libmodulemd-2.13.0/yaml_specs/modulemd_stream_v2.yaml --- libmodulemd-2.12.0/yaml_specs/modulemd_stream_v2.yaml 2021-01-15 02:04:56.000000000 +0000 +++ libmodulemd-2.13.0/yaml_specs/modulemd_stream_v2.yaml 2021-07-09 09:29:23.369000000 +0000 @@ -88,7 +88,7 @@ # Mandatory for module metadata in a yum/dnf repository. # # If 'static_context' is set to True: - # The context flag is a string of up to ten [a-zA-Z0-9] characters + # The context flag is a string of up to thirteen [a-zA-Z0-9_] characters # representing a build and runtime configuration for this stream. This # string is arbitrary but must be unique in this module stream. # @@ -385,6 +385,26 @@ rpms: - baz-nonfoo + # demodularized: + # Artifacts which became non-modular + # Defaults to no demodularization. + # Type: OPTIONAL + demodularized: + # rpms: + # A list of binary RPM package names which where removed from + # a module. This list explains to a package mananger that the packages + # are not part of the module anymore and up-to-now same-named masked + # non-modular packages should become available again. This enables + # moving a package from a module to a set of non-modular packages. The + # exact implementation of the demodularization (e.g. whether it + # applies to all modules or only to this stream) is defined by the + # package manager. + # Defaults to an empty list. + # + # Type: OPTIONAL + rpms: + - bar-old + # buildopts: # Component build options # Additional per component type module-wide build options.