Skip to content

Commit 076f253

Browse files
authored
Merge pull request #267 from compas-dev/installer-fixes
Make installer a bit more resilient
2 parents e630022 + d27f07c commit 076f253

File tree

3 files changed

+37
-15
lines changed

3 files changed

+37
-15
lines changed

src/compas/_os.py

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
"""
66
import os
77
import sys
8+
import subprocess
89

910
PY3 = sys.version_info[0] == 3
1011
system = sys.platform
@@ -66,6 +67,18 @@ def absjoin(*parts):
6667
return os.path.abspath(os.path.join(*parts))
6768

6869

70+
# Cache whatever symlink function works (native or polyfill)
71+
_os_symlink = None
72+
73+
74+
def create_symlink_polyfill():
75+
def symlink_ms(source, link_name):
76+
subprocess.check_output(
77+
['mklink', '/D', link_name, source], stderr=subprocess.STDOUT, shell=True)
78+
79+
return symlink_ms
80+
81+
6982
def create_symlink(source, link_name):
7083
"""Create a symbolic link pointing to source named link_name.
7184
@@ -77,18 +90,26 @@ def create_symlink(source, link_name):
7790
This function is a polyfill of the native ``os.symlink``
7891
for Python 2.x on Windows platforms.
7992
"""
80-
os_symlink = getattr(os, 'symlink', None)
93+
global _os_symlink
94+
enable_retry_with_polyfill = False
8195

82-
if not callable(os_symlink) and os.name == 'nt':
83-
import subprocess
96+
if not _os_symlink:
97+
_os_symlink = getattr(os, 'symlink', None)
8498

85-
def symlink_ms(source, link_name):
86-
subprocess.check_output(
87-
['mklink', '/D', link_name, source], stderr=subprocess.STDOUT, shell=True)
99+
if os.name == 'nt':
100+
if not callable(_os_symlink):
101+
_os_symlink = create_symlink_polyfill()
102+
else:
103+
enable_retry_with_polyfill = True
88104

89-
os_symlink = symlink_ms
105+
try:
106+
_os_symlink(source, link_name)
107+
except OSError:
108+
if not enable_retry_with_polyfill:
109+
raise
90110

91-
os_symlink(source, link_name)
111+
_os_symlink = create_symlink_polyfill()
112+
_os_symlink(source, link_name)
92113

93114

94115
def remove_symlink(link):

src/compas_rhino/install.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,11 @@ def _get_package_path(package):
3030
def _get_bootstrapper_data(compas_bootstrapper):
3131
data = {}
3232

33-
try:
34-
content = io.open(compas_bootstrapper, encoding='utf8').read()
35-
exec(content, data)
36-
except FileNotFoundError:
37-
pass
33+
if not os.path.exists(compas_bootstrapper):
34+
return data
35+
36+
content = io.open(compas_bootstrapper, encoding='utf8').read()
37+
exec(content, data)
3838

3939
return data
4040

@@ -83,7 +83,8 @@ def install(version=None, packages=None):
8383
package_path = _get_package_path(importlib.import_module(package))
8484
symlink_path = os.path.join(ipylib_path, package)
8585

86-
if os.path.exists(symlink_path):
86+
# Broken links return False on .exists(), so we need to check .islink() as well
87+
if os.path.islink(symlink_path) or os.path.exists(symlink_path):
8788
try:
8889
remove_symlink(symlink_path)
8990
except OSError:

src/compas_rhino/uninstall.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ def uninstall(version=None, packages=None):
7272
for package in packages:
7373
symlink_path = os.path.join(ipylib_path, package)
7474

75-
if not os.path.exists(symlink_path):
75+
if not (os.path.exists(symlink_path) or os.path.islink(symlink_path)):
7676
continue
7777

7878
try:

0 commit comments

Comments
 (0)