src/libpakfire/parser/scanner.l
libpakfire_parser_la_CFLAGS = \
- $(AM_CFLAGS)
+ $(AM_CFLAGS) \
+ $(JSON_C_CFLAGS)
libpakfire_parser_la_CPPFLAGS = \
$(AM_CPPFLAGS) \
$(TESTSUITE_CPPFLAGS) \
-DTEST_ROOTFS=\"$(TEST_ROOTFS)\"
+tests_libpakfire_main_CFLAGS = \
+ $(TESTSUITE_CFLAGS)
+
tests_libpakfire_main_LDADD = \
$(TESTSUITE_LDADD)
tests_libpakfire_packager_CPPFLAGS = \
$(TESTSUITE_CPPFLAGS)
+tests_libpakfire_packager_CFLAGS = \
+ $(TESTSUITE_CFLAGS)
+
tests_libpakfire_packager_LDADD = \
$(TESTSUITE_LDADD)
tests/testsuite.c \
tests/testsuite.h
+tests_libtestsuite_la_CFLAGS = \
+ $(TESTSUITE_CFLAGS)
+
tests_libtestsuite_la_CPPFLAGS = \
$(TESTSUITE_CPPFLAGS)
-DTEST_ROOTFS=\"$(TEST_ROOTFS)\" \
-DPAKFIRE_PRIVATE
+TESTSUITE_CFLAGS = \
+ $(JSON_C_CFLAGS)
+
TESTSUITE_LDADD = \
tests/libtestsuite.la \
libpakfire.la \
#include <stdint.h>
+#include <json.h>
+
#include <solv/pooltypes.h>
#include <uuid/uuid.h>
void pakfire_package_add_enhances(struct pakfire_package* pkg, const char* dep);
int pakfire_package_has_rich_deps(struct pakfire_package* pkg);
+struct json_object* pakfire_package_to_json(struct pakfire_package* pkg);
+
#endif
#endif /* PAKFIRE_PACKAGE_H */
// JSON Stuff
struct json_object* pakfire_json_parse_from_file(struct pakfire* pakfire, const char* path);
+int pakfire_json_add_string(struct pakfire* pakfire,
+ struct json_object* json, const char* name, const char* value);
+int pakfire_json_add_integer(struct pakfire* pakfire,
+ struct json_object* json, const char* name, int value);
+int pakfire_json_add_string_array(struct pakfire* pakfire,
+ struct json_object* json, const char* name, char** array);
// Time Stuff
#include <time.h>
#include <uuid/uuid.h>
+#include <json.h>
+
#include <solv/evr.h>
#include <solv/pool.h>
#include <solv/repo.h>
return 0;
}
+
+static int _pakfire_package_add_json_dependencies(
+ struct pakfire_package* pkg,
+ struct json_object* json,
+ const char* name,
+ char** (*func)(struct pakfire_package* pkg)) {
+ // Fetch dependencies
+ char** dependencies = func(pkg);
+
+ // Nothing to do if there are no dependencies
+ if (!dependencies)
+ return 0;
+
+ // Add dependencies
+ int r = pakfire_json_add_string_array(pkg->pakfire, json, name, dependencies);
+ if (r)
+ goto ERROR;
+
+ERROR:
+ if (dependencies) {
+ for (char** dep = dependencies; *dep; dep++)
+ free(*dep);
+ free(dependencies);
+ }
+
+ return r;
+}
+
+static int pakfire_package_add_json_dependencies(
+ struct pakfire_package* pkg, struct json_object* md) {
+ int r = 0;
+
+ // Create new dependencies object
+ struct json_object* object = json_object_new_object();
+ if (!object)
+ return 1;
+
+ // Pre-requires
+ r = _pakfire_package_add_json_dependencies(pkg, object,
+ "prerequires", pakfire_package_get_prerequires);
+ if (r)
+ goto ERROR;
+
+ // Requires
+ r = _pakfire_package_add_json_dependencies(pkg, object,
+ "requires", pakfire_package_get_requires);
+ if (r)
+ goto ERROR;
+
+ // Provides
+ r = _pakfire_package_add_json_dependencies(pkg, object,
+ "provides", pakfire_package_get_provides);
+ if (r)
+ goto ERROR;
+
+ // Conflicts
+ r = _pakfire_package_add_json_dependencies(pkg, object,
+ "conflicts", pakfire_package_get_conflicts);
+ if (r)
+ goto ERROR;
+
+ // Obsoletes
+ r = _pakfire_package_add_json_dependencies(pkg, object,
+ "obsoletes", pakfire_package_get_obsoletes);
+ if (r)
+ goto ERROR;
+
+ // Recommends
+ r = _pakfire_package_add_json_dependencies(pkg, object,
+ "recommends", pakfire_package_get_recommends);
+ if (r)
+ goto ERROR;
+
+ // Suggests
+ r = _pakfire_package_add_json_dependencies(pkg, object,
+ "suggests", pakfire_package_get_suggests);
+ if (r)
+ goto ERROR;
+
+ // Supplements
+ r = _pakfire_package_add_json_dependencies(pkg, object,
+ "supplements", pakfire_package_get_supplements);
+ if (r)
+ goto ERROR;
+
+ // Enhances
+ r = _pakfire_package_add_json_dependencies(pkg, object,
+ "enhances", pakfire_package_get_enhances);
+ if (r)
+ goto ERROR;
+
+ // Add object
+ r = json_object_object_add(md, "dependencies", object);
+ if (r)
+ goto ERROR;
+
+ERROR:
+ if (r)
+ json_object_put(object);
+
+ return r;
+}
+
+static int pakfire_package_add_build_metadata(struct pakfire_package* pkg,
+ struct json_object* md) {
+ int r;
+
+ // Create a new JSON object
+ struct json_object* object = json_object_new_object();
+ if (!object)
+ return 1;
+
+ // Add pakfire version that generated this metadata
+ r = pakfire_json_add_string(pkg->pakfire, object, "pakfire", PACKAGE_VERSION);
+ if (r)
+ goto ERROR;
+
+ // Write build host
+ const char* build_host = pakfire_package_get_build_host(pkg);
+ if (build_host) {
+ r = pakfire_json_add_string(pkg->pakfire, object, "host", build_host);
+ if (r)
+ goto ERROR;
+ }
+
+ // Write build id
+ const char* build_id = pakfire_package_get_build_id(pkg);
+ if (build_id) {
+ r = pakfire_json_add_string(pkg->pakfire, object, "id", build_id);
+ if (r)
+ goto ERROR;
+ }
+
+ // Write build host
+ time_t build_time = pakfire_package_get_build_time(pkg);
+ if (build_time) {
+ r = pakfire_json_add_integer(pkg->pakfire, object, "time", build_time);
+ if (r)
+ goto ERROR;
+ }
+
+ // Add object
+ r = json_object_object_add(md, "build", object);
+ if (r)
+ goto ERROR;
+
+ERROR:
+ if (r)
+ json_object_put(object);
+
+ return r;
+}
+
+struct json_object* pakfire_package_to_json(struct pakfire_package* pkg) {
+ struct json_object* md = json_object_new_object();
+ int r = 0;
+
+ // Name
+ const char* name = pakfire_package_get_name(pkg);
+ if (name) {
+ r = pakfire_json_add_string(pkg->pakfire, md, "name", name);
+ if (r)
+ goto ERROR;
+ }
+
+ // EVR
+ const char* evr = pakfire_package_get_evr(pkg);
+ if (evr) {
+ r = pakfire_json_add_string(pkg->pakfire, md, "evr", evr);
+ if (r)
+ goto ERROR;
+ }
+
+ // Arch
+ const char* arch = pakfire_package_get_arch(pkg);
+ if (arch) {
+ r = pakfire_json_add_string(pkg->pakfire, md, "arch", arch);
+ if (r)
+ goto ERROR;
+ }
+
+ // UUID
+ const char* uuid = pakfire_package_get_uuid(pkg);
+ if (uuid) {
+ r = pakfire_json_add_string(pkg->pakfire, md, "uuid", uuid);
+ if (r)
+ goto ERROR;
+ }
+
+ // Groups
+ char* groups = pakfire_package_get_groups(pkg);
+ if (groups) {
+ r = pakfire_json_add_string(pkg->pakfire, md, "groups", groups);
+ free(groups);
+ if (r)
+ goto ERROR;
+ }
+
+ // Maintainer
+ const char* maintainer = pakfire_package_get_maintainer(pkg);
+ if (maintainer) {
+ r = pakfire_json_add_string(pkg->pakfire, md, "maintainer", maintainer);
+ if (r)
+ goto ERROR;
+ }
+
+ // URL
+ const char* url = pakfire_package_get_url(pkg);
+ if (url) {
+ r = pakfire_json_add_string(pkg->pakfire, md, "url", url);
+ if (r)
+ goto ERROR;
+ }
+
+ // License
+ const char* license = pakfire_package_get_license(pkg);
+ if (license) {
+ r = pakfire_json_add_string(pkg->pakfire, md, "license", license);
+ if (r)
+ goto ERROR;
+ }
+
+ // Summary
+ const char* summary = pakfire_package_get_summary(pkg);
+ if (summary) {
+ r = pakfire_json_add_string(pkg->pakfire, md, "summary", summary);
+ if (r)
+ goto ERROR;
+ }
+
+ // Description
+ const char* description = pakfire_package_get_description(pkg);
+ if (description) {
+ r = pakfire_json_add_string(pkg->pakfire, md, "description", description);
+ if (r)
+ goto ERROR;
+ }
+
+ // Installed package size
+ size_t installsize = pakfire_package_get_installsize(pkg);
+ r = pakfire_json_add_integer(pkg->pakfire, md, "size", installsize);
+ if (r)
+ goto ERROR;
+
+ // Generate dependency metadata
+ r = pakfire_package_add_json_dependencies(pkg, md);
+ if (r)
+ goto ERROR;
+
+ // Generate build metadata
+ r = pakfire_package_add_build_metadata(pkg, md);
+ if (r)
+ goto ERROR;
+
+ERROR:
+ if (r)
+ json_object_put(md);
+
+ return md;
+}
#include <archive.h>
#include <archive_entry.h>
+#include <json.h>
+
#include <pakfire/archive.h>
#include <pakfire/constants.h>
#include <pakfire/logging.h>
return 0;
}
-static char* pakfire_package_make_metadata(struct pakfire_packager* packager) {
- struct pakfire_package* pkg = packager->pkg;
-
- char* buffer = NULL;
- int r;
+static char* pakfire_packager_make_metadata(struct pakfire_packager* packager) {
+ char* result = NULL;
- // Print version information
- r = asprintf(&buffer, "# Pakfire %s\n\n", PACKAGE_VERSION);
- if (r < 0)
+ // Convert all package metadata to JSON
+ struct json_object* md = pakfire_package_to_json(packager->pkg);
+ if (!md)
goto ERROR;
- // Write package information
- r = asprintf(&buffer, "%s# Package information\npackage\n", buffer);
- if (r < 0)
+ // Serialize JSON to file
+ const char* s = json_object_to_json_string_ext(md,
+ JSON_C_TO_STRING_PRETTY|JSON_C_TO_STRING_PRETTY_TAB);
+ if (!s)
goto ERROR;
- // Write package name
- r = asprintf(&buffer, "%s\tname = %s\n", buffer, pakfire_package_get_name(pkg));
- if (r < 0)
+ // Copy result onto heap
+ result = strdup(s);
+ if (!result)
goto ERROR;
- // Write package EVR
- r = asprintf(&buffer, "%s\tevr = %s\n", buffer, pakfire_package_get_evr(pkg));
- if (r < 0)
- goto ERROR;
-
- // Write package arch
- r = asprintf(&buffer, "%s\tarch = %s\n", buffer, pakfire_package_get_arch(pkg));
- if (r < 0)
- goto ERROR;
-
- // Write package UUID
- r = asprintf(&buffer, "%s\tuuid = %s\n", buffer, pakfire_package_get_uuid(pkg));
- if (r < 0)
- goto ERROR;
-
- // Write package groups
- const char* groups = pakfire_package_get_groups(pkg);
- if (groups) {
- r = asprintf(&buffer, "%s\tgroups = %s\n", buffer, groups);
- if (r < 0)
- goto ERROR;
- }
-
- // Write package maintainer
- const char* maintainer = pakfire_package_get_maintainer(pkg);
- if (maintainer) {
- r = asprintf(&buffer, "%s\tmaintainer = %s\n", buffer, maintainer);
- if (r < 0)
- goto ERROR;
- }
-
- // Write package url
- const char* url = pakfire_package_get_url(pkg);
- if (url) {
- r = asprintf(&buffer, "%s\turl = %s\n", buffer, url);
- if (r < 0)
- goto ERROR;
- }
-
- // Write package license
- const char* license = pakfire_package_get_license(pkg);
- if (license) {
- r = asprintf(&buffer, "%s\tlicense = %s\n", buffer, license);
- if (r < 0)
- goto ERROR;
- }
-
- // Write package summary
- const char* summary = pakfire_package_get_summary(pkg);
- if (summary) {
- r = asprintf(&buffer, "%s\tsummary = %s\n", buffer, summary);
- if (r < 0)
- goto ERROR;
- }
-
- // XXX description
-
- size_t size = pakfire_package_get_installsize(pkg);
- r = asprintf(&buffer, "%s\tsize = %zu\n", buffer, size);
- if (r < 0)
- goto ERROR;
-
- // End package block
- r = asprintf(&buffer, "%send\n\n", buffer);
- if (r < 0)
- goto ERROR;
-
- // Write build information
- r = asprintf(&buffer, "%s# Build information\nbuild\n", buffer);
- if (r < 0)
- goto ERROR;
-
- // Write build host
- const char* build_host = pakfire_package_get_build_host(pkg);
- if (build_host) {
- r = asprintf(&buffer, "%s\thost = %s\n", buffer, build_host);
- if (r < 0)
- goto ERROR;
- }
-
- // Write build id
- const char* build_id = pakfire_package_get_build_id(pkg);
- if (build_id) {
- r = asprintf(&buffer, "%s\tid = %s\n", buffer, build_id);
- if (r < 0)
- goto ERROR;
- }
-
- // Write build host
- time_t build_time = pakfire_package_get_build_time(pkg);
- if (build_host) {
- r = asprintf(&buffer, "%s\ttime = %lu\n", buffer, build_time);
- if (r < 0)
- goto ERROR;
- }
-
- // End build block
- r = asprintf(&buffer, "%send\n\n", buffer);
- if (r < 0)
- goto ERROR;
-
-#if 0
- // Write distribution information
- r = asprintf(&buffer, "%s# Distribution information\ndistribution\n", buffer);
- if (r < 0)
- goto ERROR;
-
- // End distribution block
- r = asprintf(&buffer, "%send\n\n", buffer);
- if (r < 0)
- goto ERROR;
-#endif
-
- // Write dependency information
- r = asprintf(&buffer, "%s# Dependency information\ndependencies\n", buffer);
- if (r < 0)
- goto ERROR;
-
- const struct dependencies {
- const char* type;
- char** (*func)(struct pakfire_package* pkg);
- } dependencies[] = {
- { "prerequires", pakfire_package_get_prerequires },
- { "requires", pakfire_package_get_requires },
- { "provides", pakfire_package_get_provides },
- { "conflicts", pakfire_package_get_conflicts },
- { "obsoletes", pakfire_package_get_obsoletes },
- { "recommends", pakfire_package_get_recommends },
- { "suggests", pakfire_package_get_suggests },
- { "supplements", pakfire_package_get_supplements },
- { "enhances", pakfire_package_get_enhances },
- { NULL },
- };
-
- for (const struct dependencies* d = dependencies; d->type; d++) {
- char** list = d->func(pkg);
- if (!list)
- continue;
-
- // Write header
- r = asprintf(&buffer, "%s\t%s\n", buffer, d->type);
- if (r < 0) {
- goto ERROR;
- }
-
- for (char** dep = list; *dep; dep++) {
- asprintf(&buffer, "%s\t\t%s\n", buffer, *dep);
- free(*dep);
- }
- free(list);
-
- // End block
- r = asprintf(&buffer, "%s\tend\n", buffer);
- if (r < 0)
- goto ERROR;
- }
-
- // End dependencies block
- r = asprintf(&buffer, "%send\n\n", buffer);
- if (r < 0)
- goto ERROR;
-
- // EOF
- r = asprintf(&buffer, "%s# EOF\n", buffer);
- if (r < 0)
- goto ERROR;
-
- return buffer;
-
ERROR:
- if (buffer)
- free(buffer);
+ // Free metadata
+ if (md)
+ json_object_put(md);
- return NULL;
+ return result;
}
static int pakfire_packager_write_metadata(struct pakfire_packager* packager,
struct archive* a, struct archive* mtree) {
// Make metadata
- char* buffer = pakfire_package_make_metadata(packager);
+ char* buffer = pakfire_packager_make_metadata(packager);
if (!buffer)
return 1;
- DEBUG(packager->pakfire, "Generated package metadata:\n%s", buffer);
+ DEBUG(packager->pakfire, "Generated package metadata:\n%s\n", buffer);
// Write buffer
int r = pakfire_packager_write_file_from_buffer(packager, a, mtree,
return json;
}
+int pakfire_json_add_string(struct pakfire* pakfire, struct json_object* json,
+ const char* name, const char* value) {
+ // No string? Nothing to do
+ if (!value)
+ return 0;
+
+ // Convert string to JSON object
+ struct json_object* object = json_object_new_string(value);
+ if (!object)
+ return 1;
+
+ // Add the object
+ return json_object_object_add(json, name, object);
+}
+
+int pakfire_json_add_string_array(struct pakfire* pakfire, struct json_object* json,
+ const char* name, char** array) {
+ int r = 1;
+
+ // Allocate a new array
+ struct json_object* object = json_object_new_array();
+ if (!object)
+ goto ERROR;
+
+ // Add all items on list to the array
+ for (char** item = array; *item; item++) {
+ r = json_object_array_add(object, json_object_new_string(*item));
+ if (r)
+ goto ERROR;
+ }
+
+ // Add object
+ r = json_object_object_add(json, name, object);
+ if (r)
+ goto ERROR;
+
+ERROR:
+ // Free JSON object on error
+ if (r)
+ json_object_put(object);
+
+ return r;
+}
+
+int pakfire_json_add_integer(struct pakfire* pakfire, struct json_object* json,
+ const char* name, int value) {
+ // Convert integer to JSON object
+ struct json_object* object = json_object_new_int64(value);
+ if (!object)
+ return 1;
+
+ // Add the object
+ return json_object_object_add(json, name, object);
+}
+
// Time Stuff
static void timespec_normalize(struct timespec* t) {