Skip to content

Commit 786d4d5

Browse files
authored
Merge pull request #922 from compas-dev/rhino-legacy-install
Update (un)install procedures
2 parents eb3e4ef + db1f87d commit 786d4d5

File tree

5 files changed

+117
-66
lines changed

5 files changed

+117
-66
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2020

2121
* Fixed bug in directions of `compas.datastructures.Mesh.from_meshgrid`.
2222
* Fixed bug in Rhino mesh face drawing.
23+
* Fixed bug related to legacy uninstall on Rhino for Mac.
2324

2425
### Removed
2526

src/compas_rhino/__init__.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,12 @@ def _get_ironpython_lib_path(version):
7272
raise Exception('Unsupported platform')
7373

7474
if not os.path.exists(ironpython_lib_path):
75-
raise Exception("The lib folder for IronPython does not exist in this location: {}".format(ironpython_lib_path))
75+
# This does not always work.
76+
# Especially not on (new) macs.
77+
# However, since it is only used to clean up potential old installations
78+
# it does not seem crucial anymore.
79+
ironpython_lib_path = None
80+
print("The lib folder for IronPython does not exist in this location: {}".format(ironpython_lib_path))
7681

7782
return ironpython_lib_path
7883

@@ -213,6 +218,7 @@ def _try_remove_bootstrapper(path):
213218

214219

215220
__all__ = [name for name in dir() if not name.startswith('_')]
221+
216222
__all_plugins__ = [
217223
'compas_rhino.geometry.booleans',
218224
'compas_rhino.geometry.trimesh',

src/compas_rhino/install.py

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -50,27 +50,33 @@ def install(version=None, packages=None):
5050
packages = _filter_installable_packages(version, packages)
5151

5252
ipylib_path = compas_rhino._get_ironpython_lib_path(version)
53+
# We install COMPAS packages in the scripts folder
54+
# instead of directly as IPy module.
5355
scripts_path = compas_rhino._get_scripts_path(version)
5456

5557
print('Installing COMPAS packages to Rhino {0} scripts folder:'.format(version))
56-
print('Location scripts folder: {}'.format(scripts_path))
57-
print()
58+
print('{}\n'.format(scripts_path))
5859

5960
results = []
6061
symlinks_to_install = []
6162
symlinks_to_uninstall = []
6263
exit_code = 0
6364

6465
for package in packages:
65-
package_path = compas_rhino._get_package_path(importlib.import_module(package))
6666
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))
69+
70+
package_path = compas_rhino._get_package_path(importlib.import_module(package))
6771
symlinks_to_install.append(dict(name=package, source_path=package_path, link=symlink_path))
68-
symlinks_to_uninstall.append(dict(name=package, link=symlink_path))
6972

7073
# Handle legacy install location
71-
legacy_path = os.path.join(ipylib_path, package)
72-
if os.path.exists(legacy_path):
73-
symlinks_to_uninstall.append(dict(name=package, link=legacy_path))
74+
# This does not always work,
75+
# and especially not in cases where it is in any case not necessary :)
76+
if ipylib_path:
77+
legacy_path = os.path.join(ipylib_path, package)
78+
if os.path.exists(legacy_path):
79+
symlinks_to_uninstall.append(dict(name=package, link=legacy_path))
7480

7581
# First uninstall existing copies of packages requested for installation
7682
symlinks = [link['link'] for link in symlinks_to_uninstall]
@@ -81,8 +87,10 @@ def install(version=None, packages=None):
8187
results.append((uninstall_data['name'], 'ERROR: Cannot remove symlink, try to run as administrator.'))
8288

8389
# Handle legacy bootstrapper
84-
if not compas_rhino._try_remove_bootstrapper(ipylib_path):
85-
results.append(('compas_bootstrapper', 'ERROR: Cannot remove legacy compas_bootstrapper, try to run as administrator.'))
90+
# Again, only if possible...
91+
if ipylib_path:
92+
if not compas_rhino._try_remove_bootstrapper(ipylib_path):
93+
results.append(('compas_bootstrapper', 'ERROR: Cannot remove legacy compas_bootstrapper, try to run as administrator.'))
8694

8795
# Ready to start installing
8896
symlinks = [(link['source_path'], link['link']) for link in symlinks_to_install]
@@ -116,13 +124,11 @@ def install(version=None, packages=None):
116124
exit_code = -1
117125

118126
if exit_code == 0 and len(installed_packages):
119-
print()
120-
print('Running post-installation steps...')
121-
print()
127+
print('\nRunning post-installation steps...\n')
122128
if not _run_post_execution_steps(after_rhino_install(installed_packages)):
123129
exit_code = -1
124130

125-
print('\nCompleted.')
131+
print('\nInstall completed.')
126132
if exit_code != 0:
127133
sys.exit(exit_code)
128134

@@ -147,9 +153,7 @@ def _run_post_execution_steps(steps_generator):
147153
post_execution_errors.append(ValueError('Step ran without errors but result is wrongly formatted: {}'.format(str(item))))
148154

149155
if post_execution_errors:
150-
print()
151-
print('One or more errors occurred:')
152-
print()
156+
print('\nOne or more errors occurred:\n')
153157
for error in post_execution_errors:
154158
print(' - {}'.format(repr(error)))
155159

src/compas_rhino/uninstall.py

Lines changed: 60 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,11 @@ def uninstall(version=None, packages=None):
4848
packages = _filter_installed_packages(version, packages)
4949

5050
ipylib_path = compas_rhino._get_ironpython_lib_path(version)
51+
# We install COMPAS packages in the scripts folder
52+
# instead of directly as IPy module.
5153
scripts_path = compas_rhino._get_scripts_path(version)
5254

53-
print('Uninstalling COMPAS packages from Rhino {0} scripts folder:'.format(version))
54-
print('Location scripts folder: {}'.format(scripts_path))
55-
print()
56-
57-
print('The following packages have been detected and will be uninstalled:')
55+
print('Uninstalling COMPAS packages from Rhino {0} scripts folder: \n{1}'.format(version, scripts_path))
5856

5957
results = []
6058
symlinks_to_uninstall = []
@@ -65,50 +63,66 @@ def uninstall(version=None, packages=None):
6563
if os.path.exists(symlink_path):
6664
symlinks_to_uninstall.append(dict(name=package, link=symlink_path))
6765

68-
legacy_path = os.path.join(ipylib_path, package)
69-
if os.path.exists(legacy_path):
70-
symlinks_to_uninstall.append(dict(name=package, link=legacy_path))
66+
# Handle legacy install location
67+
# This does not always work,
68+
# and especially not in cases where it is in any case not necessary :)
69+
if ipylib_path:
70+
legacy_path = os.path.join(ipylib_path, package)
71+
if os.path.exists(legacy_path):
72+
symlinks_to_uninstall.append(dict(name=package, link=legacy_path))
7173

72-
symlinks = [link['link'] for link in symlinks_to_uninstall]
73-
uninstall_results = compas._os.remove_symlinks(symlinks)
74+
if not symlinks_to_uninstall:
75+
print('\nNo packages to uninstall.')
7476

75-
uninstalled_packages = []
76-
for uninstall_data, success in zip(symlinks_to_uninstall, uninstall_results):
77-
if success:
78-
uninstalled_packages.append(uninstall_data['name'])
79-
result = 'OK'
80-
else:
81-
result = 'ERROR: Cannot remove symlink, try to run as administrator.'
82-
results.append((uninstall_data['name'], result))
77+
else:
78+
uninstalled_packages = []
8379

84-
if not all(uninstall_results):
85-
exit_code = -1
80+
symlinks = [link['link'] for link in symlinks_to_uninstall]
81+
uninstall_results = compas._os.remove_symlinks(symlinks)
82+
83+
for uninstall_data, success in zip(symlinks_to_uninstall, uninstall_results):
84+
if success:
85+
uninstalled_packages.append(uninstall_data['name'])
86+
result = 'OK'
87+
else:
88+
result = 'ERROR: Cannot remove symlink, try to run as administrator.'
89+
90+
results.append((uninstall_data['name'], result))
91+
92+
if not all(uninstall_results):
93+
exit_code = -1
94+
95+
if exit_code == -1:
96+
results.append(('compas_bootstrapper', 'WARNING: One or more packages failed, will not uninstall bootstrapper.'))
8697

87-
if exit_code == -1:
88-
results.append(('compas_bootstrapper', 'WARNING: One or more packages failed, will not uninstall bootstrapper.'))
89-
else:
90-
if compas_rhino._try_remove_bootstrapper(scripts_path):
91-
results.append(('compas_bootstrapper', 'OK'))
9298
else:
93-
results.append(('compas_bootstrapper', 'ERROR: Cannot remove compas_bootstrapper, try to run as administrator.'))
99+
if compas_rhino._try_remove_bootstrapper(scripts_path):
100+
results.append(('compas_bootstrapper', 'OK'))
101+
else:
102+
results.append(('compas_bootstrapper', 'ERROR: Cannot remove compas_bootstrapper, try to run as administrator.'))
94103

95-
if not compas_rhino._try_remove_bootstrapper(ipylib_path):
96-
results.append(('compas_bootstrapper', 'ERROR: Cannot remove legacy compas_bootstrapper, try to run as administrator.'))
104+
# Handle legacy bootstrapper
105+
# Again, only if possible...
106+
if ipylib_path:
107+
if not compas_rhino._try_remove_bootstrapper(ipylib_path):
108+
results.append(('compas_bootstrapper', 'ERROR: Cannot remove legacy compas_bootstrapper, try to run as administrator.'))
97109

98-
for package, status in results:
99-
print(' {} {}'.format(package.ljust(20), status))
110+
print('\nThe following packages have been detected and will be uninstalled:\n')
100111

101-
if status != 'OK':
102-
exit_code = -1
112+
for package, status in results:
113+
print(' {} {}'.format(package.ljust(20), status))
103114

104-
if exit_code == 0 and len(uninstalled_packages):
105-
print()
106-
print('Running post-uninstallation steps...')
107-
print()
108-
if not _run_post_execution_steps(after_rhino_uninstall(uninstalled_packages)):
109-
exit_code = -1
115+
if status != 'OK':
116+
exit_code = -1
117+
118+
if exit_code == 0 and uninstalled_packages:
119+
print('\nRunning post-uninstallation steps...\n')
120+
121+
if not _run_post_execution_steps(after_rhino_uninstall(uninstalled_packages)):
122+
exit_code = -1
110123

111124
print('\nUninstall completed.')
125+
112126
if exit_code != 0:
113127
sys.exit(exit_code)
114128

@@ -131,13 +145,14 @@ def _filter_installed_packages(version, packages):
131145
packages = list(itertools.chain.from_iterable(installable_rhino_packages()))
132146

133147
# Handle legacy install
134-
legacy_bootstrapper = compas_rhino._get_bootstrapper_path(ipylib_path)
135-
if os.path.exists(legacy_bootstrapper):
136-
bootstrapper_data = compas_rhino._get_bootstrapper_data(legacy_bootstrapper)
137-
legacy_packages = bootstrapper_data.get('INSTALLED_PACKAGES', None)
138-
139-
if legacy_packages:
140-
packages.extend(legacy_packages)
148+
if ipylib_path:
149+
legacy_bootstrapper = compas_rhino._get_bootstrapper_path(ipylib_path)
150+
if os.path.exists(legacy_bootstrapper):
151+
bootstrapper_data = compas_rhino._get_bootstrapper_data(legacy_bootstrapper)
152+
legacy_packages = bootstrapper_data.get('INSTALLED_PACKAGES', None)
153+
154+
if legacy_packages:
155+
packages.extend(legacy_packages)
141156

142157
return packages
143158

src/compas_rhino/uninstall_plugin.py

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,39 @@ def uninstall_plugin(plugin, version=None):
3838
version = '6.0'
3939

4040
python_plugins_path = compas_rhino._get_python_plugins_path(version)
41+
plugin_name = plugin.split('{')[0]
4142

42-
destination = os.path.join(python_plugins_path, plugin)
43+
symlinks = []
44+
dirs = []
4345

44-
print('Uninstalling PlugIn {} from Rhino PythonPlugIns.'.format(plugin))
46+
for name in os.listdir(python_plugins_path):
47+
path = os.path.join(python_plugins_path, name)
4548

46-
remove_symlink(destination)
49+
if os.path.islink(path):
50+
if name.split('{')[0] == plugin_name:
51+
symlinks.append(name)
4752

48-
print('PlugIn {} Uninstalled.'.format(plugin))
53+
elif os.path.isdir(path):
54+
if name.split('{')[0] == plugin_name:
55+
dirs.append(name)
56+
57+
print('\nUninstalling PlugIn {} from Rhino PythonPlugIns:'.format(plugin_name))
58+
59+
if not symlinks and not dirs:
60+
print('Nothing to uninstall...\n')
61+
62+
else:
63+
for name in symlinks:
64+
print('- {}'.format(name))
65+
destination = os.path.join(python_plugins_path, name)
66+
remove_symlink(destination)
67+
68+
for name in dirs:
69+
print('- {}'.format(name))
70+
destination = os.path.join(python_plugins_path, name)
71+
os.rmdir(destination)
72+
73+
print('\nPlugIn {} Uninstalled.\n'.format(plugin_name))
4974

5075

5176
# ==============================================================================

0 commit comments

Comments
 (0)