diff options
| author | Joseph Hunkeler <jhunkeler@gmail.com> | 2026-06-04 10:17:27 -0400 |
|---|---|---|
| committer | Joseph Hunkeler <jhunkeler@gmail.com> | 2026-06-04 10:17:27 -0400 |
| commit | bfec3ec509584deffc073062788a15e9efdaf1f3 (patch) | |
| tree | e53725ce857e4e7d986fc43a971b9590d693db9c /src | |
| parent | 252b9646c1cb0538123d51ced4a733f3dcfc266b (diff) | |
| download | stasis-bfec3ec509584deffc073062788a15e9efdaf1f3.tar.gz | |
Add conda_capable, conda_capable functions
* Add struct CondaCapabilities
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/core/conda.c | 69 | ||||
| -rw-r--r-- | src/lib/core/include/conda.h | 39 |
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 |
