Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cpan.rb - export the environment variables output by local::lib. #850

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
123 changes: 73 additions & 50 deletions lib/fpm/package/cpan.rb
Original file line number Diff line number Diff line change
Expand Up @@ -205,57 +205,43 @@ def input(package)
prefix = attributes[:prefix] || "/usr/local"
# TODO(sissel): Set default INSTALL path?

# Try Makefile.PL, Build.PL
#
if File.exist?("Build.PL")
# Module::Build is in use here; different actions required.
safesystem(attributes[:cpan_perl_bin],
"-Mlocal::lib=#{build_path("cpan")}",
"Build.PL")
safesystem(attributes[:cpan_perl_bin],
"-Mlocal::lib=#{build_path("cpan")}",
"./Build")

if attributes[:cpan_test?]
safesystem(attributes[:cpan_perl_bin],
"-Mlocal::lib=#{build_path("cpan")}",
"./Build", "test")
end
if attributes[:cpan_perl_lib_path]
perl_lib_path = attributes[:cpan_perl_lib_path]
safesystem("./Build install --install_path lib=#{perl_lib_path} \
--destdir #{staging_path} --prefix #{prefix} --destdir #{staging_path}")
else
safesystem("./Build", "install",
"--prefix", prefix, "--destdir", staging_path,
# Empty install_base to avoid local::lib being used.
"--install_base", "")
end
elsif File.exist?("Makefile.PL")
if attributes[:cpan_perl_lib_path]
perl_lib_path = attributes[:cpan_perl_lib_path]
safesystem(attributes[:cpan_perl_bin],
"-Mlocal::lib=#{build_path("cpan")}",
"Makefile.PL", "PREFIX=#{prefix}", "LIB=#{perl_lib_path}",
# Empty install_base to avoid local::lib being used.
"INSTALL_BASE=")
else
safesystem(attributes[:cpan_perl_bin],
"-Mlocal::lib=#{build_path("cpan")}",
"Makefile.PL", "PREFIX=#{prefix}",
# Empty install_base to avoid local::lib being used.
"INSTALL_BASE=")
end
make = [ "env", "PERL5LIB=#{build_path("cpan/lib/perl5")}", "make" ]
safesystem(*make)
safesystem(*(make + ["test"])) if attributes[:cpan_test?]
safesystem(*(make + ["DESTDIR=#{staging_path}", "install"]))
with_local_lib_env(build_path("cpan")) do
if File.exist?("Build.PL")
# Module::Build is in use here; different actions required.
safesystem(attributes[:cpan_perl_bin], "Build.PL")
safesystem(attributes[:cpan_perl_bin], "./Build")

if attributes[:cpan_test?]
safesystem(attributes[:cpan_perl_bin], "./Build", "test")
end
if attributes[:cpan_perl_lib_path]
perl_lib_path = attributes[:cpan_perl_lib_path]
safesystem("./Build install --install_path lib=#{perl_lib_path} \
--destdir #{staging_path} --prefix #{prefix} --destdir #{staging_path}")
else
safesystem("./Build", "install",
"--prefix", prefix, "--destdir", staging_path)
end
elsif File.exist?("Makefile.PL")
if attributes[:cpan_perl_lib_path]
perl_lib_path = attributes[:cpan_perl_lib_path]
safesystem(attributes[:cpan_perl_bin],
"Makefile.PL", "PREFIX=#{prefix}", "LIB=#{perl_lib_path}")
else
safesystem(attributes[:cpan_perl_bin],
"Makefile.PL", "PREFIX=#{prefix}")
end
make = [ "env", "PERL5LIB=#{build_path("cpan/lib/perl5")}", "make" ]
safesystem(*make)
safesystem(*(make + ["test"])) if attributes[:cpan_test?]
safesystem(*(make + ["DESTDIR=#{staging_path}", "install"]))


else
raise FPM::InvalidPackageConfiguration,
"I don't know how to build #{name}. No Makefile.PL nor " \
"Build.PL found"
else
raise FPM::InvalidPackageConfiguration,
"I don't know how to build #{name}. No Makefile.PL nor " \
"Build.PL found"
end
end

# Fix any files likely to cause conflicts that are duplicated
Expand Down Expand Up @@ -301,6 +287,35 @@ def input(package)
end
end

# Set up ENV with values from Perl's local::lib module. Serialize pertinent
# environment variables as JSON, then read them into this process' ENV hash.
def local_lib_env(local_lib_path)
JSON.parse safesystemout(
attributes[:cpan_perl_bin],
"-MJSON::PP",
"-mlocal::lib",
"-le",
"print encode_json(+{ local::lib->build_environment_vars_for($ARGV[0]) })",
local_lib_path,
)
end

def with_local_lib_env(local_lib_path)
orig_env = ENV.to_h

local_lib_env(local_lib_path).each_pair do |k, v|
# PERL_MM_OPT and PERL_MB_OPT are incompatible with setting PREFIX, which
# is done during the build process.
next if ["PERL_MM_OPT", "PERL_MB_OPT"].include?(k)

ENV[k] = v
end

yield
ensure
ENV.replace(orig_env)
end

def unpack(tarball)
directory = build_path("module")
::Dir.mkdir(directory)
Expand All @@ -327,7 +342,15 @@ def download(metadata, cpan_version=nil)

# Search metacpan to get download URL for this version of the module
metacpan_search_url = "https://fastapi.metacpan.org/v1/release/_search"
metacpan_search_query = '{"fields":["download_url"],"filter":{"term":{"name":"' + "#{distribution}-#{self.version}" + '"}}}'
metacpan_search_query = JSON.dump({
fields: ["download_url"],
filter: {
term: {
name: "#{distribution}-#{self.version}",
},
},
})

begin
search_response = httppost(metacpan_search_url,metacpan_search_query)
rescue Net::HTTPServerException => e
Expand Down
28 changes: 27 additions & 1 deletion spec/fpm/package/cpan_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@

it "should package File::Spec" do
pending("Disabled on travis-ci because it always fails, and there is no way to debug it?") if is_travis

# Disabled for the reasons articulated above with respect to `Digest::MD5`.
subject.attributes[:cpan_test?] = false
subject.input("File::Spec")

# the File::Spec module comes from the PathTools CPAN distribution
Expand All @@ -76,9 +79,32 @@
it "should package IPC::Session" do
pending("Disabled on travis-ci because it always fails, and there is no way to debug it?") if is_travis

# IPC::Session fails 'make test'
# Disabled for the reasons articulated above with respect to
# `Digest::MD5`.
subject.attributes[:cpan_test?] = false
subject.input("IPC::Session")
end
end

context "given a build root directory" do
let(:build_path) { Dir.getwd }

it "should export local::lib environment variables relative to the specified directory" do
subject.send(:with_local_lib_env, build_path) do
insist { ENV["PATH"].split(":").first } == File.join(build_path, "bin")
insist { ENV["PERL5LIB"].split(":").first } == File.join(build_path, "lib", "perl5")
insist { ENV["PERL_LOCAL_LIB_ROOT"] } == build_path
end
end

it "should not allow local::lib to touch PERL_MB_OPT and PERL_MM_OPT" do
stored_perl_mb_opt = ENV["PERL_MB_OPT"]
stored_perl_mm_opt = ENV["PERL_MM_OPT"]
subject.send(:with_local_lib_env, build_path) do
insist { ENV["PERL_MB_OPT"] } == stored_perl_mb_opt
insist { ENV["PERL_MM_OPT"] } == stored_perl_mm_opt
end
end
end

end # describe FPM::Package::CPAN
Loading