aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJoseph Hunkeler <jhunkeler@gmail.com>2026-06-12 13:46:41 -0400
committerJoseph Hunkeler <jhunkeler@gmail.com>2026-06-12 13:46:41 -0400
commit3fdd468551b77d2c71d6fb110f16ed847abcddb8 (patch)
tree6ce4fd62a0521e96545385da820a693093ce01f0 /src
parent024a7bf4978f7aeccbbb5b31e52cb4126b70335b (diff)
downloadstasis-3fdd468551b77d2c71d6fb110f16ed847abcddb8.tar.gz
Add python_importlib_metadata_version function
* Use it for conda and libmamapy version detection
Diffstat (limited to 'src')
-rw-r--r--src/lib/core/conda.c46
-rw-r--r--src/lib/core/include/conda.h18
2 files changed, 46 insertions, 18 deletions
diff --git a/src/lib/core/conda.c b/src/lib/core/conda.c
index 6e9389f..b94824e 100644
--- a/src/lib/core/conda.c
+++ b/src/lib/core/conda.c
@@ -136,6 +136,31 @@ int pip_exec(const char *args) {
return result;
}
+char *python_importlib_metadata_version(const char *package_name) {
+ int status = 0;
+ char cmd[PATH_MAX] = {0};
+
+ if (strpbrk(package_name, "\\/*{}()|;&\"'\r\n")) {
+ SYSERROR("package name is invalid: '%s'", package_name);
+ return NULL;
+ }
+ snprintf(cmd, sizeof(cmd), "python3 -c 'from importlib.metadata import version; print(version(r\x22%s\x22))'", package_name);
+
+ char *version = shell_output(cmd, &status);
+ if (status) {
+ SYSERROR("version detection failed");
+ guard_free(version);
+ return NULL;
+ }
+ if (!version) {
+ SYSERROR("unable to allocate version");
+ return NULL;
+ }
+ strip(version);
+ return version;
+}
+
+
static const char *PKG_ERROR_STR[] = {
"success",
"[internal] unhandled package manager mode",
@@ -739,33 +764,18 @@ int conda_capable(struct CondaCapabilities *ccap) {
}
if (cc->available) {
- int status = 0;
- char *conda_version = shell_output("python3 -c 'import conda; print(conda._version.__version__)'", &status);
- if (status) {
- SYSERROR("conda version detection failed");
- guard_free(conda_version);
- return -1;
- }
+ char *conda_version = python_importlib_metadata_version("conda");
if (!conda_version) {
- SYSERROR("unable to allocate conda_version_raw");
+ SYSERROR("conda version detection failed");
return -1;
}
- strip(conda_version);
- char *mamba_version = shell_output("python3 -c 'import libmambapy; print(libmambapy.version.__version__)'", &status);
- if (status) {
- SYSERROR("mamba version detection failed");
- guard_free(conda_version);
- guard_free(mamba_version);
- return -1;
- }
+ char *mamba_version = python_importlib_metadata_version("libmambapy");
if (!mamba_version) {
SYSERROR("unable to allocate mamba_version");
guard_free(conda_version);
- guard_free(mamba_version);
return -1;
}
- strip(mamba_version);
cc->conda_version = strdup(conda_version);
cc->mamba_version = strdup(mamba_version);
diff --git a/src/lib/core/include/conda.h b/src/lib/core/include/conda.h
index 2d96f56..19f5d07 100644
--- a/src/lib/core/include/conda.h
+++ b/src/lib/core/include/conda.h
@@ -113,6 +113,24 @@ int python_exec(const char *args);
int pip_exec(const char *args);
/**
+ * Use importlib to resolve the version of an installed package
+ *
+ * ```c
+ * char *numpy_version = python_importlib_metadata_version("numpy");
+ * if (!numpy_version) {
+ * fprintf(stderr, "failed to get numpy version\n");
+ * exit(1);
+ * }
+ *
+ * printf("numpy version: %s\n", numpy_version);
+ * free(numpy_version);
+ * ```
+ * @param package_name of installed python package
+ * @return
+ */
+char *python_importlib_metadata_version(const char *package_name);
+
+/**
* Execute conda (or if possible, mamba)
* Conda/Mamba is determined by PATH
*