diff options
| -rw-r--r-- | src/lib/core/include/utils.h | 3 | ||||
| -rw-r--r-- | src/lib/core/utils.c | 84 | ||||
| -rw-r--r-- | src/lib/delivery/delivery_build.c | 12 | ||||
| -rw-r--r-- | src/lib/delivery/delivery_test.c | 12 | 
4 files changed, 111 insertions, 0 deletions
| diff --git a/src/lib/core/include/utils.h b/src/lib/core/include/utils.h index 1512285..a9bcd2f 100644 --- a/src/lib/core/include/utils.h +++ b/src/lib/core/include/utils.h @@ -461,4 +461,7 @@ int in_ascii_range(char c, char lower, char upper);  #define GIT_HASH_LEN 40  int is_git_sha(char const *hash); + +int check_python_package_dependencies(const char *srcdir); +  #endif //STASIS_UTILS_H diff --git a/src/lib/core/utils.c b/src/lib/core/utils.c index 3d9659d..62f3bec 100644 --- a/src/lib/core/utils.c +++ b/src/lib/core/utils.c @@ -994,3 +994,87 @@ int is_git_sha(char const *hash) {      return 1;  } +static int read_vcs_records(const size_t line, char **data) { +    (void) line;  // unused +    const char *vcs_name[] = { +        "git", +        "svn", +        "hg", +        "bzr", +    }; +    for (size_t i = 0; i < sizeof(vcs_name) / sizeof(vcs_name[0]); i++) { +        const char *vcs = vcs_name[i]; +        char *data_local = strdup(*data); +        if (!data_local) { +            fprintf(stderr, "Out of memory\n"); +            return -1; +        } + +        // Remove leading/trailing blanks +        lstrip(data_local); +        strip(data_local); + +        // Ignore file comment(s) +        if (startswith(data_local, "#") || startswith(data_local, ";")) { +            // continue +            return 1; +        } + +        // Begin matching VCS package syntax +        const char *match_vcs = strstr(data_local,vcs); +        if (match_vcs) { +            const char *match_protocol_sep = strstr(match_vcs, "+"); +            if (match_protocol_sep) { +                const char *match_protocol = strstr(match_protocol_sep, "://"); +                if (match_protocol) { +                    guard_free(data_local); +                    // match found +                    return 0; +                } +            } +        } +        guard_free(data_local); +    } + +    // no match, continue +    return 1; +} +int check_python_package_dependencies(const char *srcdir) { +    const char *configs[] = { +        "pyproject.toml", +        "setup.cfg", +        "setup.py" +    }; + +    for (size_t i = 0; i < sizeof(configs) / sizeof(configs[0]); i++) { +        char path[PATH_MAX] = {0}; +        const char *configfile = configs[i]; + +        snprintf(path, sizeof(path), "%s/%s", srcdir, configfile); +        if (access(path, F_OK) < 0) { +            continue; +        } + +        //char **data = file_readlines(path, 0, 0, NULL); +        struct StrList *data = strlist_init(); +        int err = 0; +        if ((err = strlist_append_file(data, path, read_vcs_records))) { +            guard_strlist_free(&data); +            return -1; +        } +        const size_t count = strlist_count(data); +        if (count) { +            printf("\nERROR: VCS requirement(s) detected in %s:\n", configfile); +            for (size_t j = 0; j < count; j++) { +                char *record = strlist_item(data, j); +                lstrip(record); +                strip(record); +                printf("[%zu] %s\n", j, record); +            } +            guard_strlist_free(&data); +            return 1; +        } +        guard_strlist_free(&data); +    } +    return 0; +} diff --git a/src/lib/delivery/delivery_build.c b/src/lib/delivery/delivery_build.c index 2d891d2..c5093d4 100644 --- a/src/lib/delivery/delivery_build.c +++ b/src/lib/delivery/delivery_build.c @@ -173,6 +173,18 @@ struct StrList *delivery_build_wheels(struct Delivery *ctx) {                      memset(outdir, 0, sizeof(outdir));                      memset(cmd, 0, sizeof(outdir)); +                    const int dep_status = check_python_package_dependencies("."); +                    if (dep_status) { +                        fprintf(stderr, "\nPlease replace all occurrences above with standard package specs:\n" +                                        "\n" +                                        "    package==x.y.z\n" +                                        "    package>=x.y.z\n" +                                        "    package<=x.y.z\n" +                                        "    ...\n" +                                        "\n"); +                        COE_CHECK_ABORT(dep_status, "Unreproducible delivery"); +                    } +                      strcpy(dname, ctx->tests[i].name);                      tolower_s(dname);                      sprintf(outdir, "%s/%s", ctx->storage.wheel_artifact_dir, dname); diff --git a/src/lib/delivery/delivery_test.c b/src/lib/delivery/delivery_test.c index e80e0ec..6e0a226 100644 --- a/src/lib/delivery/delivery_test.c +++ b/src/lib/delivery/delivery_test.c @@ -97,6 +97,18 @@ void delivery_tests_run(struct Delivery *ctx) {              if (pushd(destdir)) {                  COE_CHECK_ABORT(1, "Unable to enter repository directory\n");              } else { +                int dep_status = check_python_package_dependencies("."); +                if (dep_status) { +                    fprintf(stderr, "\nPlease replace all occurrences above with standard package specs:\n" +                                    "\n" +                                    "    package==x.y.z\n" +                                    "    package>=x.y.z\n" +                                    "    package<=x.y.z\n" +                                    "    ...\n" +                                    "\n"); +                    COE_CHECK_ABORT(dep_status, "Unreproducible delivery"); +                } +                  char *cmd = calloc(strlen(test->script) + STASIS_BUFSIZ, sizeof(*cmd));                  if (!cmd) {                      SYSERROR("Unable to allocate test script buffer: %s", strerror(errno)); | 
