only change things on way in

This commit is contained in:
frostming
2018-03-28 16:24:08 +08:00
committed by Frost Ming
parent fc17c757de
commit 4b290407d3
3 changed files with 73 additions and 70 deletions
+1 -38
View File
@@ -290,7 +290,7 @@ def ensure_pipfile(validate=True, skip_requirements=False):
if validate and project.virtualenv_exists and not PIPENV_SKIP_VALIDATION:
# Ensure that Pipfile is using proper casing.
p = project.parsed_pipfile
changed = ensure_proper_casing(pfile=p)
changed = project.ensure_proper_casing()
# Write changes out to disk.
if changed:
click.echo(
@@ -298,7 +298,6 @@ def ensure_pipfile(validate=True, skip_requirements=False):
err=True,
)
project.write_toml(p)
project.clear_pipfile_cache()
def find_python_from_py(python):
@@ -635,42 +634,6 @@ def ensure_project(
ensure_pipfile(validate=validate, skip_requirements=skip_requirements)
def ensure_proper_casing(pfile):
"""Ensures proper casing of Pipfile packages, writes changes to disk."""
casing_changed = proper_case_section(pfile.get('packages', {}))
casing_changed |= proper_case_section(pfile.get('dev-packages', {}))
return casing_changed
def proper_case_section(section):
"""Verify proper casing is retrieved, when available, for each
dependency in the section.
"""
# Casing for section.
changed_values = False
unknown_names = [
k for k in section.keys() if k not in set(project.proper_names)
]
# Replace each package with proper casing.
for dep in unknown_names:
try:
# Get new casing for package name.
new_casing = proper_case(dep)
except IOError:
# Unable to normalize package name.
continue
if new_casing != dep:
changed_values = True
project.register_proper_name(new_casing)
# Replace old value with new value.
old_value = section[dep]
section[new_casing] = old_value
del section[dep]
# Return whether or not values have been changed.
return changed_values
def shorten_path(location, bold=False):
"""Returns a visually shorter representation of a given system path."""
original = location
+57 -25
View File
@@ -3,7 +3,6 @@ import codecs
import json
import os
import re
import six
import sys
import shlex
import base64
@@ -21,7 +20,7 @@ from .utils import (
mkdir_p,
convert_deps_from_pip,
pep423_name,
recase_file,
proper_case,
find_requirements,
is_editable,
is_file,
@@ -370,20 +369,6 @@ class Project(object):
except Exception:
return toml.loads(contents)
@property
def _pipfile(self):
"""Pipfile divided by PyPI and external dependencies."""
pfile = self.parsed_pipfile
# mutation time!
self.clear_pipfile_cache()
for section in ('packages', 'dev-packages'):
p_section = pfile.get(section, {})
for key in list(p_section.keys()):
# Normalize key name to PEP 423.
norm_key = pep423_name(key)
p_section[norm_key] = p_section.pop(key)
return pfile
@property
def settings(self):
"""A dictionary of the settings added to the Pipfile."""
@@ -416,7 +401,6 @@ class Project(object):
p['pipenv'] = settings
# Write the changes to disk.
self.write_toml(p)
self.clear_pipfile_cache()
@property
def _lockfile(self):
@@ -572,6 +556,8 @@ class Project(object):
formatted_data = cleanup_toml(formatted_data)
with open(path, 'w') as f:
f.write(formatted_data)
# pipfile is mutated!
self.clear_pipfile_cache()
@property
def sources(self):
@@ -607,17 +593,19 @@ class Project(object):
def remove_package_from_pipfile(self, package_name, dev=False):
# Read and append Pipfile.
p = self._pipfile
p = self.parsed_pipfile
package_name = pep423_name(package_name)
key = 'dev-packages' if dev else 'packages'
if key in p and package_name in p[key]:
del p[key][package_name]
# Write Pipfile.
self.write_toml(recase_file(p))
if key in p:
for name in dict(p[key]):
if pep423_name(name) == package_name:
del p[key][name]
# Write Pipfile.
return self.write_toml(p)
def add_package_to_pipfile(self, package_name, dev=False):
# Read and append Pipfile.
p = self._pipfile
p = self.parsed_pipfile
# Don't re-capitalize file URLs or VCSs.
converted = convert_deps_from_pip(package_name)
converted = converted[[k for k in converted.keys()][0]]
@@ -631,6 +619,14 @@ class Project(object):
p[key] = {}
package = convert_deps_from_pip(package_name)
package_name = [k for k in package.keys()][0]
for name in p[key]:
# Normalize names to compare
if (
pep423_name(name) == pep423_name(package_name) and
name != package_name
):
# Replace the package name
del p[key][name]
# Add the package to the group.
p[key][package_name] = package[package_name]
# Write Pipfile.
@@ -639,7 +635,7 @@ class Project(object):
def add_index_to_pipfile(self, index):
"""Adds a given index to the Pipfile."""
# Read and append Pipfile.
p = self._pipfile
p = self.parsed_pipfile
source = {'url': index, 'verify_ssl': True}
# Add the package to the group.
if 'source' not in p:
@@ -650,7 +646,8 @@ class Project(object):
self.write_toml(p)
def recase_pipfile(self):
self.write_toml(recase_file(self._pipfile))
if self.ensure_proper_casing():
self.write_toml(self.parsed_pipfile)
def get_lockfile_hash(self):
if not os.path.exists(self.lockfile_location):
@@ -664,3 +661,38 @@ class Project(object):
# Update the lockfile if it is out-of-date.
p = pipfile.load(self.pipfile_location, inject_env=False)
return p.hash
def ensure_proper_casing(self):
"""Ensures proper casing of Pipfile packages"""
pfile = self.parsed_pipfile
casing_changed = self.proper_case_section(pfile.get('packages', {}))
casing_changed |= self.proper_case_section(pfile.get('dev-packages', {}))
return casing_changed
def proper_case_section(self, section):
"""Verify proper casing is retrieved, when available, for each
dependency in the section.
"""
# Casing for section.
changed_values = False
unknown_names = [
k for k in section.keys() if k not in set(self.proper_names)
]
# Replace each package with proper casing.
for dep in unknown_names:
try:
# Get new casing for package name.
new_casing = proper_case(dep)
except IOError:
# Unable to normalize package name.
continue
if new_casing != dep:
changed_values = True
self.register_proper_name(new_casing)
# Replace old value with new value.
old_value = section[dep]
section[new_casing] = old_value
del section[dep]
# Return whether or not values have been changed.
return changed_values
+15 -7
View File
@@ -598,17 +598,20 @@ tpfd = "*"
contents = """
# Pre comment
[packages]
python_dateutil = "*" # Inline comment
python_DateUtil = "*" # Inline comment
"""
f.write(contents)
c = p.pipenv('install')
assert c.return_code == 0
c = p.pipenv('install python-dateutil')
c = p.pipenv('install requests')
assert c.return_code == 0
assert 'python_DateUtil' in p.pipfile['packages']
c = p.pipenv('install python_dateutil')
assert c.return_code == 0
assert 'python-dateutil' in p.pipfile['packages']
assert 'python_dateutil' not in p.pipfile['packages']
assert 'python_DateUtil' not in p.pipfile['packages']
contents = open(p.pipfile_path).read()
assert '# Pre comment' in contents
assert '# Inline comment' in contents
@@ -619,17 +622,22 @@ python_dateutil = "*" # Inline comment
with PipenvInstance(pypi=pypi) as p:
with open(p.pipfile_path, 'w') as f:
contents = """
# Pre comment
[packages]
python_dateutil = "*"
Requests = "*"
python_DateUtil = "*" # Inline comment
"""
f.write(contents)
c = p.pipenv('install')
assert c.return_code == 0
c = p.pipenv('uninstall python-dateutil')
assert 'python_dateutil' not in p.pipfile['packages']
assert 'python-dateutil' not in p.lockfile['default']
c = p.pipenv('uninstall python_dateutil')
assert 'Requests' in p.pipfile['packages']
assert 'python_DateUtil' not in p.pipfile['packages']
contents = open(p.pipfile_path).read()
assert '# Pre comment' in contents
assert '# Inline comment' in contents
@pytest.mark.install
@pytest.mark.resolver