Compare commits
3 Commits
main
...
issue/pyth
| Author | SHA1 | Date |
|---|---|---|
|
|
43a8e15924 | |
|
|
13e7ddf864 | |
|
|
ad8bb033c8 |
|
|
@ -21,6 +21,10 @@ jobs:
|
|||
ruby-version: ${{ matrix.ruby-version }}
|
||||
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
|
||||
- run: |
|
||||
bundle exec rspec
|
||||
if [ ! -z "$RUNNER_DEBUG" ] ; then
|
||||
DEBUG=1 bundle exec rspec -fd
|
||||
else
|
||||
bundle exec rspec
|
||||
fi
|
||||
env:
|
||||
SHELL: /usr/bin/bash
|
||||
|
|
|
|||
|
|
@ -98,22 +98,6 @@ class FPM::Package::Python < FPM::Package
|
|||
:attribute_name => :python_internal_pip,
|
||||
:default => true
|
||||
|
||||
# Environment markers which are known but not yet supported by fpm.
|
||||
# For some of these markers, it's not even clear if they are useful to fpm's packaging step.
|
||||
# https://packaging.python.org/en/latest/specifications/dependency-specifiers/#dependency-specifiers
|
||||
#
|
||||
# XXX: python's setuptools.pkg_resources can help parse and evaluate such things, even if that library is deprecated:
|
||||
# >>> f = open("spec/fixtures/python/requirements.txt"); a = pkg_resources.parse_requirements(f.read()); f.close();
|
||||
# >>> [x for x in list(a) if x.marker is None or x.marker.evaluate()]
|
||||
# [Requirement.parse('rtxt-dep1>0.1'), Requirement.parse('rtxt-dep2==0.1'), Requirement.parse('rtxt-dep4; python_version > "2.0"')]
|
||||
#
|
||||
# Another example, showing only requirements which have environment markers which evaluate to true (or have no markers)
|
||||
# python3 -c 'import pkg_resources; import json;import sys; r = pkg_resources.parse_requirements(sys.stdin); deps = [d for d in list(r) if d.marker is None or d.marker.evaluate()]; pr
|
||||
# ["rtxt-dep1>0.1", "rtxt-dep2==0.1", "rtxt-dep4; python_version > \"2.0\""]
|
||||
UNSUPPORTED_DEPENDENCY_MARKERS = %w(python_version python_full_version os_name platform_release platform_system platform_version
|
||||
platform_machine platform_python_implementation implementation_name implementation_version)
|
||||
|
||||
|
||||
class PythonMetadata
|
||||
require "strscan"
|
||||
|
||||
|
|
@ -328,32 +312,24 @@ class FPM::Package::Python < FPM::Package
|
|||
# The 'package' can be any of:
|
||||
#
|
||||
# * A name of a package on pypi (ie; easy_install some-package)
|
||||
# * The path to a directory containing setup.py or pypackage.toml
|
||||
# * The path to a setup.py or pypackage.toml
|
||||
# * The path to a directory containing setup.py or pyproject.toml
|
||||
# * The path to a setup.py or pyproject.toml
|
||||
# * The path to a python sdist file ending in .tar.gz
|
||||
# * The path to a python wheel file ending in .whl
|
||||
def input(package)
|
||||
#if attributes[:python_obey_requirements_txt?]
|
||||
#raise "--python-obey-requirements-txt is temporarily unsupported at this time."
|
||||
#end
|
||||
explore_environment
|
||||
|
||||
path_to_package = download_if_necessary(package, version)
|
||||
|
||||
# Expect a setup.py or pypackage.toml if it's a directory.
|
||||
# Expect a setup.py or pyproject.toml if it's a directory.
|
||||
if File.directory?(path_to_package)
|
||||
if !(File.exist?(File.join(path_to_package, "setup.py")) or File.exist?(File.join(path_to_package, "pypackage.toml")))
|
||||
logger.error("The path doesn't appear to be a python package directory. I expected either a pypackage.toml or setup.py but found neither.", :package => package)
|
||||
raise "Unable to find python package; tried #{setup_py}"
|
||||
end
|
||||
|
||||
if attributes[:python_obey_requirements_txt?] && File.exist?(File.join(path_to_package, "requirements.txt"))
|
||||
@requirements_txt = File.read(File.join(path_to_package, "requirements.txt"))
|
||||
if !(File.exist?(File.join(path_to_package, "setup.py")) or File.exist?(File.join(path_to_package, "pyproject.toml")))
|
||||
raise FPM::InvalidPackageConfiguration, "The path ('#{path_to_package}') doesn't appear to be a python package directory. I expected either a pyproject.toml or setup.py but found neither."
|
||||
end
|
||||
end
|
||||
|
||||
if File.file?(path_to_package)
|
||||
if ["setup.py", "pypackage.toml"].include?(File.basename(path_to_package))
|
||||
if ["setup.py", "pyproject.toml"].include?(File.basename(path_to_package))
|
||||
path_to_package = File.dirname(path_to_package)
|
||||
end
|
||||
end
|
||||
|
|
@ -365,18 +341,22 @@ class FPM::Package::Python < FPM::Package
|
|||
|
||||
path_to_package = ::Dir.glob(build_path("*.whl")).first
|
||||
if path_to_package.nil?
|
||||
log.error("Failed building python package wheel format. This might be a bug in fpm.")
|
||||
raise "Failed building python package format."
|
||||
raise FPM::InvalidPackageConfiguration, "Failed building python package format - fpm tried to build a python wheel, but didn't find the .whl file. This might be a bug in fpm."
|
||||
end
|
||||
elsif File.directory?(path_to_package)
|
||||
logger.debug("Found directory and assuming it's a python source package.")
|
||||
safesystem(*attributes[:python_pip], "wheel", "--no-deps", "-w", build_path, path_to_package)
|
||||
|
||||
if attributes[:python_obey_requirements_txt?]
|
||||
reqtxt = File.join(path_to_package, "requirements.txt")
|
||||
@requirements_txt = File.read(reqtxt).split("\n") if File.file?(reqtxt)
|
||||
end
|
||||
|
||||
path_to_package = ::Dir.glob(build_path("*.whl")).first
|
||||
if path_to_package.nil?
|
||||
log.error("Failed building python package wheel format. This might be a bug in fpm.")
|
||||
raise "Failed building python package format."
|
||||
raise FPM::InvalidPackageConfiguration, "Failed building python package format - fpm tried to build a python wheel, but didn't find the .whl file. This might be a bug in fpm."
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
load_package_info(path_to_package)
|
||||
|
|
@ -418,6 +398,11 @@ class FPM::Package::Python < FPM::Package
|
|||
# If it's a path, assume local build.
|
||||
if File.exist?(path)
|
||||
return path if File.directory?(path)
|
||||
|
||||
basename = File.basename(path)
|
||||
return File.dirname(path) if basename == "pyproject.toml"
|
||||
return File.dirname(path) if basename == "setup.py"
|
||||
|
||||
return path if path.end_with?(".tar.gz")
|
||||
return path if path.end_with?(".tgz") # amqplib v1.0.2 does this
|
||||
return path if path.end_with?(".whl")
|
||||
|
|
@ -540,9 +525,10 @@ class FPM::Package::Python < FPM::Package
|
|||
|
||||
reqs = []
|
||||
|
||||
# --python-obey-requirements-txt should replace the requirments listed from the metadata
|
||||
# --python-obey-requirements-txt should use requirements.txt
|
||||
# (if found in the python package) and replace the requirments listed from the metadata
|
||||
if attributes[:python_obey_requirements_txt?] && !@requirements_txt.nil?
|
||||
requires = @requirements_txt.split("\n")
|
||||
requires = @requirements_txt
|
||||
else
|
||||
requires = metadata.requires
|
||||
end
|
||||
|
|
|
|||
|
|
@ -0,0 +1,4 @@
|
|||
[project]
|
||||
name = "example"
|
||||
version = "1.2.3"
|
||||
authors = [ { name = "Captain Fancy", email = "foo@example.com" } ]
|
||||
|
|
@ -208,32 +208,6 @@ describe FPM::Package::Python do
|
|||
end
|
||||
end
|
||||
|
||||
context "python_scripts_executable is set" do
|
||||
it "should have scripts with a custom hashbang line" do
|
||||
skip("setup.py-specific feature is no longer supported")
|
||||
|
||||
subject.attributes[:python_scripts_executable] = "fancypants"
|
||||
# Newer versions of Django require Python 3.
|
||||
subject.attributes[:python_bin] = "python3"
|
||||
subject.input("django")
|
||||
|
||||
# Determine, where 'easy_install' is going to install scripts
|
||||
#script_dir = easy_install_default(subject.attributes[:python_bin], 'script_dir')
|
||||
#path = subject.staging_path(File.join(script_dir, "django-admin.py"))
|
||||
|
||||
# Hardcode /usr/local/bin here. On newer Python 3's I cannot figure out how to
|
||||
# determine the script_dir at installation time. easy_install's method is gone.
|
||||
path = subject.staging_path("/usr/local/bin/django-admin")
|
||||
|
||||
# Read the first line (the hashbang line) of the django-admin.py script
|
||||
fd = File.new(path, "r")
|
||||
topline = fd.readline
|
||||
fd.close
|
||||
|
||||
insist { topline.chomp } == "#!fancypants"
|
||||
end
|
||||
end
|
||||
|
||||
context "when input is a name" do
|
||||
it "should download from pypi" do
|
||||
subject.input("click==8.3.0")
|
||||
|
|
@ -247,6 +221,31 @@ describe FPM::Package::Python do
|
|||
|
||||
end
|
||||
end
|
||||
|
||||
context "when given a project containing a pyproject.toml" do
|
||||
let (:project) do
|
||||
File.expand_path("../../fixtures/python-pyproject.toml/", File.dirname(__FILE__))
|
||||
end
|
||||
|
||||
it "should package it correctly" do
|
||||
subject.input(project)
|
||||
prefix = subject.attributes[:python_package_name_prefix]
|
||||
|
||||
insist { subject.name } == "#{prefix}-example"
|
||||
insist { subject.version } == "1.2.3"
|
||||
insist { subject.maintainer } == "Captain Fancy <foo@example.com>"
|
||||
end
|
||||
|
||||
it "should package it correctly even if the path given is directly to the pyproject.toml" do
|
||||
subject.input(File.join(project, "pyproject.toml"))
|
||||
prefix = subject.attributes[:python_package_name_prefix]
|
||||
|
||||
insist { subject.name } == "#{prefix}-example"
|
||||
insist { subject.version } == "1.2.3"
|
||||
insist { subject.maintainer } == "Captain Fancy <foo@example.com>"
|
||||
end
|
||||
|
||||
end
|
||||
end # describe FPM::Package::Python
|
||||
|
||||
describe FPM::Package::Python::PythonMetadata do
|
||||
|
|
|
|||
Loading…
Reference in New Issue