4

We are using conda to manage the environment of our Python projects. One thing that bugs us is someone in the team occasionally installs a new package in the environment but forget to update the requirements.yml file.

Instead of typing this before every commit:

conda env export > requirements.yml

Is there away to have that file automatically updated when someone install or remove a package?

Mike Henderson
  • 2,028
  • 1
  • 13
  • 32

1 Answers1

1

Git Hooks

I don't know of a hook for conda (install/upgrade/remove). However, one could add a Git hook for pre-commit that checks whether or not the environment.yaml file matches the output of conda env export. Something like

.git/hooks/pre-commit

#!/bin/bash

CONDA_ENV='my_env'
ENV_FILE='environment.yaml'

echo "Checking Conda environment '$CONDA_ENV' for changes..."

CONDA_YAML=$(conda env export -n $CONDA_ENV)
DIFF=$(echo "$CONDA_YAML" | git diff --no-index -- "$ENV_FILE" -)

if [ "$DIFF" != "" ]
then
    echo "Changes were found in the Conda environment!"
    echo "$DIFF"

    echo "Updating $ENV_FILE."
    echo "$CONDA_YAML" > "$ENV_FILE"

    echo "Adding updated $ENV_FILE to commit."
    git add "$ENV_FILE"
else
echo "No changes detected. Proceeding with commit."
fi

exit 0

This is probably the most brutal way of doing it (i.e., just blindly writing over the file and putting it into the commit). A gentler option would be to throw a warning at the user and proceed with the commit as is. Then they can choose whether or not they need to amend the commit with their env YAML.

This script is mostly just proof-of-concept. Something you'll likely have to address is that, unless your team has a single instance of the env, then the prefix: ... line in the YAML is going to be different; channels: ... could also be slightly varied if users have different .condarc settings. I suppose you could filter out such differences from $CONDA_YAML to normalize across users. Otherwise, it's going to commit a new version every single time a different user commits.

Unfortunately, you can't push hook files directly, so you need to convince your team to place such a script in their local .git/hooks/ folder somehow. This thread discusses some tricks to getting it committed indirectly.

merv
  • 67,214
  • 13
  • 180
  • 245
  • 1
    This is indeed brutal but it is the only solution out there. Environment management in Python is pretty painful – Mike Henderson Sep 10 '19 at 00:28
  • @Mike hmm apparently I reinvented the wheel: https://stackoverflow.com/a/56787188/570918 Might be worth looking through theirs since it looks like they also attempted automating updating the env post-merge. – merv Sep 10 '19 at 01:11
  • Thanks for this. I've turned this into a pre-commit hook at https://github.com/RoyalTS/sync-conda-env. Feedback welcome! – RoyalTS Jan 22 '21 at 09:03