mirror of
https://github.com/Homebrew/brew.git
synced 2026-10-28 09:34:42 +08:00
pypi: resolve non-PyPI sources missing from PyPI
- `package_name` was always looked up on PyPI as `name[extras]==<formula version>`, which fails when a formula built from a non-PyPI source (e.g. a GitHub release) uses a version PyPI does not have, as with `hermes-agent`. - In that case, resolve the stable URL as a PEP 508 direct reference (`name[extras] @ <url>`) so extras' dependencies are kept. - Formulae whose version exists on PyPI are unaffected.
This commit is contained in:
3 files changed
+61
-3
No files matched your search
@@ -346,6 +346,55 @@ RSpec.describe PyPI do
|
||||
expect(described_class.update_python_resources!(formula, quiet: true)).to be true
|
||||
end
|
||||
|
||||
context "with a package name and a non-PyPI stable URL" do
|
||||
let(:url) { "https://github.com/example/foo/archive/refs/tags/v1.0.tar.gz" }
|
||||
let(:formula) do
|
||||
path = mktmpdir/"foo.rb"
|
||||
path.write <<~RUBY
|
||||
class Foo < Formula
|
||||
url "#{url}"
|
||||
sha256 "#{"a" * 64}"
|
||||
|
||||
def install
|
||||
bin.install "foo"
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
Formulary.from_contents("foo", path, path.read)
|
||||
end
|
||||
let(:report) { '{"install":[{"metadata":{"name":"foo","version":"1.0"}}]}' }
|
||||
|
||||
before do
|
||||
allow(Formula).to receive(:[]).with("python").and_return(instance_double(Formula, ensure_installed!: true))
|
||||
allow(described_class).to receive(:pip_output).and_return(report)
|
||||
end
|
||||
|
||||
it "resolves the stable URL with the package's extras when PyPI lacks the formula version" do
|
||||
allow(Utils::Curl).to receive(:curl_output)
|
||||
.and_return(instance_double(SystemCommand::Result,
|
||||
status: instance_double(Process::Status, success?: false)))
|
||||
expect(described_class).to receive(:pip_output)
|
||||
.with(array_including("--report=/dev/stdout", "foo[bar] @ #{url}"), any_args).and_return(report)
|
||||
|
||||
described_class.update_python_resources!(formula, package_name: "foo[bar]", quiet: true)
|
||||
end
|
||||
|
||||
it "resolves the package from PyPI when it has the formula version" do
|
||||
pypi_json = {
|
||||
info: { name: "foo", version: "1.0" },
|
||||
urls: [{ packagetype: "sdist", url: "https://files.pythonhosted.org/packages/foo-1.0.tar.gz",
|
||||
digests: { sha256: "b" * 64 } }],
|
||||
}.to_json
|
||||
allow(Utils::Curl).to receive(:curl_output)
|
||||
.and_return(instance_double(SystemCommand::Result,
|
||||
status: instance_double(Process::Status, success?: true), stdout: pypi_json))
|
||||
expect(described_class).to receive(:pip_output)
|
||||
.with(array_including("--report=/dev/stdout", "foo[bar]==1.0"), any_args).and_return(report)
|
||||
|
||||
described_class.update_python_resources!(formula, package_name: "foo[bar]", quiet: true)
|
||||
end
|
||||
end
|
||||
|
||||
it "keeps resources with livecheck blocks" do
|
||||
path = mktmpdir/"foo.rb"
|
||||
livecheck_resource = <<~RUBY
|
||||
|
||||
@@ -284,15 +284,22 @@ module PyPI
|
||||
(python_deps.find(&:any_version_installed?) || python_deps.first).name
|
||||
end
|
||||
|
||||
stable = formula.stable
|
||||
stable_url = stable&.url
|
||||
main_package = if package_name.present?
|
||||
package_string = package_name
|
||||
package_string += "==#{formula.version}" if version.blank? && formula.version.present?
|
||||
Package.new(package_string, python_name:)
|
||||
package = Package.new(package_string, python_name:)
|
||||
if stable && stable_url && package_string != package_name &&
|
||||
!stable_url.start_with?(PYTHONHOSTED_URL_PREFIX) && !stable.downloader.is_a?(VCSDownloadStrategy) &&
|
||||
package.pypi_info(ignore_errors: true).nil?
|
||||
Package.new("#{package_name} @ #{stable_url}", is_url: true, python_name:)
|
||||
else
|
||||
package
|
||||
end
|
||||
elsif package_name == ""
|
||||
nil
|
||||
else
|
||||
stable = formula.stable
|
||||
stable_url = stable&.url
|
||||
if stable.nil? || stable_url.nil?
|
||||
odie "#{formula.full_name} has no stable URL to determine the main Python package from."
|
||||
end
|
||||
|
||||
@@ -56,6 +56,8 @@ pypi_packages package_name: "upstream-name",
|
||||
dependencies: "resolver-dependency"
|
||||
```
|
||||
|
||||
If the stable URL is not on PyPI and PyPI has no release matching the formula's version, `package_name` (including any extras such as `upstream-name[all]`) is resolved against the stable URL instead.
|
||||
|
||||
### Installing a Python application
|
||||
|
||||
Include `Language::Python::Virtualenv` and use `virtualenv_install_with_resources` for the standard application layout.
|
||||
|
||||
Reference in new issue
Block a user