1919]
2020
2121
22- def install (version = None , packages = None ):
22+ def install (version = None , packages = None , clean = False ):
2323 """Install COMPAS for Rhino.
2424
2525 Parameters
2626 ----------
27- version : {'5.0', '6.0', '7.0'}, optional
27+ version : {'5.0', '6.0', '7.0', '8.0' }, optional
2828 The version number of Rhino.
2929 Default is ``'6.0'``.
3030 packages : list of str, optional
3131 List of packages to install or None to use default package list.
32- Default is ``['compas', 'compas_rhino', 'compas_ghpython']``.
32+ Default is the result of ``installable_rhino_packages``,
33+ which collects all installable packages in the current environment.
34+ clean : bool, optional
35+ If ``True``, this will clean up the entire scripts folder and remove
36+ also existing symlinks that are not importable in the current environment.
3337
3438 Examples
3539 --------
@@ -44,28 +48,62 @@ def install(version=None, packages=None):
4448
4549 """
4650
47- if version not in ('5.0' , '6.0' , '7.0' ):
51+ if version not in ('5.0' , '6.0' , '7.0' , '8.0' ):
4852 version = '6.0'
4953
50- packages = _filter_installable_packages (version , packages )
51-
52- ipylib_path = compas_rhino ._get_ironpython_lib_path (version )
5354 # We install COMPAS packages in the scripts folder
5455 # instead of directly as IPy module.
5556 scripts_path = compas_rhino ._get_scripts_path (version )
5657
57- print ('Installing COMPAS packages to Rhino {0} scripts folder:' .format (version ))
58- print ('{}\n ' .format (scripts_path ))
58+ # This is for old installs
59+ ipylib_path = compas_rhino ._get_ironpython_lib_path (version )
60+
61+ packages = _filter_installable_packages (version , packages )
5962
6063 results = []
6164 symlinks_to_install = []
6265 symlinks_to_uninstall = []
6366 exit_code = 0
6467
68+ # check all installable packages
69+ # add the packages that can't be imported from the current env to the list of symlinks to uninstall
70+ # and remove the package name from the list of installable packages
71+ # make a copy of the list to avoid problems with removing items
72+ # note: perhaps this should already happen in the filter function...
73+ for name in packages [:]:
74+ try :
75+ importlib .import_module (name )
76+ except ImportError :
77+ path = os .path .join (scripts_path , name )
78+ symlinks_to_uninstall .append (dict (name = name , link = path ))
79+ packages .remove (name )
80+
81+ # Also remove all broken symlinks from the scripts folder
82+ # because ... they're broken!
83+ # If it is an actual folder or a file, leave it alone
84+ # because probably someone put it there on purpose.
85+ for name in os .listdir (scripts_path ):
86+ path = os .path .join (scripts_path , name )
87+ if os .path .islink (path ):
88+ if not os .path .exists (path ):
89+ symlinks_to_uninstall .append (dict (name = name , link = path ))
90+ else :
91+ if clean :
92+ try :
93+ importlib .import_module (name )
94+ except ImportError :
95+ path = os .path .join (scripts_path , name )
96+ symlinks_to_uninstall .append (dict (name = name , link = path ))
97+ else :
98+ if name not in packages :
99+ packages .append (name )
100+
101+ # add all of the packages in the list of installable packages
102+ # to the list of symlinks to uninstall
103+ # and to the list of symlinks to install
65104 for package in packages :
66105 symlink_path = os .path .join (scripts_path , package )
67- if os .path .exists (symlink_path ):
68- symlinks_to_uninstall .append (dict (name = package , link = symlink_path ))
106+ symlinks_to_uninstall .append (dict (name = package , link = symlink_path ))
69107
70108 package_path = compas_rhino ._get_package_path (importlib .import_module (package ))
71109 symlinks_to_install .append (dict (name = package , source_path = package_path , link = symlink_path ))
@@ -92,10 +130,21 @@ def install(version=None, packages=None):
92130 if not compas_rhino ._try_remove_bootstrapper (ipylib_path ):
93131 results .append (('compas_bootstrapper' , 'ERROR: Cannot remove legacy compas_bootstrapper, try to run as administrator.' ))
94132
133+ # -------------------------
95134 # Ready to start installing
135+ # -------------------------
136+
137+ # create new symlinks and register the results
96138 symlinks = [(link ['source_path' ], link ['link' ]) for link in symlinks_to_install ]
97139 install_results = compas ._os .create_symlinks (symlinks )
98140
141+ # set the exit code based on the installation results
142+ if not all (install_results ):
143+ exit_code = - 1
144+
145+ # make a list of installed packages
146+ # based on the installation results
147+ # and update the general results list
99148 installed_packages = []
100149 for install_data , success in zip (symlinks_to_install , install_results ):
101150 if success :
@@ -105,9 +154,7 @@ def install(version=None, packages=None):
105154 result = 'ERROR: Cannot create symlink, try to run as administrator.'
106155 results .append ((install_data ['name' ], result ))
107156
108- if not all (install_results ):
109- exit_code = - 1
110-
157+ # finalize the general results list with info about the bootstrapper
111158 if exit_code == - 1 :
112159 results .append (('compas_bootstrapper' , 'WARNING: One or more packages failed, will not install bootstrapper, try uninstalling first' ))
113160 else :
@@ -117,9 +164,13 @@ def install(version=None, packages=None):
117164 except : # noqa: E722
118165 results .append (('compas_bootstrapper' , 'ERROR: Could not create compas_bootstrapper to auto-determine Python environment' ))
119166
167+ # output the outcome of the installation process
168+ # perhaps we should more info here
169+ print ('Installing COMPAS packages to Rhino {0} scripts folder:' .format (version ))
170+ print ('{}\n ' .format (scripts_path ))
171+
120172 for package , status in results :
121173 print (' {} {}' .format (package .ljust (20 ), status ))
122-
123174 if status != 'OK' :
124175 exit_code = - 1
125176
@@ -271,9 +322,10 @@ def _filter_installable_packages(version, packages):
271322
272323 parser = argparse .ArgumentParser ()
273324
274- parser .add_argument ('-v' , '--version' , choices = ['5.0' , '6.0' , '7.0' ], default = '6.0' , help = "The version of Rhino to install the packages in." )
325+ parser .add_argument ('-v' , '--version' , choices = ['5.0' , '6.0' , '7.0' , '8.0' ], default = '6.0' , help = "The version of Rhino to install the packages in." )
275326 parser .add_argument ('-p' , '--packages' , nargs = '+' , help = "The packages to install." )
327+ parser .add_argument ('--clean' , dest = 'clean' , default = False , action = 'store_true' )
276328
277329 args = parser .parse_args ()
278330
279- install (version = args .version , packages = args .packages )
331+ install (version = args .version , packages = args .packages , clean = args . clean )
0 commit comments