Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into pr-3880
Browse files Browse the repository at this point in the history
  • Loading branch information
kalefranz committed Nov 21, 2016
2 parents 50324b6 + 6730a6c commit addf02b
Show file tree
Hide file tree
Showing 14 changed files with 266 additions and 308 deletions.
16 changes: 12 additions & 4 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,18 @@ matrix:
- os: osx
env: PYTHON_VERSION=3.5
language: generic
# - python: '3.5'
# env: CONDA_BUILD=2.0.6
# os: linux
# language: python
- python: '3.5'
env: CONDA_BUILD=1.21.14
os: linux
language: python
- python: '3.5'
env: CONDA_BUILD=2.0.1
os: linux
language: python
- python: '3.5'
env: CONDA_BUILD=2.0.10
os: linux
language: python

install:
- source ./utils/travis-install.sh
Expand Down
132 changes: 1 addition & 131 deletions conda/cli/main_clean.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
from ..base.context import context
from ..exceptions import ArgumentError
from ..gateways.disk.delete import rm_rf
from ..lock import LOCK_EXTENSION
from ..utils import human_bytes
from ..common.compat import CrossPlatformStLink

descr = """
Remove unused packages and caches.
Expand Down Expand Up @@ -72,129 +72,6 @@ def configure_parser(sub_parsers):
p.set_defaults(func=execute)


# work-around for python bug on Windows prior to python 3.2
# https://bugs.python.org/issue10027
# Adapted from the ntfsutils package, Copyright (c) 2012, the Mozilla Foundation
class CrossPlatformStLink(object):
_st_nlink = None

def __call__(self, path):
return self.st_nlink(path)

@classmethod
def st_nlink(cls, path):
if cls._st_nlink is None:
cls._initialize()
return cls._st_nlink(path)

@classmethod
def _standard_st_nlink(cls, path):
return lstat(path).st_nlink

@classmethod
def _windows_st_nlink(cls, path):
st_nlink = cls._standard_st_nlink(path)
if st_nlink != 0:
return st_nlink
else:
# cannot trust python on Windows when st_nlink == 0
# get value using windows libraries to be sure of its true value
# Adapted from the ntfsutils package, Copyright (c) 2012, the Mozilla Foundation
GENERIC_READ = 0x80000000
FILE_SHARE_READ = 0x00000001
OPEN_EXISTING = 3
hfile = cls.CreateFile(path, GENERIC_READ, FILE_SHARE_READ, None,
OPEN_EXISTING, 0, None)
if hfile is None:
from ctypes import WinError
raise WinError()
info = cls.BY_HANDLE_FILE_INFORMATION()
rv = cls.GetFileInformationByHandle(hfile, info)
cls.CloseHandle(hfile)
if rv == 0:
from ctypes import WinError
raise WinError()
return info.nNumberOfLinks

@classmethod
def _initialize(cls):
if os.name != 'nt':
cls._st_nlink = cls._standard_st_nlink
else:
# http://msdn.microsoft.com/en-us/library/windows/desktop/aa363858
import ctypes
from ctypes import POINTER
from ctypes.wintypes import DWORD, HANDLE, BOOL

cls.CreateFile = ctypes.windll.kernel32.CreateFileW
cls.CreateFile.argtypes = [ctypes.c_wchar_p, DWORD, DWORD, ctypes.c_void_p,
DWORD, DWORD, HANDLE]
cls.CreateFile.restype = HANDLE

# http://msdn.microsoft.com/en-us/library/windows/desktop/ms724211
cls.CloseHandle = ctypes.windll.kernel32.CloseHandle
cls.CloseHandle.argtypes = [HANDLE]
cls.CloseHandle.restype = BOOL

class FILETIME(ctypes.Structure):
_fields_ = [("dwLowDateTime", DWORD),
("dwHighDateTime", DWORD)]

class BY_HANDLE_FILE_INFORMATION(ctypes.Structure):
_fields_ = [("dwFileAttributes", DWORD),
("ftCreationTime", FILETIME),
("ftLastAccessTime", FILETIME),
("ftLastWriteTime", FILETIME),
("dwVolumeSerialNumber", DWORD),
("nFileSizeHigh", DWORD),
("nFileSizeLow", DWORD),
("nNumberOfLinks", DWORD),
("nFileIndexHigh", DWORD),
("nFileIndexLow", DWORD)]
cls.BY_HANDLE_FILE_INFORMATION = BY_HANDLE_FILE_INFORMATION

# http://msdn.microsoft.com/en-us/library/windows/desktop/aa364952
cls.GetFileInformationByHandle = ctypes.windll.kernel32.GetFileInformationByHandle
cls.GetFileInformationByHandle.argtypes = [HANDLE, POINTER(BY_HANDLE_FILE_INFORMATION)]
cls.GetFileInformationByHandle.restype = BOOL

cls._st_nlink = cls._windows_st_nlink


def find_lock(file_ending=LOCK_EXTENSION, extra_path=None):
from os.path import join
lock_dirs = context.pkgs_dirs[:]
lock_dirs += [context.root_dir]
for envs_dir in context.envs_dirs:
if os.path.exists(envs_dir):
for fn in os.listdir(envs_dir):
if os.path.isdir(join(envs_dir, fn)):
lock_dirs.append(join(envs_dir, fn))

try:
from conda_build.config import croot
lock_dirs.append(croot)
except ImportError:
pass

lock_dirs = lock_dirs + list(extra_path) if extra_path else lock_dirs
for dir in lock_dirs:
if not os.path.exists(dir):
continue
for dn in os.listdir(dir):
if os.path.exists(join(dir, dn)) and dn.endswith(file_ending):
path = join(dir, dn)
yield path


def rm_lock(locks, verbose=True):
from ..install import rm_rf
for path in locks:
if verbose:
print('removing: %s' % path)
rm_rf(path)


def find_tarballs():
pkgs_dirs = defaultdict(list)
for pkgs_dir in context.pkgs_dirs:
Expand Down Expand Up @@ -406,13 +283,6 @@ def execute(args, parser):
'success': True
}

if args.lock or args.all:
locks = list(find_lock())
json_result['lock'] = {
'files': locks
}
rm_lock(locks, verbose=not context.json)

if args.tarballs or args.all:
pkgs_dirs, totalsize = find_tarballs()
first = sorted(pkgs_dirs)[0] if pkgs_dirs else ''
Expand Down
3 changes: 2 additions & 1 deletion conda/cli/main_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from .common import (add_parser_help, add_parser_json, add_parser_prefix,
add_parser_show_channel_urls, disp_features, stdout_json)
from ..base.context import context
from ..common.compat import text_type
from ..egg_info import get_egg_info
from ..exceptions import CondaEnvironmentNotFoundError, CondaFileNotFoundError

Expand Down Expand Up @@ -171,7 +172,7 @@ def print_packages(prefix, regex=None, format='human', piplist=False,
exitcode, output = list_packages(prefix, installed, regex, format=format,
show_channel_urls=show_channel_urls)
if not json:
print('\n'.join(output))
print('\n'.join(map(text_type, output)))
else:
stdout_json(output)
return exitcode
Expand Down
92 changes: 92 additions & 0 deletions conda/common/compat.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import, division, print_function, unicode_literals

from os import lstat
import os
from logging import getLogger

from .._vendor.auxlib.compat import (iteritems, with_metaclass, itervalues, # NOQA
string_types, primitive_types, text_type, odict, # NOQA
StringIO, isiterable) # NOQA

from ..compat import * # NOQA

log = getLogger(__name__)
Expand All @@ -17,3 +20,92 @@ def ensure_binary(value):

def ensure_text_type(value):
return value.decode('utf-8') if hasattr(value, 'decode') else value


# work-around for python bug on Windows prior to python 3.2
# https://bugs.python.org/issue10027
# Adapted from the ntfsutils package, Copyright (c) 2012, the Mozilla Foundation
class CrossPlatformStLink(object):
_st_nlink = None

def __call__(self, path):
return self.st_nlink(path)

@classmethod
def st_nlink(cls, path):
if cls._st_nlink is None:
cls._initialize()
return cls._st_nlink(path)

@classmethod
def _standard_st_nlink(cls, path):
return lstat(path).st_nlink

@classmethod
def _windows_st_nlink(cls, path):
st_nlink = cls._standard_st_nlink(path)
if st_nlink != 0:
return st_nlink
else:
# cannot trust python on Windows when st_nlink == 0
# get value using windows libraries to be sure of its true value
# Adapted from the ntfsutils package, Copyright (c) 2012, the Mozilla Foundation
GENERIC_READ = 0x80000000
FILE_SHARE_READ = 0x00000001
OPEN_EXISTING = 3
hfile = cls.CreateFile(path, GENERIC_READ, FILE_SHARE_READ, None,
OPEN_EXISTING, 0, None)
if hfile is None:
from ctypes import WinError
raise WinError()
info = cls.BY_HANDLE_FILE_INFORMATION()
rv = cls.GetFileInformationByHandle(hfile, info)
cls.CloseHandle(hfile)
if rv == 0:
from ctypes import WinError
raise WinError()
return info.nNumberOfLinks

@classmethod
def _initialize(cls):
if os.name != 'nt':
cls._st_nlink = cls._standard_st_nlink
else:
# http://msdn.microsoft.com/en-us/library/windows/desktop/aa363858
import ctypes
from ctypes import POINTER
from ctypes.wintypes import DWORD, HANDLE, BOOL

cls.CreateFile = ctypes.windll.kernel32.CreateFileW
cls.CreateFile.argtypes = [ctypes.c_wchar_p, DWORD, DWORD, ctypes.c_void_p,
DWORD, DWORD, HANDLE]
cls.CreateFile.restype = HANDLE

# http://msdn.microsoft.com/en-us/library/windows/desktop/ms724211
cls.CloseHandle = ctypes.windll.kernel32.CloseHandle
cls.CloseHandle.argtypes = [HANDLE]
cls.CloseHandle.restype = BOOL

class FILETIME(ctypes.Structure):
_fields_ = [("dwLowDateTime", DWORD),
("dwHighDateTime", DWORD)]

class BY_HANDLE_FILE_INFORMATION(ctypes.Structure):
_fields_ = [("dwFileAttributes", DWORD),
("ftCreationTime", FILETIME),
("ftLastAccessTime", FILETIME),
("ftLastWriteTime", FILETIME),
("dwVolumeSerialNumber", DWORD),
("nFileSizeHigh", DWORD),
("nFileSizeLow", DWORD),
("nNumberOfLinks", DWORD),
("nFileIndexHigh", DWORD),
("nFileIndexLow", DWORD)]
cls.BY_HANDLE_FILE_INFORMATION = BY_HANDLE_FILE_INFORMATION

# http://msdn.microsoft.com/en-us/library/windows/desktop/aa364952
cls.GetFileInformationByHandle = ctypes.windll.kernel32.GetFileInformationByHandle
cls.GetFileInformationByHandle.argtypes = [HANDLE, POINTER(BY_HANDLE_FILE_INFORMATION)]
cls.GetFileInformationByHandle.restype = BOOL

cls._st_nlink = cls._windows_st_nlink
9 changes: 3 additions & 6 deletions conda/core/index.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
from functools import wraps
from logging import DEBUG, getLogger
from os import makedirs
from os.path import dirname, join
from requests.exceptions import ConnectionError, HTTPError, SSLError
from requests.packages.urllib3.exceptions import InsecureRequestWarning
from os.path import join

from .linked_data import linked_data
from .package_cache import package_cache
Expand All @@ -20,10 +20,9 @@
from ..base.constants import CONDA_HOMEPAGE_URL, DEFAULTS, MAX_CHANNEL_PRIORITY
from ..base.context import context
from ..common.compat import iteritems, itervalues
from ..common.url import join_url, url_to_path
from ..common.url import join_url
from ..connection import CondaSession
from ..exceptions import CondaHTTPError, CondaRuntimeError
from ..lock import FileLock
from ..models.channel import Channel, offline_keep, prioritize_channels
from ..models.dist import Dist
from ..models.record import EMPTY_LINK, Record
Expand Down Expand Up @@ -146,9 +145,7 @@ def get_json_str(filename, resp_content):
return resp_content.decode('utf-8')

if url.startswith('file://'):
file_path = url_to_path(url)
with FileLock(dirname(file_path)):
json_str = get_json_str(filename, resp.content)
json_str = get_json_str(filename, resp.content)
else:
json_str = get_json_str(filename, resp.content)

Expand Down
Loading

0 comments on commit addf02b

Please sign in to comment.