#include <pakfire/dist.h>
#include <pakfire/pakfire.h>
+#include <pakfire/path.h>
static const char* args_doc = "dist MAKEFILES...";
return 0;
}
+static int do_dist(struct pakfire* pakfire, const char* makefile, const char* resultdir) {
+ struct pakfire_archive* archive = NULL;
+ char* filename = NULL;
+ char path[PATH_MAX];
+ int r;
+
+ // Create the archive
+ r = pakfire_dist(pakfire, makefile, &archive, &filename);
+ if (r < 0)
+ goto ERROR;
+
+ // Make the final path
+ r = pakfire_path_append(path, resultdir, filename);
+ if (r < 0)
+ goto ERROR;
+
+ // Copy or link the archive
+ r = pakfire_archive_link_or_copy(archive, path);
+ if (r < 0)
+ goto ERROR;
+
+ // Unlink the temporary archive
+ r = pakfire_archive_unlink(archive);
+ if (r < 0)
+ goto ERROR;
+
+ERROR:
+ if (archive)
+ pakfire_archive_unref(archive);
+ if (filename)
+ free(filename);
+
+ return r;
+}
+
int cli_dist(void* data, int argc, char* argv[]) {
struct cli_global_args* global_args = data;
struct cli_local_args local_args = {};
// Process all packages
for (unsigned int i = 0; i < local_args.num_makefiles; i++) {
- r = pakfire_dist(pakfire, local_args.makefiles[i], local_args.resultdir, NULL);
- if (r) {
- fprintf(stderr, "Could not dist %s\n", local_args.makefiles[i]);
+ r = do_dist(pakfire, local_args.makefiles[i], local_args.resultdir);
+ if (r < 0) {
+ fprintf(stderr, "Could not dist %s: %s\n", local_args.makefiles[i], strerror(-r));
goto ERROR;
}
}
static int pakfire_build_package(struct pakfire_build* build, struct pakfire_parser* makefile,
const char* buildroot, const char* namespace) {
+ struct pakfire_archive* archive = NULL;
struct pakfire_package* pkg = NULL;
struct pakfire_packager* packager = NULL;
const char* path = pakfire_repo_get_path(build->repo);
- // Write the finished package
- r = pakfire_packager_finish_to_directory(packager, path, NULL);
- if (r) {
- ERROR(build->ctx, "pakfire_packager_finish() failed: %m\n");
+ // Write the archive
+ r = pakfire_packager_write_archive(packager, &archive);
+ if (r < 0) {
+ ERROR(build->ctx, "pakfire_packager_finish() failed: %s\n", strerror(-r));
goto ERROR;
}
if (r)
goto ERROR;
- // Success
- r = 0;
+ // Add the package to the repository
+ r = pakfire_repo_add_archive(build->repo, archive, &pkg);
+ if (r < 0)
+ goto ERROR;
ERROR:
+ if (archive)
+ pakfire_archive_unref(archive);
if (packager)
pakfire_packager_unref(packager);
if (pkg)
goto ERROR;
}
- // Rescan the build repository to import all packages again
- r = pakfire_repo_scan(build->repo, 0);
- if (r)
- goto ERROR;
-
// Create a new packagelist
r = pakfire_packagelist_create(&build->packages, build->ctx);
if (r)
}
int pakfire_dist(struct pakfire* pakfire, const char* path,
- const char* target, char** result) {
- struct pakfire_parser* makefile;
- struct pakfire_parser_error* error = NULL;
-
+ struct pakfire_archive** archive, char** filename) {
struct pakfire_packager* packager = NULL;
struct pakfire_package* pkg = NULL;
+ struct pakfire_parser* makefile = NULL;
+ struct pakfire_parser_error* error = NULL;
+ struct pakfire_archive* a = NULL;
+ int r;
// Fetch context
struct pakfire_ctx* ctx = pakfire_ctx(pakfire);
// Load makefile
- int r = pakfire_read_makefile(&makefile, pakfire, path, &error);
+ r = pakfire_read_makefile(&makefile, pakfire, path, &error);
if (r) {
if (error)
pakfire_parser_error_unref(error);
if (r)
goto ERROR;
- // Write the finished package
- r = pakfire_packager_finish_to_directory(packager, target, result);
- if (r)
+ // Write the archive
+ r = pakfire_packager_write_archive(packager, &a);
+ if (r < 0)
goto ERROR;
- // XXX Lint the package
+ // Link the archive
+ r = pakfire_archive_lint(a, NULL, NULL);
+ if (r < 0)
+ goto ERROR;
+
+ // Return the filename
+ if (filename)
+ *filename = pakfire_packager_filename(packager);
+
+ // Return a reference to the archive
+ *archive = pakfire_archive_ref(a);
ERROR:
if (packager)
pakfire_package_unref(pkg);
if (makefile)
pakfire_parser_unref(makefile);
+ if (a)
+ pakfire_archive_unref(a);
if (ctx)
pakfire_ctx_unref(ctx);
#ifndef PAKFIRE_DIST_H
#define PAKFIRE_DIST_H
+#include <pakfire/archive.h>
#include <pakfire/pakfire.h>
#include <pakfire/parser.h>
-int pakfire_dist(struct pakfire* pakfire, const char* path, const char* target,
- char** result);
+int pakfire_dist(struct pakfire* pakfire, const char* path,
+ struct pakfire_archive** archive, char** filename);
int pakfire_read_makefile(struct pakfire_parser** parser, struct pakfire* pakfire,
const char* path, struct pakfire_parser_error** error);
#include <pakfire/package.h>
#include <pakfire/packager.h>
#include <pakfire/pakfire.h>
+#include <pakfire/path.h>
#include <pakfire/pwd.h>
#include <pakfire/string.h>
#include <pakfire/util.h>
return NULL;
}
-const char* pakfire_packager_filename(struct pakfire_packager* packager) {
+char* pakfire_packager_filename(struct pakfire_packager* packager) {
const char* filename = NULL;
- const char* arch = NULL;
- int r;
- if (!*packager->filename) {
- filename = pakfire_package_get_string(packager->pkg, PAKFIRE_PKG_FILENAME);
- if (!filename)
- return NULL;
-
- // Store the string for source packages
- if (pakfire_package_is_source(packager->pkg)) {
- r = pakfire_string_set(packager->filename, filename);
- if (r < 0)
- return NULL;
-
- // For binary packages, we prepend the architecture
- } else {
- arch = pakfire_package_get_string(packager->pkg, PAKFIRE_PKG_ARCH);
- if (!arch)
- return NULL;
-
- r = pakfire_string_format(packager->filename, "%s/%s", arch, filename);
- if (r < 0)
- return NULL;
- }
- }
+ // Fetch the filename from the package
+ filename = pakfire_package_get_string(packager->pkg, PAKFIRE_PKG_FILENAME);
+ if (!filename)
+ return NULL;
- return packager->filename;
+ // Copy the string
+ return strdup(filename);
}
static struct archive_entry* pakfire_packager_create_file(
return r;
}
-int pakfire_packager_finish_to_directory(struct pakfire_packager* packager,
- const char* target, char** result) {
- char tmppath[PATH_MAX] = "";
- char path[PATH_MAX];
+int pakfire_packager_write_archive(struct pakfire_packager* self,
+ struct pakfire_archive** archive) {
FILE* f = NULL;
- int r = 1;
-
- // target cannot be empty
- if (!target) {
- errno = EINVAL;
- return 1;
- }
+ char path[PATH_MAX];
+ int r;
- // Get the filename of the package
- const char* filename = pakfire_packager_filename(packager);
+ // Fetch the filename of the package
+ const char* filename = pakfire_package_get_string(self->pkg, PAKFIRE_PKG_FILENAME);
if (!filename) {
- ERROR(packager->ctx, "Could not generate filename for package: %m\n");
- r = 1;
+ r = -EINVAL;
goto ERROR;
}
- // Make the package path
- r = pakfire_string_format(path, "%s/%s", target, filename);
- if (r)
- goto ERROR;
-
- // Create the parent directory
- r = pakfire_mkparentdir(path, 0755);
- if (r)
+ // Compose the path for a temporary file
+ r = pakfire_path_format(path, "%s/.%s.XXXXXX", PAKFIRE_TMP_DIR, filename);
+ if (r < 0)
goto ERROR;
- // Create a temporary file in the target directory
- r = pakfire_string_format(tmppath, "%s.XXXXXX", path);
- if (r)
- goto ERROR;
-
- // Create a temporary result file
- f = pakfire_mktemp(tmppath, 0);
- if (!f)
- goto ERROR;
-
- // Write the finished package
- r = pakfire_packager_finish(packager, f);
- if (r) {
- ERROR(packager->ctx, "pakfire_packager_finish() failed: %m\n");
+ // Create the temporary file
+ f = pakfire_mktemp(path, 0644);
+ if (!f) {
+ ERROR(self->ctx, "Could not create temporary file: %m\n");
+ r = -errno;
goto ERROR;
}
- // Move the temporary file to destination
- r = rename(tmppath, path);
- if (r) {
- ERROR(packager->ctx, "Could not move %s to %s: %m\n", tmppath, path);
+ // Write everything to the temporary file
+ r = pakfire_packager_finish(self, f);
+ if (r < 0)
goto ERROR;
- }
- DEBUG(packager->ctx, "Package written to %s\n", path);
+ // Close the file
+ fclose(f);
+ f = NULL;
- // Store result path if requested
- if (result) {
- *result = strdup(path);
- if (!*result) {
- r = 1;
- goto ERROR;
- }
+ // Open the archive
+ r = pakfire_archive_open(archive, self->pakfire, path);
+ if (r < 0) {
+ ERROR(self->ctx, "Could not open the generated archive at %s: %s\n",
+ path, strerror(-r));
+ goto ERROR;
}
- // Success
- r = 0;
-
ERROR:
if (f)
fclose(f);
- // Remove temporary file
- if (r && *tmppath)
- unlink(tmppath);
-
return r;
}
struct pakfire_packager* pakfire_packager_ref(struct pakfire_packager* packager);
struct pakfire_packager* pakfire_packager_unref(struct pakfire_packager* packager);
-const char* pakfire_packager_filename(struct pakfire_packager* packager);
+char* pakfire_packager_filename(struct pakfire_packager* packager);
+
+int pakfire_packager_write_archive(struct pakfire_packager* self,
+ struct pakfire_archive** archive);
int pakfire_packager_finish(struct pakfire_packager* packager, FILE* f);
-int pakfire_packager_finish_to_directory(struct pakfire_packager* packager,
- const char* target, char** result);
int pakfire_packager_add_file(
struct pakfire_packager* packager, struct pakfire_file* file);
Convenience function to dist() a package on the fly
*/
static int pakfire_commandline_dist(struct pakfire* pakfire, struct pakfire_repo* repo,
- const char* path, struct pakfire_package** package) {
- char* result = NULL;
+ const char* path, struct pakfire_package** pkg) {
+ struct pakfire_archive* archive = NULL;
int r;
- // XXX result is not unique!
-
// Run dist()
- r = pakfire_dist(pakfire, path, PAKFIRE_TMP_DIR, &result);
- if (r)
+ r = pakfire_dist(pakfire, path, &archive, NULL);
+ if (r < 0)
goto ERROR;
- // Try to add the package to the repository
- r = pakfire_repo_add(repo, result, package);
+ // Add the archive to the repository
+ r = pakfire_repo_add_archive(repo, archive, pkg);
+ if (r < 0)
+ goto ERROR;
ERROR:
- if (result)
- free(result);
+ if (archive)
+ pakfire_archive_unref(archive);
return r;
}
}
static PyObject* Pakfire_dist(PakfireObject* self, PyObject* args) {
+ struct pakfire_archive* archive = NULL;
const char* path = NULL;
const char* target = NULL;
char* result = NULL;
Py_BEGIN_ALLOW_THREADS
- r = pakfire_dist(self->pakfire, path, target, &result);
+ r = pakfire_dist(self->pakfire, path, &archive, &result);
if (r) {
Py_BLOCK_THREADS
PyErr_SetFromErrno(PyExc_OSError);
PyObject* ret = PyUnicode_FromString(result);
free(result);
+ // XXX This is now very broken
+
return ret;
}
// Attempt to dist the dummy package
ASSERT_SUCCESS(pakfire_dist(t->pakfire,
- TEST_SRC_PATH "data/packages/dummy/dummy.nm", tmp, &filename));
+ TEST_SRC_PATH "data/packages/dummy/dummy.nm", &archive, &filename));
// Check if filename is set
ASSERT(filename);
- // Check if we can read the archive
- ASSERT_SUCCESS(pakfire_archive_open(&archive, t->pakfire, filename));
-
// Extract all package metadata
ASSERT_SUCCESS(pakfire_archive_make_package(archive, NULL, &package));