Skip to content

Commit b1a46ca

Browse files
committed
Merge branch 'main' into assembly-suggestions
2 parents 1f20e7b + eb6b5dc commit b1a46ca

File tree

7 files changed

+165
-78
lines changed

7 files changed

+165
-78
lines changed

.github/workflows/docs.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ jobs:
4747
with:
4848
ref: gh-pages
4949

50-
- uses: compas-dev/[email protected].0
50+
- uses: compas-dev/[email protected].1
5151
with:
5252
current_version: ${{ needs.build.outputs.current_version }}
5353

CHANGELOG.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99

1010
### Added
1111

12+
* Added `compas_rhino.DEFAULT_VERSION`.
13+
* Added `clean` option to `compas_rhino.install` to remove existing symlinks if they cannot be imported from the current environment.
1214
* Added basic implementation of `compas.datastructures.Assembly`.
1315

1416
### Changed
@@ -19,6 +21,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1921
* Fixed error in parameter list of `compas_rhino.geometry.curves.new_nurbscurve_from_interpolation`.
2022
* Fixed error in parameter list of `compas_rhino.geometry.curves.new_nurbscurve_from_step`.
2123

24+
* Changed `compas_rhino.install` to remove broken symlinks.
25+
* Changed `compas_rhino.install` to reinstall broken symlinks if they can be imported from the current environment.
26+
* Changed `compas_rhino.uninstall` to remove broken symlinks.
27+
* Changed `compas_rhino.install_plugin` to remove broken symlinks.
28+
* Changed default Rhino version for installation to `7.0`.
29+
2230
### Removed
2331

2432

@@ -40,6 +48,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
4048
### Changed
4149

4250
* Fixed bug in `compas_rhino.conversions.RhinoPoint.from_geometry`.
51+
* Changed `compas_rhino.install` to remove broken symlinks.
52+
* Changed `compas_rhino.install` to reinstall broken symlinks if they can be imported from the current environment.
53+
* Changed `compas_rhino.uninstall` to remove broken symlinks.
54+
* Changed `compas_rhino.install_plugin` to remove broken symlinks.
4355

4456
### Removed
4557

src/compas_rhino/__init__.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@
3636
PURGE_ON_DELETE = True
3737

3838
INSTALLABLE_PACKAGES = ['compas', 'compas_rhino', 'compas_ghpython']
39+
SUPPORTED_VERSIONS = ['5.0', '6.0', '7.0', '8.0']
40+
DEFAULT_VERSION = '7.0'
3941

4042

4143
def clear():
@@ -49,12 +51,10 @@ def redraw():
4951

5052

5153
def _check_rhino_version(version):
52-
supported_versions = ['5.0', '6.0', '7.0']
53-
5454
if not version:
55-
return '6.0'
55+
return DEFAULT_VERSION
5656

57-
if version not in supported_versions:
57+
if version not in SUPPORTED_VERSIONS:
5858
raise Exception('Unsupported Rhino version: {}'.format(version))
5959

6060
return version
@@ -99,7 +99,8 @@ def _get_ironpython_lib_path_mac(version):
9999
lib_paths = {
100100
'5.0': ['/', 'Applications', 'Rhinoceros.app', 'Contents'],
101101
'6.0': ['/', 'Applications', 'Rhinoceros.app', 'Contents', 'Frameworks', 'RhCore.framework', 'Versions', 'A'],
102-
'7.0': ['/', 'Applications', 'Rhino7.app', 'Contents', 'Frameworks', 'RhCore.framework', 'Versions', 'A']
102+
'7.0': ['/', 'Applications', 'Rhino7.app', 'Contents', 'Frameworks', 'RhCore.framework', 'Versions', 'A'],
103+
'8.0': ['/', 'Applications', 'Rhino8.app', 'Contents', 'Frameworks', 'RhCore.framework', 'Versions', 'A'],
103104
}
104105
return os.path.join(*lib_paths.get(version) + ['Resources', 'ManagedPlugIns', 'RhinoDLR_Python.rhp', 'Lib'])
105106

src/compas_rhino/install.py

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,7 @@ def install(version=None, packages=None, clean=False):
4747
python -m compas_rhino.install -v 6.0
4848
4949
"""
50-
51-
if version not in ('5.0', '6.0', '7.0', '8.0'):
52-
version = '6.0'
50+
version = compas_rhino._check_rhino_version(version)
5351

5452
# We install COMPAS packages in the scripts folder
5553
# instead of directly as IPy module.
@@ -58,6 +56,9 @@ def install(version=None, packages=None, clean=False):
5856
# This is for old installs
5957
ipylib_path = compas_rhino._get_ironpython_lib_path(version)
6058

59+
# Filter the provided list of packages
60+
# If no packages are provided
61+
# this first collects all installable packages from the environment.
6162
packages = _filter_installable_packages(version, packages)
6263

6364
results = []
@@ -87,8 +88,22 @@ def install(version=None, packages=None, clean=False):
8788
if os.path.islink(path):
8889
if not os.path.exists(path):
8990
symlinks_to_uninstall.append(dict(name=name, link=path))
90-
else:
91-
if clean:
91+
try:
92+
importlib.import_module(name)
93+
except ImportError:
94+
pass
95+
else:
96+
if name not in packages:
97+
packages.append(name)
98+
99+
# If the scripts folder is supposed to be cleaned
100+
# also remove all existing symlinks that cannot be imported
101+
# and reinstall symlinks that can be imported
102+
if clean:
103+
for name in os.listdir(scripts_path):
104+
path = os.path.join(scripts_path, name)
105+
if os.path.islink(path):
106+
if os.path.exists(path):
92107
try:
93108
importlib.import_module(name)
94109
except ImportError:
@@ -110,16 +125,20 @@ def install(version=None, packages=None, clean=False):
110125

111126
# Handle legacy install location
112127
# This does not always work,
113-
# and especially not in cases where it is in any case not necessary :)
128+
# and especially not in cases where it is not necessary :)
114129
if ipylib_path:
115130
legacy_path = os.path.join(ipylib_path, package)
116131
if os.path.exists(legacy_path):
117132
symlinks_to_uninstall.append(dict(name=package, link=legacy_path))
118133

119-
# First uninstall existing copies of packages requested for installation
134+
# -------------------------
135+
# Uninstall first
136+
# -------------------------
137+
120138
symlinks = [link['link'] for link in symlinks_to_uninstall]
121139
uninstall_results = compas._os.remove_symlinks(symlinks)
122140

141+
# Let the user know if some symlinks could not be removed.
123142
for uninstall_data, success in zip(symlinks_to_uninstall, uninstall_results):
124143
if not success:
125144
results.append((uninstall_data['name'], 'ERROR: Cannot remove symlink, try to run as administrator.'))
@@ -322,7 +341,13 @@ def _filter_installable_packages(version, packages):
322341

323342
parser = argparse.ArgumentParser()
324343

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.")
344+
parser.add_argument(
345+
'-v',
346+
'--version',
347+
choices=compas_rhino.SUPPORTED_VERSIONS,
348+
default=compas_rhino.DEFAULT_VERSION,
349+
help="The version of Rhino to install the packages in."
350+
)
326351
parser.add_argument('-p', '--packages', nargs='+', help="The packages to install.")
327352
parser.add_argument('--clean', dest='clean', default=False, action='store_true')
328353

src/compas_rhino/install_plugin.py

Lines changed: 46 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -58,32 +58,53 @@ def install_plugin(plugin, version=None):
5858
python -m compas_rhino.install_plugin -v 7.0 ui/Rhino/XXX
5959
6060
"""
61-
if version not in ('5.0', '6.0', '7.0', '8.0'):
62-
version = '6.0'
63-
6461
if not os.path.isdir(plugin):
6562
raise Exception('Cannot find the plugin: {}'.format(plugin))
6663

67-
plugin_dir = os.path.abspath(plugin)
68-
69-
# clean up the plugin directory
64+
version = compas_rhino._check_rhino_version(version)
7065

71-
# # Also remove all broken symlinks
72-
# # because ... they're broken!
73-
# broken = []
74-
# for name in os.listdir(plugin_dir):
75-
# path = os.path.join(plugin_dir, name)
76-
# if os.path.islink(path):
77-
# if not os.path.exists(path):
78-
# broken.append(path)
79-
# if broken:
80-
# pass
66+
plugin_dir = os.path.abspath(plugin)
8167

68+
# Clean up the plugin directory
69+
# by removing all broken symlinks
70+
# because ... they're broken!
71+
72+
symlinks_to_remove = []
73+
74+
for name in os.listdir(plugin_dir):
75+
path = os.path.join(plugin_dir, name)
76+
if os.path.islink(path):
77+
if not os.path.exists(path):
78+
symlinks_to_remove.append(dict(name=name, link=path))
79+
80+
symlinks_removed = []
81+
symlinks_unremoved = []
82+
83+
if symlinks_to_remove:
84+
symlinks = [link['link'] for link in symlinks_to_remove]
85+
removal_results = remove_symlinks(symlinks)
86+
for uninstall_data, success in zip(symlinks_to_remove, removal_results):
87+
if success:
88+
symlinks_removed.append(uninstall_data['name'])
89+
else:
90+
symlinks_unremoved.append(uninstall_data['name'])
91+
92+
if symlinks_removed:
93+
print('\nThe following package symlinks are broken and were removed:\n')
94+
for name in symlinks_removed:
95+
print(' {}'.format(name.ljust(20)))
96+
97+
if symlinks_unremoved:
98+
print('\nThe following package symlinks are broken but could not be removed:\n')
99+
for name in symlinks_unremoved:
100+
print(' {}'.format(name.ljust(20)))
101+
102+
# -----------------------------
82103
# proceed with the installation
104+
# -----------------------------
83105

84106
plugin_path, plugin_name = os.path.split(plugin_dir)
85-
if not plugin_path:
86-
plugin_path = os.getcwd()
107+
plugin_path = plugin_path or os.getcwd()
87108

88109
plugin_dev = os.path.join(plugin_dir, 'dev')
89110

@@ -134,7 +155,13 @@ def install_plugin(plugin, version=None):
134155
description='COMPAS Rhino Plugin Installation command-line utility.')
135156

136157
parser.add_argument('plugin', help="The path to the plugin directory.")
137-
parser.add_argument('-v', '--version', choices=['5.0', '6.0', '7.0', '8.0'], default='6.0', help="The version of Rhino.")
158+
parser.add_argument(
159+
'-v',
160+
'--version',
161+
choices=compas_rhino.SUPPORTED_VERSIONS,
162+
default=compas_rhino.DEFAULT_VERSION,
163+
help="The version of Rhino."
164+
)
138165

139166
args = parser.parse_args()
140167

src/compas_rhino/uninstall.py

Lines changed: 58 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,7 @@ def uninstall(version=None, packages=None):
4242
python -m compas_rhino.uninstall -v 6.0
4343
4444
"""
45-
if version not in ('5.0', '6.0', '7.0', '8.0'):
46-
version = '6.0'
45+
version = compas_rhino._check_rhino_version(version)
4746

4847
# We install COMPAS packages in the scripts folder
4948
# instead of directly as IPy module.
@@ -52,6 +51,9 @@ def uninstall(version=None, packages=None):
5251
# This is for old installs
5352
ipylib_path = compas_rhino._get_ironpython_lib_path(version)
5453

54+
# Filter the provided list of packages
55+
# If no packages are provided
56+
# this first collects all installable packages from the environment.
5557
packages = _filter_installed_packages(version, packages)
5658

5759
# Also remove all broken symlinks
@@ -63,11 +65,8 @@ def uninstall(version=None, packages=None):
6365
if name not in packages:
6466
packages.append(name)
6567

66-
print('Uninstalling COMPAS packages from Rhino {0} scripts folder: \n{1}'.format(version, scripts_path))
67-
68-
results = []
68+
# Collect paths for removal based on package names
6969
symlinks_to_uninstall = []
70-
exit_code = 0
7170

7271
for package in packages:
7372
symlink_path = os.path.join(scripts_path, package)
@@ -81,55 +80,67 @@ def uninstall(version=None, packages=None):
8180
if os.path.exists(legacy_path):
8281
symlinks_to_uninstall.append(dict(name=package, link=legacy_path))
8382

83+
# There is nothing to uninstall
8484
if not symlinks_to_uninstall:
85-
print('\nNo packages to uninstall.')
85+
print('\nNo packages to uninstall from Rhino {0} scripts folder: \n{1}.'.format(version, scripts_path))
86+
return
8687

87-
else:
88-
uninstalled_packages = []
88+
# -------------------------
89+
# Start uninstalling
90+
# -------------------------
91+
92+
uninstalled_packages = []
93+
results = []
94+
exit_code = 0
8995

90-
symlinks = [link['link'] for link in symlinks_to_uninstall]
91-
uninstall_results = compas._os.remove_symlinks(symlinks)
96+
symlinks = [link['link'] for link in symlinks_to_uninstall]
97+
uninstall_results = compas._os.remove_symlinks(symlinks)
9298

93-
for uninstall_data, success in zip(symlinks_to_uninstall, uninstall_results):
94-
if success:
95-
uninstalled_packages.append(uninstall_data['name'])
96-
result = 'OK'
97-
else:
98-
result = 'ERROR: Cannot remove symlink, try to run as administrator.'
99+
for uninstall_data, success in zip(symlinks_to_uninstall, uninstall_results):
100+
if success:
101+
uninstalled_packages.append(uninstall_data['name'])
102+
result = 'OK'
103+
else:
104+
result = 'ERROR: Cannot remove symlink, try to run as administrator.'
99105

100-
results.append((uninstall_data['name'], result))
106+
results.append((uninstall_data['name'], result))
101107

102-
if not all(uninstall_results):
103-
exit_code = -1
108+
if not all(uninstall_results):
109+
exit_code = -1
104110

105-
if exit_code == -1:
106-
results.append(('compas_bootstrapper', 'WARNING: One or more packages failed, will not uninstall bootstrapper.'))
111+
if exit_code == -1:
112+
results.append(('compas_bootstrapper', 'WARNING: One or more packages failed, will not uninstall bootstrapper.'))
107113

114+
else:
115+
if compas_rhino._try_remove_bootstrapper(scripts_path):
116+
results.append(('compas_bootstrapper', 'OK'))
108117
else:
109-
if compas_rhino._try_remove_bootstrapper(scripts_path):
110-
results.append(('compas_bootstrapper', 'OK'))
111-
else:
112-
results.append(('compas_bootstrapper', 'ERROR: Cannot remove compas_bootstrapper, try to run as administrator.'))
118+
results.append(('compas_bootstrapper', 'ERROR: Cannot remove compas_bootstrapper, try to run as administrator.'))
119+
120+
# Handle legacy bootstrapper
121+
# Again, only if possible...
122+
if ipylib_path:
123+
if not compas_rhino._try_remove_bootstrapper(ipylib_path):
124+
results.append(('compas_bootstrapper', 'ERROR: Cannot remove legacy compas_bootstrapper, try to run as administrator.'))
113125

114-
# Handle legacy bootstrapper
115-
# Again, only if possible...
116-
if ipylib_path:
117-
if not compas_rhino._try_remove_bootstrapper(ipylib_path):
118-
results.append(('compas_bootstrapper', 'ERROR: Cannot remove legacy compas_bootstrapper, try to run as administrator.'))
126+
# -------------------------
127+
# Output results
128+
# -------------------------
119129

120-
print('\nThe following packages have been detected and will be uninstalled:\n')
130+
print('Uninstalling COMPAS packages from Rhino {0} scripts folder: \n{1}'.format(version, scripts_path))
131+
print('\nThe following packages have been detected and will be uninstalled:\n')
121132

122-
for package, status in results:
123-
print(' {} {}'.format(package.ljust(20), status))
133+
for package, status in results:
134+
print(' {} {}'.format(package.ljust(20), status))
124135

125-
if status != 'OK':
126-
exit_code = -1
136+
if status != 'OK':
137+
exit_code = -1
127138

128-
if exit_code == 0 and uninstalled_packages:
129-
print('\nRunning post-uninstallation steps...\n')
139+
if exit_code == 0 and uninstalled_packages:
140+
print('\nRunning post-uninstallation steps...\n')
130141

131-
if not _run_post_execution_steps(after_rhino_uninstall(uninstalled_packages)):
132-
exit_code = -1
142+
if not _run_post_execution_steps(after_rhino_uninstall(uninstalled_packages)):
143+
exit_code = -1
133144

134145
print('\nUninstall completed.')
135146

@@ -207,7 +218,13 @@ def after_rhino_uninstall(uninstalled_packages):
207218

208219
parser = argparse.ArgumentParser()
209220

210-
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.")
221+
parser.add_argument(
222+
'-v',
223+
'--version',
224+
choices=compas_rhino.SUPPORTED_VERSIONS,
225+
default=compas_rhino.DEFAULT_VERSION,
226+
help="The version of Rhino to install the packages in."
227+
)
211228
parser.add_argument('-p', '--packages', nargs='+', help="The packages to uninstall.")
212229

213230
args = parser.parse_args()

0 commit comments

Comments
 (0)