Add `pacparse` utility to parse package files
This commit is contained in:
parent
bf67d1914d
commit
df55813d59
|
@ -42,4 +42,4 @@ link_directories(${LIBREPOMGR_BINARY_DIR})
|
|||
add_subdirectory(srv)
|
||||
add_subdirectory(cli)
|
||||
add_subdirectory(pacfind)
|
||||
|
||||
add_subdirectory(pacparse)
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
cmake_minimum_required(VERSION 3.17.0 FATAL_ERROR)
|
||||
|
||||
# add project files
|
||||
set(HEADER_FILES)
|
||||
set(SRC_FILES main.cpp)
|
||||
set(TEST_HEADER_FILES)
|
||||
set(TEST_SRC_FILES tests/cppunit.cpp tests/check.cpp)
|
||||
|
||||
# meta data
|
||||
set(META_PROJECT_NAME pacparse)
|
||||
set(META_PROJECT_TYPE application)
|
||||
set(META_PROJECT_VARNAME REPO_CLEAN)
|
||||
set(META_APP_NAME "Package parser")
|
||||
set(META_APP_AUTHOR "Martchus")
|
||||
set(META_APP_DESCRIPTION "Tool to parse an Arch Linux package printing the results as JSON")
|
||||
set(META_VERSION_MAJOR 0)
|
||||
set(META_VERSION_MINOR 0)
|
||||
set(META_VERSION_PATCH 1)
|
||||
|
||||
# find c++utilities
|
||||
set(CONFIGURATION_PACKAGE_SUFFIX
|
||||
""
|
||||
CACHE STRING "sets the suffix for find_package() calls to packages configured via c++utilities")
|
||||
find_package(c++utilities${CONFIGURATION_PACKAGE_SUFFIX} 5.0.0 REQUIRED)
|
||||
use_cpp_utilities()
|
||||
|
||||
# find backend libraries
|
||||
find_package(libpkg ${META_APP_VERSION} REQUIRED)
|
||||
use_libpkg()
|
||||
|
||||
list(APPEND PRIVATE_LIBRARIES pthread)
|
||||
|
||||
# include modules to apply configuration
|
||||
include(BasicConfig)
|
||||
include(WindowsResources)
|
||||
include(AppTarget)
|
||||
include(TestTarget)
|
||||
include(ShellCompletion)
|
||||
include(ConfigHeader)
|
|
@ -0,0 +1,82 @@
|
|||
#include "../libpkg/parser/binary.h"
|
||||
#include "../libpkg/parser/package.h"
|
||||
|
||||
#include "resources/config.h"
|
||||
|
||||
#include <c++utilities/application/argumentparser.h>
|
||||
#include <c++utilities/conversion/stringbuilder.h>
|
||||
#include <c++utilities/io/path.h>
|
||||
#include <c++utilities/misc/math.h>
|
||||
#include <c++utilities/misc/parseerror.h>
|
||||
|
||||
#include <reflective_rapidjson/json/reflector.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
using namespace CppUtilities;
|
||||
|
||||
int main(int argc, const char *argv[])
|
||||
{
|
||||
SET_APPLICATION_INFO;
|
||||
|
||||
// read cli args
|
||||
auto parser = ArgumentParser();
|
||||
auto packagesArg = Argument("packages", 'p', "specifies the paths of the package files to parse");
|
||||
packagesArg.setRequiredValueCount(Argument::varValueCount);
|
||||
packagesArg.setValueNames({ "path" });
|
||||
packagesArg.setImplicit(true);
|
||||
parser.setMainArguments({ &packagesArg, &parser.helpArg() });
|
||||
parser.setDefaultArgument(&parser.helpArg());
|
||||
parser.parseArgs(argc, argv);
|
||||
|
||||
auto packages = std::vector<std::shared_ptr<LibPkg::Package>>();
|
||||
auto packageMutex = std::mutex();
|
||||
|
||||
auto pi = std::vector<const char *>::const_iterator();
|
||||
auto pend = std::vector<const char *>::const_iterator();
|
||||
auto piMutex = std::mutex();
|
||||
if (packagesArg.isPresent()) {
|
||||
const auto &packagePaths = packagesArg.values();
|
||||
pi = packagePaths.begin();
|
||||
pend = packagePaths.end();
|
||||
packages.reserve(packagePaths.size());
|
||||
}
|
||||
|
||||
const auto processPackage = [&] {
|
||||
for (;;) {
|
||||
// get next package path
|
||||
auto piLock = std::unique_lock<std::mutex>(piMutex);
|
||||
if (pi == pend) {
|
||||
return;
|
||||
}
|
||||
auto packagePath = *(pi++);
|
||||
piLock.unlock();
|
||||
|
||||
// parse package
|
||||
try {
|
||||
auto package = LibPkg::Package::fromPkgFile(packagePath);
|
||||
auto packageLock = std::unique_lock<std::mutex>(packageMutex);
|
||||
packages.emplace_back(std::move(package));
|
||||
} catch (const std::runtime_error &e) {
|
||||
std::cerr << "Unable to parse \"" << packagePath << "\": " << e.what() << '\n';
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
auto threads
|
||||
= std::vector<std::thread>(std::max<std::size_t>(std::min<std::size_t>(std::thread::hardware_concurrency(), packages.capacity()), 1u) - 1);
|
||||
for (auto &t : threads) {
|
||||
t = std::thread(processPackage);
|
||||
}
|
||||
processPackage();
|
||||
for (auto &t : threads) {
|
||||
t.join();
|
||||
}
|
||||
|
||||
const auto json = ReflectiveRapidJSON::JsonReflector::toJson(packages);
|
||||
std::cout << std::string_view(json.GetString(), json.GetSize());
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
#include <c++utilities/tests/testutils.h>
|
||||
|
||||
#include <cppunit/TestFixture.h>
|
||||
#include <cppunit/extensions/HelperMacros.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace CPPUNIT_NS;
|
||||
using namespace CppUtilities;
|
||||
|
||||
class PacParseTests : public TestFixture {
|
||||
CPPUNIT_TEST_SUITE(PacParseTests);
|
||||
CPPUNIT_TEST(test);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
|
||||
public:
|
||||
PacParseTests();
|
||||
void setUp() override;
|
||||
void tearDown() override;
|
||||
|
||||
void test();
|
||||
};
|
||||
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION(PacParseTests);
|
||||
|
||||
PacParseTests::PacParseTests()
|
||||
{
|
||||
}
|
||||
|
||||
void PacParseTests::setUp()
|
||||
{
|
||||
}
|
||||
|
||||
void PacParseTests::tearDown()
|
||||
{
|
||||
}
|
||||
|
||||
void PacParseTests::test()
|
||||
{
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
#include <c++utilities/tests/cppunit.h>
|
Loading…
Reference in New Issue