]>
Commit | Line | Data |
---|---|---|
060a1182 MT |
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 <errno.h> | |
22 | #include <getopt.h> | |
23 | #include <stdlib.h> | |
6bda496c | 24 | #include <sys/syslog.h> |
060a1182 MT |
25 | |
26 | #include "build.h" | |
6bda496c | 27 | #include "color.h" |
060a1182 MT |
28 | #include "command.h" |
29 | ||
30 | #include <pakfire/build.h> | |
31 | #include <pakfire/pakfire.h> | |
32 | ||
33 | struct config { | |
34 | const char* id; | |
35 | const char* target; | |
36 | int flags; | |
37 | }; | |
38 | ||
39 | static void help(void) { | |
40 | printf( | |
41 | "%s [OPTIONS...] build [OPTIONS...] MAKEFILE\n\n" | |
42 | "Options:\n" | |
43 | " --disable-ccache Disables using ccache\n" | |
44 | " --disable-snapshot Do not use the snapshot\n" | |
45 | " --disable-tests Do not run tests\n" | |
46 | " --non-interactive Run the build non-interactively\n" | |
47 | " --target Output all packages to this directory\n" | |
48 | " -h --help Show help\n", | |
49 | program_invocation_short_name | |
50 | ); | |
51 | ||
52 | exit(0); | |
53 | } | |
54 | ||
55 | static int parse_argv(struct config* config, int argc, char* argv[]) { | |
56 | enum { | |
57 | ARG_DISABLE_CCACHE, | |
58 | ARG_DISABLE_SNAPSHOT, | |
59 | ARG_DISABLE_TESTS, | |
60 | ARG_ID, | |
61 | ARG_NON_INTERACTIVE, | |
62 | ARG_TARGET, | |
63 | }; | |
64 | ||
65 | static const struct option options[] = { | |
66 | { "disable-ccache", no_argument, NULL, ARG_DISABLE_CCACHE }, | |
67 | { "disable-snapshot", no_argument, NULL, ARG_DISABLE_SNAPSHOT }, | |
68 | { "disable-tests", no_argument, NULL, ARG_DISABLE_TESTS }, | |
69 | { "id", required_argument, NULL, ARG_ID }, | |
70 | { "non-interactive", no_argument, NULL, ARG_NON_INTERACTIVE }, | |
71 | { "target", required_argument, NULL, ARG_TARGET }, | |
72 | { "help", no_argument, NULL, 'h' }, | |
73 | { NULL }, | |
74 | }; | |
75 | int c; | |
76 | ||
77 | for (;;) { | |
78 | c = getopt_long(argc, argv, "h", options, NULL); | |
79 | if (c < 0) | |
80 | break; | |
81 | ||
82 | switch (c) { | |
83 | case 'h': | |
84 | help(); | |
85 | ||
86 | case ARG_DISABLE_CCACHE: | |
87 | config->flags |= PAKFIRE_BUILD_DISABLE_CCACHE; | |
88 | break; | |
89 | ||
90 | case ARG_DISABLE_SNAPSHOT: | |
91 | config->flags |= PAKFIRE_BUILD_DISABLE_SNAPSHOT; | |
92 | break; | |
93 | ||
94 | case ARG_DISABLE_TESTS: | |
95 | config->flags |= PAKFIRE_BUILD_DISABLE_TESTS; | |
96 | break; | |
97 | ||
98 | case ARG_ID: | |
99 | config->id = optarg; | |
100 | break; | |
101 | ||
102 | case ARG_NON_INTERACTIVE: | |
103 | config->flags &= ~PAKFIRE_BUILD_INTERACTIVE; | |
104 | break; | |
105 | ||
106 | case ARG_TARGET: | |
107 | config->target = optarg; | |
108 | break; | |
109 | ||
110 | case '?': | |
101b03bb | 111 | break; |
060a1182 MT |
112 | |
113 | default: | |
114 | break; | |
115 | } | |
116 | } | |
117 | ||
118 | return 0; | |
119 | } | |
120 | ||
dc173159 MT |
121 | static int log_callback(struct pakfire_build* build, void* data, |
122 | int priority, int error, const char* file, int line, const char* function, const char* format, ...) { | |
123 | char* buffer = NULL; | |
124 | va_list args; | |
125 | int r; | |
126 | ||
127 | // Format the message | |
128 | va_start(args, format); | |
129 | r = vasprintf(&buffer, format, args); | |
130 | va_end(args); | |
131 | ||
132 | // Fail if we could not format the message | |
133 | if (r < 0) | |
134 | return r; | |
135 | ||
6bda496c | 136 | switch (priority) { |
dc173159 | 137 | // Highlight any error messages |
6bda496c | 138 | case LOG_ERR: |
dc173159 | 139 | fprintf(stderr, "%s%s%s", color_highlight(), buffer, color_reset()); |
6bda496c MT |
140 | break; |
141 | ||
dc173159 | 142 | // Print the rest to stdout |
6bda496c | 143 | default: |
dc173159 | 144 | fprintf(stdout, "%s", buffer); |
6bda496c MT |
145 | break; |
146 | } | |
147 | ||
dc173159 MT |
148 | // Cleanup |
149 | if (buffer) | |
150 | free(buffer); | |
151 | ||
6bda496c MT |
152 | return 0; |
153 | } | |
154 | ||
060a1182 MT |
155 | int cli_build(struct pakfire* pakfire, int argc, char* argv[]) { |
156 | struct pakfire_build* build = NULL; | |
157 | struct config config = { | |
158 | .id = NULL, | |
159 | .target = NULL, | |
160 | .flags = PAKFIRE_BUILD_INTERACTIVE, | |
161 | }; | |
162 | int r; | |
163 | ||
164 | // Parse commandline | |
165 | r = parse_argv(&config, argc, argv); | |
166 | if (r) | |
167 | return r; | |
168 | ||
169 | // Setup the build environment | |
170 | r = pakfire_build_create(&build, pakfire, config.id, config.flags); | |
171 | if (r) { | |
172 | fprintf(stderr, "Could not setup the build environment: %m\n"); | |
173 | goto ERROR; | |
174 | } | |
175 | ||
6bda496c MT |
176 | // Set log callback |
177 | pakfire_build_set_log_callback(build, log_callback, NULL); | |
178 | ||
060a1182 MT |
179 | // Set target |
180 | if (config.target) { | |
181 | r = pakfire_build_set_target(build, config.target); | |
182 | if (r) { | |
183 | fprintf(stderr, "Could not set target directory %s: %m\n", config.target); | |
184 | goto ERROR; | |
185 | } | |
186 | } | |
187 | ||
188 | // Process all packages | |
732e2f37 | 189 | for (int i = 0; i < argc; i++) { |
060a1182 MT |
190 | // Run the build |
191 | r = pakfire_build_exec(build, argv[i]); | |
192 | if (r) { | |
193 | fprintf(stderr, "Could not build %s\n", argv[i]); | |
194 | goto ERROR; | |
195 | } | |
196 | } | |
197 | ||
198 | ERROR: | |
199 | if (build) | |
200 | pakfire_build_unref(build); | |
201 | ||
202 | return r; | |
203 | } |