|
12 | 12 | # See the License for the specific language governing permissions and |
13 | 13 | # limitations under the License. |
14 | 14 |
|
| 15 | +import hashlib |
15 | 16 | import os |
16 | 17 | import re |
17 | 18 | import unicodedata |
|
24 | 25 | import six |
25 | 26 |
|
26 | 27 |
|
27 | | -def _normalize_path(path): |
28 | | - """Normalizes a string to be a "safe" filesystem path.""" |
| 28 | +def _normalize_path(envdir, path): |
| 29 | + """Normalizes a string to be a "safe" filesystem path for a virtualenv.""" |
29 | 30 | if isinstance(path, six.binary_type): |
30 | 31 | path = path.decode('utf-8') |
31 | 32 |
|
32 | 33 | path = unicodedata.normalize('NFKD', path).encode('ascii', 'ignore') |
33 | 34 | path = path.decode('ascii') |
34 | 35 | path = re.sub('[^\w\s-]', '-', path).strip().lower() |
35 | 36 | path = re.sub('[-\s]+', '-', path) |
36 | | - path = path.strip('-')[:255] |
37 | | - return path |
| 37 | + path = path.strip('-') |
| 38 | + |
| 39 | + full_path = os.path.join(envdir, path) |
| 40 | + if len(full_path) > 128 - len('bin/pythonX.Y'): |
| 41 | + if len(envdir) < 128 - 9: |
| 42 | + path = hashlib.sha1(path.encode('ascii')).hexdigest()[:8] |
| 43 | + full_path = os.path.join(envdir, path) |
| 44 | + logger.warning( |
| 45 | + 'The virtualenv name was hashed to avoid being too long.') |
| 46 | + else: |
| 47 | + logger.error( |
| 48 | + 'The virtualenv path {} is too long and will cause issues on ' |
| 49 | + 'some environments. Use the --envdir path to modify where ' |
| 50 | + 'nox stores virtualenvs.'.format(full_path)) |
| 51 | + |
| 52 | + return full_path |
38 | 53 |
|
39 | 54 |
|
40 | 55 | class _SessionQuit(Exception): |
@@ -175,9 +190,8 @@ def _create_venv(self): |
175 | 190 | return |
176 | 191 |
|
177 | 192 | self.venv = VirtualEnv( |
178 | | - os.path.join( |
179 | | - self.global_config.envdir, |
180 | | - _normalize_path(self.signature or self.name)), |
| 193 | + _normalize_path( |
| 194 | + self.global_config.envdir, self.signature or self.name), |
181 | 195 | interpreter=self.config.interpreter, |
182 | 196 | reuse_existing=( |
183 | 197 | self.config.reuse_existing_virtualenv or |
|
0 commit comments