diff --git a/lib/fpm/package/python.rb b/lib/fpm/package/python.rb index fec9b7873b..22a3dfcfff 100644 --- a/lib/fpm/package/python.rb +++ b/lib/fpm/package/python.rb @@ -79,7 +79,11 @@ class FPM::Package::Python < FPM::Package option "--setup-py-arguments", "setup_py_argument", "Arbitrary argument(s) to be passed to setup.py", :multivalued => true, :attribute_name => :python_setup_py_arguments, - :default => [] + :default => [] + option "--internal-pip", :flag, + "Use the pip module within python to install modules - aka 'python -m pip'. This is the recommended usage since Python 3.4 (2014) instead of invoking the 'pip' script", + :attribute_name => :python_internal_pip, + :default => true private @@ -130,23 +134,24 @@ def download_if_necessary(package, version=nil) target = build_path(package) FileUtils.mkdir(target) unless File.directory?(target) - if attributes[:python_pip].nil? - # no pip, use easy_install - logger.debug("no pip, defaulting to easy_install", :easy_install => attributes[:python_easyinstall]) - safesystem(attributes[:python_easyinstall], "-i", - attributes[:python_pypi], "--editable", "-U", - "--build-directory", target, want_pkg) - else + if attributes[:python_internal_pip?] + # XXX: Should we detect if internal pip is available? + attributes[:python_pip] = [ attributes[:python_bin], "-m", "pip"] + end + + # attributes[:python_pip] -- expected to be a path + if attributes[:python_pip] logger.debug("using pip", :pip => attributes[:python_pip]) # TODO: Support older versions of pip + pip = [attributes[:python_pip]] if pip.is_a?(String) setup_cmd = [ - attributes[:python_pip], + *attributes[:python_pip], "download", "--no-clean", "--no-deps", - "--no-binary", - ":all:", + "--no-binary", ":all:", + "-d", build_path, "-i", attributes[:python_pypi], ] @@ -164,6 +169,12 @@ def download_if_necessary(package, version=nil) ] safesystem(*setup_cmd) + else + # no pip, use easy_install + logger.debug("no pip, defaulting to easy_install", :easy_install => attributes[:python_easyinstall]) + safesystem(attributes[:python_easyinstall], "-i", + attributes[:python_pypi], "--editable", "-U", + "--build-directory", target, want_pkg) end # easy_install will put stuff in @tmpdir/packagename/, so find that: diff --git a/spec/fixtures/python/setup.py b/spec/fixtures/python/setup.py index 2c1f4a9a9b..a82cb9cd50 100644 --- a/spec/fixtures/python/setup.py +++ b/spec/fixtures/python/setup.py @@ -10,6 +10,9 @@ package_dir={}, install_requires=[ "Dependency1", "dependency2", + # XXX: I don't know what these python_version-dependent deps mean + # needs investigation + # Reference: PEP-0508 'rtxt-dep3; python_version == "2.0"', 'rtxt-dep4; python_version > "2.0"', ], diff --git a/spec/fpm/package/python_spec.rb b/spec/fpm/package/python_spec.rb index a6a2468e66..8161058b77 100644 --- a/spec/fpm/package/python_spec.rb +++ b/spec/fpm/package/python_spec.rb @@ -3,13 +3,19 @@ require "fpm/package/python" # local require "find" # stdlib +def find_python + [ "python", "python3", "python2" ].each do |i| + return i if program_exists?(i) + end + return nil +end + def python_usable? - return program_exists?("python") && program_exists?("easy_install") + return find_python end if !python_usable? - Cabin::Channel.get("rspec").warn("Skipping Python#input tests because " \ - "'python' and/or 'easy_install' isn't in your PATH") + Cabin::Channel.get("rspec").warn("Skipping Python#input tests because 'python' wasn't found in $PATH") end is_travis = ENV["TRAVIS_OS_NAME"] && !ENV["TRAVIS_OS_NAME"].empty? @@ -28,7 +34,8 @@ def easy_install_default(python_bin, option) describe FPM::Package::Python do before do - skip("Python and/or easy_install not found") unless python_usable? + skip("Python program not found") unless python_usable? + subject.attributes[:python_bin] = find_python end let (:example_dir) do @@ -124,7 +131,8 @@ def easy_install_default(python_bin, option) it "it should include the dependencies from setup.py" do subject.input(example_dir) - insist { subject.dependencies.sort } == ["python-dependency1 ","python-dependency2 "] + # XXX: Why is there extra whitespace in these strings? + insist { subject.dependencies.sort } == ["python-dependency1 ","python-dependency2 ", "python-rtxt-dep4 "] end context "and :python_disable_dependency is set" do @@ -134,7 +142,7 @@ def easy_install_default(python_bin, option) it "it should exclude the dependency" do subject.input(example_dir) - insist { subject.dependencies.sort } == ["python-dependency2 "] + insist { subject.dependencies.sort } == ["python-dependency2 ", "python-rtxt-dep4 "] end end end