Permalink
Browse files

Refactor symlink code (#77)

* Patch: Refactor symlink code into a standalone utility. This makes it reusable by other tools which needs to make
  symlinks.
  • Loading branch information...
mortenvp committed Dec 30, 2017
1 parent 7ef2e39 commit e6cd2f4ac6e15671f8005f32abe1975f081ef484
View
@@ -6,6 +6,9 @@ of every change, see the Git log.
Latest
------
* Patch: Refactor symlink code into a standalone utility. This makes it reusable by other tools which needs to make
symlinks.
* Patch: Update to newest pytest-testdirectory plugin
* Minor: Adding override attribute.
* Minor: Added post_resolve.
* Minor: Use a version of python-archive which perseveres file permissions.
@@ -2,7 +2,8 @@
# encoding: utf-8
import os
import sys
from .symlink import create_symlink
class CreateSymlinkResolver(object):
@@ -48,37 +49,14 @@ def resolve(self):
self.dependency.real_path = os.path.realpath(path)
return link_path
# os.symlink() is not available in Python 2.7 on Windows.
# We use the original function if it is available, otherwise we
# create a helper function for Windows
os_symlink = getattr(os, "symlink", None)
if not callable(os_symlink) and sys.platform == 'win32':
def symlink_windows(target, link_path):
# mklink is used to create an NTFS junction, i.e. symlink
cmd = 'mklink /J "{}" "{}"'.format(
link_path.replace('/', '\\'), target.replace('/', '\\'))
self.ctx.cmd_and_log(cmd)
os_symlink = symlink_windows
try:
self.ctx.to_log('wurf: CreateSymlinkResolver {} -> {}'.format(
link_path, path))
# We need to remove the symlink if it already exists,
# since it may point to an incorrect folder
if os.path.lexists(link_path):
if sys.platform == 'win32':
# On Windows, the symlink is not considered a link, but
# a directory, so it is removed with rmdir. The contents
# of the original folder will not be removed.
os.rmdir(link_path)
else:
# On Unix, we remove the symlink with unlink
os.unlink(link_path)
os_symlink(path, link_path)
# We set overwrite True since We need to remove the symlink if it
# already exists since it may point to an incorrect folder
create_symlink(from_path=path, to_path=link_path, overwrite=True)
except Exception:
View
@@ -0,0 +1,67 @@
#! /usr/bin/env python
# encoding: utf-8
import os
import sys
import subprocess
from .compat import IS_PY2
def create_symlink(from_path, to_path, overwrite=False):
""" Creates a symlink.
:param from_path: The path to the directory or file we want to create a
symlink to.
:param to_path: The path where the symbolic link should be created.
:param overwrite: If overwrite is True we first remove the path where the
symbolic link should be created.
"""
if overwrite and os.path.lexists(path=to_path):
_remove_symlink(path=to_path)
if IS_PY2 and sys.platform == 'win32':
_py2_win32_create_symlink(from_path=from_path, to_path=to_path)
elif IS_PY2:
_py2_unix_create_symlink(from_path=from_path, to_path=to_path)
else:
_py3_create_symlink(from_path=from_path, to_path=to_path)
def _remove_symlink(path):
if sys.platform == 'win32' and os.path.isdir(path):
# On Windows, the symlink is not considered a link, but
# a directory, so it is removed with rmdir. The contents
# of the original folder will not be removed.
os.rmdir(path)
else:
# On Unix, we remove the symlink with unlink
os.unlink(path)
def _py2_win32_create_symlink(from_path, to_path):
# os.symlink() is not available in Python 2.7 on Windows.
# We use the original function if it is available, otherwise we
# create a helper function for Windows
# mklink is used to create an NTFS junction, i.e. symlink
# https://stackoverflow.com/a/22225651/1717320
cmd = ['mklink']
if os.path.isdir(from_path):
cmd += ['/J']
cmd += ['"{}"'.format(to_path.replace('/', '\\')),
'"{}"'.format(from_path.replace('/', '\\'))]
subprocess.call(' '.join(cmd), shell=True)
def _py2_unix_create_symlink(from_path, to_path):
os.symlink(from_path, to_path)
def _py3_create_symlink(from_path, to_path):
os.symlink(src=from_path, dst=to_path)
Oops, something went wrong.

0 comments on commit e6cd2f4

Please sign in to comment.