]> git.ipfire.org Git - pakfire.git/commitdiff
packager: Write package metadata
authorMichael Tremer <michael.tremer@ipfire.org>
Tue, 9 Mar 2021 18:01:09 +0000 (18:01 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Tue, 9 Mar 2021 18:01:09 +0000 (18:01 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libpakfire/packager.c

index f17a07e6eeaf591b05d06360a125a45386096a20..da1fc55740f85a1522932dab897bde7a8650413d 100644 (file)
@@ -281,6 +281,44 @@ static int pakfire_packager_copy_data(struct pakfire_packager* packager,
        return 0;
 }
 
+static int pakfire_packager_write_file_from_buffer(struct pakfire_packager* packager,
+               struct archive* a, const char* filename, const char* buffer) {
+       // Create a new file entry
+       struct archive_entry* entry = archive_entry_new();
+       if (!entry)
+               return 1;
+
+       // Set filename
+       archive_entry_set_pathname(entry, filename);
+
+       // This is a regular file
+    archive_entry_set_filetype(entry, AE_IFREG);
+    archive_entry_set_perm(entry, 0644);
+
+       // Set length
+       archive_entry_set_size(entry, strlen(buffer));
+
+       // This is the end of the header
+       int r = archive_write_header(a, entry);
+       if (r) {
+               ERROR(packager->pakfire, "Error writing header: %s\n", archive_error_string(a));
+               archive_entry_free(entry);
+               return r;
+       }
+
+       // Write content
+       r = archive_write_data(a, buffer, strlen(buffer));
+       if (r < 0) {
+               ERROR(packager->pakfire, "Error writing data: %s\n", archive_error_string(a));
+               archive_entry_free(entry);
+               return r;
+       }
+
+       archive_entry_free(entry);
+
+       return 0;
+}
+
 static int pakfire_packager_write_format(struct pakfire_packager* packager,
                struct archive* a) {
        const char buffer[] = TO_STRING(PACKAGE_FORMAT) "\n";
@@ -321,6 +359,255 @@ static int pakfire_packager_write_format(struct pakfire_packager* packager,
        return 0;
 }
 
+static char* pakfire_package_make_metadata(struct pakfire_packager* packager) {
+       PakfirePackage pkg = packager->pkg;
+
+       char* buffer = NULL;
+       int r;
+
+       // Print version information
+       r = asprintf(&buffer, "# Pakfire %s\n\n", PACKAGE_VERSION);
+       if (r < 0)
+               goto ERROR;
+
+       // Write package information
+       r = asprintf(&buffer, "%s# Package information\npackage\n", buffer);
+       if (r < 0)
+               goto ERROR;
+
+       // Write package name
+       r = asprintf(&buffer, "%s\tname        = %s\n", buffer, pakfire_package_get_name(pkg));
+       if (r < 0)
+               goto ERROR;
+
+       // Write package version
+       r = asprintf(&buffer, "%s\tversion     = %s\n", buffer, pakfire_package_get_version(pkg));
+       if (r < 0)
+               goto ERROR;
+
+       // Write package release
+       r = asprintf(&buffer, "%s\trelease     = %s\n", buffer, pakfire_package_get_release(pkg));
+       if (r < 0)
+               goto ERROR;
+
+       // Write package epoch
+       r = asprintf(&buffer, "%s\tepoch       = %lu\n", buffer, pakfire_package_get_epoch(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_maintainer(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;
+       }
+
+#if 0
+       // 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;
+       }
+#endif
+
+       // 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;
+               PakfireRelationList (*func)(PakfirePackage 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++) {
+               PakfireRelationList list = d->func(pkg);
+               if (!list)
+                       continue;
+
+               size_t l = pakfire_relationlist_size(list);
+
+               // Skip for empty lists
+               if (l == 0) {
+                       pakfire_relationlist_unref(list);
+                       continue;
+               }
+
+               // Write header
+               r = asprintf(&buffer, "%s\t%s\n", buffer, d->type);
+               if (r < 0) {
+                       pakfire_relationlist_unref(list);
+                       goto ERROR;
+               }
+
+               for (unsigned int i = 0; i < l; i++) {
+                       PakfireRelation rel = pakfire_relationlist_get(list, i);
+
+                       char* s = pakfire_relation_str(rel);
+                       if (s) {
+                               r = asprintf(&buffer, "%s\t\t%s\n", buffer, s);
+                               free(s);
+                               if (r < 0) {
+                                       pakfire_relationlist_unref(list);
+                                       pakfire_relation_unref(rel);
+                                       goto ERROR;
+                               }
+                       }
+
+                       pakfire_relation_unref(rel);
+               }
+
+               // End block
+               r = asprintf(&buffer, "%s\tend\n", buffer);
+               if (r < 0)
+                       goto ERROR;
+
+               pakfire_relationlist_unref(list);
+       }
+
+       // 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);
+
+       return NULL;
+}
+
+static int pakfire_packager_write_metadata(struct pakfire_packager* packager,
+               struct archive* a) {
+       // Make metadata
+       char* buffer = pakfire_package_make_metadata(packager);
+       if (!buffer)
+               return 1;
+
+       DEBUG(packager->pakfire, "Generated package metadata:\n%s", buffer);
+
+       // Write buffer
+       int r = pakfire_packager_write_file_from_buffer(packager, a,
+               PAKFIRE_ARCHIVE_FN_METADATA, buffer);
+
+       free(buffer);
+
+       return r;
+}
+
 static int pakfire_packager_write_payload(struct pakfire_packager* packager,
                struct archive* a) {
        struct stat st;
@@ -419,6 +706,11 @@ PAKFIRE_EXPORT char* pakfire_packager_finish(struct pakfire_packager* packager,
        if (r)
                goto ERROR;
 
+       // Write the metadata
+       r = pakfire_packager_write_metadata(packager, a);
+       if (r)
+               goto ERROR;
+
        // Write the payload
        r = pakfire_packager_write_payload(packager, a);
        if (r)