diff --git a/tools/please_pex/preamble/path.c b/tools/please_pex/preamble/path.c index eaf4de4..4f5ed0a 100644 --- a/tools/please_pex/preamble/path.c +++ b/tools/please_pex/preamble/path.c @@ -79,7 +79,7 @@ err_t *get_pex_path(char **pex_path) { * directory (which is assumed to be the value of TMP_DIR in the environment, as created by Please). * Otherwise, get_plz_bin_path returns the path to the bin/ subdirectory within the plz-out/ directory * to which this .pex file belongs. If the .pex file does not exist within a plz-out/ directory - * tree, get_plz_bin_path fails. + * tree, get_plz_bin_path stores NULL in path. */ err_t *get_plz_bin_path(char **path) { char *pex_path = NULL; @@ -90,6 +90,8 @@ err_t *get_plz_bin_path(char **path) { size_t tmp_dir_len = 0; err_t *err = NULL; + (*path) = NULL; + if ((err = get_pex_path(&pex_path)) != NULL) { err = err_wrap("get_pex_path", err); goto end; @@ -141,8 +143,7 @@ err_t *get_plz_bin_path(char **path) { } if (STREQ(pex_dir, "/") || STREQ(pex_dir, ".")) { // If we reached the left-most component in the path, the .pex file doesn't exist within a - // plz-out/ directory tree. - err = err_from_str(".pex file is in neither a Please build environment nor a Please repo"); + // plz-out/ directory tree - return NULL. goto end; } MALLOC(*path, char, strlen(pex_dir) + strlen("/bin") + 1); diff --git a/tools/please_pex/preamble/preamble.c b/tools/please_pex/preamble/preamble.c index b615ca6..6e20491 100644 --- a/tools/please_pex/preamble/preamble.c +++ b/tools/please_pex/preamble/preamble.c @@ -1,4 +1,5 @@ #include +#include #include #include "cJSON.h" @@ -211,9 +212,11 @@ static err_t *get_interpreter_args(const cJSON *config, int *len, strlist_t **ar */ static err_t *get_interpreters(const cJSON *config, strlist_t **interps) { strlist_elem_t *interp = NULL; + bool tried_plz_bin_path = false; char *plz_bin_path = NULL; const cJSON *json_interps = NULL; const cJSON *json_interp = NULL; + int added = 0; err_t *err = NULL; json_interps = cJSON_GetObjectItemCaseSensitive(config, "interpreters"); @@ -235,30 +238,47 @@ static err_t *get_interpreters(const cJSON *config, strlist_t **interps) { goto end; } - STAILQ_ENTRY_NEW(interp, strlist_elem_t); - if (STRPREFIX(json_interp->valuestring, "$PLZ_BIN_PATH/")) { - if (plz_bin_path == NULL) { + if (!tried_plz_bin_path) { + tried_plz_bin_path = true; + if ((err = get_plz_bin_path(&plz_bin_path)) != NULL) { - err = err_wrap("PLZ_BIN_PATH resolution failure", err); + err = err_wrap("$PLZ_BIN_PATH resolution failure", err); goto end; } - log_debug("Resolved $PLZ_BIN_PATH to %s", plz_bin_path); + + if (plz_bin_path == NULL) { + log_warn(".pex file is not inside a Please repo; omitting interpreters prepended with '$PLZ_BIN_PATH'"); + } else { + log_debug("Resolved $PLZ_BIN_PATH to %s", plz_bin_path); + } + } + + if (plz_bin_path == NULL) { + log_info("Omitting interpreter from search path: %s", json_interp->valuestring); + continue; } // Replace "$PLZ_BIN_PATH" with the path to Please's binary outputs directory at the // start of the interpreter path. + STAILQ_ENTRY_NEW(interp, strlist_elem_t); MALLOC(interp->str, char, strlen(plz_bin_path) + JSON_STRLEN(json_interp) - strlen("$PLZ_BIN_PATH") + 1); // 1 extra byte for trailing null strncpy(interp->str, plz_bin_path, strlen(plz_bin_path)); strcpy(interp->str + strlen(plz_bin_path), json_interp->valuestring + strlen("$PLZ_BIN_PATH")); + STAILQ_INSERT_TAIL(*interps, interp, next); } else { + STAILQ_ENTRY_NEW(interp, strlist_elem_t); MALLOC(interp->str, char, JSON_STRLEN(json_interp) + 1); // 1 extra byte for trailing null strcpy(interp->str, json_interp->valuestring); + STAILQ_INSERT_TAIL(*interps, interp, next); } - STAILQ_INSERT_TAIL(*interps, interp, next); - log_debug("Added interpreter to search path: %s", interp->str); + added++; + } + + if (added == 0) { + err = err_from_str("interpreters list contains no resolvable paths"); } end: