]> git.ipfire.org Git - people/ms/pakfire.git/commitdiff
cli: Implement scaffolding for pakfire-builder
authorMichael Tremer <michael.tremer@ipfire.org>
Thu, 28 Sep 2023 10:24:30 +0000 (10:24 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Thu, 28 Sep 2023 10:24:30 +0000 (10:24 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
.gitignore
Makefile.am
src/cli/lib/version.c [new file with mode: 0644]
src/cli/lib/version.h [new file with mode: 0644]
src/cli/pakfire-builder/main.c [new file with mode: 0644]
src/cli/pakfire/main.c

index d91d0af796f0912552a699ffd3bb23541606193e..1574e1415e36b89c61059ca6a6b4d831f7065274 100644 (file)
@@ -7,6 +7,7 @@
 /missing
 /contrib/pakfire.nm
 /pakfire
+/pakfire-builder
 /src/pakfire/__version__.py
 /src/scripts/pakfire-builder
 /src/scripts/pakfire-client
index 4234668b85d813da67652f1cef07621ea0ca7171..ea2a4badc9b7f28dddc27764d55634ec520c153b 100644 (file)
@@ -428,6 +428,29 @@ pakfire_LDADD = \
 
 # ------------------------------------------------------------------------------
 
+bin_PROGRAMS += \
+       pakfire-builder
+
+pakfire_builder_SOURCES = \
+       src/cli/pakfire-builder/main.c
+
+pakfire_builder_CPPFLAGS = \
+       $(AM_CPPFLAGS) \
+       -I$(top_srcdir)/src/libpakfire/include \
+       -I$(top_srcdir)/src/cli/lib
+
+pakfire_builder_CFLAGS = \
+       $(AM_CFLAGS)
+
+pakfire_builder_LDFLAGS = \
+       $(AM_LDFLAGS)
+
+pakfire_builder_LDADD = \
+       libpakfire.la \
+       libcli.la
+
+# ------------------------------------------------------------------------------
+
 noinst_LTLIBRARIES += \
        libcli.la
 
@@ -437,7 +460,9 @@ libcli_la_SOURCES = \
        src/cli/lib/dump.c \
        src/cli/lib/dump.h \
        src/cli/lib/terminal.c \
-       src/cli/lib/terminal.h
+       src/cli/lib/terminal.h \
+       src/cli/lib/version.c \
+       src/cli/lib/version.h
 
 libcli_la_CPPFLAGS = \
        $(AM_CPPFLAGS) \
diff --git a/src/cli/lib/version.c b/src/cli/lib/version.c
new file mode 100644 (file)
index 0000000..8b18130
--- /dev/null
@@ -0,0 +1,28 @@
+/*#############################################################################
+#                                                                             #
+# Pakfire - The IPFire package management system                              #
+# Copyright (C) 2023 Pakfire development team                                 #
+#                                                                             #
+# This program is free software: you can redistribute it and/or modify        #
+# it under the terms of the GNU General Public License as published by        #
+# the Free Software Foundation, either version 3 of the License, or           #
+# (at your option) any later version.                                         #
+#                                                                             #
+# This program is distributed in the hope that it will be useful,             #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of              #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               #
+# GNU General Public License for more details.                                #
+#                                                                             #
+# You should have received a copy of the GNU General Public License           #
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.       #
+#                                                                             #
+#############################################################################*/
+
+#include <errno.h>
+#include <stdio.h>
+
+#include "version.h"
+
+void cli_version() {
+       printf("%s %s\n", program_invocation_short_name, PACKAGE_VERSION);
+}
diff --git a/src/cli/lib/version.h b/src/cli/lib/version.h
new file mode 100644 (file)
index 0000000..dfccadf
--- /dev/null
@@ -0,0 +1,26 @@
+/*#############################################################################
+#                                                                             #
+# Pakfire - The IPFire package management system                              #
+# Copyright (C) 2023 Pakfire development team                                 #
+#                                                                             #
+# This program is free software: you can redistribute it and/or modify        #
+# it under the terms of the GNU General Public License as published by        #
+# the Free Software Foundation, either version 3 of the License, or           #
+# (at your option) any later version.                                         #
+#                                                                             #
+# This program is distributed in the hope that it will be useful,             #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of              #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               #
+# GNU General Public License for more details.                                #
+#                                                                             #
+# You should have received a copy of the GNU General Public License           #
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.       #
+#                                                                             #
+#############################################################################*/
+
+#ifndef PAKFIRE_CLI_VERSION_H
+#define PAKFIRE_CLI_VERSION_H
+
+void cli_version(void);
+
+#endif /* PAKFIRE_CLI_VERSION_H */
diff --git a/src/cli/pakfire-builder/main.c b/src/cli/pakfire-builder/main.c
new file mode 100644 (file)
index 0000000..f47f1b4
--- /dev/null
@@ -0,0 +1,269 @@
+/*#############################################################################
+#                                                                             #
+# Pakfire - The IPFire package management system                              #
+# Copyright (C) 2023 Pakfire development team                                 #
+#                                                                             #
+# This program is free software: you can redistribute it and/or modify        #
+# it under the terms of the GNU General Public License as published by        #
+# the Free Software Foundation, either version 3 of the License, or           #
+# (at your option) any later version.                                         #
+#                                                                             #
+# This program is distributed in the hope that it will be useful,             #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of              #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               #
+# GNU General Public License for more details.                                #
+#                                                                             #
+# You should have received a copy of the GNU General Public License           #
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.       #
+#                                                                             #
+#############################################################################*/
+
+#include <errno.h>
+#include <getopt.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <pakfire/pakfire.h>
+#include <pakfire/string.h>
+
+#include "command.h"
+#include "terminal.h"
+#include "version.h"
+
+#define MAX_REPOS 16
+
+struct config {
+       const char* distro;
+       char* arch;
+       int flags;
+
+       // Repos
+       const char* enable_repos[MAX_REPOS];
+       unsigned int num_enable_repos;
+       const char* disable_repos[MAX_REPOS];
+       unsigned int num_disable_repos;
+};
+
+static int cli_main(struct pakfire* pakfire, int argc, char* argv[]) {
+       static const struct command commands[] = {
+               { NULL },
+       };
+
+       return command_dispatch(pakfire, commands, argc, argv);
+}
+
+static void help(void) {
+       printf(
+               "%s [OPTIONS...] COMMAND\n\n"
+               "Options:\n"
+               "  -a --arch          Run in different architecture\n"
+               "     --config        Configuration File\n"
+               "     --debug         Run in debug mode\n"
+               "  -h --help          Show help\n"
+               "     --offline       Run in offline mode\n"
+               "     --root          The path to operate in\n"
+               "     --version       Show version\n"
+               "  -y --yes           Assume yes for all questions\n"
+               "\n"
+               "Commands:\n"
+               "  install            Install packages\n"
+               "  remove             Removes packages\n"
+               "  update             Updates all installed packages\n"
+               "  sync               Synchronises the system with upstream\n"
+               "  search             Search for packages\n"
+               "  provides           Shows which package provides a dependency\n"
+               "  requires           Shows which package requries a dependency\n"
+               "  repolist           Show all configured repositories\n"
+               "  clean              Cleans up no longer needed resources\n",
+               program_invocation_short_name
+       );
+
+       exit(0);
+}
+
+static int parse_argv(struct config* config, int argc, char* argv[]) {
+       enum {
+               ARG_DEBUG,
+               ARG_DISTRO,
+               ARG_VERSION,
+
+               // Repos
+               ARG_ENABLE_REPO,
+               ARG_DISABLE_REPO,
+       };
+
+       static const struct option options[] = {
+               { "arch",         required_argument, NULL, 'a' },
+               { "debug",        no_argument,       NULL, ARG_DEBUG },
+               { "distro",       required_argument, NULL, ARG_DISTRO },
+               { "help",         no_argument,       NULL, 'h' },
+               { "version",      no_argument,       NULL, ARG_VERSION },
+
+               // Repos
+               { "enable-repo",  required_argument, NULL, ARG_ENABLE_REPO },
+               { "disable-repo", required_argument, NULL, ARG_DISABLE_REPO },
+               { NULL },
+       };
+       int c;
+
+       for (;;) {
+               c = getopt_long(argc, argv, "ah", options, NULL);
+               if (c < 0)
+                       break;
+
+               switch (c) {
+                       case 'a':
+                               config->arch = optarg;
+                               break;
+
+                       case 'h':
+                               help();
+
+                       case ARG_DEBUG:
+                               config->flags |= PAKFIRE_FLAGS_DEBUG;
+                               break;
+
+                       case ARG_DISTRO:
+                               config->distro = optarg;
+                               break;
+
+                       case ARG_VERSION:
+                               cli_version();
+                               exit(0);
+
+                       case ARG_ENABLE_REPO:
+                               if (config->num_enable_repos >= MAX_REPOS)
+                                       return -ENOBUFS;
+
+                               config->enable_repos[config->num_enable_repos++] = optarg;
+                               break;
+
+                       case ARG_DISABLE_REPO:
+                               if (config->num_disable_repos >= MAX_REPOS)
+                                       return -ENOBUFS;
+
+                               config->disable_repos[config->num_disable_repos++] = optarg;
+                               break;
+
+                       case '?':
+                               return -EINVAL;
+
+                       default:
+                               break;
+               }
+       }
+
+       return 0;
+}
+
+static void cli_set_repo_enabled(struct pakfire* pakfire, const char* name, int enabled) {
+       struct pakfire_repo* repo = NULL;
+
+       // Find the repository
+       repo = pakfire_get_repo(pakfire, name);
+
+       // Ignore if the repository could not be found
+       if (!repo)
+               return;
+
+       // Set status
+       pakfire_repo_set_enabled(repo, enabled);
+       pakfire_repo_unref(repo);
+}
+
+static FILE* open_distro_config(const char* distro) {
+       char path[PATH_MAX];
+       FILE* f = NULL;
+       int r;
+
+       // XXX hard-coded path
+
+       // Make the path
+       r = snprintf(path, sizeof(path), "/etc/pakfire/distros/%s.conf", distro);
+       if (r < 0)
+               return NULL;
+
+       // Open the configuration file
+       f = fopen(path, "r");
+       if (!f) {
+               switch (errno) {
+                       case ENOENT:
+                               fprintf(stderr, "Could not find distro '%s': %m\n", distro);
+                               break;
+
+                       default:
+                               break;
+               }
+       }
+
+       return f;
+}
+
+static int setup_pakfire(const struct config* config, struct pakfire** pakfire) {
+       struct pakfire* p = NULL;
+       FILE* f = NULL;
+       int r;
+
+       // Open the distro configuration
+       f = open_distro_config(config->distro);
+       if (!f) {
+               fprintf(stderr, "Could not find distro '%s'\n", config->distro);
+               r = 1;
+               goto ERROR;
+       }
+
+       // Initialize Pakfire
+       r = pakfire_create(&p, NULL, config->arch, f, config->flags, NULL, NULL);
+       if (r)
+               goto ERROR;
+
+       // Enable repositories
+       for (unsigned int i = 0; i < config->num_enable_repos; i++)
+               cli_set_repo_enabled(p, config->enable_repos[i], 1);
+
+       // Disable repositories
+       for (unsigned int i = 0; i < config->num_disable_repos; i++)
+               cli_set_repo_enabled(p, config->disable_repos[i], 0);
+
+       // Return pointer
+       *pakfire = p;
+
+ERROR:
+       if (f)
+               fclose(f);
+
+       return r;
+}
+
+int main(int argc, char* argv[]) {
+       struct pakfire* pakfire = NULL;
+       int r;
+
+       struct config config = {
+               // XXX hard-coded distro
+               .distro   = "ipfire3",
+               .arch     = NULL,
+               .flags    = 0,
+       };
+
+       // Parse command line arguments
+       r = parse_argv(&config, argc, argv);
+       if (r)
+               goto ERROR;
+
+       // Setup Pakfire
+       r = setup_pakfire(&config, &pakfire);
+       if (r)
+               goto ERROR;
+
+       // Run a command
+       r = cli_main(pakfire, argc - optind, argv + optind);
+
+ERROR:
+       if (pakfire)
+               pakfire_unref(pakfire);
+
+       return r;
+}
index fe574d59f6703cd098df56760fe05fbb36b2cefe..602bb4c084ad57db8061da7292bca2db1ecd1c52 100644 (file)
@@ -28,6 +28,7 @@
 
 #include "command.h"
 #include "terminal.h"
+#include "version.h"
 
 #include "clean.h"
 #include "info.h"
@@ -74,12 +75,6 @@ static int cli_main(struct pakfire* pakfire, int argc, char* argv[]) {
        return command_dispatch(pakfire, commands, argc, argv);
 }
 
-static void version(void) {
-       printf("%s %s\n", PACKAGE_NAME, PACKAGE_VERSION);
-
-       exit(0);
-}
-
 static void help(void) {
        printf(
                "%s [OPTIONS...] COMMAND\n\n"
@@ -173,7 +168,8 @@ static int parse_argv(struct config* config, int argc, char* argv[]) {
                                break;
 
                        case ARG_VERSION:
-                               version();
+                               cli_version();
+                               exit(0);
 
                        case ARG_ENABLE_REPO:
                                if (config->num_enable_repos >= MAX_REPOS)