]>
Commit | Line | Data |
---|---|---|
1 | /*############################################################################# | |
2 | # # | |
3 | # Pakfire - The IPFire package management system # | |
4 | # Copyright (C) 2023 Pakfire development team # | |
5 | # # | |
6 | # This program is free software: you can redistribute it and/or modify # | |
7 | # it under the terms of the GNU General Public License as published by # | |
8 | # the Free Software Foundation, either version 3 of the License, or # | |
9 | # (at your option) any later version. # | |
10 | # # | |
11 | # This program is distributed in the hope that it will be useful, # | |
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # | |
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # | |
14 | # GNU General Public License for more details. # | |
15 | # # | |
16 | # You should have received a copy of the GNU General Public License # | |
17 | # along with this program. If not, see <http://www.gnu.org/licenses/>. # | |
18 | # # | |
19 | #############################################################################*/ | |
20 | ||
21 | #include <argp.h> | |
22 | #include <limits.h> | |
23 | #include <stdio.h> | |
24 | #include <stdlib.h> | |
25 | #include <syslog.h> | |
26 | #include <unistd.h> | |
27 | ||
28 | #include <pakfire/arch.h> | |
29 | #include <pakfire/root.h> | |
30 | #include <pakfire/string.h> | |
31 | ||
32 | #include "lib/assert.h" | |
33 | #include "lib/build.h" | |
34 | #include "lib/clean.h" | |
35 | #include "lib/command.h" | |
36 | #include "lib/config.h" | |
37 | #include "lib/dist.h" | |
38 | #include "lib/image.h" | |
39 | #include "lib/info.h" | |
40 | #include "lib/lint.h" | |
41 | #include "lib/pakfire.h" | |
42 | #include "lib/progressbar.h" | |
43 | #include "lib/provides.h" | |
44 | #include "lib/repo.h" | |
45 | #include "lib/repolist.h" | |
46 | #include "lib/requires.h" | |
47 | #include "lib/shell.h" | |
48 | #include "lib/search.h" | |
49 | #include "lib/snapshot.h" | |
50 | #include "lib/terminal.h" | |
51 | #include "lib/version.h" | |
52 | ||
53 | const char* argp_program_version = PACKAGE_FULLVERSION; | |
54 | ||
55 | enum { | |
56 | OPT_ARCH = 1, | |
57 | OPT_DEBUG = 2, | |
58 | OPT_DISTRO = 3, | |
59 | ||
60 | OPT_ENABLE_REPO = 4, | |
61 | OPT_DISABLE_REPO = 5, | |
62 | }; | |
63 | ||
64 | static struct argp_option options[] = { | |
65 | { "arch", OPT_ARCH, "ARCH", 0, "Choose an architecture", 0 }, | |
66 | { "debug", OPT_DEBUG, NULL, 0, "Run in debug mode", 0 }, | |
67 | { "distro", OPT_DISTRO, "DISTRO", 0, "Build for this distribution", 0 }, | |
68 | { "enable-repo", OPT_ENABLE_REPO, "REPO", 0, "Enable a repository", 0 }, | |
69 | { "disable-repo", OPT_DISABLE_REPO, "REPO", 0, "Disable a repository", 0 }, | |
70 | { NULL }, | |
71 | }; | |
72 | ||
73 | static const struct command commands[] = { | |
74 | { "build", cli_build, 1, -1, 0 }, | |
75 | { "clean", cli_clean, 0, 0, 0 }, | |
76 | { "dist", cli_dist, 1, -1, 0 }, | |
77 | { "image", cli_image, -1, -1, 0 }, | |
78 | { "info", cli_info, 1, -1, 0 }, | |
79 | { "lint", cli_lint, 1, -1, 0 }, | |
80 | { "provides", cli_provides, 1, -1, 0 }, | |
81 | { "repo", cli_repo, -1, -1, 0 }, | |
82 | { "repolist", cli_repolist, 0, 0, 0 }, | |
83 | { "requires", cli_requires, 1, -1, 0 }, | |
84 | { "shell", cli_shell, 0, -1, 0 }, | |
85 | { "search", cli_search, 1, -1, 0 }, | |
86 | { "snapshot", cli_snapshot, 1, -1, 0 }, | |
87 | { NULL }, | |
88 | }; | |
89 | ||
90 | const char* args_doc = | |
91 | "build [OPTIONS...] MAKEFILES...\n" | |
92 | "clean\n" | |
93 | "dist MAKEFILES...\n" | |
94 | "image ...\n" | |
95 | "lint [ARCHIVE...]\n" | |
96 | "provides PATTERN\n" | |
97 | "repo compose PATH PACKAGES...\n" | |
98 | "repolist\n" | |
99 | "requires PATTERN\n" | |
100 | "shell [OPTIONS...] [COMMAND...]\n" | |
101 | "search [OPTIONS...] PATTERN\n" | |
102 | "snapshot [COMMAND...]"; | |
103 | ||
104 | static error_t parse(int key, char* arg, struct argp_state* state, void* data) { | |
105 | struct cli_global_args* args = data; | |
106 | ||
107 | switch (key) { | |
108 | case OPT_ARCH: | |
109 | // Check if the architecture is supported | |
110 | if (!pakfire_arch_is_supported_by_host(arg)) | |
111 | argp_failure(state, EXIT_FAILURE, 0, "Unsupported architecture: %s", arg); | |
112 | ||
113 | args->arch = arg; | |
114 | break; | |
115 | ||
116 | case OPT_DEBUG: | |
117 | pakfire_ctx_set_log_level(args->ctx, LOG_DEBUG); | |
118 | break; | |
119 | ||
120 | case OPT_DISTRO: | |
121 | args->distro = arg; | |
122 | break; | |
123 | ||
124 | // Enable/Disable Repositories | |
125 | ||
126 | case OPT_ENABLE_REPO: | |
127 | if (args->num_enable_repos >= MAX_REPOS) | |
128 | return -ENOBUFS; | |
129 | ||
130 | args->enable_repos[args->num_enable_repos++] = arg; | |
131 | break; | |
132 | ||
133 | case OPT_DISABLE_REPO: | |
134 | if (args->num_disable_repos >= MAX_REPOS) | |
135 | return -ENOBUFS; | |
136 | ||
137 | args->disable_repos[args->num_disable_repos++] = arg; | |
138 | break; | |
139 | ||
140 | default: | |
141 | return ARGP_ERR_UNKNOWN; | |
142 | } | |
143 | ||
144 | return 0; | |
145 | } | |
146 | ||
147 | static int cli_confirm(pakfire_ctx* ctx, pakfire_root* root, | |
148 | void* data, const char* message, const char* question) { | |
149 | // Just print the message | |
150 | if (message) | |
151 | printf("%s\n", message); | |
152 | ||
153 | return 0; | |
154 | } | |
155 | ||
156 | int main(int argc, char* argv[]) { | |
157 | pakfire_ctx* ctx = NULL; | |
158 | int r; | |
159 | ||
160 | // Setup the context | |
161 | r = pakfire_ctx_create(&ctx, NULL); | |
162 | if (r) | |
163 | goto ERROR; | |
164 | ||
165 | // Write logs to the console | |
166 | pakfire_ctx_set_log_callback(ctx, pakfire_log_stderr, NULL); | |
167 | ||
168 | // Setup confirm callback | |
169 | pakfire_ctx_set_confirm_callback(ctx, cli_confirm, NULL); | |
170 | ||
171 | // Setup progress callback | |
172 | pakfire_ctx_set_progress_callback(ctx, cli_setup_progressbar, NULL); | |
173 | ||
174 | // Set the default cache path | |
175 | r = pakfire_ctx_set_cache_path(ctx, "~/.cache/pakfire"); | |
176 | if (r) | |
177 | goto ERROR; | |
178 | ||
179 | struct cli_global_args args = { | |
180 | .ctx = ctx, | |
181 | .distro = cli_get_default_distro(ctx), | |
182 | .arch = NULL, | |
183 | .flags = PAKFIRE_ROOT_FLAGS_BUILD, | |
184 | }; | |
185 | ||
186 | // Parse the command line and run any commands | |
187 | r = cli_parse(options, commands, args_doc, NULL, | |
188 | parse, CLI_REQUIRE_ROOT, argc, argv, &args); | |
189 | ||
190 | ERROR: | |
191 | if (ctx) { | |
192 | ctx = pakfire_ctx_unref(ctx); | |
193 | if (ctx) { | |
194 | fprintf(stderr, "Context was not freed\n"); | |
195 | return 1; | |
196 | } | |
197 | } | |
198 | ||
199 | return r; | |
200 | } |