Skip to content

Commit

Permalink
Fix crash when updating libraries with multiple manifests
Browse files Browse the repository at this point in the history
If a library has both a pyproject.toml file and a standard
requirements.txt file, we'd end up using the `:widen` strategy for the
dependencies in the `requirements.txt` file and eventually crashing with
an error like the following:

```
/home/dependabot/dependabot-core/common/lib/dependabot/update_checkers/base.rb:266:in `block in preferred_version_resolvable_with_unlock?': undefined method `[]' for nil:NilClass (NoMethodError)

        updated_requirements.none? { |r| r[:requirement] == :unfixable }
                                          ^^^^^^^^^^^^^^
        from /home/dependabot/dependabot-core/common/lib/dependabot/update_checkers/base.rb:266:in `none?'
        from /home/dependabot/dependabot-core/common/lib/dependabot/update_checkers/base.rb:266:in `preferred_version_resolvable_with_unlock?'
        from /home/dependabot/dependabot-core/common/lib/dependabot/update_checkers/base.rb:249:in `numeric_version_can_update?'
        from /home/dependabot/dependabot-core/common/lib/dependabot/update_checkers/base.rb:199:in `version_can_update?'
        from /home/dependabot/dependabot-core/common/lib/dependabot/update_checkers/base.rb:44:in `can_update?'
        from bin/dry-run.rb:709:in `block in <main>'
        from bin/dry-run.rb:661:in `each'
        from bin/dry-run.rb:661:in `<main>'
```

I think the crash happens because the requirements.txt file updater does
not supoort the `:widen` strategy. So my fix is to fallback to
`increase` in this case, since requirements.txt files usually include
pinned dependencies so widening probably doesn't make much sense there.
  • Loading branch information
deivid-rodriguez committed Oct 20, 2022
1 parent 458d3ff commit 7a25e2c
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 33 deletions.
2 changes: 1 addition & 1 deletion python/lib/dependabot/python/update_checker.rb
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ def latest_version_finder
end

def poetry_library?
return false unless pyproject
return false unless updating_pyproject?

# Hit PyPi and check whether there are details for a library with a
# matching name and description
Expand Down
78 changes: 46 additions & 32 deletions python/spec/dependabot/python/update_checker_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
)
end
let(:requirements_fixture_name) { "version_specified.txt" }
let(:dependency) do
let(:requirements_dependency) do
Dependabot::Dependency.new(
name: dependency_name,
version: dependency_version,
Expand All @@ -76,6 +76,8 @@
}]
end

let(:dependency) { requirements_dependency }

describe "#can_update?" do
subject { checker.can_update?(requirements_to_unlock: :own) }

Expand Down Expand Up @@ -507,44 +509,56 @@
let(:dependency_files) { [requirements_file, pyproject] }
let(:pyproject_fixture_name) { "caret_version.toml" }

let(:dependency) do
Dependabot::Dependency.new(
name: "requests",
version: "1.2.3",
requirements: [{
file: "pyproject.toml",
requirement: "^1.0.0",
groups: [],
source: nil
}],
package_manager: "pip"
)
end
context "and updating a dependency inside" do
let(:dependency) do
Dependabot::Dependency.new(
name: "requests",
version: "1.2.3",
requirements: [{
file: "pyproject.toml",
requirement: "^1.0.0",
groups: [],
source: nil
}],
package_manager: "pip"
)
end

let(:pypi_url) { "https://pypi.org/simple/requests/" }
let(:pypi_response) do
fixture("pypi", "pypi_simple_response_requests.html")
end
let(:pypi_url) { "https://pypi.org/simple/requests/" }
let(:pypi_response) do
fixture("pypi", "pypi_simple_response_requests.html")
end

context "for a library" do
before do
stub_request(:get, "https://pypi.org/pypi/pendulum/json/").
to_return(
status: 200,
body: fixture("pypi", "pypi_response_pendulum.json")
)
context "for a library" do
before do
stub_request(:get, "https://pypi.org/pypi/pendulum/json/").
to_return(
status: 200,
body: fixture("pypi", "pypi_response_pendulum.json")
)
end

its([:requirement]) { is_expected.to eq(">=1,<3") }
end

its([:requirement]) { is_expected.to eq(">=1,<3") }
end
context "for a non-library" do
before do
stub_request(:get, "https://pypi.org/pypi/pendulum/json/").
to_return(status: 404)
end

context "for a non-library" do
before do
stub_request(:get, "https://pypi.org/pypi/pendulum/json/").
to_return(status: 404)
its([:requirement]) { is_expected.to eq("^2.19.1") }
end
end

context "and updating a dependency in an additional requirements file" do
let(:dependency_files) { super().append(requirements_file) }

its([:requirement]) { is_expected.to eq("^2.19.1") }
let(:dependency) { requirements_dependency }

it "does not get affected by whether it's a library or not and updates using the :increase strategy" do
expect(subject[:requirement]).to eq("==2.6.0")
end
end
end

Expand Down

0 comments on commit 7a25e2c

Please sign in to comment.