diff --git a/docs/cli-reference.rst b/docs/cli-reference.rst index 744bfe9b21..fd9676ad51 100644 --- a/docs/cli-reference.rst +++ b/docs/cli-reference.rst @@ -246,6 +246,9 @@ General Options * ``--freebsd-origin ABI`` - (freebsd only) Sets the FreeBSD 'origin' pkg field +* ``--freebsd-osversion VERSION`` + - (freebsd only) Sets the FreeBSD 'version' pkg field, ie. 12 or 13, use '*' for all. + * ``--gem-bin-path DIRECTORY`` - (gem only) The directory to install gem executables @@ -766,6 +769,9 @@ freebsd * ``--freebsd-origin ABI`` - Sets the FreeBSD 'origin' pkg field +* ``--freebsd-osversion VERSION`` + - Sets the FreeBSD 'version' pkg field, ie. 12 or 13, use '*' for all. + gem --- diff --git a/docs/contributing.rst b/docs/contributing.rst index 2f2390f420..3ab6b740a4 100644 --- a/docs/contributing.rst +++ b/docs/contributing.rst @@ -56,10 +56,15 @@ when it lists the FPM gem: If your system doesn't have `bsdtar` by default, make sure to install it or some tests will fail: - apt-get install bsdtar + apt-get install bsdtar || apt install libarchive-tools yum install bsdtar + +You also need these tools: + + apt-get install lintian cpanminus + Next, run make in root of the FPM repo. If there are any problems (such as missing dependencies) you should receive an error diff --git a/docs/packages/cli/freebsd.rst b/docs/packages/cli/freebsd.rst index 3f16a015e8..017872feb2 100644 --- a/docs/packages/cli/freebsd.rst +++ b/docs/packages/cli/freebsd.rst @@ -1,3 +1,5 @@ * ``--freebsd-origin ABI`` - Sets the FreeBSD 'origin' pkg field +* ``--freebsd-osversion VERSION`` + - Sets the FreeBSD 'version' pkg field, ie. 12 or 13, use '*' for all. diff --git a/lib/fpm/package/deb.rb b/lib/fpm/package/deb.rb index 71cccd84ff..e9790ad301 100644 --- a/lib/fpm/package/deb.rb +++ b/lib/fpm/package/deb.rb @@ -27,7 +27,7 @@ class FPM::Package::Deb < FPM::Package } unless defined?(SCRIPT_MAP) # The list of supported compression types. Default is gz (gzip) - COMPRESSION_TYPES = [ "gz", "bzip2", "xz", "none" ] + COMPRESSION_TYPES = [ "gz", "bzip2", "xz", "zst", "none" ] # https://www.debian.org/doc/debian-policy/ch-relationships.html#syntax-of-relationship-fields # Example value with version relationship: libc6 (>= 2.2.1) @@ -73,7 +73,7 @@ class FPM::Package::Deb < FPM::Package option "--compression", "COMPRESSION", "The compression type to use, must " \ "be one of #{COMPRESSION_TYPES.join(", ")}.", :default => "gz" do |value| if !COMPRESSION_TYPES.include?(value) - raise ArgumentError, "deb compression value of '#{value}' is invalid. " \ + raise FPM::Package::InvalidArgument, "deb compression value of '#{value}' is invalid. " \ "Must be one of #{COMPRESSION_TYPES.join(", ")}" end value @@ -337,6 +337,9 @@ def extract_info(package) when "xz" controltar = "control.tar.xz" compression = "-J" + when "zst" + controltar = "control.tar.zst" + compression = "-I zstd" when 'tar' controltar = "control.tar" compression = "" @@ -349,7 +352,7 @@ def extract_info(package) build_path("control").tap do |path| FileUtils.mkdir(path) if !File.directory?(path) - # unpack the control.tar.{,gz,bz2,xz} from the deb package into staging_path + # unpack the control.tar.{,gz,bz2,xz,zst} from the deb package into staging_path # Unpack the control tarball safesystem(ar_cmd[0] + " p #{package} #{controltar} | tar #{compression} -xf - -C #{path}") @@ -369,7 +372,7 @@ def extract_info(package) version_re = /^(?:([0-9]+):)?(.+?)(?:-(.*))?$/ m = version_re.match(parse.call("Version")) if !m - raise "Unsupported version string '#{parse.call("Version")}'" + raise FPM::InvalidPackageConfiguration, "Unsupported version string '#{parse.call("Version")}'" end self.epoch, self.version, self.iteration = m.captures @@ -459,6 +462,9 @@ def extract_files(package) when "xz" datatar = "data.tar.xz" compression = "-J" + when "zst" + datatar = "data.tar.zst" + compression = "-I zstd" when 'tar' datatar = "data.tar" compression = "" @@ -509,27 +515,36 @@ def output(output_path) end if attributes[:source_date_epoch] == "0" logger.error("Alas, ruby's Zlib::GzipWriter does not support setting an mtime of zero. Aborting.") - raise "#{name}: source_date_epoch of 0 not supported." + raise FPM::InvalidPackageConfiguration, "#{name}: source_date_epoch of 0 not supported." end if not attributes[:source_date_epoch].nil? and not ar_cmd_deterministic? logger.error("Alas, could not find an ar that can handle -D option. Try installing recent gnu binutils. Aborting.") - raise "#{name}: ar is insufficient to support source_date_epoch." + raise FPM::InvalidPackageConfiguration, "#{name}: ar is insufficient to support source_date_epoch." end if not attributes[:source_date_epoch].nil? and not tar_cmd_supports_sort_names_and_set_mtime? logger.error("Alas, could not find a tar that can set mtime and sort. Try installing recent gnu tar. Aborting.") - raise "#{name}: tar is insufficient to support source_date_epoch." + raise FPM::InvalidPackageConfiguration, "#{name}: tar is insufficient to support source_date_epoch." end attributes[:deb_systemd] = [] attributes.fetch(:deb_systemd_list, []).each do |systemd| - name = File.basename(systemd, ".service") - dest_systemd = staging_path(File.join(attributes[:deb_systemd_path], "#{name}.service")) + name = File.basename(systemd) + extname = File.extname(name) + + name_with_extension = if extname.empty? + "#{name}.service" + elsif [".service", ".timer"].include?(extname) + name + else + raise FPM::InvalidPackageConfiguration, "Invalid systemd unit file extension: #{extname}. Expected .service or .timer, or no extension." + end + + dest_systemd = staging_path(File.join(attributes[:deb_systemd_path], "#{name_with_extension}")) mkdir_p(File.dirname(dest_systemd)) FileUtils.cp(systemd, dest_systemd) File.chmod(0644, dest_systemd) - # add systemd service name to attribute - attributes[:deb_systemd] << name + attributes[:deb_systemd] << name_with_extension end if script?(:before_upgrade) or script?(:after_upgrade) or attributes[:deb_systemd].any? @@ -632,8 +647,12 @@ def output(output_path) end attributes.fetch(:deb_systemd_list, []).each do |systemd| - name = File.basename(systemd, ".service") - dest_systemd = staging_path(File.join(attributes[:deb_systemd_path], "#{name}.service")) + name = File.basename(systemd) + extname = File.extname(systemd) + name_with_extension = extname.empty? ? "#{name}.service" : name + + dest_systemd = staging_path(File.join(attributes[:deb_systemd_path], "#{name_with_extension}")) + mkdir_p(File.dirname(dest_systemd)) FileUtils.cp(systemd, dest_systemd) File.chmod(0644, dest_systemd) @@ -655,6 +674,10 @@ def output(output_path) datatar = build_path("data.tar.xz") controltar = build_path("control.tar.xz") compression_flags = ["-J"] + when "zst" + datatar = build_path("data.tar.zst") + controltar = build_path("control.tar.zst") + compression_flags = ["-I zstd"] when "none" datatar = build_path("data.tar") controltar = build_path("control.tar") @@ -726,7 +749,7 @@ def converted_from(origin) else # Also replace '::' in the perl module name with '-' modulename = m["name"].gsub("::", "-") - + # Fix any upper-casing or other naming concerns Debian has about packages name = "#{attributes[:cpan_package_name_prefix]}-#{modulename}" @@ -942,6 +965,9 @@ def write_control_tarball when "xz" controltar = "control.tar.xz" compression_flags = ["-J"] + when "zst" + controltar = "control.tar.zst" + compression_flags = ["-I zstd"] when "none" controltar = "control.tar" compression_flags = [] diff --git a/lib/fpm/package/freebsd.rb b/lib/fpm/package/freebsd.rb index 42d3df9823..2aab74be4b 100644 --- a/lib/fpm/package/freebsd.rb +++ b/lib/fpm/package/freebsd.rb @@ -16,6 +16,10 @@ class FPM::Package::FreeBSD < FPM::Package "Sets the FreeBSD 'origin' pkg field", :default => "fpm/" + option "--osversion", "VERSION", + "Sets the FreeBSD 'version' pkg field, ie 12 or 13, use '*' for all.", + :default => "13" + def output(output_path) output_check(output_path) @@ -90,28 +94,36 @@ def output(output_path) end # def output # Handle architecture naming conversion: - # :::[.other] + # :: def architecture - osname = %x{uname -s}.chomp - osversion = %x{uname -r}.chomp.split('.').first - - # Essentially because no testing on other platforms - arch = 'x86' + osname = 'FreeBSD' - wordsize = case @architecture + arch = case @architecture when nil, 'native' %x{getconf LONG_BIT}.chomp # 'native' is current arch when 'arm64' - '64' + 'arm64' + when 'aarch64' + 'arm64' when 'amd64' - '64' + 'amd64' + when 'x86_64' + 'amd64' when 'i386' - '32' + 'i386' + when 'i686' + 'i386' + when 'any' + '*' + when 'all' + '*' + when 'noarch' + '*' else %x{getconf LONG_BIT}.chomp # default to native, the current arch end - return [osname, osversion, arch, wordsize].join(':') + return [osname, attributes[:freebsd_osversion], arch].join(':') end def add_path(tar, tar_path, path) diff --git a/lib/fpm/package/python.rb b/lib/fpm/package/python.rb index 5754a053d4..7e0dfac1d3 100644 --- a/lib/fpm/package/python.rb +++ b/lib/fpm/package/python.rb @@ -171,13 +171,19 @@ def download_if_necessary(package, version=nil) # behind a directory with the Python package extracted and ready to be used. # For example, `pip download ... Django` puts `Django-4.0.4.tar.tz` into the build_path directory. # If we expect `pip` to leave an unknown-named file in the `build_path` directory, let's check for - # a single file and unpack it. I don't know if it will /always/ be a .tar.gz though. - files = ::Dir.glob(File.join(build_path, "*.tar.gz")) + # a single file and unpack it. + files = ::Dir.glob(File.join(build_path, "*.{tar.gz,zip}")) if files.length != 1 raise "Unexpected directory layout after `pip download ...`. This might be an fpm bug? The directory is #{build_path}" end - safesystem("tar", "-zxf", files[0], "-C", target) + if files[0].end_with?("tar.gz") + safesystem("tar", "-zxf", files[0], "-C", target) + elsif files[0].end_with?("zip") + safesystem("unzip", files[0], "-d", target) + else + raise "Unexpected file format after `pip download ...`. This might be an fpm bug? The file is #{files[0]}" + end else # no pip, use easy_install logger.debug("no pip, defaulting to easy_install", :easy_install => attributes[:python_easyinstall]) diff --git a/lib/fpm/package/rpm.rb b/lib/fpm/package/rpm.rb index a925256561..861568bc06 100644 --- a/lib/fpm/package/rpm.rb +++ b/lib/fpm/package/rpm.rb @@ -473,6 +473,7 @@ def output(output_path) args += ["--define", "dist .#{attributes[:rpm_dist]}"] if attributes[:rpm_dist] args += [ + "--buildroot", "#{build_path}/BUILD", "--define", "buildroot #{build_path}/BUILD", "--define", "_topdir #{build_path}", "--define", "_sourcedir #{build_path}", diff --git a/spec/fpm/package/deb_spec.rb b/spec/fpm/package/deb_spec.rb index 5334bb5d9d..687dedf924 100644 --- a/spec/fpm/package/deb_spec.rb +++ b/spec/fpm/package/deb_spec.rb @@ -413,7 +413,7 @@ def dpkg_field(field) context "when run against lintian" do before do - skip("Missing lintian program") unless have_lintian + skip("Missing lintian program") unless have_lintian end lintian_errors_to_ignore = [ @@ -535,7 +535,8 @@ def dpkg_field(field) { "bzip2" => "bz2", "xz" => "xz", - "gz" => "gz" + "gz" => "gz", + "zst" => "zst" }.each do |flag,suffix| context "when --deb-compression is #{flag}" do let(:target) { Stud::Temporary.pathname + ".deb" }