Skip to content

Commit

Permalink
Automatically select latest prereleases if only prereleases are avail…
Browse files Browse the repository at this point in the history
…able
  • Loading branch information
sdispater committed Jul 12, 2019
1 parent da8d398 commit 352d0ce
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 20 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
- Changed the way virtualenvs are stored (names now depend on the project's path).
- The `--git` option of the `add` command has been removed.
- The `--path` option of the `add` command has been removed.
- The `add` command will now automatically select the latest prerelease if only prereleases are available.

### Fixed

Expand Down
2 changes: 1 addition & 1 deletion poetry/console/commands/init.py
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ def _find_best_version_for_package(
"Could not find a matching version of package {}".format(name)
)

return (package.pretty_name, selector.find_recommended_require_version(package))
return package.pretty_name, selector.find_recommended_require_version(package)

def _parse_requirements(
self, requirements
Expand Down
24 changes: 13 additions & 11 deletions poetry/version/version_selector.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,9 @@ def find_best_candidate(
constraint = parse_constraint("*")

candidates = self._pool.find_packages(
package_name, constraint, allow_prereleases=allow_prereleases
package_name, constraint, allow_prereleases=True
)
only_prereleases = all([c.version.is_prerelease() for c in candidates])

if not candidates:
return False
Expand All @@ -37,7 +38,12 @@ def find_best_candidate(
# Select highest version if we have many
package = candidates[0]
for candidate in candidates:
if candidate.is_prerelease() and not dependency.allows_prereleases():
if (
candidate.is_prerelease()
and not dependency.allows_prereleases()
and not allow_prereleases
and not only_prereleases
):
continue

# Select highest version of the two
Expand All @@ -52,24 +58,20 @@ def find_recommended_require_version(self, package):
return self._transform_version(version.text, package.pretty_version)

def _transform_version(self, version, pretty_version):
# attempt to transform 2.1.1 to 2.1
# this allows you to upgrade through minor versions
try:
parsed = Version.parse(version)
parts = [parsed.major, parsed.minor, parsed.patch]
except ValueError:
return pretty_version

# check to see if we have a semver-looking version
if len(parts) == 3:
# remove the last parts (the patch version number and any extra)
if parts[0] != 0:
del parts[2]
parts = parts[: parsed.precision]

# check to see if we have a semver-looking version
if len(parts) < 3:
version = pretty_version
else:
version = ".".join(str(p) for p in parts)
if parsed.is_prerelease():
version += "-{}".format(".".join(str(p) for p in parsed.prerelease))
else:
return pretty_version

return "^{}".format(version)
52 changes: 52 additions & 0 deletions tests/console/commands/test_add.py
Original file line number Diff line number Diff line change
Expand Up @@ -499,3 +499,55 @@ def test_add_should_display_an_error_when_adding_existing_package_with_no_constr
tester.execute("foo")

assert "Package foo is already present" == str(e.value)


def test_add_chooses_prerelease_if_only_prereleases_are_available(app, repo, installer):
command = app.find("add")
tester = CommandTester(command)

repo.add_package(get_package("foo", "1.2.3b0"))
repo.add_package(get_package("foo", "1.2.3b1"))

tester.execute("foo")

expected = """\
Using version ^1.2.3-beta.1 for foo
Updating dependencies
Resolving dependencies...
Writing lock file
Package operations: 1 install, 0 updates, 0 removals
- Installing foo (1.2.3b1)
"""

assert expected in tester.io.fetch_output()


def test_add_preferes_stable_releases(app, repo, installer):
command = app.find("add")
tester = CommandTester(command)

repo.add_package(get_package("foo", "1.2.3"))
repo.add_package(get_package("foo", "1.2.4b1"))

tester.execute("foo")

expected = """\
Using version ^1.2.3 for foo
Updating dependencies
Resolving dependencies...
Writing lock file
Package operations: 1 install, 0 updates, 0 removals
- Installing foo (1.2.3)
"""

assert expected in tester.io.fetch_output()
16 changes: 8 additions & 8 deletions tests/console/commands/test_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,10 @@ def test_interactive_with_dependencies(app, repo, mocker, poetry):
[tool.poetry.dependencies]
python = "~2.7 || ^3.6"
pendulum = "^2.0"
pendulum = "^2.0.0"
[tool.poetry.dev-dependencies]
pytest = "^3.6"
pytest = "^3.6.0"
"""

assert expected in tester.io.fetch_output()
Expand Down Expand Up @@ -181,7 +181,7 @@ def test_interactive_with_git_dependencies(app, repo, mocker, poetry):
demo = {git = "https://github.com/demo/demo.git"}
[tool.poetry.dev-dependencies]
pytest = "^3.6"
pytest = "^3.6.0"
"""

assert expected in tester.io.fetch_output()
Expand Down Expand Up @@ -231,7 +231,7 @@ def test_interactive_with_git_dependencies_with_reference(app, repo, mocker, poe
demo = {git = "https://github.com/demo/demo.git", rev = "develop"}
[tool.poetry.dev-dependencies]
pytest = "^3.6"
pytest = "^3.6.0"
"""

assert expected in tester.io.fetch_output()
Expand Down Expand Up @@ -281,7 +281,7 @@ def test_interactive_with_git_dependencies_and_other_name(app, repo, mocker, poe
demo = {git = "https://github.com/demo/pyproject-demo.git"}
[tool.poetry.dev-dependencies]
pytest = "^3.6"
pytest = "^3.6.0"
"""

assert expected in tester.io.fetch_output()
Expand Down Expand Up @@ -331,7 +331,7 @@ def test_interactive_with_directory_dependency(app, repo, mocker, poetry):
demo = {path = "../../fixtures/git/github.com/demo/demo"}
[tool.poetry.dev-dependencies]
pytest = "^3.6"
pytest = "^3.6.0"
"""

assert expected in tester.io.fetch_output()
Expand Down Expand Up @@ -383,7 +383,7 @@ def test_interactive_with_directory_dependency_and_other_name(
demo = {path = "../../fixtures/git/github.com/demo/pyproject-demo"}
[tool.poetry.dev-dependencies]
pytest = "^3.6"
pytest = "^3.6.0"
"""

assert expected in tester.io.fetch_output()
Expand Down Expand Up @@ -433,7 +433,7 @@ def test_interactive_with_file_dependency(app, repo, mocker, poetry):
demo = {path = "../../fixtures/distributions/demo-0.1.0-py2.py3-none-any.whl"}
[tool.poetry.dev-dependencies]
pytest = "^3.6"
pytest = "^3.6.0"
"""

assert expected in tester.io.fetch_output()

0 comments on commit 352d0ce

Please sign in to comment.