1
1
#! /bin/bash
2
2
3
+ set -e # exit on error
4
+
5
+ # Initialize conda if not already initialized
6
+ for conda_path in " $HOME /miniconda3" " $HOME /anaconda3" " /opt/conda" " /usr/local/miniconda3" " /usr/local/anaconda3" ; do
7
+ if [ -f " $conda_path /etc/profile.d/conda.sh" ]; then
8
+ echo
9
+ echo " Initializing conda from $conda_path "
10
+ source " $conda_path /etc/profile.d/conda.sh"
11
+ break
12
+ else
13
+ echo
14
+ echo " ERROR: Unable to find conda in expected locations"
15
+ exit 1
16
+ fi
17
+ done
18
+
3
19
# Reset OPTIND so help can be invoked multiple times per shell session.
4
20
OPTIND=1
5
21
Help ()
6
22
{
7
23
# Display Help
24
+ echo
8
25
echo " Script to automatically create and validate conda environments."
9
26
echo
10
27
echo " Syntax: source environment.sh [-h|t|v]"
@@ -20,22 +37,25 @@ username=$(whoami)
20
37
env_type=" simulation"
21
38
make_new=" no"
22
39
install_git_lfs=" no"
40
+ days_until_stale=7 # Number of days until environment is considered stale
41
+
23
42
24
43
# Process input options
25
44
while getopts " :hflt:" option; do
26
45
case $option in
27
46
h) # display help
28
47
Help
29
- return ;;
48
+ exit 0 ;;
30
49
t) # Type of conda environment to build
31
50
env_type=$OPTARG ;;
32
51
f) # Force creation of a new environment
33
52
make_new=" yes" ;;
34
53
l) # Install git lfs
35
54
install_git_lfs=" yes" ;;
36
55
\? ) # Invalid option
37
- echo " Error: Invalid option"
38
- return ;;
56
+ echo
57
+ echo " ERROR: Invalid option"
58
+ exit 1;;
39
59
esac
40
60
done
41
61
@@ -49,80 +69,101 @@ if [ $env_type == 'simulation' ]; then
49
69
elif [ $env_type == ' artifact' ]; then
50
70
install_file=" artifact_requirements.txt"
51
71
else
72
+ echo
52
73
echo " Invalid environment type. Valid argument types are 'simulation' and 'artifact'."
53
- return
74
+ exit 1
54
75
fi
55
76
56
77
# Pull repo to get latest changes from remote if remote exists
78
+ set +e # Do not exit on error for git ls-remote
57
79
git ls-remote --exit-code --heads origin $branch_name > /dev/null 2>&1
58
80
exit_code=$?
81
+ set -e # Re-enable exit on error
59
82
if [[ $exit_code == ' 0' ]]; then
60
83
git fetch --all
61
- echo " Git branch '$branch_name ' exists in the remote repository, pulling latest changes..."
84
+ echo
85
+ echo " Git branch '$branch_name ' exists in the remote repository; pulling latest changes"
62
86
git pull origin $branch_name
63
87
fi
64
88
65
89
# Check if environment exists already
66
- create_env =$( conda info --envs | grep $env_name | head -n 1)
67
- if [[ $create_env == ' ' ]]; then
90
+ env_info =$( conda info --envs | grep $env_name | head -n 1)
91
+ if [[ $env_info == ' ' ]]; then
68
92
# No environment exists with this name
69
- echo " Environment $env_name does not exist."
93
+ echo
94
+ echo " Environment $env_name does not exist"
70
95
create_env=" yes"
71
96
env_exists=" no"
72
97
elif [[ $make_new == ' yes' ]]; then
73
98
# User has requested to make a new environment
74
- echo " Making a new environment."
99
+ echo
100
+ echo " Making a new environment"
75
101
create_env=" yes"
76
102
env_exists=" yes"
77
103
else
78
104
env_exists=" yes"
79
105
conda activate $env_name
80
106
# Check if existing environment needs to be recreated
81
- echo " Existing environment found for $env_name ."
82
- one_week_ago=$( date -d " 7 days ago" ' +%Y-%m-%d %H:%M:%S' )
107
+ echo
108
+ echo " Existing environment found for $env_name "
109
+ expiration_time=$( date -d " $days_until_stale days ago" +%s)
83
110
creation_time=" $( head -n1 $CONDA_PREFIX /conda-meta/history) "
84
111
creation_time=$( echo $creation_time | sed -e ' s/^==>\ //g' -e ' s/\ <==//g' )
85
- requirements_modification_time=" $( date -r $install_file ' +%Y-%m-%d %H:%M:%S' ) "
112
+ creation_time=" $( date -d " $creation_time " +%s) "
113
+ requirements_modification_time=" $( date -r $install_file +%s) "
86
114
# Check if existing environment is older than a week or if environment was built
87
115
# before last modification to requirements file. If so, mark for recreation.
88
- if [[ $one_week_ago > $creation_time ]] | [[ $creation_time < $requirements_modification_time ]]; then
89
- echo " Environment is stale. Deleting and remaking environment..."
116
+ if [[ $creation_time < $expiration_time ]] || [[ $creation_time < $requirements_modification_time ]]; then
117
+ echo
118
+ echo " Environment is stale; deleting and remaking"
90
119
create_env=" yes"
91
120
else
92
- # Install json parser if it is not installed
93
- jq_exists=$( conda list | grep -w jq)
94
- if [[ $jq_exists == ' ' ]]; then
95
- # Empty string is no return on grep
96
- conda install jq -c anaconda -y
97
- fi
98
- echo " Checking framework packages are up to date..."
99
- # Check if there has been an update to vivarium packages since last modification to requirements file
100
- # or more reccent than environment creation
101
- # Note: The lines we will return via grep will look like 'vivarium>=#.#.#' or will be of the format
102
- # 'vivarium @ git+https://github.com/ihmeuw/vivarium@SOME_BRANCH'
103
- framework_packages=$( grep -E ' vivarium|gbd|risk_distribution|layered_config' $install_file )
104
- num_packages=$( grep -E ' vivarium|gbd|risk_distribution|layered_config' -c $install_file )
121
+ echo
122
+ echo " Environment is up to date; no action needed"
123
+
124
+ # #############################################################################
125
+ # FIXME [MIC-6259]
126
+ # This if/else block has never worked correctly due to using a single |
127
+ # instead of double || (or) in the above 'if' check.
128
+ # As such, we are commenting out the following complicated logic to not drastically
129
+ # change behavior, but this needs to all be fixed.
130
+ # #############################################################################
131
+
132
+ # else
133
+ # # Install json parser if it is not installed
134
+ # jq_exists=$(conda list | grep -w jq)
135
+ # if [[ $jq_exists == '' ]]; then
136
+ # # Empty string is no return on grep
137
+ # conda install jq -c anaconda -y
138
+ # fi
139
+ # echo "Checking framework packages are up to date..."
140
+ # # Check if there has been an update to vivarium packages since last modification to requirements file
141
+ # # or more reccent than environment creation
142
+ # # Note: The lines we will return via grep will look like 'vivarium>=#.#.#' or will be of the format
143
+ # # 'vivarium @ git+https://github.com/ihmeuw/vivarium@SOME_BRANCH'
144
+ # framework_packages=$(grep -E 'vivarium|gbd|risk_distribution|layered_config' $install_file)
145
+ # num_packages=$(grep -E 'vivarium|gbd|risk_distribution|layered_config' -c $install_file)
105
146
106
- # Iterate through each return of the grep output
107
- for (( i = 1 ; i <= $num_packages ; i++ )) ; do
108
- line=$( echo " $framework_packages " | sed -n " ${i} p" )
109
- # Check if the line contains '@'
110
- if [[ " $line " == * " @" * ]]; then
111
- repo_info=(${line//@/ } )
112
- repo=${repo_info[0]}
113
- repo_branch=${repo_info[2]}
114
- last_update_time=$( curl -H " Accept: application/vnd.github.v3+json" https://api.github.com/repos/ihmeuw/$repo /commits? sha=$repo_branch | jq .[0].commit.committer.date)
115
- else
116
- repo=$( echo " $line " | cut -d ' >' -f1)
117
- last_update_time=$( curl -s https://pypi.org/pypi/$repo /json | jq -r ' .releases | to_entries | max_by(.key) | .value | .[0].upload_time' )
118
- fi
119
- last_update_time=$( date -d " $last_update_time " ' +%Y-%m-%d %H:%M:%S' )
120
- if [[ $creation_time < $last_update_time ]]; then
121
- create_env=" yes"
122
- echo " Last update time for $repo : $last_update_time . Environment is stale. Remaking environment..."
123
- break
124
- fi
125
- done
147
+ # # Iterate through each return of the grep output
148
+ # for ((i = 1; i <= $num_packages; i++)); do
149
+ # line=$(echo "$framework_packages" | sed -n "${i}p")
150
+ # # Check if the line contains '@'
151
+ # if [[ "$line" == *"@"* ]]; then
152
+ # repo_info=(${line//@/ })
153
+ # repo=${repo_info[0]}
154
+ # repo_branch=${repo_info[2]}
155
+ # last_update_time=$(curl -H "Accept: application/vnd.github.v3+json" https://api.github.com/repos/ihmeuw/$repo/commits?sha=$repo_branch | jq .[0].commit.committer.date)
156
+ # else
157
+ # repo=$(echo "$line" | cut -d '>' -f1)
158
+ # last_update_time=$(curl -s https://pypi.org/pypi/$repo/json | jq -r '.releases | to_entries | max_by(.key) | .value | .[0].upload_time')
159
+ # fi
160
+ # last_update_time=$(date -d "$last_update_time" '+%Y-%m-%d %H:%M:%S')
161
+ # if [[ $creation_time < $last_update_time ]]; then
162
+ # create_env="yes"
163
+ # echo "Last update time for $repo: $last_update_time. Environment is stale. Remaking environment..."
164
+ # break
165
+ # fi
166
+ # done
126
167
fi
127
168
fi
128
169
@@ -131,12 +172,17 @@ if [[ $create_env == 'yes' ]]; then
131
172
if [[ $env_name == $CONDA_DEFAULT_ENV ]]; then
132
173
conda deactivate
133
174
fi
175
+ echo
176
+ echo " Removing existing environment $env_name "
134
177
conda remove -n $env_name --all -y
135
178
fi
136
179
# Create conda environment
180
+ echo
181
+ echo " Creating new conda environment $env_name "
137
182
conda create -n $env_name python=3.11 -c anaconda -y
138
183
conda activate $env_name
139
184
# NOTE: update branch name if you update requirements.txt in a branch
185
+ echo
140
186
echo " Installing packages for $env_type environment"
141
187
pip install uv
142
188
artifactory_url=" https://artifactory.ihme.washington.edu/artifactory/api/pypi/pypi-shared/simple"
@@ -152,5 +198,12 @@ if [[ $create_env == 'yes' ]]; then
152
198
git lfs install
153
199
fi
154
200
else
201
+ echo
155
202
echo " Existing environment validated"
156
203
fi
204
+
205
+ echo
206
+ echo " *** FINISHED ***"
207
+ echo
208
+ echo " Don't forget to activate the environment:"
209
+ echo " conda activate $env_name "
0 commit comments