Skip to content

Commit

Permalink
Truncate or warn about long virtualenv paths (#12)
Browse files Browse the repository at this point in the history
  • Loading branch information
Jon Wayne Parrott authored Dec 15, 2016
1 parent 8c7193b commit b9a6af0
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 17 deletions.
8 changes: 4 additions & 4 deletions appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,11 @@ install:
# target Python version and architecture
- "pip install wheel"

init:
- ps: iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
# init:
# - ps: iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))

on_finish:
- ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
# on_finish:
# - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))

build_script:
- "pip install ."
Expand Down
28 changes: 21 additions & 7 deletions nox/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.

import hashlib
import os
import re
import unicodedata
Expand All @@ -24,17 +25,31 @@
import six


def _normalize_path(path):
"""Normalizes a string to be a "safe" filesystem path."""
def _normalize_path(envdir, path):
"""Normalizes a string to be a "safe" filesystem path for a virtualenv."""
if isinstance(path, six.binary_type):
path = path.decode('utf-8')

path = unicodedata.normalize('NFKD', path).encode('ascii', 'ignore')
path = path.decode('ascii')
path = re.sub('[^\w\s-]', '-', path).strip().lower()
path = re.sub('[-\s]+', '-', path)
path = path.strip('-')[:255]
return path
path = path.strip('-')

full_path = os.path.join(envdir, path)
if len(full_path) > 128 - len('bin/pythonX.Y'):
if len(envdir) < 128 - 9:
path = hashlib.sha1(path.encode('ascii')).hexdigest()[:8]
full_path = os.path.join(envdir, path)
logger.warning(
'The virtualenv name was hashed to avoid being too long.')
else:
logger.error(
'The virtualenv path {} is too long and will cause issues on '
'some environments. Use the --envdir path to modify where '
'nox stores virtualenvs.'.format(full_path))

return full_path


class _SessionQuit(Exception):
Expand Down Expand Up @@ -175,9 +190,8 @@ def _create_venv(self):
return

self.venv = VirtualEnv(
os.path.join(
self.global_config.envdir,
_normalize_path(self.signature or self.name)),
_normalize_path(
self.global_config.envdir, self.signature or self.name),
interpreter=self.config.interpreter,
reuse_existing=(
self.config.reuse_existing_virtualenv or
Expand Down
29 changes: 23 additions & 6 deletions tests/test_session.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,31 @@


def test__normalize_path():
assert nox.session._normalize_path(u'hello') == 'hello'
assert nox.session._normalize_path(b'hello') == 'hello'
assert nox.session._normalize_path('hello(world)') == 'hello-world'
envdir = 'envdir'
assert nox.session._normalize_path(envdir, u'hello') == 'envdir/hello'
assert nox.session._normalize_path(envdir, b'hello') == 'envdir/hello'
assert nox.session._normalize_path(
'hello(world, meep)') == 'hello-world-meep'
envdir, 'hello(world)') == 'envdir/hello-world'
assert nox.session._normalize_path(
'tests(interpreter="python2.7", django="1.10")') == (
'tests-interpreter-python2-7-django-1-10')
envdir, 'hello(world, meep)') == 'envdir/hello-world-meep'
assert nox.session._normalize_path(
envdir, 'tests(interpreter="python2.7", django="1.10")') == (
'envdir/tests-interpreter-python2-7-django-1-10')


def test__normalize_path_hash():
envdir = 'd' * (128 - len('bin/pythonX.Y') - 10)
norm_path = nox.session._normalize_path(
envdir, 'a-really-long-virtualenv-path')
assert 'a-really-long-virtualenv-path' not in norm_path
assert len(norm_path) < 128


def test__normalize_path_give_up():
envdir = 'd' * 128
norm_path = nox.session._normalize_path(
envdir, 'any-path')
assert 'any-path' in norm_path


@pytest.fixture
Expand Down

0 comments on commit b9a6af0

Please sign in to comment.