7
7
import subprocess
8
8
import yaml
9
9
10
- from distutils .version import LooseVersion
11
-
12
- from cloudbio .custom import shared
13
- from cloudbio .fabutils import quiet
14
- from cloudbio .flavor .config import get_config_file
15
10
from cloudbio .package .shared import _yaml_to_packages
16
11
17
12
ENV_PY_VERSIONS = collections .defaultdict (lambda : "python=2" )
18
13
ENV_PY_VERSIONS ["python3" ] = "python=3"
19
14
20
15
def install_packages (env , to_install = None , packages = None ):
16
+ """Old installation, based on pre-configured fabric inputs.
17
+ """
18
+ from cloudbio .flavor .config import get_config_file
19
+ from cloudbio .custom import shared
20
+
21
21
if shared ._is_anaconda (env ):
22
22
conda_bin = shared ._conda_cmd (env )
23
23
if hasattr (env , "conda_yaml" ):
24
24
Config = collections .namedtuple ("Config" , "base dist" )
25
25
config_file = Config (base = env .conda_yaml , dist = None )
26
26
else :
27
27
config_file = get_config_file (env , "packages-conda.yaml" )
28
- if config_file .base is None and packages is None :
29
- packages = []
30
- channels = ""
31
- else :
32
- if to_install :
33
- (packages , _ ) = _yaml_to_packages (config_file .base , to_install , config_file .dist )
34
- with open (config_file .base ) as in_handle :
35
- channels = " " .join (["-c %s" % x for x in yaml .safe_load (in_handle ).get ("channels" , [])])
36
- conda_envs = _create_environments (env , conda_bin , packages )
37
- for env_dir in conda_envs .values ():
38
- _clean_environment (env_dir )
39
- conda_info = json .loads (env .safe_run_output ("{conda_bin} info --json" .format (** locals ())))
40
- # Uninstall old R packages that clash with updated versions
41
- # Temporary fix to allow upgrades from older versions that have migrated
42
- # r-tximport is now bioconductor-tximport
43
- # py2cairo is incompatible with r 3.4.1
44
- for problem in ["r-tximport" , "py2cairo" , "libedit" ]:
45
- cur_packages = [x ["name" ] for x in
46
- json .loads (env .safe_run_output ("{conda_bin} list --json {problem}" .format (** locals ())))]
47
- if problem in cur_packages :
48
- env .safe_run ("{conda_bin} remove --force -y {problem}" .format (** locals ()))
49
- # install our customized packages
50
- if len (packages ) > 0 :
51
- for env_name , env_packages in _split_by_condaenv (packages ):
52
- if env_name :
53
- assert env_name in conda_envs , (env_name , conda_envs )
54
- env_str = "-n %s" % env_name
55
- else :
56
- env_str = ""
57
- pkgs_str = " " .join (["'%s'" % x for x in sorted (env_packages )])
58
- py_version = ENV_PY_VERSIONS [env_name ]
59
- if "deepvariant" in env_packages :
60
- # Ignore /etc/boto.cfg which creates conflicts with conda gsutils
61
- # https://github.com/GoogleCloudPlatform/gsutil/issues/516
62
- exports = "export BOTO_CONFIG=/ignoreglobal && "
63
- else :
64
- exports = ""
65
- env .safe_run ("{exports}{conda_bin} install -y {env_str} {channels} "
66
- "{py_version} {pkgs_str}" .format (** locals ()))
67
- conda_pkg_list = json .loads (env .safe_run_output (
68
- "{conda_bin} list --json {env_str}" .format (** locals ())))
69
- for package in env_packages :
70
- _link_bin (package , env , conda_info , conda_bin , conda_pkg_list ,
71
- conda_envdir = conda_envs .get (env_name ))
72
- conda_pkg_list = json .loads (env .safe_run_output ("{conda_bin} list --json" .format (** locals ())))
73
- for pkg in ["python" , "conda" , "pip" ]:
74
- _link_bin (pkg , env , conda_info , conda_bin , conda_pkg_list , files = [pkg ], prefix = "bcbio_" )
75
-
76
- def _link_bin (package , env , conda_info , conda_bin , conda_pkg_list , files = None , prefix = "" , conda_env = None ,
77
- conda_envdir = None ):
28
+ install_in (conda_bin , env .system_install , config_file .base , packages )
29
+
30
+ def install_in (conda_bin , system_installdir , config_file = None , packages = None ):
31
+ """Install packages inside a given anaconda directory.
32
+
33
+ New approach, local only and not dependent on fabric.
34
+ """
35
+ if config_file is None and packages is None :
36
+ packages = []
37
+ channels = ""
38
+ else :
39
+ (packages , _ ) = _yaml_to_packages (config_file )
40
+ with open (config_file ) as in_handle :
41
+ channels = " " .join (["-c %s" % x for x in yaml .safe_load (in_handle ).get ("channels" , [])])
42
+ conda_envs = _create_environments (conda_bin , packages )
43
+ for env_dir in conda_envs .values ():
44
+ _clean_environment (env_dir )
45
+ conda_info = json .loads (subprocess .check_output ("{conda_bin} info --json" .format (** locals ()), shell = True ))
46
+ # Uninstall old R packages that clash with updated versions
47
+ # Temporary fix to allow upgrades from older versions that have migrated
48
+ # r-tximport is now bioconductor-tximport
49
+ # py2cairo is incompatible with r 3.4.1
50
+ problems = ["r-tximport" , "py2cairo" , "libedit" ]
51
+ if problems :
52
+ print ("Checking for problematic packages: %s" % ", " .join (problems ))
53
+ cur_packages = [x ["name" ] for x in
54
+ json .loads (subprocess .check_output ("%s list --json '%s'" % (conda_bin , "|" .join (problems )),
55
+ shell = True )) if x ["name" ] in problems ]
56
+ for problem in cur_packages :
57
+ subprocess .check_call ("{conda_bin} remove --force -y {problem}" .format (** locals ()), shell = True )
58
+ # install our customized packages
59
+ if len (packages ) > 0 :
60
+ for env_name , env_packages in _split_by_condaenv (packages ):
61
+ print ("# Installing into conda environment %s: %s" % (env_name or "default" , ", " .join (env_packages )))
62
+ if env_name :
63
+ assert env_name in conda_envs , (env_name , conda_envs )
64
+ env_str = "-n %s" % env_name
65
+ else :
66
+ env_str = ""
67
+ pkgs_str = " " .join (["'%s'" % x for x in sorted (env_packages )])
68
+ py_version = ENV_PY_VERSIONS [env_name ]
69
+ if "deepvariant" in env_packages :
70
+ # Ignore /etc/boto.cfg which creates conflicts with conda gsutils
71
+ # https://github.com/GoogleCloudPlatform/gsutil/issues/516
72
+ exports = "export BOTO_CONFIG=/ignoreglobal && "
73
+ else :
74
+ exports = ""
75
+ subprocess .check_call ("{exports}{conda_bin} install -y {env_str} {channels} "
76
+ "{py_version} {pkgs_str}" .format (** locals ()), shell = True )
77
+ conda_pkg_list = json .loads (subprocess .check_output (
78
+ "{conda_bin} list --json {env_str}" .format (** locals ()), shell = True ))
79
+ for package in env_packages :
80
+ _link_bin (package , system_installdir , conda_info , conda_bin , conda_pkg_list ,
81
+ conda_envdir = conda_envs .get (env_name ))
82
+ conda_pkg_list = json .loads (subprocess .check_output ("{conda_bin} list --json" .format (** locals ()), shell = True ))
83
+ for pkg in ["python" , "conda" , "pip" ]:
84
+ _link_bin (pkg , system_installdir , conda_info , conda_bin , conda_pkg_list , files = [pkg ], prefix = "bcbio_" )
85
+
86
+ def _link_bin (package , system_installdir , conda_info , conda_bin , conda_pkg_list , files = None ,
87
+ prefix = "" , conda_env = None , conda_envdir = None ):
78
88
"""Link files installed in the bin directory into the install directory.
79
89
80
90
This is imperfect but we're trying not to require injecting everything in the anaconda
81
91
directory into a user's path.
82
92
"""
83
93
package = package .split ("=" )[0 ]
84
- final_bindir = os .path .join (env . system_install , "bin" )
94
+ final_bindir = os .path .join (system_installdir , "bin" )
85
95
if conda_envdir :
86
96
base_bindir = os .path .join (conda_envdir , "bin" )
87
97
else :
88
98
base_bindir = os .path .dirname (conda_bin )
89
99
# resolve any symlinks in the final and base heirarchies
90
- with quiet ():
91
- final_bindir = env .safe_run_output ("cd %s && pwd -P" % final_bindir )
92
- base_bindir = env .safe_run_output ("cd %s && pwd -P" % base_bindir )
100
+ final_bindir = subprocess .check_output ("cd %s && pwd -P" % final_bindir , shell = True )
101
+ base_bindir = subprocess .check_output ("cd %s && pwd -P" % base_bindir , shell = True )
93
102
for pkg_subdir in [x for x in conda_pkg_list if x ["name" ] == package ]:
94
103
pkg_subdir = pkg_subdir ["dist_name" ].split ("::" )[- 1 ]
95
104
for pkg_dir in conda_info ["pkgs_dirs" ]:
96
105
pkg_bindir = os .path .join (pkg_dir , pkg_subdir , "bin" )
97
- if env . safe_exists (pkg_bindir ):
106
+ if os . path . exists (pkg_bindir ):
98
107
if not files :
99
- with quiet ():
100
- files = env .safe_run_output ("ls -1 {pkg_bindir}" .format (** locals ())).split ()
108
+ files = subprocess .check_output ("ls -1 {pkg_bindir}" .format (** locals ()), shell = True ).split ()
101
109
for fname in files :
102
110
# symlink to the original file in the /anaconda/bin directory
103
111
# this could be a hard or soft link
@@ -139,13 +147,13 @@ def _split_by_condaenv(packages):
139
147
if k == "env" :
140
148
condaenv = v
141
149
out [condaenv ].append (name )
142
- return dict (out ).items ()
150
+ return sorted ( dict (out ).items () )
143
151
144
- def _get_conda_envs (env , conda_bin ):
145
- info = json .loads (env . safe_run_output ("{conda_bin} info --envs --json" .format (** locals ())))
152
+ def _get_conda_envs (conda_bin ):
153
+ info = json .loads (subprocess . check_output ("{conda_bin} info --envs --json" .format (** locals ()), shell = True ))
146
154
return [e for e in info ["envs" ] if e .startswith (info ["conda_prefix" ])]
147
155
148
- def _create_environments (env , conda_bin , packages ):
156
+ def _create_environments (conda_bin , packages ):
149
157
"""Creates custom local environments that conflict with global dependencies.
150
158
151
159
Available environments:
@@ -157,17 +165,19 @@ def _create_environments(env, conda_bin, packages):
157
165
"""
158
166
env_names = set ([e for e , ps in _split_by_condaenv (packages ) if e ])
159
167
out = {}
160
- conda_envs = _get_conda_envs (env , conda_bin )
168
+ conda_envs = _get_conda_envs (conda_bin )
161
169
if "python3" in env_names :
162
170
if not any (x .endswith ("/python3" ) for x in conda_envs ):
163
- env .safe_run ("{conda_bin} create --no-default-packages -y --name python3 python=3" .format (** locals ()))
164
- conda_envs = _get_conda_envs (env , conda_bin )
171
+ subprocess .check_call ("{conda_bin} create --no-default-packages -y --name python3 python=3"
172
+ .format (** locals ()), shell = True )
173
+ conda_envs = _get_conda_envs (conda_bin )
165
174
out ["python3" ] = [x for x in conda_envs if x .endswith ("/python3" )][0 ]
166
175
for addenv in ["samtools0" , "dv" ]:
167
176
if addenv in env_names :
168
177
if not any (x .endswith ("/%s" % addenv ) for x in conda_envs ):
169
- env .safe_run ("{conda_bin} create --no-default-packages -y --name {addenv} python=2" .format (** locals ()))
170
- conda_envs = _get_conda_envs (env , conda_bin )
178
+ subprocess .check_call ("{conda_bin} create --no-default-packages -y --name {addenv} python=2"
179
+ .format (** locals ()), shell = True )
180
+ conda_envs = _get_conda_envs (conda_bin )
171
181
out [addenv ] = [x for x in conda_envs if x .endswith ("/%s" % addenv )][0 ]
172
182
return out
173
183
0 commit comments