diff --git a/piptools/sync.py b/piptools/sync.py index 34bd4da4d..4e2bb4940 100644 --- a/piptools/sync.py +++ b/piptools/sync.py @@ -158,10 +158,12 @@ def sync( """ Install and uninstalls the given sets of modules. """ + exit_code = 0 + if not to_uninstall and not to_install: if verbose: click.echo("Everything up-to-date") - return 0 + return exit_code pip_flags = [] if not verbose: @@ -181,8 +183,11 @@ def sync( for ireq in sorted(to_install, key=key_from_ireq): click.echo(" {}".format(format_requirement(ireq))) + exit_code = 1 + if ask and click.confirm("Would you like to proceed with these changes?"): dry_run = False + exit_code = 0 if not dry_run: if to_uninstall: @@ -215,4 +220,4 @@ def sync( finally: os.unlink(tmp_req_file.name) - return 0 + return exit_code diff --git a/tests/test_cli_sync.py b/tests/test_cli_sync.py index 22cf6f0c1..1db8cc56d 100644 --- a/tests/test_cli_sync.py +++ b/tests/test_cli_sync.py @@ -120,7 +120,7 @@ def test_merge_error(req_lines, should_raise, runner): assert out.exit_code == 2 assert "Incompatible requirements found" in out.stderr else: - assert out.exit_code == 0 + assert out.exit_code == 1 @pytest.mark.parametrize( @@ -231,3 +231,15 @@ def test_sync_ask_accepted(check_call, runner): runner.invoke(cli, ["--ask", "--dry-run"], input="y\n") assert check_call.call_count == 2 + + +def test_sync_dry_run_returns_non_zero_exit_code(runner): + """ + Make sure non-zero exit code is returned when --dry-run is given. + """ + with open("requirements.txt", "w") as req_in: + req_in.write("small-fake-a==1.10.0") + + out = runner.invoke(cli, ["--dry-run"]) + + assert out.exit_code == 1