fpm 1.14.1 → 1.15.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '079f0bd8cc1fe2a84b6e5dfc38cc0ae2e509d271d9752e0fb739c7cde79c746b'
4
- data.tar.gz: 28ed14320c22c0dc5767781d3f325cd4e817b16e42999b0a2d1e2713522d0761
3
+ metadata.gz: ea647fcf022326ec4218db722e99c134664446ef0f5ce1885a7440acb1bc6a85
4
+ data.tar.gz: 8fa7b284c275629fac6d598211c2c54628c527435afbc835582279c760162786
5
5
  SHA512:
6
- metadata.gz: b6287a7079c1f00a327d92a268f46df825cdbcc5008d719a23a4dd8f4fdba574bedf735f559207781794c7c29cf39153092d1f1452d8d3ddd4d23f808a8856ae
7
- data.tar.gz: 4c90779c8b7990818a76dc4fd60035311fe8ad461e7717271abd11318d1cad10bff03783468ee78fa17bc8455d692deabd69c41bb0ffef8195d6c4be61a56d6e
6
+ metadata.gz: a8f4c7e20bc10732d29febc59824562d2da5d1273d6ca96788d0e033b08b9b4dad1fac8281f8030f70a65dd465fbffc194448f13291cc51105172e35370c1800
7
+ data.tar.gz: 4fcd3503b21ec04b1edb28ffca688898799d35f437cf097f4a3938adab78644bd0294bf9a4af327827bea63df04028150ada442727a0a41c005b59911c2d7a42
data/CHANGELOG.rst CHANGED
@@ -1,6 +1,38 @@
1
1
  Release Notes and Change Log
2
2
  ============================
3
3
 
4
+ 1.15.0 (November 13, 2022)
5
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^
6
+ * New flag ``--fpm-options-file path/to/file`` which allows you to specify additional fpm flags in an external file of your choosing. (`#1905`_, `#1902`_, `#1827`_; Jordan Sissel, Will Furnell, hjpotter92)
7
+ * deb: Periods are now accepted in package names (`#1899`_; C. Cooke)
8
+ * Fix bug where fpm would crash if ``--workdir`` pointed at a path that didn't
9
+ exist. (`#1959`_; Jordan Sissel)
10
+ * osxpkg: this package format now supports the fpm ``--prefix`` flag(`#1909`_, `#1908`_; Jordan Sissel, mcataga)
11
+ * cpan: Fix bug where fpm would fail on certain Perl modules due to their source tarball structure (`#1940`_; Nicholas Hubbard, William N. Braswell, Jr.)
12
+ * cpan: Fix crash on certain CPAN modules where the author field was blank (`#1942`_, `#1937`_, `#1523`_, `#1528`_; Nicholas Hubbard, William N. Braswell, Jr.)
13
+ * deb: The distribution field of the debian changelog and changes files will now use the value set by ``--deb-dist`` (default is "unstable") (`#1934`_; Chabert Loïc)
14
+ * python: Fix errors in how fpm invoked ``pip``. Previously, fpm would use pip's ``--build`` flag, but this was removed a while ago, and fpm is now aware! (`#1896`_, `#1831`_, `#1893`_, `#1916`_; Jordan Sissel, Svyatogor Chuykov)
15
+ * pleaserun: Add ``--pleaserun-user`` flag. (`#1912`_; Evgeny Stambulchik)
16
+ * deb: The default ``--deb-priority`` is now "optional" instead of "extra" (`#1913`_; Chris Novakovic)
17
+ * https://github.com/jordansissel/fpm/pull/1897 (`#1897`_; Jordan Sissel)
18
+ * Enable installation of fpm on older versions of ruby. This change removed ``git`` rubygem dependency. (`#1946`_, `#1923`_; Jordan Sissel, Andreas Wirooks, Ruslan Kuprieiev, jamshid, Lorenzo Castellino, Sam Hughes)
19
+ * Enable operation of fpm on very old versions of ruby (as old as Ruby 1.9.3). This changed removed ``json`` rubygem dependency. (`#1950`_, `#1949`_, `#1741`_, `#1264`_, `#1798`_, `#1800`_, `#1784`_; Jordan Sissel and many others)
20
+ * Fix bug where subprocesses could hang waiting for input (`#1955`_, `#1519`_, `#1522`_; Nicholas Hubbard, William N. Braswell, Jr.)
21
+ * Update Dockerfile to use ubuntu:20.04 (`#1935`_; Gnought)
22
+ * internal: Fix a code typo (`#1948`_; Nicholas Hubbard)
23
+ * internal tests: Support newer versions of lintian (`#1939`_, `#1907`_; Jordan Sissel)
24
+ * Improve support for Ruby 3.1.0 and newer that would previously crash with an error mentioning Psych::DisallowedClass (`#1898`_, `#1895`_; Jordan Sissel, Alexandre ZANNI)
25
+ * Improve support for Ruby 3.1.0 and newer that changed the API for ERB
26
+
27
+ 1.14.2 (March 30, 2022)
28
+ ^^^^^^^^^^^^^^^^^^^^^^^
29
+ * deb: fix bug causing ``--deb-compression none`` to invoke ``tar`` incorrectly (`#1879`_; John Howard)
30
+ * rpm: Better support for paths that have spaces and mixed quotation marks in them. (`#1882`_, `#1886`_, `#1385`_; John Bollinger and Jordan Sissel)
31
+ * pacman: Fix typo preventing the use of ``--pacman-compression xz`` (`#1876`_; mszprejda)
32
+ * docs: All supported package types now have dedicated documentation pages. Some pages are small stubs and would benefit from future improvement. (`#1884`_; mcandre, Jordan Sissel)
33
+ * docs: Small but lovely documentation fixes (`#1875`_ by Corey Quinn, `#1864`_ by Geoff Beier)
34
+ * Fixed mistake causing the test suite to fail when ``rake`` wasn't available. (`#1877`_; Jordan Sissel)
35
+
4
36
  1.14.1 (November 10, 2021)
5
37
  ^^^^^^^^^^^^^^^^^^^^^^^^^^
6
38
  * Fix a bug that impacted fpm api usage (from other ruby programs) that caused an error "NameError: uninitialized constant FPM::Package::CPAN" when trying to output a Deb package. (`#1854`_, `#1856`_; Karol Bucek, Jordan Sissel)
data/lib/fpm/command.rb CHANGED
@@ -247,6 +247,13 @@ class FPM::Command < Clamp::Command
247
247
  "See https://reproducible-builds.org/specs/source-date-epoch ",
248
248
  :environment_variable => "SOURCE_DATE_EPOCH"
249
249
 
250
+ option "--fpm-options-file", "FPM_OPTIONS_FILE",
251
+ "A file that contains additional fpm options. Any fpm flag format is valid in this file. " \
252
+ "This can be useful on build servers where you want to use a common configuration or " \
253
+ "inject other parameters from a file instead of from a command-line flag.." do |path|
254
+ load_options(path)
255
+ end
256
+
250
257
  parameter "[ARGS] ...",
251
258
  "Inputs to the source package type. For the 'dir' type, this is the files" \
252
259
  " and directories you want to include in the package. For others, like " \
@@ -291,6 +298,15 @@ class FPM::Command < Clamp::Command
291
298
  args << "."
292
299
  end
293
300
 
301
+ if !File.exists?(workdir)
302
+ logger.fatal("Given --workdir=#{workdir} is not a path that exists.")
303
+ raise FPM::Package::InvalidArgument, "The given workdir '#{workdir}' does not exist."
304
+ end
305
+ if !File.directory?(workdir)
306
+ logger.fatal("Given --workdir=#{workdir} must be a directory")
307
+ raise FPM::Package::InvalidArgument, "The given workdir '#{workdir}' must be a directory."
308
+ end
309
+
294
310
  logger.info("Setting workdir", :workdir => workdir)
295
311
  ENV["TMP"] = workdir
296
312
 
@@ -571,12 +587,86 @@ class FPM::Command < Clamp::Command
571
587
 
572
588
  ARGV.unshift(*flags)
573
589
  ARGV.push(*args)
590
+
574
591
  super(run_args)
575
592
  rescue FPM::Package::InvalidArgument => e
576
593
  logger.error("Invalid package argument: #{e}")
577
594
  return 1
578
595
  end # def run
579
596
 
597
+ def load_options(path)
598
+ @loaded_files ||= []
599
+
600
+ if @loaded_files.include?(path)
601
+ #logger.error("Options file was already loaded once. Refusing to load a second time.", :path => path)
602
+ raise FPM::Package::InvalidArgument, "Options file already loaded once. Refusing to load a second time. Maybe a file tries to load itself? Path: #{path}"
603
+ end
604
+
605
+ if !File.exist?(path)
606
+ logger.fatal("Cannot load options from file because the file doesn't exist.", :path => path)
607
+ end
608
+
609
+ if !File.readable?(path)
610
+ logger.fatal("Cannot load options from file because the file isn't readable.", :path => path)
611
+ end
612
+
613
+ @loaded_files << path
614
+
615
+ logger.info("Loading flags from file", :path => path)
616
+
617
+ # Safety check, abort if the file is huge. Arbitrarily chosen limit is 100kb
618
+ stat = File.stat(path)
619
+ max = 100 * 1024
620
+ if stat.size > max
621
+ logger.fatal("Refusing to load options from file because the file seems pretty large.", :path => path, :size => stat.size)
622
+ raise FPM::Package::InvalidArgument, "Options file given to --fpm-options-file is seems too large. For safety, fpm is refusing to load this. Path: #{path} - Size: #{stat.size}, maximum allowed size #{max}."
623
+ end
624
+
625
+ File.read(path).split($/).each do |line|
626
+ logger.info("Processing flags from file", :path => path, :line => line)
627
+ # With apologies for this hack to mdub (Mike Williams, author of Clamp)...
628
+ # The following code will read a file and parse the file
629
+ # as flags as if they were in same argument position as the given --fpm-options-file option.
630
+
631
+ args = Shellwords.split(line)
632
+ while args.any?
633
+ arg = args.shift
634
+
635
+ # Lookup the Clamp option by its --flag-name or short name like -f
636
+ if arg =~ /^-/
637
+ # Single-letter options like -a or -z
638
+ if single_letter = arg.match(/^(-[A-Za-z0-9])(.*)$/)
639
+ option = self.class.find_option(single_letter.match(1))
640
+ arg, remainder = single_letter.match(1), single_letter.match(2)
641
+ if option.flag?
642
+ # Flags aka switches take no arguments, so we push the rest of the 'arg' entry back onto the args list
643
+
644
+ # For combined letter flags, like `-abc`, we want to consume the
645
+ # `-a` and then push `-bc` back to be processed.
646
+ # Only do this if there's more flags, like, not for `-a` but yes for `-abc`
647
+ args.unshift("-" + remainder) unless remainder.empty?
648
+ else
649
+ # Single letter options that take arguments, like `-ohello` same as `-o hello`
650
+
651
+ # For single letter flags with values, like `-ofilename` aka `-o filename`, push the remainder ("filename")
652
+ # back onto the args list so that it is consumed when we extract the flag value.
653
+ args.unshift(remainder) unless remainder.empty?
654
+ end
655
+ elsif arg.match(/^--/)
656
+ # Lookup the flag by its long --flag-name
657
+ option = self.class.find_option(arg)
658
+ end
659
+ end
660
+
661
+ # Extract the flag value, if any, from the remaining args list.
662
+ value = option.extract_value(arg, args)
663
+
664
+ # Process the flag into `self`
665
+ option.of(self).take(value)
666
+ end
667
+ end
668
+ end
669
+
580
670
  # A simple flag validator
581
671
  #
582
672
  # The goal of this class is to ensure the flags and arguments given
@@ -112,6 +112,7 @@ class FPM::Package::CPAN < FPM::Package
112
112
  self.vendor = case metadata["author"]
113
113
  when String; metadata["author"]
114
114
  when Array; metadata["author"].join(", ")
115
+ when NilClass; "No Vendor Or Author Provided"
115
116
  else
116
117
  raise FPM::InvalidPackageConfiguration, "Unexpected CPAN 'author' field type: #{metadata["author"].class}. This is a bug."
117
118
  end if metadata.include?("author")
@@ -304,7 +305,7 @@ class FPM::Package::CPAN < FPM::Package
304
305
  directory = build_path("module")
305
306
  ::Dir.mkdir(directory)
306
307
  args = [ "-C", directory, "-zxf", tarball,
307
- "--strip-components", "1" ]
308
+ %q{--transform=s,[./]*[^/]*/,,} ]
308
309
  safesystem("tar", *args)
309
310
  return directory
310
311
  end
@@ -33,12 +33,17 @@ class FPM::Package::Deb < FPM::Package
33
33
  # Example value with version relationship: libc6 (>= 2.2.1)
34
34
  # Example value: libc6
35
35
 
36
+ # Package name docs here: https://www.debian.org/doc/debian-policy/ch-controlfields.html#s-f-source
37
+ # Package names (both source and binary, see Package) must consist only of lower case letters (a-z),
38
+ # digits (0-9), plus (+) and minus (-) signs, and periods (.).
39
+ # They must be at least two characters long and must start with an alphanumeric character.
40
+
36
41
  # Version string docs here: https://www.debian.org/doc/debian-policy/ch-controlfields.html#s-f-version
37
42
  # The format is: [epoch:]upstream_version[-debian_revision].
38
43
  # epoch - This is a single (generally small) unsigned integer
39
44
  # upstream_version - must contain only alphanumerics 6 and the characters . + - ~
40
45
  # debian_revision - only alphanumerics and the characters + . ~
41
- RELATIONSHIP_FIELD_PATTERN = /^(?<name>[A-z0-9_-]+)(?: *\((?<relation>[<>=]+) *(?<version>(?:[0-9]+:)?[0-9A-Za-z+~.-]+(?:-[0-9A-Za-z+~.]+)?)\))?$/
46
+ RELATIONSHIP_FIELD_PATTERN = /^(?<name>[A-z0-9][A-z0-9_.-]+)(?: *\((?<relation>[<>=]+) *(?<version>(?:[0-9]+:)?[0-9A-Za-z+~.-]+(?:-[0-9A-Za-z+~.]+)?)\))?$/
42
47
 
43
48
  option "--ignore-iteration-in-dependencies", :flag,
44
49
  "For '=' (equal) dependencies, allow iterations on the specified " \
@@ -93,7 +98,7 @@ class FPM::Package::Deb < FPM::Package
93
98
  end
94
99
 
95
100
  option "--priority", "PRIORITY",
96
- "The debian package 'priority' value.", :default => "extra"
101
+ "The debian package 'priority' value.", :default => "optional"
97
102
 
98
103
  option "--use-file-permissions", :flag,
99
104
  "Use existing file permissions when defining ownership and modes"
@@ -216,7 +221,7 @@ class FPM::Package::Deb < FPM::Package
216
221
 
217
222
  def initialize(*args)
218
223
  super(*args)
219
- attributes[:deb_priority] = "extra"
224
+ attributes[:deb_priority] = "optional"
220
225
  end # def initialize
221
226
 
222
227
  private
@@ -613,25 +618,24 @@ class FPM::Package::Deb < FPM::Package
613
618
  when "gz", nil
614
619
  datatar = build_path("data.tar.gz")
615
620
  controltar = build_path("control.tar.gz")
616
- compression = "-z"
621
+ compression_flags = ["-z"]
617
622
  when "bzip2"
618
623
  datatar = build_path("data.tar.bz2")
619
624
  controltar = build_path("control.tar.gz")
620
- compression = "-j"
625
+ compression_flags = ["-j"]
621
626
  when "xz"
622
627
  datatar = build_path("data.tar.xz")
623
628
  controltar = build_path("control.tar.xz")
624
- compression = "-J"
629
+ compression_flags = ["-J"]
625
630
  when "none"
626
631
  datatar = build_path("data.tar")
627
632
  controltar = build_path("control.tar")
628
- compression = ""
633
+ compression_flags = []
629
634
  else
630
635
  raise FPM::InvalidPackageConfiguration,
631
636
  "Unknown compression type '#{self.attributes[:deb_compression]}'"
632
637
  end
633
-
634
- args = [ tar_cmd, "-C", staging_path, compression ] + data_tar_flags + [ "-cf", datatar, "." ]
638
+ args = [ tar_cmd, "-C", staging_path ] + compression_flags + data_tar_flags + [ "-cf", datatar, "." ]
635
639
  if tar_cmd_supports_sort_names_and_set_mtime? and not attributes[:source_date_epoch].nil?
636
640
  # Use gnu tar options to force deterministic file order and timestamp
637
641
  args += ["--sort=name", ("--mtime=@%s" % attributes[:source_date_epoch])]
@@ -906,13 +910,13 @@ class FPM::Package::Deb < FPM::Package
906
910
  case self.attributes[:deb_compression]
907
911
  when "gz", "bzip2", nil
908
912
  controltar = "control.tar.gz"
909
- compression = "-z"
913
+ compression_flags = ["-z"]
910
914
  when "xz"
911
915
  controltar = "control.tar.xz"
912
- compression = "-J"
916
+ compression_flags = ["-J"]
913
917
  when "none"
914
918
  controltar = "control.tar"
915
- compression = ""
919
+ compression_flags = []
916
920
  else
917
921
  raise FPM::InvalidPackageConfiguration,
918
922
  "Unknown compression type '#{self.attributes[:deb_compression]}'"
@@ -922,7 +926,7 @@ class FPM::Package::Deb < FPM::Package
922
926
  build_path(controltar).tap do |controltar|
923
927
  logger.info("Creating", :path => controltar, :from => control_path)
924
928
 
925
- args = [ tar_cmd, "-C", control_path, compression, "-cf", controltar,
929
+ args = [ tar_cmd, "-C", control_path ] + compression_flags + [ "-cf", controltar,
926
930
  "--owner=0", "--group=0", "--numeric-owner", "." ]
927
931
  if tar_cmd_supports_sort_names_and_set_mtime? and not attributes[:source_date_epoch].nil?
928
932
  # Force deterministic file order and timestamp
@@ -104,19 +104,18 @@ class FPM::Package::Gem < FPM::Package
104
104
  FileUtils.mkdir(download_dir) unless File.directory?(download_dir)
105
105
 
106
106
  if attributes[:gem_git_repo]
107
- require "git"
108
107
  logger.debug("Git cloning in directory #{download_dir}")
109
- g = Git.clone(attributes[:gem_git_repo],gem_name,:path => download_dir)
108
+ safesystem("git", "-C", download_dir, "clone", attributes[:gem_git_repo], ".")
110
109
  if attributes[:gem_git_branch]
111
- g.branch(attributes[:gem_git_branch]).checkout
112
- g.pull('origin',attributes[:gem_git_branch])
110
+ safesystem("git", "-C", download_dir, "checkout", attributes[:gem_git_branch])
113
111
  end
114
- gem_build = [ "#{attributes[:gem_gem]}", "build", "#{g.dir.to_s}/#{gem_name}.gemspec"]
115
- ::Dir.chdir(g.dir.to_s) do |dir|
112
+
113
+ gem_build = [ "#{attributes[:gem_gem]}", "build", "#{download_dir}/#{gem_name}.gemspec"]
114
+ ::Dir.chdir(download_dir) do |dir|
116
115
  logger.debug("Building in directory #{dir}")
117
116
  safesystem(*gem_build)
118
117
  end
119
- gem_files = ::Dir.glob(File.join(g.dir.to_s, "*.gem"))
118
+ gem_files = ::Dir.glob(File.join(download_dir, "*.gem"))
120
119
  else
121
120
  gem_fetch = [ "#{attributes[:gem_gem]}", "fetch", gem_name]
122
121
  gem_fetch += ["--prerelease"] if attributes[:gem_prerelease?]
@@ -135,9 +134,19 @@ class FPM::Package::Gem < FPM::Package
135
134
  return gem_files.first
136
135
  end # def download
137
136
 
137
+ GEMSPEC_YAML_CLASSES = [ ::Gem::Specification, ::Gem::Version, Time, ::Gem::Dependency, ::Gem::Requirement, Symbol ]
138
138
  def load_package_info(gem_path)
139
-
140
- spec = YAML.load(%x{#{attributes[:gem_gem]} specification #{gem_path} --yaml})
139
+ # TODO(sissel): Maybe we should check if `safe_load` method exists instead of this version check?
140
+ if ::Gem::Version.new(RUBY_VERSION) >= ::Gem::Version.new("3.1.0")
141
+ # Ruby 3.1.0 switched to a Psych/YAML version that defaults to "safe" loading
142
+ # and unfortunately `gem specification --yaml` emits YAML that requires
143
+ # class loaders to process correctly
144
+ spec = YAML.load(%x{#{attributes[:gem_gem]} specification #{gem_path} --yaml},
145
+ :permitted_classes => GEMSPEC_YAML_CLASSES)
146
+ else
147
+ # Older versions of ruby call this method YAML.safe_load
148
+ spec = YAML.safe_load(%x{#{attributes[:gem_gem]} specification #{gem_path} --yaml}, GEMSPEC_YAML_CLASSES)
149
+ end
141
150
 
142
151
  if !attributes[:gem_package_prefix].nil?
143
152
  attributes[:gem_package_name_prefix] = attributes[:gem_package_prefix]
@@ -4,7 +4,6 @@ require "fileutils"
4
4
  require "fpm/package/dir"
5
5
  require 'tempfile' # stdlib
6
6
  require 'pathname' # stdlib
7
- require 'rexml/document' # stdlib
8
7
 
9
8
  # Use an OS X pkg built with pkgbuild.
10
9
  #
@@ -103,6 +102,7 @@ class FPM::Package::OSXpkg < FPM::Package
103
102
 
104
103
  # Extract name and version from PackageInfo XML
105
104
  def extract_info(package)
105
+ require 'rexml/document'
106
106
  build_path("expand").tap do |path|
107
107
  doc = REXML::Document.new File.open(File.join(path, "PackageInfo"))
108
108
  pkginfo_elem = doc.elements["pkg-info"]
@@ -148,6 +148,11 @@ class FPM::Package::OSXpkg < FPM::Package
148
148
  write_scripts
149
149
  args += ["--scripts", scripts_path]
150
150
  end
151
+
152
+ if attributes[:prefix]
153
+ args += ["--install-location", attributes[:prefix]]
154
+ end
155
+
151
156
  args << output_path
152
157
 
153
158
  safesystem("pkgbuild", *args)
@@ -234,7 +234,7 @@ class FPM::Package::Pacman < FPM::Package
234
234
  return ""
235
235
  when "gz"
236
236
  return ".gz"
237
- when "zx"
237
+ when "xz"
238
238
  return ".xz"
239
239
  when "bzip2"
240
240
  return ".bz2"
@@ -18,6 +18,7 @@ class FPM::Package::PleaseRun < FPM::Package
18
18
 
19
19
  option "--name", "SERVICE_NAME", "The name of the service you are creating"
20
20
  option "--chdir", "CHDIR", "The working directory used by the service"
21
+ option "--user", "USER", "The user to use for executing this program."
21
22
 
22
23
  private
23
24
  def input(command)
@@ -162,13 +162,22 @@ class FPM::Package::Python < FPM::Package
162
162
  ]
163
163
  end
164
164
 
165
- setup_cmd += [
166
- "--build",
167
- target,
168
- want_pkg,
169
- ]
170
-
165
+ setup_cmd << want_pkg
166
+
171
167
  safesystem(*setup_cmd)
168
+
169
+ # Pip removed the --build flag sometime in 2021, it seems: https://github.com/pypa/pip/issues/8333
170
+ # A workaround for pip removing the `--build` flag. Previously, `pip download --build ...` would leave
171
+ # behind a directory with the Python package extracted and ready to be used.
172
+ # For example, `pip download ... Django` puts `Django-4.0.4.tar.tz` into the build_path directory.
173
+ # If we expect `pip` to leave an unknown-named file in the `build_path` directory, let's check for
174
+ # a single file and unpack it. I don't know if it will /always/ be a .tar.gz though.
175
+ files = ::Dir.glob(File.join(build_path, "*.tar.gz"))
176
+ if files.length != 1
177
+ raise "Unexpected directory layout after `pip download ...`. This might be an fpm bug? The directory is #{build_path}"
178
+ end
179
+
180
+ safesystem("tar", "-zxf", files[0], "-C", target)
172
181
  else
173
182
  # no pip, use easy_install
174
183
  logger.debug("no pip, defaulting to easy_install", :easy_install => attributes[:python_easyinstall])
@@ -192,17 +192,26 @@ class FPM::Package::RPM < FPM::Package
192
192
  # Replace * with [*] to make rpm not use globs
193
193
  # Replace ? with [?] to make rpm not use globs
194
194
  # Replace % with [%] to make rpm not expand macros
195
+ # Replace whitespace with ? to make rpm not split the filename
196
+ # If and only if any of the above are done, then also replace ' with \', " with \", and \ with \\\\
197
+ # to accommodate escape and quote processing that rpm will perform in that case (but not otherwise)
195
198
  def rpm_fix_name(name)
196
- name = name.gsub(/(\ |\[|\]|\*|\?|\%|\$|')/, {
197
- ' ' => '?',
198
- '%' => '[%]',
199
- '$' => '[$]',
200
- '?' => '[?]',
201
- '*' => '[*]',
202
- '[' => '[\[]',
203
- ']' => '[\]]',
204
- "'" => "\\'",
205
- })
199
+ if name.match?(/[ \t*?%$\[\]]/)
200
+ name = name.gsub(/(\ |\t|\[|\]|\*|\?|\%|\$|'|"|\\)/, {
201
+ ' ' => '?',
202
+ "\t" => '?',
203
+ '%' => '[%]',
204
+ '$' => '[$]',
205
+ '?' => '[?]',
206
+ '*' => '[*]',
207
+ '[' => '[\[]',
208
+ ']' => '[\]]',
209
+ '"' => '\\"',
210
+ "'" => "\\'",
211
+ '\\' => '\\\\\\\\',
212
+ })
213
+ end
214
+ name
206
215
  end
207
216
 
208
217
  def rpm_file_entry(file)
data/lib/fpm/package.rb CHANGED
@@ -331,11 +331,12 @@ class FPM::Package
331
331
  template_path = File.join(template_dir, path)
332
332
  template_code = File.read(template_path)
333
333
  logger.info("Reading template", :path => template_path)
334
- erb = ERB.new(template_code, nil, "-")
334
+ erb = erbnew(template_code)
335
335
  erb.filename = template_path
336
336
  return erb
337
337
  end # def template
338
338
 
339
+
339
340
  #######################################
340
341
  # The following methods are provided to
341
342
  # easily override particular substitut-
@@ -518,7 +519,7 @@ class FPM::Package
518
519
  # flag), then apply it as an ERB template.
519
520
  def script(script_name)
520
521
  if attributes[:template_scripts?]
521
- erb = ERB.new(scripts[script_name], nil, "-")
522
+ erb = erbnew(scripts[script_name])
522
523
  # TODO(sissel): find the original file name for the file.
523
524
  erb.filename = "script(#{script_name})"
524
525
  return erb.result(binding)
data/lib/fpm/util.rb CHANGED
@@ -154,10 +154,13 @@ module FPM::Util
154
154
 
155
155
  yield(*args3)
156
156
 
157
- stdin_w_close if opts[:stdin] and not stdin_w.closed?
157
+ stdin_w.close if opts[:stdin] and not stdin_w.closed?
158
158
  stdout_r.close unless stdout_r.closed?
159
159
  stderr_r.close unless stderr_r.closed?
160
160
  else
161
+ # If no block given (not interactive) we should close stdin_w because we
162
+ # won't be able to give input which may cause a hang.
163
+ stdin_w.close
161
164
  # Log both stdout and stderr as 'info' because nobody uses stderr for
162
165
  # actually reporting errors and as a result 'stderr' is a misnomer.
163
166
  logger.pipe(stdout_r => :info, stderr_r => :info)
@@ -406,6 +409,33 @@ module FPM::Util
406
409
  def logger
407
410
  @logger ||= Cabin::Channel.get
408
411
  end # def logger
412
+
413
+ def erbnew(template_code)
414
+ # In Ruby 2.6(?), Ruby changed how ERB::new is invoked.
415
+ # First, it added keyword args like `ERB.new(..., trim_mode: "-")`
416
+ # Later, it deprecated then removed the safe_level feature.
417
+ # As of Ruby 3.1, warnings are printed at runtime when ERB.new is called with the old syntax.
418
+ # Ruby 2.5 and older does not support the ERB.new keyword args.
419
+ #
420
+ # My tests showed:
421
+ # * Ruby 2.3.0 through 3.0 work correctly with the old syntax.
422
+ # * Ruby 3.1.0 and newer (at time of writing, Ruby 3.2) require the new syntax
423
+ # Therefore, in order to support the most versions of ruby, we need to do a version check
424
+ # to invoke ERB.new correctly and without printed warnings.
425
+ # References: https://github.com/jordansissel/fpm/issues/1894
426
+ # Honestly, I'm not sure if Gem::Version is correct to use in this situation, but it works.
427
+
428
+ # on older versions of Ruby, RUBY_VERSION is a frozen string, and
429
+ # Gem::Version.new calls String#strip! which throws an exception.
430
+ # so we have to call String#dup to get an unfrozen copy.
431
+ if Gem::Version.new(RUBY_VERSION.dup) < Gem::Version.new("3.1.0")
432
+ # Ruby 3.0.x and older
433
+ return ERB.new(template_code, nil, "-")
434
+ else
435
+ # Ruby 3.1.0 and newer
436
+ return ERB.new(template_code, trim_mode: "-")
437
+ end
438
+ end
409
439
  end # module FPM::Util
410
440
 
411
441
  require 'fpm/util/tar_writer'
data/lib/fpm/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module FPM
2
- VERSION = "1.14.1"
2
+ VERSION = "1.15.0"
3
3
  end
@@ -1,4 +1,4 @@
1
- <%= name %> (<%= "#{epoch}:" if epoch %><%= version %><%= "-" + iteration.to_s if iteration %>) whatever; urgency=medium
1
+ <%= name %> (<%= "#{epoch}:" if epoch %><%= version %><%= "-" + iteration.to_s if iteration %>) <%= distribution %>; urgency=medium
2
2
 
3
3
  * Package created with FPM.
4
4
 
@@ -14,7 +14,7 @@ Description: <%= firstline %>
14
14
  <%= remainder.collect { |l| l =~ /^ *$/ ? " ." : " #{l}" }.join("\n") %>
15
15
  <% end -%>
16
16
  Changes:
17
- <%= name %> (<%= "#{epoch}:" if epoch %><%= version %><%= "-" + iteration.to_s if iteration %>) whatever; urgency=medium
17
+ <%= name %> (<%= "#{epoch}:" if epoch %><%= version %><%= "-" + iteration.to_s if iteration %>) <%= distribution %>; urgency=medium
18
18
  * Package created with FPM.
19
19
  Checksums-Sha1:
20
20
  <% changes_files.each do |file| -%>
metadata CHANGED
@@ -1,35 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fpm
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.14.1
4
+ version: 1.15.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jordan Sissel
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-11-10 00:00:00.000000000 Z
11
+ date: 2022-11-14 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: json
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - ">="
18
- - !ruby/object:Gem::Version
19
- version: 1.7.7
20
- - - "<"
21
- - !ruby/object:Gem::Version
22
- version: '3.0'
23
- type: :runtime
24
- prerelease: false
25
- version_requirements: !ruby/object:Gem::Requirement
26
- requirements:
27
- - - ">="
28
- - !ruby/object:Gem::Version
29
- version: 1.7.7
30
- - - "<"
31
- - !ruby/object:Gem::Version
32
- version: '3.0'
33
13
  - !ruby/object:Gem::Dependency
34
14
  name: cabin
35
15
  requirement: !ruby/object:Gem::Requirement
@@ -100,26 +80,6 @@ dependencies:
100
80
  - - "~>"
101
81
  - !ruby/object:Gem::Version
102
82
  version: 0.0.29
103
- - !ruby/object:Gem::Dependency
104
- name: git
105
- requirement: !ruby/object:Gem::Requirement
106
- requirements:
107
- - - ">="
108
- - !ruby/object:Gem::Version
109
- version: 1.3.0
110
- - - "<"
111
- - !ruby/object:Gem::Version
112
- version: '2.0'
113
- type: :runtime
114
- prerelease: false
115
- version_requirements: !ruby/object:Gem::Requirement
116
- requirements:
117
- - - ">="
118
- - !ruby/object:Gem::Version
119
- version: 1.3.0
120
- - - "<"
121
- - !ruby/object:Gem::Version
122
- version: '2.0'
123
83
  - !ruby/object:Gem::Dependency
124
84
  name: stud
125
85
  requirement: !ruby/object:Gem::Requirement
@@ -190,6 +150,20 @@ dependencies:
190
150
  - - ">="
191
151
  - !ruby/object:Gem::Version
192
152
  version: '0'
153
+ - !ruby/object:Gem::Dependency
154
+ name: rake
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ">="
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
193
167
  description: Convert directories, rpms, python eggs, rubygems, and more to rpms, debs,
194
168
  solaris packages and more. Win at package management without wasting pointless hours
195
169
  debugging bad rpm specs!
@@ -280,7 +254,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
280
254
  - !ruby/object:Gem::Version
281
255
  version: '0'
282
256
  requirements: []
283
- rubygems_version: 3.2.31
257
+ rubygems_version: 3.3.20
284
258
  signing_key:
285
259
  specification_version: 4
286
260
  summary: fpm - package building and mangling