13 | AppStream is a metadata specification which permits software components to provide information about themselves
14 | to automated systems and end-users before the software is actually installed.
15 |
16 |
17 | The appstream-generator tool generates AppStream metadata from the repositories of a software distribution.
18 | It currently supports the following repository formats / distributions: Debian, Ubuntu, Arch Linux, RPM-MD (Fedora, Mageia).
19 |
20 |
21 | The generator will produce AppStream catalog metadata files in the AppStream YAML or XML format to be shipped
22 | to users, as well as a detailed HTML report about found components and HTML and JSON reports on issues detected
23 | with the scanned metadata. It reads .desktop files as well as metainfo files, renders fonts, scales images, caches
24 | screenshots etc. to produce high-quality metadata for AppStream based software centers to consume.
25 | Usually, appstream-generator is integrated with the existing software build & packaging workflow of
26 | a distribution.
27 |
28 |
29 |
30 | https://github.com/ximion/appstream-generator
31 | https://github.com/ximion/appstream-generator/blob/master/docs/index.md
32 | https://github.com/ximion/appstream-generator/issues
33 |
34 | Freedesktop
35 |
36 | Matthias Klumpp
37 |
38 |
39 |
40 | appstream-generator
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/src/meson.build:
--------------------------------------------------------------------------------
1 |
2 | subdir('backends')
3 |
4 | asgencpp_src = files(
5 | 'config.cpp',
6 | 'contentsstore.cpp',
7 | 'cptmodifiers.cpp',
8 | 'datainjectpkg.cpp',
9 | 'datastore.cpp',
10 | 'dataunits.cpp',
11 | 'downloader.cpp',
12 | 'engine.cpp',
13 | 'extractor.cpp',
14 | 'hintregistry.cpp',
15 | 'iconhandler.cpp',
16 | 'logging.cpp',
17 | 'reportgenerator.cpp',
18 | 'result.cpp',
19 | 'utils.cpp',
20 | 'yaml-utils.cpp',
21 | 'zarchive.cpp',
22 | 'backends/interfaces.cpp',
23 | )
24 |
25 | asgencpp_hdr = files(
26 | 'config.h',
27 | 'contentsstore.h',
28 | 'cptmodifiers.h',
29 | 'datainjectpkg.h',
30 | 'datastore.h',
31 | 'dataunits.h',
32 | 'downloader.h',
33 | 'engine.h',
34 | 'extractor.h',
35 | 'hintregistry.h',
36 | 'iconhandler.h',
37 | 'logging.h',
38 | 'reportgenerator.h',
39 | 'result.h',
40 | 'utils.h',
41 | 'yaml-utils.h',
42 | 'zarchive.h',
43 | 'backends/interfaces.h',
44 | )
45 |
46 | conf_data = configuration_data()
47 | conf_data.set_quoted('INSTALL_PREFIX', get_option('prefix'))
48 | conf_data.set_quoted('DATADIR', join_paths(get_option('prefix'), get_option('datadir'), 'appstream'))
49 | conf_data.set_quoted('ASGEN_VERSION', asgen_version)
50 | conf_data.set('HAVE_BACKWARD', backward_dep.found())
51 | defines_h = configure_file(
52 | output: 'defines.h',
53 | configuration: conf_data
54 | )
55 |
56 | asgen_deps = [
57 | glib_dep,
58 | appstream_dep,
59 | ascompose_dep,
60 | fyaml_dep,
61 | lmdb_dep,
62 | archive_dep,
63 | curl_dep,
64 | tbb_dep,
65 | icu_dep,
66 | inja_dep,
67 | libxml2_dep,
68 | ]
69 |
70 | asgen_args = [
71 | '-DI_KNOW_THE_APPSTREAM_COMPOSE_API_IS_SUBJECT_TO_CHANGE'
72 | ]
73 |
74 | asgen_lib = static_library(
75 | 'asgenlib',
76 | [asgencpp_src, asgencpp_hdr, defines_h, backends_src],
77 | dependencies: asgen_deps,
78 | cpp_args: asgen_args,
79 | )
80 |
81 | asgen_lib_dep = declare_dependency(
82 | link_with: asgen_lib,
83 | include_directories: [src_dir],
84 | dependencies: asgen_deps,
85 | compile_args: asgen_args,
86 | )
87 |
88 | asgen_exe = executable('appstream-generator',
89 | ['main.cpp'],
90 | dependencies: [
91 | asgen_lib_dep,
92 | backward_deps,
93 | ],
94 | install: true
95 | )
96 |
--------------------------------------------------------------------------------
/src/backends/ubuntu/ubupkgindex.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016-2020 Canonical Ltd
3 | * Author: Iain Lane
4 | *
5 | * Licensed under the GNU Lesser General Public License Version 3
6 | *
7 | * This program is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the license, or
10 | * (at your option) any later version.
11 | *
12 | * This software is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Lesser General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with this software. If not, see .
19 | */
20 |
21 | #pragma once
22 |
23 | #include
24 | #include
25 | #include
26 | #include
27 | #include
28 |
29 | #include "../debian/debpkgindex.h"
30 | #include "ubupkg.h"
31 |
32 | namespace ASGenerator
33 | {
34 |
35 | class UbuntuPackageIndex : public DebianPackageIndex
36 | {
37 | public:
38 | explicit UbuntuPackageIndex(const std::string &dir);
39 |
40 | void release() override;
41 |
42 | std::vector> packagesFor(
43 | const std::string &suite,
44 | const std::string §ion,
45 | const std::string &arch,
46 | bool withLongDescs = true) override;
47 |
48 | std::shared_ptr packageForFile(
49 | const std::string &fname,
50 | const std::string &suite = "",
51 | const std::string §ion = "") override;
52 |
53 | protected:
54 | // Make tmpDir accessible to this class
55 | using DebianPackageIndex::m_tmpDir;
56 |
57 | std::shared_ptr newPackage(const std::string &name, const std::string &ver, const std::string &arch)
58 | override;
59 |
60 | private:
61 | std::shared_ptr m_langpacks;
62 |
63 | // holds the IDs of suite/section/arch combinations where we scanned language packs
64 | std::unordered_set m_checkedLangPacks;
65 | };
66 |
67 | } // namespace ASGenerator
68 |
--------------------------------------------------------------------------------
/.github/workflows/build-test.yml:
--------------------------------------------------------------------------------
1 | name: Build Test
2 |
3 | permissions:
4 | contents: read
5 |
6 | on: [push, pull_request]
7 |
8 | jobs:
9 | build-debian-testing:
10 | name: Debian Testing
11 | runs-on: ubuntu-latest
12 |
13 | steps:
14 | - uses: actions/checkout@v6
15 |
16 | - name: Create Build Environment
17 | run: cd tests/ci/ && podman build -t asgen -f ./Dockerfile-debian-testing .
18 |
19 | - name: Build
20 | run: podman run -a stdout -a stderr -e CXX=g++ -v `pwd`:/build asgen
21 | ./tests/ci/run-build.sh
22 |
23 | - name: Tests
24 | run: podman run -a stdout -a stderr -e CXX=g++ -v `pwd`:/build asgen
25 | ./tests/ci/run-tests.sh
26 |
27 |
28 | build-debian-stable:
29 | name: Debian Stable
30 | runs-on: ubuntu-latest
31 |
32 | steps:
33 | - uses: actions/checkout@v6
34 |
35 | - name: Create Build Environment
36 | run: cd tests/ci/ && podman build -t asgen -f ./Dockerfile-debian-stable .
37 |
38 | - name: Build
39 | run: podman run -a stdout -a stderr -e CXX=g++ -v `pwd`:/build asgen
40 | ./tests/ci/run-build.sh
41 |
42 | - name: Tests
43 | run: podman run -a stdout -a stderr -e CXX=g++ -v `pwd`:/build asgen
44 | ./tests/ci/run-tests.sh
45 |
46 |
47 | build-fedora-latest:
48 | name: Fedora Latest
49 | runs-on: ubuntu-latest
50 |
51 | steps:
52 | - uses: actions/checkout@v6
53 |
54 | - name: Create Build Environment
55 | run: cd tests/ci/ && podman build -t asgen -f ./Dockerfile-fedora-latest .
56 |
57 | - name: Build
58 | run: podman run -a stdout -a stderr -e CXX=g++ -v `pwd`:/build asgen
59 | ./tests/ci/run-build.sh
60 |
61 | - name: Tests
62 | run: podman run -a stdout -a stderr -e CXX=g++ -v `pwd`:/build asgen
63 | ./tests/ci/run-tests.sh
64 |
65 |
66 | build-ubuntu-lts:
67 | name: Ubuntu LTS
68 | runs-on: ubuntu-24.04
69 | env:
70 | CC: gcc-14
71 | CXX: g++-14
72 | steps:
73 | - uses: actions/checkout@v6
74 |
75 | - name: Create Build Environment
76 | run: sudo ./tests/ci/install-deps-deb.sh
77 |
78 | - name: Make & Install 3rd-party
79 | run: sudo ./tests/ci/ci-install-extern.sh
80 |
81 | - name: Build
82 | run: ./tests/ci/run-build.sh
83 |
84 | - name: Tests
85 | run: ./tests/ci/run-tests.sh
86 |
--------------------------------------------------------------------------------
/src/backends/debian/debutils.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016-2025 Matthias Klumpp
3 | * Copyright (C) The APT development team.
4 | * Copyright (C) 2016 Canonical Ltd
5 | * Author(s): Iain Lane
6 | *
7 | * Licensed under the GNU Lesser General Public License Version 3
8 | *
9 | * This program is free software: you can redistribute it and/or modify
10 | * it under the terms of the GNU Lesser General Public License as published by
11 | * the Free Software Foundation, either version 3 of the license, or
12 | * (at your option) any later version.
13 | *
14 | * This software is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 | * GNU Lesser General Public License for more details.
18 | *
19 | * You should have received a copy of the GNU Lesser General Public License
20 | * along with this software. If not, see .
21 | */
22 |
23 | #pragma once
24 |
25 | #include
26 |
27 | namespace ASGenerator
28 | {
29 |
30 | class Downloader;
31 |
32 | /**
33 | * If prefix is remote, download the first of (prefix + suffix).{xz,bz2,gz},
34 | * otherwise check if any of (prefix + suffix).{xz,bz2,gz} exists.
35 | *
36 | * Returns: Path to the file, which is guaranteed to exist.
37 | *
38 | * Params:
39 | * prefix = First part of the address, i.e.
40 | * "http://ftp.debian.org/debian/" or "/srv/mirrors/debian/"
41 | * destPrefix = If the file is remote, the directory to save it under,
42 | * which is created if necessary.
43 | * suffix = the rest of the address, so that (prefix +
44 | * suffix).format({xz,bz2,gz}) is a full path or URL, i.e.
45 | * "dists/unstable/main/binary-i386/Packages.%s". The suffix must
46 | * contain exactly one "%s"; this function is only suitable for
47 | * finding `.xz`, `.bz2` and `.gz` files.
48 | */
49 | std::string downloadIfNecessary(
50 | const std::string &prefix,
51 | const std::string &destPrefix,
52 | const std::string &suffix,
53 | Downloader *downloader = nullptr);
54 |
55 | /**
56 | * Compare two Debian-style version numbers.
57 | */
58 | int compareVersions(const std::string &a, const std::string &b);
59 |
60 | } // namespace ASGenerator
61 |
--------------------------------------------------------------------------------
/src/backends/archlinux/alpkgindex.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016-2025 Matthias Klumpp
3 | *
4 | * Licensed under the GNU Lesser General Public License Version 3
5 | *
6 | * This program is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU Lesser General Public License as published by
8 | * the Free Software Foundation, either version 3 of the license, or
9 | * (at your option) any later version.
10 | *
11 | * This software is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with this software. If not, see .
18 | */
19 |
20 | #pragma once
21 |
22 | #include
23 | #include
24 | #include
25 | #include
26 |
27 | #include "../interfaces.h"
28 | #include "../../utils.h"
29 | #include "alpkg.h"
30 | #include "listfile.h"
31 |
32 | namespace ASGenerator
33 | {
34 |
35 | class ArchPackageIndex : public PackageIndex
36 | {
37 | public:
38 | explicit ArchPackageIndex(const std::string &dir);
39 |
40 | void release() override;
41 |
42 | std::vector> packagesFor(
43 | const std::string &suite,
44 | const std::string §ion,
45 | const std::string &arch,
46 | bool withLongDescs = true) override;
47 |
48 | std::shared_ptr packageForFile(
49 | const std::string &fname,
50 | const std::string &suite = "",
51 | const std::string §ion = "") override;
52 |
53 | bool hasChanges(
54 | std::shared_ptr dstore,
55 | const std::string &suite,
56 | const std::string §ion,
57 | const std::string &arch) override;
58 |
59 | private:
60 | fs::path m_rootDir;
61 | std::unordered_map>> m_pkgCache;
62 |
63 | void setPkgDescription(std::shared_ptr pkg, const std::string &pkgDesc);
64 | std::vector> loadPackages(
65 | const std::string &suite,
66 | const std::string §ion,
67 | const std::string &arch);
68 | };
69 |
70 | } // namespace ASGenerator
71 |
--------------------------------------------------------------------------------
/data/templates/default/main.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 |
3 | {% block title %}Start{% endblock %}
4 |
5 | {% block header_content %}
6 | AppStream data hints for {{project_name}}
7 | {% endblock %}
8 |
9 | {% block content %}
10 |
11 |
12 |
Welcome!
13 |
Welcome to the AppStream Generator HTML pages!
14 |
15 | These pages exist to provide a user-friendly view on the issues discovered by the
16 | AppStream metadata generator while extracting metadata from packages in the {{project_name}} archive.
17 | They can also be used to take a look at the raw metadata, to spot possible problems
18 | with the data itself or the generation process.
19 |
34 | AppStream is a cross-distro XML format to provide metadata for software components and to assign unique identifiers to software.
35 | In {{project_name}}, we parse all XML provided by upstream projects as well as other metadata (.desktop-files, ...), and compile a single
36 | metadata file from it, which is then shipped to users.
37 |
38 |
39 | The generated metadata can for example be used by software centers like GNOME Software or KDE Discover to display a user-friendly application-centric
40 | view on the package archive.
41 | It can also be used by other software to find missing plugins, codecs, fonts, etc. or simply by users to install software on any Linux distribution
42 | without knowing the exact package name.
43 |
44 |
45 |
More information
46 |
47 | The offical AppStream specification can be found at freedesktop.org.
48 |
49 |
50 | You can find the source-code of the AppStream Generator here.
51 |
52 |
53 |
54 | {% endblock %}
55 |
--------------------------------------------------------------------------------
/src/backends/dummy/dummypkg.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016-2025 Matthias Klumpp
3 | *
4 | * Licensed under the GNU Lesser General Public License Version 3
5 | *
6 | * This program is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU Lesser General Public License as published by
8 | * the Free Software Foundation, either version 3 of the license, or
9 | * (at your option) any later version.
10 | *
11 | * This software is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with this software. If not, see .
18 | */
19 |
20 | #pragma once
21 |
22 | #include
23 | #include
24 | #include
25 | #include
26 |
27 | #include "../interfaces.h"
28 |
29 | namespace ASGenerator
30 | {
31 |
32 | class DummyPackage : public Package
33 | {
34 | private:
35 | std::string m_name;
36 | std::string m_version;
37 | std::string m_arch;
38 | std::string m_maintainer;
39 | std::unordered_map m_description;
40 | std::string m_testPkgFilename;
41 | PackageKind m_kind;
42 | std::vector m_contents;
43 |
44 | public:
45 | DummyPackage(const std::string &pname, const std::string &pver, const std::string &parch);
46 |
47 | std::string name() const override;
48 | std::string ver() const override;
49 | std::string arch() const override;
50 | std::string maintainer() const override;
51 |
52 | const std::unordered_map &description() const override;
53 |
54 | std::string getFilename() override;
55 | void setFilename(const std::string &fname);
56 |
57 | void setMaintainer(const std::string &maint);
58 |
59 | const std::vector &contents() override;
60 |
61 | std::vector getFileData(const std::string &fname) override;
62 |
63 | void finish() override;
64 |
65 | PackageKind kind() const noexcept override;
66 | void setKind(PackageKind v) noexcept;
67 |
68 | void setDescription(const std::string &text, const std::string &locale);
69 | };
70 |
71 | } // namespace ASGenerator
72 |
--------------------------------------------------------------------------------
/src/hintregistry.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016-2025 Matthias Klumpp
3 | *
4 | * Licensed under the GNU Lesser General Public License Version 3
5 | *
6 | * This program is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU Lesser General Public License as published by
8 | * the Free Software Foundation, either version 3 of the license, or
9 | * (at your option) any later version.
10 | *
11 | * This software is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with this software. If not, see .
18 | */
19 |
20 | #pragma once
21 |
22 | #include
23 | #include
24 | #include
25 | #include
26 |
27 | namespace ASGenerator
28 | {
29 |
30 | /**
31 | * Each issue hint type has a severity assigned to it:
32 | *
33 | * ERROR: A fatal error which resulted in the component being excluded from the final metadata.
34 | * WARNING: An issue which did not prevent generating meaningful data, but which is still serious
35 | * and should be fixed (warning of this kind usually result in less data).
36 | * INFO: Information, no immediate action needed (but will likely be an issue later).
37 | * PEDANTIC: Information which may improve the data, but could also be ignored.
38 | */
39 |
40 | /**
41 | * Definition of an issue hint.
42 | */
43 | struct HintDefinition {
44 | std::string tag; /// Unique issue tag
45 | AsIssueSeverity severity; /// Issue severity
46 | std::string explanation; /// Explanation template
47 | };
48 |
49 | /**
50 | * Load all issue hints from file and register them globally.
51 | */
52 | void loadHintsRegistry();
53 |
54 | /**
55 | * Save information about all hint templates we know about to a JSON file.
56 | */
57 | void saveHintsRegistryToJsonFile(const std::string &fname);
58 |
59 | /**
60 | * Retrieve hint definition for a given tag.
61 | */
62 | HintDefinition retrieveHintDef(const char *tag);
63 |
64 | /**
65 | * Convert a hint to JSON format.
66 | */
67 | std::string hintToJsonString(const std::string &tag, const std::unordered_map &vars);
68 |
69 | } // namespace ASGenerator
70 |
--------------------------------------------------------------------------------
/src/backends/freebsd/fbsdpkgindex.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2023-2025 Serenity Cyber Security, LLC
3 | * Author: Gleb Popov
4 | *
5 | * Licensed under the GNU Lesser General Public License Version 3
6 | *
7 | * This program is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the license, or
10 | * (at your option) any later version.
11 | *
12 | * This software is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Lesser General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with this software. If not, see .
19 | */
20 |
21 | #pragma once
22 |
23 | #include
24 | #include
25 | #include
26 | #include
27 | #include
28 | #include
29 | #include
30 |
31 | #include "../interfaces.h"
32 | #include "../../utils.h"
33 | #include "fbsdpkg.h"
34 |
35 | namespace ASGenerator
36 | {
37 |
38 | class FreeBSDPackageIndex : public PackageIndex
39 | {
40 | public:
41 | explicit FreeBSDPackageIndex(const std::string &dir);
42 |
43 | void release() override;
44 |
45 | std::vector> packagesFor(
46 | const std::string &suite,
47 | const std::string §ion,
48 | const std::string &arch,
49 | bool withLongDescs = true) override;
50 |
51 | std::shared_ptr packageForFile(
52 | const std::string &fname,
53 | const std::string &suite = "",
54 | const std::string §ion = "") override;
55 |
56 | bool hasChanges(
57 | std::shared_ptr dstore,
58 | const std::string &suite,
59 | const std::string §ion,
60 | const std::string &arch) override;
61 |
62 | private:
63 | fs::path m_rootDir;
64 | std::unordered_map>> m_pkgCache;
65 | std::mutex m_cacheMutex; // Thread safety for cache access
66 |
67 | std::vector> loadPackages(
68 | const std::string &suite,
69 | const std::string §ion,
70 | const std::string &arch);
71 | };
72 |
73 | } // namespace ASGenerator
74 |
--------------------------------------------------------------------------------
/src/cptmodifiers.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2021-2025 Matthias Klumpp
3 | *
4 | * Licensed under the GNU Lesser General Public License Version 3
5 | *
6 | * This program is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU Lesser General Public License as published by
8 | * the Free Software Foundation, either version 3 of the license, or
9 | * (at your option) any later version.
10 | *
11 | * This software is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with this software. If not, see .
18 | */
19 |
20 | #pragma once
21 |
22 | #include
23 | #include
24 | #include
25 | #include
26 | #include
27 |
28 | #include "config.h"
29 |
30 | namespace ASGenerator
31 | {
32 |
33 | class GeneratorResult;
34 |
35 | /**
36 | * Helper class to provide information about repository-specific metadata modifications.
37 | * Instances of this class must be thread safe.
38 | */
39 | class InjectedModifications
40 | {
41 | public:
42 | InjectedModifications();
43 | ~InjectedModifications();
44 |
45 | void loadForSuite(std::shared_ptr suite);
46 |
47 | bool hasRemovedComponents() const;
48 |
49 | /**
50 | * Test if component was marked for deletion.
51 | */
52 | bool isComponentRemoved(const std::string &cid) const;
53 |
54 | /**
55 | * Get injected custom data entries.
56 | */
57 | std::optional> injectedCustomData(const std::string &cid) const;
58 |
59 | void addRemovalRequestsToResult(GeneratorResult *gres) const;
60 |
61 | // Delete copy constructor and assignment operator
62 | InjectedModifications(const InjectedModifications &) = delete;
63 | InjectedModifications &operator=(const InjectedModifications &) = delete;
64 |
65 | private:
66 | std::unordered_map m_removedComponents;
67 | std::unordered_map> m_injectedCustomData;
68 |
69 | bool m_hasRemovedCpts;
70 | bool m_hasInjectedCustom;
71 |
72 | mutable std::shared_mutex m_mutex;
73 | };
74 |
75 | } // namespace ASGenerator
76 |
--------------------------------------------------------------------------------
/docs/usage.md:
--------------------------------------------------------------------------------
1 | # AppStream Generator Usage
2 |
3 | ## How to use
4 |
5 | ### Generating distro metadata
6 | To generate AppStream distribution metadata for your repository, create a local
7 | mirror of the repository first.
8 | Then create a new folder, and write a `asgen-config.json` configuration file for the
9 | metadata generator. Details on the file and an example can be found in [the asgen-config docs](asgen-config.md).
10 |
11 | After the config file has been written, you can generate the metadata as follows:
12 | ```Bash
13 | cd /srv/asgen/workspace # path where the asgen-config.json file is located
14 | appstream-generator process chromodoris # replace "chromodoris" with the name of the suite you want to analyze
15 | ```
16 | The generator is assuming you have enough memory and disk space on your machine to cache stuff.
17 | Resulting metadata will be placed in `export/data/`, machine-readable issue-hints can be found in `export/hints/` and the processed screenshots and icons are located in `export/media/`.
18 |
19 | In order to drop old packages and cruft from the databases, you should run
20 | ```Bash
21 | appstream-generator cleanup
22 | ```
23 | every once in a while. This will drop all superseded packages and data from the caches.
24 |
25 | If you do not want to `cd` into the workspace directory, you can also use the `--workspace|-w` flag to define a workspace.
26 |
27 | ### Validating metadata
28 | You can validate the resulting metadata using the AppStream client tools.
29 | Use `appstreamcli validate .xml.gz` for XML metadata, and `dep11-validate .yml.gz` for YAML. This will check the files for mistakes and compliance with the specification.
30 |
31 | Keep in mind that the generator will always generate spec-compliant metadata, but might - depending on the input - produce data which has smaller flaws (e.g. formatting issues in the long descriptions). In these cases, issue-hints will have been emitted, so the package maintainers can address the metadata issues.
32 |
33 | ## Troubleshooting
34 |
35 | ### Memory Usage
36 | The `appstream-generator` will not hesitate to use RAM, and also decide to use lots of it if enough is available. This is especially true when scanning new packages for their contents and storing the information in the LMDB database.
37 | Ideally make sure that you are running a 64bit system with at least 4GB of RAM if you want to use the generator properly.
38 | For the generator, speed matters more than RAM usage. You can use cgroups to limit the amount of memory the generator uses.
39 |
40 | ### Profiling
41 | TODO
42 |
--------------------------------------------------------------------------------
/tests/tests-engine.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2019-2025 Matthias Klumpp
3 | *
4 | * SPDX-License-Identifier: LGPL-3.0-or-later
5 | */
6 |
7 | #define CATCH_CONFIG_MAIN
8 | #include
9 |
10 | #include
11 | #include
12 |
13 | #include "logging.h"
14 | #include "utils.h"
15 | #include "config.h"
16 | #include "engine.h"
17 |
18 | using namespace ASGenerator;
19 |
20 | static struct TestSetup {
21 | TestSetup()
22 | {
23 | setVerbose(true);
24 | }
25 | } testSetup;
26 |
27 | TEST_CASE("Engine with test data", "[engine][integration]")
28 | {
29 | auto tempDir = fs::temp_directory_path() / std::format("asgen-test-{}", Utils::randomString(8));
30 | fs::create_directories(tempDir);
31 | auto samplesDir = Utils::getTestSamplesDir();
32 |
33 | SECTION("Test init with Debian backend")
34 | {
35 | auto debianSamplesDir = samplesDir / "debian";
36 |
37 | auto &config = Config::get();
38 | config.setWorkspaceDir("/tmp");
39 | config.backend = Backend::Debian;
40 | config.archiveRoot = debianSamplesDir.string();
41 |
42 | REQUIRE_NOTHROW([]() {
43 | Engine engine;
44 | }());
45 | }
46 |
47 | fs::remove_all(tempDir);
48 | }
49 |
50 | TEST_CASE("Engine package info functionality", "[engine]")
51 | {
52 | auto tempDir = fs::temp_directory_path() / std::format("asgen-test-{}", Utils::randomString(8));
53 | fs::create_directories(tempDir);
54 |
55 | auto &config = Config::get();
56 | config.backend = Backend::Dummy;
57 | config.setWorkspaceDir("/tmp");
58 | config.archiveRoot = (Utils::getTestSamplesDir() / "debian").string();
59 |
60 | Engine engine;
61 |
62 | SECTION("Print package info with invalid ID format")
63 | {
64 | // Test with malformed package ID (should return false)
65 | REQUIRE_FALSE(engine.printPackageInfo("invalid-package-id"));
66 | REQUIRE_FALSE(engine.printPackageInfo("too/many/slashes/here"));
67 | REQUIRE_FALSE(engine.printPackageInfo("notEnoughSlashes"));
68 | }
69 |
70 | SECTION("Print package info with valid ID format")
71 | {
72 | // Test with properly formatted package ID (even if package doesn't exist)
73 | // This should return true as the format is correct, even if no data is found
74 | REQUIRE(engine.printPackageInfo("package/1.0.0/amd64"));
75 | REQUIRE(engine.printPackageInfo("test-pkg/2.1.0/i386"));
76 | }
77 |
78 | fs::remove_all(tempDir);
79 | }
80 |
--------------------------------------------------------------------------------
/tests/tests-backend-misc.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2019-2025 Matthias Klumpp
3 | *
4 | * SPDX-License-Identifier: LGPL-3.0-or-later
5 | */
6 |
7 | #define CATCH_CONFIG_MAIN
8 | #include
9 |
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 |
18 | #include "logging.h"
19 | #include "utils.h"
20 |
21 | #include "backends/archlinux/listfile.h"
22 | #include "backends/rpmmd/rpmpkgindex.h"
23 |
24 | using namespace ASGenerator;
25 |
26 | static struct TestSetup {
27 | TestSetup()
28 | {
29 | setVerbose(true);
30 | }
31 | } testSetup;
32 |
33 | TEST_CASE("ListFile parsing", "[backend][archlinux]")
34 | {
35 | SECTION("Parse Arch Linux package format")
36 | {
37 | const std::string testData = R"(%FILENAME%
38 | a2ps-4.14-6-x86_64.pkg.tar.xz
39 |
40 | %NAME%
41 | a2ps
42 |
43 | %VERSION%
44 | 4.14-6
45 |
46 | %DESC%
47 | An Any to PostScript filter
48 |
49 | %CSIZE%
50 | 629320
51 |
52 | %MULTILINE%
53 | Blah1
54 | BLUBB2
55 | EtcEtcEtc3
56 |
57 | %SHA256SUM%
58 | a629a0e0eca0d96a97eb3564f01be495772439df6350600c93120f5ac7f3a1b5)";
59 |
60 | ListFile lf;
61 | std::vector testDataBytes(testData.begin(), testData.end());
62 | lf.loadData(testDataBytes);
63 |
64 | // Test single-line entries
65 | REQUIRE(lf.getEntry("FILENAME") == "a2ps-4.14-6-x86_64.pkg.tar.xz");
66 | REQUIRE(lf.getEntry("VERSION") == "4.14-6");
67 | REQUIRE(lf.getEntry("NAME") == "a2ps");
68 | REQUIRE(lf.getEntry("DESC") == "An Any to PostScript filter");
69 | REQUIRE(lf.getEntry("CSIZE") == "629320");
70 |
71 | // Test multiline entry
72 | REQUIRE(lf.getEntry("MULTILINE") == "Blah1\nBLUBB2\nEtcEtcEtc3");
73 |
74 | // Test SHA256SUM entry
75 | REQUIRE(lf.getEntry("SHA256SUM") == "a629a0e0eca0d96a97eb3564f01be495772439df6350600c93120f5ac7f3a1b5");
76 |
77 | // Test non-existent entry
78 | REQUIRE(lf.getEntry("NONEXISTENT").empty());
79 | }
80 | }
81 |
82 | TEST_CASE("RPMPackageIndex", "[backend][rpmmd]")
83 | {
84 | SECTION("Load RPM packages from test repository")
85 | {
86 | auto samplesDir = Utils::getTestSamplesDir();
87 | auto rpmmdDir = samplesDir / "rpmmd";
88 |
89 | RPMPackageIndex pi(rpmmdDir.string());
90 | auto pkgs = pi.packagesFor("26", "Workstation", "x86_64");
91 |
92 | REQUIRE(pkgs.size() == 4);
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/src/backends/archlinux/alpkg.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016-2025 Matthias Klumpp
3 | *
4 | * Licensed under the GNU Lesser General Public License Version 3
5 | *
6 | * This program is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU Lesser General Public License as published by
8 | * the Free Software Foundation, either version 3 of the license, or
9 | * (at your option) any later version.
10 | *
11 | * This software is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with this software. If not, see .
18 | */
19 |
20 | #pragma once
21 |
22 | #include
23 | #include
24 | #include
25 | #include
26 | #include
27 |
28 | #include "../interfaces.h"
29 |
30 | namespace ASGenerator
31 | {
32 |
33 | class ArchiveDecompressor;
34 |
35 | class ArchPackage : public Package
36 | {
37 | public:
38 | ArchPackage();
39 | ~ArchPackage() override = default;
40 |
41 | std::string name() const override;
42 | void setName(const std::string &val);
43 |
44 | std::string ver() const override;
45 | void setVersion(const std::string &val);
46 |
47 | std::string arch() const override;
48 | void setArch(const std::string &val);
49 |
50 | const std::unordered_map &description() const override;
51 |
52 | void setFilename(const std::string &fname);
53 | std::string getFilename() override;
54 |
55 | std::string maintainer() const override;
56 | void setMaintainer(const std::string &maint);
57 |
58 | void setDescription(const std::string &text, const std::string &locale);
59 |
60 | std::vector getFileData(const std::string &fname) override;
61 |
62 | const std::vector &contents() override;
63 | void setContents(const std::vector &c);
64 |
65 | void finish() override;
66 |
67 | private:
68 | std::string m_pkgname;
69 | std::string m_pkgver;
70 | std::string m_pkgarch;
71 | std::string m_pkgmaintainer;
72 | std::unordered_map m_desc;
73 | std::string m_pkgFname;
74 |
75 | std::vector m_contentsL;
76 | std::unique_ptr m_archive;
77 | };
78 |
79 | } // namespace ASGenerator
80 |
--------------------------------------------------------------------------------
/src/backends/rpmmd/rpmpkgindex.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016-2025 Matthias Klumpp
3 | *
4 | * Licensed under the GNU Lesser General Public License Version 3
5 | *
6 | * This program is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU Lesser General Public License as published by
8 | * the Free Software Foundation, either version 3 of the license, or
9 | * (at your option) any later version.
10 | *
11 | * This software is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with this software. If not, see .
18 | */
19 |
20 | #pragma once
21 |
22 | #include
23 | #include
24 | #include
25 | #include
26 | #include
27 | #include
28 | #include
29 |
30 | #include "../interfaces.h"
31 | #include "rpmpkg.h"
32 |
33 | namespace fs = std::filesystem;
34 |
35 | namespace ASGenerator
36 | {
37 |
38 | class RPMPackageIndex : public PackageIndex
39 | {
40 | public:
41 | explicit RPMPackageIndex(const std::string &dir);
42 | ~RPMPackageIndex();
43 |
44 | void release() override;
45 |
46 | std::vector> packagesFor(
47 | const std::string &suite,
48 | const std::string §ion,
49 | const std::string &arch,
50 | bool withLongDescs = true) override;
51 |
52 | std::shared_ptr packageForFile(
53 | const std::string &fname,
54 | const std::string &suite = "",
55 | const std::string §ion = "") override;
56 |
57 | bool hasChanges(
58 | std::shared_ptr dstore,
59 | const std::string &suite,
60 | const std::string §ion,
61 | const std::string &arch) override;
62 |
63 | private:
64 | fs::path m_rootDir;
65 | fs::path m_tmpRootDir;
66 | std::unordered_map>> m_pkgCache;
67 | mutable std::mutex m_cacheMutex; // Thread safety for cache access
68 |
69 | void setPkgDescription(std::shared_ptr pkg, const std::string &pkgDesc);
70 | std::vector> loadPackages(
71 | const std::string &suite,
72 | const std::string §ion,
73 | const std::string &arch);
74 | };
75 |
76 | } // namespace ASGenerator
77 |
--------------------------------------------------------------------------------
/.clang-format:
--------------------------------------------------------------------------------
1 | ---
2 | BasedOnStyle: LLVM
3 | IndentWidth: 4
4 | ---
5 | Language: Cpp
6 | Standard: C++11
7 | ColumnLimit: 120
8 | BreakBeforeBraces: Linux
9 | PointerAlignment: Right
10 | AlignAfterOpenBracket: AlwaysBreak
11 | AllowAllParametersOfDeclarationOnNextLine: false
12 | AlwaysBreakBeforeMultilineStrings: true
13 | BreakBeforeBinaryOperators: NonAssignment
14 | AlignArrayOfStructures: Left
15 |
16 | # format C++11 braced lists like function calls
17 | Cpp11BracedListStyle: true
18 |
19 | # do not put a space before C++11 braced lists
20 | SpaceBeforeCpp11BracedList: false
21 |
22 | # no namespace indentation to keep indent level low
23 | NamespaceIndentation: None
24 |
25 | # we use template< without space.
26 | SpaceAfterTemplateKeyword: false
27 |
28 | # Always break after template declaration
29 | AlwaysBreakTemplateDeclarations: true
30 |
31 | # macros for which the opening brace stays attached.
32 | ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH, forever, Q_FOREVER, QBENCHMARK, QBENCHMARK_ONCE ]
33 |
34 | # keep lambda formatting multi-line if not empty
35 | AllowShortLambdasOnASingleLine: Empty
36 |
37 | # return types should not be on their own lines
38 | AlwaysBreakAfterReturnType: None
39 | PenaltyReturnTypeOnItsOwnLine: 1000
40 | AlwaysBreakAfterDefinitionReturnType: None
41 |
42 | # Break constructor initializers before the colon and after the commas,
43 | # and never put the all in one line.
44 | BreakConstructorInitializers: BeforeColon
45 | BreakInheritanceList: BeforeColon
46 | PackConstructorInitializers: Never
47 |
48 | # Place ternary operators after line breaks
49 | BreakBeforeTernaryOperators: true
50 |
51 | # No own indentation level for access modifiers
52 | IndentAccessModifiers: false
53 | AccessModifierOffset: -4
54 |
55 | # Add empty line only when access modifier starts a new logical block.
56 | EmptyLineBeforeAccessModifier: LogicalBlock
57 |
58 | # Only merge empty functions.
59 | AllowShortFunctionsOnASingleLine: Empty
60 |
61 | # Don't indent case labels.
62 | IndentCaseLabels: false
63 |
64 | # No space after C-style cast
65 | SpaceAfterCStyleCast: false
66 |
67 | # Never pack arguments or parameters
68 | BinPackArguments: false
69 | BinPackParameters: false
70 |
71 | # Avoid breaking around an assignment operator
72 | PenaltyBreakAssignment: 150
73 |
74 | # Left-align newline escapes, e.g. in macros
75 | AlignEscapedNewlines: Left
76 |
77 | # Enums should be one entry per line
78 | AllowShortEnumsOnASingleLine: false
79 |
80 | # we want consecutive macros to be aligned
81 | AlignConsecutiveMacros: true
82 |
83 | # never sort includes, only regroup (in rare cases)
84 | IncludeBlocks: Regroup
85 | SortIncludes: Never
86 |
--------------------------------------------------------------------------------
/src/backends/freebsd/fbsdpkg.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2023-2025 Serenity Cyber Security, LLC
3 | * Author: Gleb Popov
4 | *
5 | * Licensed under the GNU Lesser General Public License Version 3
6 | *
7 | * This program is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the license, or
10 | * (at your option) any later version.
11 | *
12 | * This software is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Lesser General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with this software. If not, see .
19 | */
20 |
21 | #pragma once
22 |
23 | #include
24 | #include
25 | #include
26 | #include
27 | #include
28 | #include
29 | #include
30 |
31 | #include "../interfaces.h"
32 | #include "../../utils.h"
33 |
34 | namespace ASGenerator
35 | {
36 |
37 | class ArchiveDecompressor;
38 |
39 | class FreeBSDPackage : public Package
40 | {
41 | public:
42 | FreeBSDPackage(const std::string &pkgRoot, const nlohmann::json &j);
43 | ~FreeBSDPackage() override = default;
44 |
45 | std::string name() const override;
46 | std::string ver() const override;
47 | std::string arch() const override;
48 | std::string maintainer() const override;
49 | std::string getFilename() override;
50 |
51 | const std::unordered_map &summary() const override;
52 | const std::unordered_map &description() const override;
53 |
54 | std::vector getFileData(const std::string &fname) override;
55 |
56 | const std::vector &contents() override;
57 |
58 | void finish() override;
59 |
60 | PackageKind kind() const noexcept override;
61 |
62 | private:
63 | nlohmann::json m_pkgjson;
64 | fs::path m_pkgFname;
65 | PackageKind m_kind;
66 | std::unique_ptr m_pkgArchive;
67 | std::vector m_contentsL;
68 |
69 | // Mutable cache members for lazy initialization of summary/description
70 | mutable std::unordered_map m_summaryCache;
71 | mutable std::unordered_map m_descriptionCache;
72 |
73 | mutable std::mutex m_mutex;
74 | };
75 |
76 | } // namespace ASGenerator
77 |
--------------------------------------------------------------------------------
/src/datainjectpkg.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2018-2025 Matthias Klumpp
3 | *
4 | * Licensed under the GNU Lesser General Public License Version 3
5 | *
6 | * This program is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU Lesser General Public License as published by
8 | * the Free Software Foundation, either version 3 of the license, or
9 | * (at your option) any later version.
10 | *
11 | * This software is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with this software. If not, see .
18 | */
19 |
20 | #pragma once
21 |
22 | #include
23 | #include
24 | #include
25 | #include
26 |
27 | #include "backends/interfaces.h"
28 |
29 | namespace ASGenerator
30 | {
31 |
32 | /**
33 | * Fake package which has the sole purpose of allowing easy injection of local
34 | * data that does not reside in packages.
35 | */
36 | class DataInjectPackage final : public Package
37 | {
38 | public:
39 | DataInjectPackage(const std::string &pname, const std::string &parch, const std::string &prefix);
40 |
41 | std::string name() const override;
42 | std::string ver() const override;
43 | std::string arch() const override;
44 | PackageKind kind() const noexcept override;
45 | const std::unordered_map &description() const override;
46 | std::string getFilename() override;
47 | std::string maintainer() const override;
48 | void setMaintainer(const std::string &maint);
49 |
50 | const std::string &dataLocation() const;
51 | void setDataLocation(const std::string &value);
52 |
53 | const std::string &archDataLocation() const;
54 | void setArchDataLocation(const std::string &value);
55 |
56 | const std::vector &contents() override;
57 | std::vector getFileData(const std::string &fname) override;
58 | void finish() override;
59 |
60 | private:
61 | std::string m_pkgname;
62 | std::string m_pkgarch;
63 | std::string m_pkgmaintainer;
64 | std::unordered_map m_desc;
65 | std::unordered_map m_contents;
66 | std::string m_fakePrefix;
67 | std::string m_dataLocation;
68 | std::string m_archDataLocation;
69 |
70 | mutable std::vector m_contentsVector;
71 | };
72 |
73 | } // namespace ASGenerator
74 |
--------------------------------------------------------------------------------
/src/backends/alpinelinux/apkpkg.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2020-2025 Rasmus Thomsen
3 | * Copyright (C) 2016-2025 Matthias Klumpp
4 | *
5 | * Licensed under the GNU Lesser General Public License Version 3
6 | *
7 | * This program is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the license, or
10 | * (at your option) any later version.
11 | *
12 | * This software is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Lesser General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with this software. If not, see .
19 | */
20 |
21 | #pragma once
22 |
23 | #include
24 | #include
25 | #include
26 | #include
27 | #include
28 |
29 | #include "../interfaces.h"
30 | #include "../../utils.h"
31 |
32 | namespace ASGenerator
33 | {
34 |
35 | class ArchiveDecompressor;
36 |
37 | class AlpinePackage : public Package
38 | {
39 | public:
40 | AlpinePackage(const std::string &pkgname, const std::string &pkgver, const std::string &pkgarch);
41 | ~AlpinePackage() override = default;
42 |
43 | std::string name() const override;
44 | void setName(const std::string &val);
45 |
46 | std::string ver() const override;
47 | void setVersion(const std::string &val);
48 |
49 | std::string arch() const override;
50 | void setArch(const std::string &val);
51 |
52 | const std::unordered_map &description() const override;
53 |
54 | void setFilename(const std::string &fname);
55 | std::string getFilename() override;
56 |
57 | std::string maintainer() const override;
58 | void setMaintainer(const std::string &maint);
59 |
60 | void setDescription(const std::string &text, const std::string &locale);
61 |
62 | std::vector getFileData(const std::string &fname) override;
63 |
64 | const std::vector &contents() override;
65 | void setContents(const std::vector &c);
66 |
67 | void finish() override;
68 |
69 | private:
70 | std::string m_pkgname;
71 | std::string m_pkgver;
72 | std::string m_pkgarch;
73 | std::string m_pkgmaintainer;
74 | std::unordered_map m_desc;
75 | std::string m_pkgFname;
76 | fs::path m_localPkgFName;
77 | fs::path m_tmpDir;
78 |
79 | std::vector m_contentsL;
80 | std::unique_ptr m_archive;
81 |
82 | mutable std::mutex m_mutex;
83 | };
84 |
85 | } // namespace ASGenerator
86 |
--------------------------------------------------------------------------------
/src/backends/rpmmd/rpmpkg.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016-2025 Matthias Klumpp
3 | *
4 | * Licensed under the GNU Lesser General Public License Version 3
5 | *
6 | * This program is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU Lesser General Public License as published by
8 | * the Free Software Foundation, either version 3 of the license, or
9 | * (at your option) any later version.
10 | *
11 | * This software is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with this software. If not, see .
18 | */
19 |
20 | #pragma once
21 |
22 | #include
23 | #include
24 | #include
25 | #include
26 | #include
27 |
28 | #include "../interfaces.h"
29 | #include "../../utils.h"
30 |
31 | namespace ASGenerator
32 | {
33 |
34 | class ArchiveDecompressor;
35 |
36 | class RPMPackage : public Package
37 | {
38 | public:
39 | RPMPackage();
40 | ~RPMPackage() override = default;
41 |
42 | std::string name() const override;
43 | void setName(const std::string &val);
44 |
45 | std::string ver() const override;
46 | void setVersion(const std::string &val);
47 |
48 | std::string arch() const override;
49 | void setArch(const std::string &val);
50 |
51 | const std::unordered_map &description() const override;
52 | const std::unordered_map &summary() const override;
53 |
54 | std::string getFilename() override;
55 | void setFilename(const std::string &fname);
56 |
57 | std::string maintainer() const override;
58 | void setMaintainer(const std::string &maint);
59 |
60 | void setDescription(const std::string &text, const std::string &locale);
61 | void setSummary(const std::string &text, const std::string &locale);
62 |
63 | std::vector getFileData(const std::string &fname) override;
64 |
65 | const std::vector &contents() override;
66 | void setContents(const std::vector &c);
67 |
68 | void finish() override;
69 |
70 | private:
71 | std::string m_pkgname;
72 | std::string m_pkgver;
73 | std::string m_pkgarch;
74 | std::string m_pkgmaintainer;
75 | std::unordered_map m_desc;
76 | std::unordered_map m_summ;
77 | std::string m_pkgFname;
78 | fs::path m_localPkgFname;
79 |
80 | std::vector m_contentsL;
81 | std::unique_ptr m_archive;
82 |
83 | mutable std::mutex m_mutex;
84 | };
85 |
86 | } // namespace ASGenerator
87 |
--------------------------------------------------------------------------------
/src/backends/alpinelinux/apkpkgindex.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2020-2025 Rasmus Thomsen
3 | *
4 | * Licensed under the GNU Lesser General Public License Version 3
5 | *
6 | * This program is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU Lesser General Public License as published by
8 | * the Free Software Foundation, either version 3 of the license, or
9 | * (at your option) any later version.
10 | *
11 | * This software is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with this software. If not, see .
18 | */
19 |
20 | #pragma once
21 |
22 | #include
23 | #include
24 | #include
25 | #include
26 |
27 | #include "../interfaces.h"
28 | #include "../../utils.h"
29 | #include "apkpkg.h"
30 |
31 | namespace ASGenerator
32 | {
33 |
34 | struct ApkIndexEntry {
35 | std::string pkgname;
36 | std::string pkgversion;
37 | std::string arch;
38 | std::string archiveName;
39 | std::string maintainer;
40 | std::string pkgdesc;
41 | };
42 |
43 | class AlpinePackageIndex : public PackageIndex
44 | {
45 | public:
46 | explicit AlpinePackageIndex(const std::string &dir);
47 |
48 | void release() override;
49 |
50 | std::vector> packagesFor(
51 | const std::string &suite,
52 | const std::string §ion,
53 | const std::string &arch,
54 | bool withLongDescs = true) override;
55 |
56 | std::shared_ptr packageForFile(
57 | const std::string &fname,
58 | const std::string &suite = "",
59 | const std::string §ion = "") override;
60 |
61 | bool hasChanges(
62 | std::shared_ptr dstore,
63 | const std::string &suite,
64 | const std::string §ion,
65 | const std::string &arch) override;
66 |
67 | private:
68 | fs::path m_rootDir;
69 | fs::path m_tmpDir;
70 | std::unordered_map>> m_pkgCache;
71 |
72 | void setPkgDescription(std::shared_ptr pkg, const std::string &pkgDesc);
73 | std::vector> loadPackages(
74 | const std::string &suite,
75 | const std::string §ion,
76 | const std::string &arch);
77 | std::vector parseApkIndex(const std::string &indexString);
78 | std::string downloadIfNecessary(
79 | const std::string &apkRootPath,
80 | const std::string &tmpDir,
81 | const std::string &fileName,
82 | const std::string &cacheFileName);
83 | };
84 |
85 | } // namespace ASGenerator
86 |
--------------------------------------------------------------------------------
/src/backends/dummy/dummypkg.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016-2025 Matthias Klumpp
3 | *
4 | * Licensed under the GNU Lesser General Public License Version 3
5 | *
6 | * This program is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU Lesser General Public License as published by
8 | * the Free Software Foundation, either version 3 of the license, or
9 | * (at your option) any later version.
10 | *
11 | * This software is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with this software. If not, see .
18 | */
19 |
20 | #include "dummypkg.h"
21 |
22 | #include "../../logging.h"
23 |
24 | namespace ASGenerator
25 | {
26 |
27 | DummyPackage::DummyPackage(const std::string &pname, const std::string &pver, const std::string &parch)
28 | : m_name(pname),
29 | m_version(pver),
30 | m_arch(parch),
31 | m_kind(PackageKind::Physical),
32 | m_contents({"NOTHING1", "NOTHING2"})
33 | {
34 | }
35 |
36 | std::string DummyPackage::name() const
37 | {
38 | return m_name;
39 | }
40 |
41 | std::string DummyPackage::ver() const
42 | {
43 | return m_version;
44 | }
45 |
46 | std::string DummyPackage::arch() const
47 | {
48 | return m_arch;
49 | }
50 |
51 | std::string DummyPackage::maintainer() const
52 | {
53 | return m_maintainer;
54 | }
55 |
56 | const std::unordered_map &DummyPackage::description() const
57 | {
58 | return m_description;
59 | }
60 |
61 | std::string DummyPackage::getFilename()
62 | {
63 | return m_testPkgFilename;
64 | }
65 |
66 | void DummyPackage::setFilename(const std::string &fname)
67 | {
68 | m_testPkgFilename = fname;
69 | }
70 |
71 | void DummyPackage::setMaintainer(const std::string &maint)
72 | {
73 | m_maintainer = maint;
74 | }
75 |
76 | const std::vector &DummyPackage::contents()
77 | {
78 | return m_contents;
79 | }
80 |
81 | std::vector DummyPackage::getFileData(const std::string &fname)
82 | {
83 | if (fname == "TEST") {
84 | return {'N', 'O', 'T', 'H', 'I', 'N', 'G'};
85 | }
86 | return {};
87 | }
88 |
89 | void DummyPackage::finish()
90 | {
91 | // No-op for dummy package
92 | }
93 |
94 | PackageKind DummyPackage::kind() const noexcept
95 | {
96 | return m_kind;
97 | }
98 |
99 | void DummyPackage::setKind(PackageKind v) noexcept
100 | {
101 | m_kind = v;
102 | }
103 |
104 | void DummyPackage::setDescription(const std::string &text, const std::string &locale)
105 | {
106 | m_description[locale] = text;
107 | }
108 |
109 | } // namespace ASGenerator
110 |
--------------------------------------------------------------------------------
/src/backends/ubuntu/ubupkg.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016-2020 Canonical Ltd
3 | * Author: Iain Lane
4 | *
5 | * Licensed under the GNU Lesser General Public License Version 3
6 | *
7 | * This program is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the license, or
10 | * (at your option) any later version.
11 | *
12 | * This software is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Lesser General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with this software. If not, see .
19 | */
20 |
21 | #pragma once
22 |
23 | #include
24 | #include
25 | #include
26 | #include
27 | #include
28 | #include
29 |
30 | #include "../debian/debpkg.h"
31 |
32 | namespace ASGenerator
33 | {
34 |
35 | class UbuntuPackage;
36 |
37 | /**
38 | * A helper class that provides functions to work with language packs
39 | * used in Ubuntu.
40 | */
41 | class LanguagePackProvider
42 | {
43 | public:
44 | explicit LanguagePackProvider(const fs::path &globalTmpDir);
45 |
46 | void addLanguagePacks(const std::vector> &langpacks);
47 | void clear();
48 | std::unordered_map getTranslations(const std::string &domain, const std::string &text);
49 |
50 | private:
51 | std::vector> m_langpacks;
52 | fs::path m_globalTmpDir;
53 | fs::path m_langpackDir;
54 | fs::path m_localeDir;
55 | std::string m_localedefExe;
56 | std::vector m_langpackLocales;
57 |
58 | mutable std::mutex m_mutex;
59 |
60 | void extractLangpacks();
61 | std::unordered_map getTranslationsPrivate(
62 | const std::string &domain,
63 | const std::string &text);
64 | };
65 |
66 | /**
67 | * Ubuntu package - extends Debian package with language pack support
68 | */
69 | class UbuntuPackage : public DebPackage
70 | {
71 | public:
72 | UbuntuPackage(
73 | const std::string &pname,
74 | const std::string &pver,
75 | const std::string &parch,
76 | std::shared_ptr l10nTexts = nullptr);
77 |
78 | void setLanguagePackProvider(std::shared_ptr provider);
79 |
80 | std::unordered_map getDesktopFileTranslations(
81 | GKeyFile *desktopFile,
82 | const std::string &text) override;
83 |
84 | bool hasDesktopFileTranslations() const override;
85 |
86 | private:
87 | std::shared_ptr m_langpackProvider;
88 | };
89 |
90 | } // namespace ASGenerator
91 |
--------------------------------------------------------------------------------
/src/extractor.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016-2025 Matthias Klumpp
3 | *
4 | * Licensed under the GNU Lesser General Public License Version 3
5 | *
6 | * This program is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU Lesser General Public License as published by
8 | * the Free Software Foundation, either version 3 of the license, or
9 | * (at your option) any later version.
10 | *
11 | * This software is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public License
17 | * along with this software. If not, see .
18 | */
19 |
20 | #pragma once
21 |
22 | #include
23 | #include
24 | #include
25 |
26 | #include "config.h"
27 | #include "datastore.h"
28 | #include "iconhandler.h"
29 | #include "result.h"
30 | #include "backends/interfaces.h"
31 | #include "cptmodifiers.h"
32 | #include "dataunits.h"
33 |
34 | namespace ASGenerator
35 | {
36 |
37 | /**
38 | * Class for extracting AppStream metadata from packages.
39 | */
40 | class DataExtractor
41 | {
42 | public:
43 | DataExtractor(
44 | std::shared_ptr db,
45 | std::shared_ptr iconHandler,
46 | AsgLocaleUnit *localeUnit,
47 | std::shared_ptr