forked from iterative/dvc
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Windows symlink: extract all system depended code to System static class
- Loading branch information
Showing
16 changed files
with
147 additions
and
137 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +0,0 @@ | ||
from dvc.runtime import Runtime | ||
|
||
|
||
def setup(): | ||
Runtime.symlink_setup() | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
import ctypes | ||
import os | ||
import re | ||
|
||
if os.name == 'nt': | ||
from ctypes import create_unicode_buffer, windll | ||
|
||
from dvc.executor import Executor | ||
|
||
|
||
class System(object): | ||
SYMLINK_OUTPUT = '<SYMLINK>' | ||
LONG_PATH_BUFFER_SIZE = 1024 | ||
|
||
@staticmethod | ||
def is_unix(): | ||
return os.name != 'nt' | ||
|
||
@staticmethod | ||
def symlink(source, link_name): | ||
if System.is_unix(): | ||
return os.symlink(source, link_name) | ||
|
||
flags = 0 | ||
if source is not None and os.path.isdir(source): | ||
flags = 1 | ||
|
||
func = ctypes.windll.kernel32.CreateSymbolicLinkW | ||
func.argtypes = (ctypes.c_wchar_p, ctypes.c_wchar_p, ctypes.c_uint32) | ||
func.restype = ctypes.c_ubyte | ||
|
||
if func(link_name, source, flags) == 0: | ||
raise ctypes.WinError() | ||
|
||
@staticmethod | ||
def islink(path): | ||
# It is definitely not the best way to check a symlink. | ||
|
||
if System.is_unix(): | ||
return os.path.islink(path) | ||
|
||
if not os.path.exists(path): | ||
return False | ||
|
||
if not os.path.isfile(path): | ||
return False | ||
|
||
return System._get_symlink_string() is not None | ||
|
||
@staticmethod | ||
def _get_symlink_string(path): | ||
code, output, _ = Executor.exec_cmd(["dir", path], shell=True) | ||
if code != 0: | ||
return False | ||
|
||
lines = output.split('\n') | ||
for line in lines: | ||
if System.SYMLINK_OUTPUT in line: | ||
return line | ||
return None | ||
|
||
@staticmethod | ||
def realpath(path): | ||
# It is definitely not the best way to check a symlink. | ||
|
||
if System.is_unix(): | ||
return os.path.realpath(path) | ||
|
||
output = System._get_symlink_string(path) | ||
if output is None: | ||
return os.path.realpath(path) | ||
|
||
groups = re.compile(r'\[\S+\]$').findall(output.strip()) | ||
if len(groups) < 1: | ||
return os.path.realpath(path) | ||
|
||
resolved_link = groups[0][1:-1] | ||
return resolved_link | ||
|
||
@staticmethod | ||
def ls_command_name(): | ||
if System.is_unix(): | ||
return 'ls' | ||
return 'dir' | ||
|
||
@staticmethod | ||
def get_long_path(path): | ||
"""Convert short path to a full path. It is needed for Windows.""" | ||
if System.is_unix(): | ||
return path | ||
|
||
buffer = create_unicode_buffer(System.LONG_PATH_BUFFER_SIZE) | ||
get_long_path_name = windll.kernel32.GetLongPathNameW | ||
result = get_long_path_name(unicode(path), buffer, System.LONG_PATH_BUFFER_SIZE) | ||
if result == 0 or result > System.LONG_PATH_BUFFER_SIZE: | ||
return path | ||
return buffer.value | ||
|
||
@staticmethod | ||
def get_cwd(): | ||
return System.get_long_path(os.getcwd()) |
Oops, something went wrong.