Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 24 additions & 2 deletions hashin.py
Original file line number Diff line number Diff line change
Expand Up @@ -388,17 +388,39 @@ def amend_requirements_content(requirements, all_new_lines):
padding = " " * 4

def is_different_lines(old_lines, new_lines, indent):
# This regex is used to only temporarily normalize the names of packages
# in the lines being compared. This results in "old" names matching
# "new" names so that hashin correctly replaces them when it looks for
# them.
match_delims = re.compile(r"[-_]")

# This assumes that the package is already mentioned in the old
# requirements. Now we just need to double-check that its lines are
# different.
# The 'new_lines` is what we might intend to replace it with.
old = set([l.strip(" \\") for l in old_lines])
old = set([match_delims.sub("-", line.strip(" \\")) for line in old_lines])
new = set([indent + x.strip(" \\") for x in new_lines])
return old != new

for package, old_name, new_text in all_new_lines:
# The call to `escape` will turn hyphens into escaped hyphens
#
# ex.
# - becomes \\-
#
escaped = re.escape(old_name)

# This changes those escaped hypens into a pattern to match
#
# ex.
# \\- becomes [-_]
#
# This is necessary so that hashin will correctly find underscored (old)
# and hyphenated (new) package names so that it will correctly replace an
# old name with the new name when there is a version update.
escape_replaced = escaped.replace("\\-", "[-_]")
regex = re.compile(
r"^(?P<indent>[ \t]*){0}(\[.*\])?==".format(re.escape(old_name)),
r"^(?P<indent>[ \t]*){0}(\[.*\])?==".format(escape_replaced),
re.IGNORECASE | re.MULTILINE,
)
# if the package wasn't already there, add it to the bottom
Expand Down
239 changes: 239 additions & 0 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,26 @@ def test_amend_requirements_content_new():
assert result == requirements + new_lines[2]


def test_amend_requirements_content_new_2():
requirements = (
"""
# empty so far
""".strip()
+ "\n"
)
new_lines = (
"discogs-client",
"Discogs_client",
"""
discogs-client==1.1 \\
--hash=sha256:4d64ed1b9e0e73095f5cfa87f0e97ddb4c840049e8efeb7e63b46118ba1d623a
""".strip()
+ "\n",
)
result = hashin.amend_requirements_content(requirements, [new_lines])
assert result == requirements + new_lines[2]


def test_amend_requirements_different_old_name():
requirements = (
"""
Expand Down Expand Up @@ -2665,3 +2685,222 @@ def mock_input(question):
"hashin", old_version, new_version, force_yes=True
)
assert result == "YES"


class TestIssue116:
"""Tests for validating fix related to GH issue #116

https://github.com/peterbe/hashin/issues/116
"""

def test_amend_requirements_content_new_without_env_markers(self):
requirements = (
"""
# empty so far
""".strip()
+ "\n"
)
new_lines = (
"discogs-client",
"discogs-client",
"""
discogs-client==1.1 \\
--hash=sha256:4d64ed1b9e0e73095f5cfa87f0e97ddb4c840049e8efeb7e63b46118ba1d623a
""".strip()
+ "\n",
)
result = hashin.amend_requirements_content(requirements, [new_lines])
assert result == requirements + new_lines[2]

def test_amend_requirements_content_new_with_env_markers(self):
requirements = (
"""
# empty so far
""".strip()
+ "\n"
)
new_lines = (
"discogs-client; python_version <= '3.4'",
"discogs-client; python_version <= '3.4'",
"""
discogs-client==1.1; python_version <= '3.4' \\
--hash=sha256:4d64ed1b9e0e73095f5cfa87f0e97ddb4c840049e8efeb7e63b46118ba1d623a
""".strip()
+ "\n",
)
result = hashin.amend_requirements_content(requirements, [new_lines])
assert result == requirements + new_lines[2]

def test_amend_requirements_different_old_name_without_env_markers(self):
requirements = (
"""
readme_renderer==25.0 \\
--hash=sha256:1b6d8dd1673a0b293766b4106af766b6eff3654605f9c4f239e65de6076bc222 \\
--hash=sha256:e67d64242f0174a63c3b727801a2fff4c1f38ebe5d71d95ff7ece081945a6cd4

""".strip()
+ "\n"
)

new_lines = (
"readme-renderer",
"readme-renderer",
"""
readme-renderer==26.0 \\
--hash=sha256:cbe9db71defedd2428a1589cdc545f9bd98e59297449f69d721ef8f1cfced68d \\
--hash=sha256:cc4957a803106e820d05d14f71033092537a22daa4f406dfbdd61177e0936376

""".strip()
+ "\n",
)
result = hashin.amend_requirements_content(requirements, [new_lines])
assert result == new_lines[2]

def test_amend_requirements_different_old_name_with_env_markers(self):
requirements = (
"""
readme_renderer==25.0; python_version <= "3.4" \\
--hash=sha256:1b6d8dd1673a0b293766b4106af766b6eff3654605f9c4f239e65de6076bc222 \\
--hash=sha256:e67d64242f0174a63c3b727801a2fff4c1f38ebe5d71d95ff7ece081945a6cd4

""".strip()
+ "\n"
)

new_lines = (
"readme-renderer",
"readme-renderer",
"""
readme-renderer==26.0; python_version <= "3.4" \\
--hash=sha256:cbe9db71defedd2428a1589cdc545f9bd98e59297449f69d721ef8f1cfced68d \\
--hash=sha256:cc4957a803106e820d05d14f71033092537a22daa4f406dfbdd61177e0936376

""".strip()
+ "\n",
)
result = hashin.amend_requirements_content(requirements, [new_lines])
assert result == new_lines[2]

def test_amend_requirements_without_env_markers_same_version(self):
requirements = (
"""
readme_renderer==25.0 \\
--hash=sha256:1b6d8dd1673a0b293766b4106af766b6eff3654605f9c4f239e65de6076bc222 \\
--hash=sha256:e67d64242f0174a63c3b727801a2fff4c1f38ebe5d71d95ff7ece081945a6cd4

""".strip()
+ "\n"
)

new_lines = (
"readme-renderer",
"readme-renderer",
"""
readme_renderer==25.0 \\
--hash=sha256:1b6d8dd1673a0b293766b4106af766b6eff3654605f9c4f239e65de6076bc222 \\
--hash=sha256:e67d64242f0174a63c3b727801a2fff4c1f38ebe5d71d95ff7ece081945a6cd4

""".strip()
+ "\n",
)
result = hashin.amend_requirements_content(requirements, [new_lines])
assert result == requirements

def test_amend_requirements_with_env_markers_same_version(self):
requirements = (
"""
readme_renderer==25.0; python_version <= "3.4" \\
--hash=sha256:1b6d8dd1673a0b293766b4106af766b6eff3654605f9c4f239e65de6076bc222 \\
--hash=sha256:e67d64242f0174a63c3b727801a2fff4c1f38ebe5d71d95ff7ece081945a6cd4

""".strip()
+ "\n"
)

new_lines = (
"readme-renderer",
"readme-renderer",
"""
readme_renderer==25.0; python_version <= "3.4" \\
--hash=sha256:1b6d8dd1673a0b293766b4106af766b6eff3654605f9c4f239e65de6076bc222 \\
--hash=sha256:e67d64242f0174a63c3b727801a2fff4c1f38ebe5d71d95ff7ece081945a6cd4

""".strip()
+ "\n",
)
result = hashin.amend_requirements_content(requirements, [new_lines])
assert result == requirements

def test_run_old_name_no_version_change(self, murlopen, tmpfile, capsys):
def mocked_get(url, **options):
if url == "https://pypi.org/pypi/readme_renderer/json":
return _Response(
{
"info": {"version": "0.25", "name": "readme-renderer"},
"releases": {
"25.0": [
{
"url": "https://pypi.org/packages/source/p/readme-renderer/readme_renderer-25.0.tar.gz",
"digests": {"sha256": "bbbbb"},
}
],
"26.0": [
{
"url": "https://pypi.org/packages/source/p/readme-renderer/readme_renderer-26.0.tar.gz",
"digests": {"sha256": "aaaaa"},
}
],
},
}
)

murlopen.side_effect = mocked_get

with tmpfile() as filename:
with open(filename, "w") as f:
f.write("readme_renderer==25.0 \\\n")
f.write(" --hash=sha256:bbbbb\n")
f.write("\n")

retcode = hashin.run("readme_renderer==25.0", filename, "sha256")
assert retcode == 0
with open(filename) as f:
output = f.read()
assert "readme_renderer==25.0" in output

def test_run_old_name_new_version_change(self, murlopen, tmpfile, capsys):
def mocked_get(url, **options):
if url == "https://pypi.org/pypi/readme_renderer/json":
return _Response(
{
"info": {"version": "0.25", "name": "readme-renderer"},
"releases": {
"25.0": [
{
"url": "https://pypi.org/packages/source/p/readme-renderer/readme_renderer-25.0.tar.gz",
"digests": {"sha256": "bbbbb"},
}
],
"26.0": [
{
"url": "https://pypi.org/packages/source/p/readme-renderer/readme_renderer-26.0.tar.gz",
"digests": {"sha256": "aaaaa"},
}
],
},
}
)

murlopen.side_effect = mocked_get

with tmpfile() as filename:
with open(filename, "w") as f:
f.write("readme_renderer==26.0 \\\n")
f.write(" --hash=sha256:bbbbb\n")
f.write("\n")

retcode = hashin.run("readme_renderer==26.0", filename, "sha256")
assert retcode == 0
with open(filename) as f:
output = f.read()
assert "readme-renderer==26.0" in output
3 changes: 2 additions & 1 deletion tox.ini
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
[tox]
envlist = py{27,34,35,36}, lint, restlint
envlist = py{27,34,35,36,37}, lint, restlint

[travis]
python =
2.7: py27
3.4: py34
3.5: py35
3.6: py36, lint, restlint
3.7: py37, lint, restlint
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note-to-self; we should probably drop 3.4 and add 3.8.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you want me to change this in this PR? lemme know

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have a new PR coming that'll also do this. So leave it as is.


[testenv]
usedevelop = True
Expand Down