aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJoseph Hunkeler <jhunkeler@gmail.com>2026-06-04 10:17:27 -0400
committerJoseph Hunkeler <jhunkeler@gmail.com>2026-06-04 10:17:27 -0400
commitbfec3ec509584deffc073062788a15e9efdaf1f3 (patch)
treee53725ce857e4e7d986fc43a971b9590d693db9c /src
parent252b9646c1cb0538123d51ced4a733f3dcfc266b (diff)
downloadstasis-bfec3ec509584deffc073062788a15e9efdaf1f3.tar.gz
Add conda_capable, conda_capable functions
* Add struct CondaCapabilities
Diffstat (limited to 'src')
-rw-r--r--src/lib/core/conda.c69
-rw-r--r--src/lib/core/include/conda.h39
2 files changed, 108 insertions, 0 deletions
diff --git a/src/lib/core/conda.c b/src/lib/core/conda.c
index c9eb750..411f61a 100644
--- a/src/lib/core/conda.c
+++ b/src/lib/core/conda.c
@@ -691,3 +691,72 @@ int conda_env_exists(const char *root, const char *name) {
snprintf(path, sizeof(path), "%s/envs/%s", root, name);
return access(path, F_OK) == 0;
}
+
+void conda_capable_free(struct CondaCapabilities *ccap) {
+ guard_free(ccap->conda_version);
+ guard_free(ccap->mamba_version);
+ memset(ccap, 0, sizeof(*ccap));
+}
+
+int conda_capable(struct CondaCapabilities *ccap) {
+ struct CondaCapabilities *cc = ccap;
+ memset(cc, 0, sizeof(*cc));
+
+ if (find_program("conda")) {
+ cc->available = true;
+ }
+
+ 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;
+ }
+ if (!conda_version) {
+ SYSERROR("unable to allocate conda_version_raw");
+ 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;
+ }
+ 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);
+ if (version_compare(GT | EQ, cc->conda_version, "25.3.0")) {
+ cc->require_explicit_export_format = true;
+ cc->require_boa = false;
+ } else {
+ cc->require_explicit_export_format = false;
+ cc->require_manual_activation_shim = true;
+ cc->require_boa = true;
+ cc->require_libmamba_solver = true;
+ }
+
+ struct Process proc = {0};
+ safe_strncpy(proc.f_stderr, "/dev/null", sizeof(proc.f_stderr));
+ if (shell(&proc, "mamba install --use-local --dry-run conda")) {
+ cc->missing_use_local = true;
+ }
+
+ cc->usable = true;
+
+ guard_free(mamba_version);
+ guard_free(conda_version);
+ }
+ return 0;
+} \ No newline at end of file
diff --git a/src/lib/core/include/conda.h b/src/lib/core/include/conda.h
index cc9426d..7a0023e 100644
--- a/src/lib/core/include/conda.h
+++ b/src/lib/core/include/conda.h
@@ -26,6 +26,45 @@
#define PKG_INDEX_PROVIDES_E_MANAGER_EXEC (PKG_INDEX_PROVIDES_ERROR_MESSAGE_OFFSET + 5)
#define PKG_INDEX_PROVIDES_FAILED(ECODE) ((ECODE) <= PKG_INDEX_PROVIDES_ERROR_MESSAGE_OFFSET)
+/**
+ * @struct CondaCapabilities
+ * @brief Collection of feature flags to support older, newer, and transitional versions of conda/mamba.
+ * @see implementation in `conda_capable`
+ */
+struct CondaCapabilities {
+ /// Currently installed version of Conda
+ char *conda_version;
+ /// Currently installed version of Mamba
+ char *mamba_version;
+ /// Is conda available in the runtime environment?
+ bool available;
+ /// Can conda execute?
+ bool usable;
+ /// Do we need to pass extra arguments to "conda env export"?
+ bool require_explicit_export_format;
+ /// Do we need to inject our own shim to make Conda available?
+ bool require_manual_activation_shim;
+ /// Does this version of Conda support building with boa?
+ bool require_boa;
+ /// Does this version of Conda need to be configured to use libmamba?
+ bool require_libmamba_solver;
+ /// Does "mamba install --use-local" work on this version of mamba?
+ bool missing_use_local;
+};
+
+/**
+ * Check for the existence of "Conda" and set flags based on the availability of features
+ * @param ccap a pointer to an empty `struct CondaCapabilities`
+ * @return 0 on success
+ */
+int conda_capable(struct CondaCapabilities *ccap);
+
+/**
+ * Free memory allocated by `conda_capable`
+ * @param ccap a pointer to a populated `struct CondaCapabilities`
+ */
+void conda_capable_free(struct CondaCapabilities *ccap);
+
struct MicromambaInfo {
char *micromamba_prefix; //!< Path to write micromamba binary
char *conda_prefix; //!< Path to install conda base tree