aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoseph Hunkeler <jhunkeler@gmail.com>2019-12-19 00:41:43 -0500
committerJoseph Hunkeler <jhunkeler@gmail.com>2019-12-19 00:41:43 -0500
commitb3fcaefd320b0b4999d2d380139ab8610c6a0233 (patch)
tree1cc11b783eb9e8dc1e4b63c3ea27b91798d47b3c
parent534657dd6fc2ee98159e41d2700554fed0da2c4e (diff)
downloadspmc-b3fcaefd320b0b4999d2d380139ab8610c6a0233.tar.gz
Make command line argument a thing
-rw-r--r--src/deps.c2
-rw-r--r--src/spm.c185
-rw-r--r--src/strings.c14
3 files changed, 167 insertions, 34 deletions
diff --git a/src/deps.c b/src/deps.c
index 99f6148..ded7fab 100644
--- a/src/deps.c
+++ b/src/deps.c
@@ -183,6 +183,6 @@ void dep_show(Dependencies **deps) {
return;
}
for (int i = 0; i < (*deps)->records; i++) {
- printf("%d: %s\n", i, (*deps)->list[i]);
+ printf(" -> %s\n", (*deps)->list[i]);
}
}
diff --git a/src/spm.c b/src/spm.c
index 3607117..14ebd2d 100644
--- a/src/spm.c
+++ b/src/spm.c
@@ -2,9 +2,31 @@
* SPM - Simple Package Manager
* @file spm.c
*/
+#include <errno.h>
#include "spm.h"
+int RUNTIME_VERBOSE = 0;
+int RUNTIME_INSTALL = 0;
+int RUNTIME_ROOTDIR = 0;
+const int PACKAGE_MAX = 0xff;
+
+void usage(const char *program_name) {
+ printf(
+ "usage: %s [-hVv] [-I|--install {package ...}]\n"
+ " -h, --help show this help message\n"
+ " -V, --version show version\n"
+ " -v, --verbose show more information\n"
+ " -I, --install install package(s)\n"
+ , program_name
+ );
+}
+
int main(int argc, char *argv[]) {
+ char program_name[strlen(argv[0]) + 1];
+ memset(program_name, '\0', sizeof(program_name) + 1);
+ strcpy(program_name, basename(argv[0]));
+
+
// not much to see here yet
// at the moment this will all be random tests, for better or worse
// everything here is subject to change without notice
@@ -16,45 +38,150 @@ int main(int argc, char *argv[]) {
// Ensure external programs are available for use.
check_runtime_environment();
- // Install a package to test things out
- char *match;
- char *package;
- const char *root = "/tmp/root";
- if ((match = find_package("python")) == NULL) {
- fprintf(SYSERROR);
- exit(1);
- }
- if ((package = basename(match)) == NULL) {
- fprintf(stderr, "Unable to derive package name from package path:\n\t-> %s\n", match);
- exit(1);
- }
+ char root[PATH_MAX];
+ memset(root, '\0', PATH_MAX);
- Dependencies *deps = NULL;
- dep_init(&deps);
+ char *packages[PACKAGE_MAX];
+ memset(packages, '\0', sizeof(char *));
- if (dep_all(&deps, package) < 0) {
- dep_free(&deps);
- free_global_config();
+ if (argc < 2) {
+ usage(program_name);
exit(1);
}
- printf("%s requires:\n", package);
- dep_show(&deps);
+ for (int i = 1; i < argc; i++) {
+ char *arg = argv[i];
+ char *arg_next = argv[i + 1] ? argv[i + 1] : NULL;
- // Install dependencies first
- for (int i = 0; i < deps->records; i++) {
- if (install(root, deps->list[i]) < 0) {
- fprintf(SYSERROR);
- exit(errno);
+ // options
+ if (*arg == '-' || strncmp(arg, "--", 2) == 0) {
+ if (strcmp(arg, "-h") == 0 || strcmp(arg, "--help") == 0) {
+ usage(program_name);
+ exit(0);
+ }
+ else if (strcmp(arg, "-V") == 0 || strcmp(arg, "--version") == 0) {
+ printf("want version\n");
+ }
+ else if (strcmp(arg, "-v") == 0 || strcmp(arg, "--verbose") == 0) {
+ printf("verbose mode\n");
+ RUNTIME_VERBOSE = 1;
+ }
+ else if (strcmp(arg, "-r") == 0 || strcmp(arg, "--root") == 0) {
+ RUNTIME_ROOTDIR = 1;
+ if (!arg_next) {
+ fprintf(stderr, "-r|--root requires a path\n");
+ usage(program_name);
+ exit(1);
+ }
+ strcpy(root, arg_next);
+ i++;
+ }
+ else if (strcmp(arg, "-I") == 0 || strcmp(arg, "--install") == 0) {
+ RUNTIME_INSTALL = 1;
+ for (int p = 0; i < argc; p++) {
+ i++;
+ if (startswith(argv[i], "-") == 0 || startswith(argv[i], "--") == 0) {
+ if (!p) {
+ fprintf(stderr, "-I|--install requires at least one package (got: '%s')\n", argv[i]);
+ exit(1);
+ }
+ i--;
+ break;
+ }
+ packages[p] = argv[i];
+ }
+ }
}
+ else {
+ printf("Unknown option: %s\n", arg);
+ usage(program_name);
+ exit(1);
+ }
+ }
+
+ if (RUNTIME_ROOTDIR && !RUNTIME_INSTALL) {
+ fprintf(stderr, "-r|--root requires -I|--install\n");
+ usage(program_name);
+ exit(1);
}
- // Install package
- if (install(root, package) < 0) {
- fprintf(SYSERROR);
- exit(errno);
+
+ if (isempty(root)) {
+ printf("Using default installation root\n");
+ sprintf(root, "%s%c%s", getenv("HOME"), DIRSEP, "spm_root");
}
- dep_free(&deps);
+ if (RUNTIME_INSTALL) {
+ Dependencies *deps = NULL;
+ dep_init(&deps);
+
+ printf("Installation root: %s\n", root);
+ printf("Requested packages:\n");
+ for (int i = 0; i < PACKAGE_MAX; i++) {
+ if (packages[i] == NULL) {
+ break;
+ }
+ printf(" -> %s\n", packages[i]);
+ }
+
+ printf("Resolving package requirements...\n");
+ for (int i = 0; i < PACKAGE_MAX; i++) {
+ if (packages[i] == NULL) {
+ break;
+ }
+
+ // Install a package to test things out
+ char *match = NULL;
+ char *package = NULL;
+ if ((match = find_package(packages[i])) == NULL) {
+ fprintf(SYSERROR);
+ exit(1);
+ }
+ if ((package = basename(match)) == NULL) {
+ fprintf(stderr, "Unable to derive package name from package path:\n\t-> %s\n", match);
+ exit(1);
+ }
+
+ if (dep_all(&deps, package) < 0) {
+ dep_free(&deps);
+ free_global_config();
+ exit(1);
+ }
+ }
+ dep_show(&deps);
+
+ printf("Installing package requirements:\n");
+ for (int i = 0; i < deps->records; i++) {
+ printf(" -> %s\n", deps->list[i]);
+ if (install(root, deps->list[i]) < 0) {
+ fprintf(SYSERROR);
+ exit(errno);
+ }
+ }
+
+
+ printf("Installing package:\n");
+ for (int i = 0; i < PACKAGE_MAX; i++) {
+ if (!packages[i]) {
+ break;
+ }
+
+ char *match = find_package(packages[i]);
+ char *package = basename(match);
+
+ // If the package was already installed as a requirement of another dependency, skip it
+ if (dep_seen(&deps, package)) {
+ continue;
+ }
+
+ printf(" -> %s\n", package);
+ if (install(root, packages[i]) < 0) {
+ fprintf(SYSERROR);
+ exit(errno);
+ }
+ free(match);
+ }
+ dep_free(&deps);
+ }
free_global_config();
return 0;
}
diff --git a/src/strings.c b/src/strings.c
index ad784d1..87d2eca 100644
--- a/src/strings.c
+++ b/src/strings.c
@@ -21,12 +21,15 @@ int num_chars(const char *sptr, int ch) {
*
* @param sptr string to scan
* @param pattern string to search for
- * @return 0 = success, -1 = failure
+ * @return 0 = found, 1 = not found, -1 = error
*/
int startswith(const char *sptr, const char *pattern) {
+ if (!sptr) {
+ return -1;
+ }
for (size_t i = 0; i < strlen(pattern); i++) {
if (sptr[i] != pattern[i]) {
- return -1;
+ return 1;
}
}
return 0;
@@ -37,14 +40,17 @@ int startswith(const char *sptr, const char *pattern) {
*
* @param sptr string to scan
* @param pattern string to search for
- * @return 0 = success, -1 = failure
+ * @return 0 = found, 1 = not found, -1 = error
*/
int endswith(const char *sptr, const char *pattern) {
+ if (!sptr) {
+ return -1;
+ }
size_t sptr_size = strlen(sptr);
size_t pattern_size = strlen(pattern);
for (size_t s = sptr_size - pattern_size, p = 0 ; s < sptr_size; s++, p++) {
if (sptr[s] != pattern[p]) {
- return -1;
+ return 1;
}
}
return 0;