jr-paperclip 8.0.0.beta.1 → 8.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '08e0a02cb6a9a3a1b126b744de6afe4654e9db7bf841bb710ac29b3cb702f5a2'
4
- data.tar.gz: 5c3c603853869aa41d56026de0d71788f87f7b98ec4d8382adc811e23bc9eb42
3
+ metadata.gz: 3a0a10e43e470a988afe5f30de3f2144f18bca45154654abdbf09b57817bee4b
4
+ data.tar.gz: 59df71bd9e4c0577f252165bf5b1d55202ffe8d363f0eae235d30db9c90b14fb
5
5
  SHA512:
6
- metadata.gz: 9b71eb967b7cb2b0980e665c4886bbb5754bac409677b0af4e13578101dde22d710ab2bc11e31287dac3e99520f53f9e9b44fe79f5285f5fd5aa2cfe070edf43
7
- data.tar.gz: ab955ec831d70c792bcaccbb41b5e2b6754fe0badddc1a52735d5a974f0982e3cdda316e5db9a274da73132482515ebf5b74775780d8e179e6d2493154370610
6
+ metadata.gz: 4ac11878b1797097dd0c6a369f39f03bc52153f2c9db2c2991d533b171a9f36fbec873b5859b55b378dbcb541d2d477f40de92d99456c7c3f5fb86c1d53eae5b
7
+ data.tar.gz: 8ec53d673eee2ddbfab2008ab3a3977d659dda2df53f9e7c34d9cef307b1889d53ead7ae3a3c4d4cebdc33452c9ec3e9a5c7abfefb36f46ca5e5f68ecf0bc644
@@ -7,32 +7,12 @@ assignees: ''
7
7
 
8
8
  ---
9
9
 
10
- **Describe the bug**
11
- A clear and concise description of what the bug is.
10
+ Ruby version:
11
+ Rails version:
12
+ Paperclip version:
13
+ ImageMagick version:
14
+ libvips version:
12
15
 
13
- **To Reproduce**
14
- Steps to reproduce the behavior:
15
- 1. Go to '...'
16
- 2. Click on '....'
17
- 3. Scroll down to '....'
18
- 4. See error
16
+ Please include your initializer, Paperclip related options, and any error message with the full backtrace.
19
17
 
20
- **Expected behavior**
21
- A clear and concise description of what you expected to happen.
22
-
23
- **Screenshots**
24
- If applicable, add screenshots to help explain your problem.
25
-
26
- **Desktop (please complete the following information):**
27
- - OS: [e.g. iOS]
28
- - Browser [e.g. chrome, safari]
29
- - Version [e.g. 22]
30
-
31
- **Smartphone (please complete the following information):**
32
- - Device: [e.g. iPhone6]
33
- - OS: [e.g. iOS8.1]
34
- - Browser [e.g. stock browser, safari]
35
- - Version [e.g. 22]
36
-
37
- **Additional context**
38
- Add any other context about the problem here.
18
+ If you are using an old version, have you checked the changelogs to see if your issue has been fixed in a later version?
@@ -46,7 +46,7 @@ jobs:
46
46
  - name: Install dependencies
47
47
  run: |
48
48
  sudo apt-get update
49
- sudo apt-get install -y ghostscript imagemagick libvips
49
+ sudo apt-get install -y ghostscript imagemagick libvips libvips-tools
50
50
  sudo rm -f /etc/ImageMagick-6/policy.xml
51
51
 
52
52
  - name: Run tests
data/NEWS CHANGED
@@ -1,4 +1,4 @@
1
- 8.0.0.beta.1 (2026-01-09)
1
+ 8.0.0 (2026-01-13)
2
2
 
3
3
  * Feature: Add libvips backend alongside ImageMagick via the image_processing gem
4
4
  * Feature: Per-attachment and per-style backend selection (`:backend` option)
data/README.md CHANGED
@@ -14,20 +14,17 @@ Legacy versions were dropped to reduce maintenance overhead and keep up with upd
14
14
 
15
15
  Additional maintainers are very welcome.
16
16
 
17
- ---
18
-
19
- We plan to support and maintain paperclip, as well as clean it up.
17
+ ## Version 8.0.0 brings major new features and improvements:
20
18
 
21
- Please feel free to contribute Issues and pull requests.
22
-
23
- ---
19
+ * Support for libvips backend alongside ImageMagick via the image_processing gem
20
+ * ImageMagick 7 support (uses `magick` command when available)
21
+ * Added `ALLOWED_IMAGEMAGICK_OPTIONS` security whitelist (GHSA-r4mg-4433-c7g3)
22
+ * Cross-platform convert_options support (-strip, -quality, -rotate, etc.)
24
23
 
25
- # Existing documentation
24
+ Please check the [Image Processor](#image-processor) and [Post Processing](#post-processing) sections for more details and the [VIPS Migration Guide](https://github.com/jukra/jr-paperclip/blob/master/VIPS_MIGRATION_GUIDE.md) for migration instructions.
26
25
 
27
26
  ## Documentation valid for `master` branch
28
27
 
29
- ---
30
-
31
28
  <!-- START doctoc generated TOC please keep comment here to allow auto update -->
32
29
  <!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
33
30
 
@@ -100,7 +97,7 @@ Requirements
100
97
 
101
98
  ### Ruby and Rails
102
99
 
103
- Paperclip now requires Ruby version **>= 2.3** and Rails version **>= 4.2**
100
+ Paperclip now requires Ruby version **>= 3.0** and Rails version **>= 7.0**
104
101
  (only if you're going to use Paperclip with Ruby on Rails).
105
102
 
106
103
  ### Image Processor
@@ -149,6 +146,9 @@ brew install vips
149
146
 
150
147
  # Ubuntu/Debian
151
148
  sudo apt install libvips
149
+
150
+ # If you also need the vips and vipsheader command line tools (for example custom processors)
151
+ sudo apt install libvips-tools
152
152
  ```
153
153
 
154
154
  Then configure Paperclip to use it as the default backend in `config/initializers/paperclip.rb` (or in your environment configuration):
@@ -211,7 +211,7 @@ Paperclip is distributed as a gem, which is how it should be used in your app.
211
211
  Include the gem in your Gemfile:
212
212
 
213
213
  ```ruby
214
- gem "jr-paperclip", "~> 7.3"
214
+ gem "jr-paperclip", "~> 8.0"
215
215
  ```
216
216
 
217
217
  Or, if you want to get the latest, you can get master from the main paperclip repository:
@@ -723,6 +723,7 @@ has_attached_file :avatar, styles: { thumb: ["32x32#", :png] }
723
723
  This will convert the "thumb" style to a 32x32 square in PNG format, regardless
724
724
  of what was uploaded. If the format is not specified, it is kept the same (e.g.
725
725
  JPGs will remain JPGs). `Paperclip::Thumbnail` uses the [image_processing](https://github.com/janko/image_processing) gem to process images. This allows support for both ImageMagick (via MiniMagick) and libvips backends.
726
+
726
727
  [ImageMagick's geometry documentation](http://www.imagemagick.org/script/command-line-processing.php#geometry)
727
728
  has more information on the accepted style formats, which are generally supported by both backends in Paperclip.
728
729
 
@@ -734,12 +735,14 @@ has_attached_file :image, styles: { regular: ['800x800>', :png]},
734
735
  convert_options: { regular: "-posterize 3"}
735
736
  ```
736
737
 
737
- Since Paperclip now delegates to the `image_processing` gem, you should refer to its documentation for available methods/operations for your chosen backend:
738
+ Paperclip delegates to the `image_processing` gem, but **whitelists supported options** for security. For ImageMagick, most standard options are supported. For libvips, a curated set of common options is available (see table below) and `Paperclip::Thumbnail` class for details. Unsupported options are logged as warnings and skipped.
739
+
740
+ For full backend capabilities, refer to the image_processing documentation:
738
741
 
739
742
  * **ImageMagick:** [ImageProcessing::MiniMagick documentation](https://github.com/janko/image_processing/blob/master/doc/minimagick.md)
740
743
  * **libvips:** [ImageProcessing::Vips documentation](https://github.com/janko/image_processing/blob/master/doc/vips.md)
741
744
 
742
- Common options like `-strip`, `-quality`, `-rotate`, `-blur` are supported on both backends, but backend-specific options (like `-density` for ImageMagick) might not be available or behave differently on libvips.
745
+ Common options like `-strip`, `-quality`, `-rotate`, `-blur` are supported on both backends. Backend-specific options (like `-density` for ImageMagick) may not be available on libvips.
743
746
 
744
747
  ### Cross-Platform Convert Options
745
748
 
@@ -757,6 +760,7 @@ Many common `convert_options` now work with **both** ImageMagick and libvips bac
757
760
  | `-colorspace X` | Color space (Gray, sRGB, CMYK) | `convert_options: "-colorspace Gray"` |
758
761
  | `-negate` | Invert colors | `convert_options: "-negate"` |
759
762
  | `-flatten` | Flatten transparency | `convert_options: "-flatten"` |
763
+ | `-gamma N` | Adjust image gamma | `convert_options: "-gamma 1.5"` |
760
764
  | `-auto-orient` | Auto-rotate via EXIF | `convert_options: "-auto-orient"` |
761
765
  | `-interlace X` | Progressive output | `convert_options: "-interlace Plane"` |
762
766
 
@@ -770,14 +774,6 @@ has_attached_file :avatar,
770
774
 
771
775
  **Note:** Some options only work with ImageMagick (e.g., `-density`, `-depth`, `-gravity`, `-crop`, `-trim`). When using the vips backend, these will be skipped with a warning logged.
772
776
 
773
- ImageMagick supports a number of environment variables for controlling its resource limits. For example, you can enforce memory or execution time limits by setting the following variables in your application's process environment:
774
-
775
- * `MAGICK_MEMORY_LIMIT=128MiB`
776
- * `MAGICK_MAP_LIMIT=64MiB`
777
- * `MAGICK_TIME_LIMIT=30`
778
-
779
- For a full list of variables and description, see [ImageMagick's resources documentation](http://www.imagemagick.org/script/resources.php).
780
-
781
777
  ---
782
778
 
783
779
  Image Processing Backends
@@ -787,16 +783,24 @@ jr-paperclip supports two image processing backends:
787
783
 
788
784
  ### ImageMagick (Default)
789
785
 
790
- The traditional backend, using ImageMagick via shell commands.
786
+ The traditional backend. Paperclip uses the `image_processing` gem (via `mini_magick`) to generate shell commands for ImageMagick.
791
787
 
792
788
  ```ruby
793
789
  has_attached_file :avatar,
794
790
  styles: { thumb: "100x100#" }
795
791
  ```
796
792
 
793
+ ImageMagick supports a number of environment variables for controlling its resource limits. For example, you can enforce memory or execution time limits by setting the following variables in your application's process environment:
794
+
795
+ * `MAGICK_MEMORY_LIMIT=128MiB`
796
+ * `MAGICK_MAP_LIMIT=64MiB`
797
+ * `MAGICK_TIME_LIMIT=30`
798
+
799
+ For a full list of variables and description, see [ImageMagick's resources documentation](http://www.imagemagick.org/script/resources.php).
800
+
797
801
  ### libvips (Recommended for Performance)
798
802
 
799
- libvips is significantly faster and uses less memory than ImageMagick.
803
+ libvips is significantly faster and uses less memory than ImageMagick. Paperclip uses the `image_processing` gem (via `ruby-vips`) to interface with libvips.
800
804
 
801
805
  **Usage:**
802
806
 
@@ -820,6 +824,12 @@ has_attached_file :document,
820
824
  }
821
825
  ```
822
826
 
827
+ libvips keeps a cache of recently executed operations. You can disable this for a drop in memory use:
828
+ ```ruby
829
+ Vips::cache_set_max 0
830
+ ```
831
+ **Note:** Typically this is not needed as libvips is already memory efficient. Disabling the cache is mostly useful in extremely memory-constrained environments (like AWS Lambda) where every MB counts. This [issue](https://github.com/libvips/ruby-vips/issues/225) has more information on memory usage.
832
+
823
833
  ---
824
834
 
825
835
  Custom Attachment Processors
@@ -14,6 +14,9 @@ brew install vips
14
14
 
15
15
  # Ubuntu/Debian
16
16
  sudo apt install libvips
17
+
18
+ # If you also need the vips and vipsheader command line tools (for example custom processors)
19
+ sudo apt install libvips-tools
17
20
  ```
18
21
 
19
22
  ## Step 1: Update your Gemfile
@@ -23,7 +26,7 @@ sudo apt install libvips
23
26
  Ensure you are using the latest version of the gem:
24
27
 
25
28
  ```ruby
26
- gem "jr-paperclip", "~> 8.0.0.beta"
29
+ gem "jr-paperclip", "~> 8.0"
27
30
  ```
28
31
 
29
32
  ## Step 2: Gradual Migration (Per-Attachment)
@@ -73,7 +76,7 @@ has_attached_file :avatar,
73
76
 
74
77
  ### ImageMagick-Only Options
75
78
 
76
- The following options only work with ImageMagick. When used with the vips backend, they will be skipped and a warning will be logged:
79
+ For example the following options only work with ImageMagick. When used with the vips backend, they will be skipped and a warning will be logged:
77
80
 
78
81
  `-density`, `-depth`, `-gravity`, `-crop`, `-extent`, `-alpha`, `-background`, `-type`, `-posterize`, `-dither`, `-colors`, `-channel`, `-transpose`, `-transverse`, `-normalize`, `-equalize`, `-trim`, `-monochrome`
79
82
 
@@ -89,6 +92,9 @@ However, if you want to migrate a custom processor to libvips, you can now use t
89
92
  module Paperclip
90
93
  class MyVipsProcessor < Processor
91
94
  def make
95
+ basename = File.basename(file.path, File.extname(file.path))
96
+ dst = Paperclip::TempfileFactory.new.generate("#{basename}.png")
97
+
92
98
  # Use the new vips helper instead of convert
93
99
  vips("thumbnail :src :dst 100",
94
100
  src: File.expand_path(file.path),
@@ -48,7 +48,7 @@ module Paperclip
48
48
  begin
49
49
  require "vips"
50
50
  rescue LoadError => e
51
- raise Errors::CommandNotFoundError.new("Could not load ruby-vips. Please install libvips and the image_processing gem.")
51
+ raise Errors::CommandNotFoundError.new("Could not load ruby-vips. Please install libvips.")
52
52
  end
53
53
 
54
54
  begin
@@ -80,7 +80,7 @@ module Paperclip
80
80
  begin
81
81
  require "vips"
82
82
  rescue LoadError
83
- raise Errors::CommandNotFoundError.new("Could not load ruby-vips. Please install libvips and the vips gem.")
83
+ raise Errors::CommandNotFoundError.new("Could not load ruby-vips. Please install libvips.")
84
84
  end
85
85
  Vips::Image.new_from_file(file_path, **options)
86
86
  end
@@ -476,30 +476,51 @@ module Paperclip
476
476
  pipeline.custom(&:flipver)
477
477
  when "flop"
478
478
  pipeline.custom(&:fliphor)
479
- when "blur"
479
+ when "blur", "gaussian_blur", "gaussblur"
480
480
  # Vips uses gaussblur with sigma parameter
481
481
  # ImageMagick blur is "radiusxsigma", extract sigma
482
482
  sigma = extract_blur_sigma(value)
483
- sigma ? pipeline.custom { |img| img.gaussblur(sigma) } : pipeline
484
- when "gaussian_blur"
485
- sigma = extract_blur_sigma(value)
486
- sigma ? pipeline.custom { |img| img.gaussblur(sigma) } : pipeline
483
+ sigma ? pipeline.gaussblur(sigma) : pipeline
487
484
  when "sharpen"
488
485
  # Vips sharpen has different parameters than ImageMagick
489
486
  # Use sensible defaults for unsharp masking
490
487
  pipeline.custom(&:sharpen)
491
- when "colorspace"
488
+ when "colorspace", "colourspace"
492
489
  # Vips uses British spelling "colourspace"
493
- value ? pipeline.custom { |img| img.colourspace(vips_colorspace(value)) } : pipeline
490
+ value ? pipeline.colourspace(vips_colorspace(value)) : pipeline
491
+ when "gamma"
492
+ # Vips gamma uses keyword argument
493
+ value ? pipeline.custom { |img| img.gamma(exponent: value.to_f) } : pipeline
494
494
  when "flatten"
495
495
  pipeline.custom { |img| img.flatten(background: [255, 255, 255]) }
496
496
  when "negate", "invert"
497
497
  pipeline.custom(&:invert)
498
- when "auto_orient"
498
+ when "auto_orient", "autorot"
499
499
  pipeline.autorot
500
500
  when "interlace"
501
501
  # Vips handles interlacing via saver options
502
502
  pipeline.saver(interlace: true)
503
+ # Vips-native options (direct vips method names)
504
+ when "median"
505
+ value ? pipeline.median(value.to_i) : pipeline
506
+ when "rot90"
507
+ pipeline.rot90
508
+ when "rot180"
509
+ pipeline.rot180
510
+ when "rot270"
511
+ pipeline.rot270
512
+ when "similarity"
513
+ # similarity for arbitrary rotation/scale
514
+ value ? pipeline.custom { |img| img.similarity(angle: value.to_f) } : pipeline
515
+ # Edge detection filters (no arguments)
516
+ when "canny"
517
+ pipeline.canny
518
+ when "sobel"
519
+ pipeline.sobel
520
+ when "prewitt"
521
+ pipeline.custom(&:prewitt)
522
+ when "scharr"
523
+ pipeline.custom(&:scharr)
503
524
  else
504
525
  # Unknown option - log warning for vips
505
526
  Paperclip.log("Warning: -#{opt_name} is not supported with vips backend, skipping")
@@ -1,3 +1,3 @@
1
1
  module Paperclip
2
- VERSION = "8.0.0.beta.1" unless defined?(Paperclip::VERSION)
2
+ VERSION = "8.0.0".freeze
3
3
  end
@@ -0,0 +1,44 @@
1
+ require "spec_helper"
2
+
3
+ module Paperclip
4
+ class MyVipsProcessor < Processor
5
+ def make
6
+ basename = File.basename(file.path, File.extname(file.path))
7
+ dst = Paperclip::TempfileFactory.new.generate("#{basename}.png")
8
+
9
+ # Use the new vips helper instead of convert
10
+ vips("thumbnail :src :dst 100",
11
+ src: File.expand_path(file.path),
12
+ dst: File.expand_path(dst.path))
13
+ dst
14
+ end
15
+ end
16
+ end
17
+
18
+ describe Paperclip::MyVipsProcessor do
19
+ let(:file) { File.open(fixture_file("50x50.png")) }
20
+ let(:options) { {} }
21
+ let(:attachment) { double }
22
+ let(:processor) { Paperclip::MyVipsProcessor.new(file, options, attachment) }
23
+
24
+ subject { processor.make }
25
+
26
+ it "processes the image using vips helper" do
27
+ expect(subject).to respond_to(:path)
28
+ expect(File.exist?(subject.path)).to be true
29
+
30
+ # Check width using vipsheader
31
+ require "shellwords"
32
+ dimensions = `identify -format "%wx%h" "#{Shellwords.escape(subject.path)}"`.strip
33
+ expect(dimensions).to eq("100x100")
34
+ end
35
+
36
+ it "calls the vips command" do
37
+ expect(Paperclip).to receive(:run).with(
38
+ "vips",
39
+ "thumbnail :src :dst 100",
40
+ hash_including(:src, :dst),
41
+ )
42
+ processor.make
43
+ end
44
+ end
@@ -11,8 +11,8 @@ describe Paperclip::Thumbnail do
11
11
 
12
12
  it "correctly applies options starting with +" do
13
13
  # The user's specific options - with Shellwords, quoted values are parsed correctly
14
- convert_options = '-coalesce +profile "!icc,*" +set date:modify +set date:create +set date:timestamp'
15
-
14
+ convert_options = '-coalesce -quality 90 +profile "!icc,*" +set date:modify ' \
15
+ "+set date:create +set date:timestamp -define jpeg:dct-method=float"
16
16
  thumb = Paperclip::Thumbnail.new(@file, {
17
17
  geometry: "100x100",
18
18
  convert_options: convert_options,
@@ -20,15 +20,17 @@ describe Paperclip::Thumbnail do
20
20
  }, @attachment)
21
21
 
22
22
  # Spy on the pipeline to verify the correct methods/arguments are called on it.
23
- allow(thumb).to receive(:apply_single_option).and_call_original
23
+ allow(thumb).to receive(:apply_imagemagick_option).and_call_original
24
24
  expect { thumb.make }.not_to raise_error
25
25
 
26
26
  # With Shellwords parsing, the outer quotes are stripped from "!icc,*" -> !icc,*
27
- expect(thumb).to have_received(:apply_single_option).with(anything, "coalesce", nil, "-")
28
- expect(thumb).to have_received(:apply_single_option).with(anything, "profile", "!icc,*", "+")
29
- expect(thumb).to have_received(:apply_single_option).with(anything, "set", "date:modify", "+")
30
- expect(thumb).to have_received(:apply_single_option).with(anything, "set", "date:create", "+")
31
- expect(thumb).to have_received(:apply_single_option).with(anything, "set", "date:timestamp", "+")
27
+ expect(thumb).to have_received(:apply_imagemagick_option).with(anything, "coalesce", nil, "-")
28
+ expect(thumb).to have_received(:apply_imagemagick_option).with(anything, "quality", "90", "-")
29
+ expect(thumb).to have_received(:apply_imagemagick_option).with(anything, "profile", "!icc,*", "+")
30
+ expect(thumb).to have_received(:apply_imagemagick_option).with(anything, "set", "date:modify", "+")
31
+ expect(thumb).to have_received(:apply_imagemagick_option).with(anything, "set", "date:create", "+")
32
+ expect(thumb).to have_received(:apply_imagemagick_option).with(anything, "set", "date:timestamp", "+")
33
+ expect(thumb).to have_received(:apply_imagemagick_option).with(anything, "define", "jpeg:dct-method=float", "-")
32
34
  end
33
35
  end
34
36
 
@@ -170,4 +172,54 @@ describe Paperclip::Thumbnail do
170
172
  expect(output).to include("second_prop: Second Value")
171
173
  end
172
174
  end
175
+
176
+ context "with vips-specific convert_options" do
177
+ before do
178
+ begin
179
+ require "vips"
180
+ rescue LoadError
181
+ skip "libvips not installed"
182
+ end
183
+ @file = File.new(fixture_file("5k.png"), "rb")
184
+ @attachment = double("Attachment", options: {})
185
+ end
186
+
187
+ after { @file.close if @file && !@file.closed? }
188
+
189
+ it "processes vips-native options correctly" do
190
+ convert_options = "-rot90"
191
+ file = File.new(fixture_file("rotated.jpg"), "rb")
192
+
193
+ thumb = Paperclip::Thumbnail.new(file, {
194
+ geometry: "100x100",
195
+ convert_options: convert_options,
196
+ backend: :vips,
197
+ }, @attachment)
198
+
199
+ # Processes without error
200
+ result = nil
201
+ expect { result = thumb.make }.not_to raise_error
202
+
203
+ require "shellwords"
204
+ dimensions = `identify -format "%wx%h" "#{Shellwords.escape(result.path)}"`.strip
205
+ width, height = dimensions.split("x").map(&:to_i)
206
+ # After 90 degree rotate, width should be greater than height
207
+ expect(width).to be > height
208
+ file.close
209
+ end
210
+
211
+ it "logs warning for unsupported vips options" do
212
+ convert_options = "-coalesce -unknown_vips_option foo"
213
+
214
+ thumb = Paperclip::Thumbnail.new(@file, {
215
+ geometry: "100x100",
216
+ convert_options: convert_options,
217
+ backend: :vips,
218
+ }, @attachment)
219
+
220
+ expect(Paperclip).to receive(:log).with(/Warning.*coalesce.*not supported/)
221
+ expect(Paperclip).to receive(:log).with(/Warning.*unknown_vips_option.*not supported/)
222
+ expect { thumb.make }.not_to raise_error
223
+ end
224
+ end
173
225
  end
@@ -71,20 +71,20 @@ describe Paperclip::Thumbnail do
71
71
 
72
72
  # Process with vips backend
73
73
  vips_processor = described_class.new(@file, {
74
- geometry: "50x50#",
75
- backend: :vips,
76
- style: :vips_thumb
77
- }, attachment)
74
+ geometry: "50x50#",
75
+ backend: :vips,
76
+ style: :vips_thumb,
77
+ }, attachment)
78
78
  vips_result = vips_processor.make
79
79
 
80
80
  @file.rewind
81
81
 
82
82
  # Process with image_magick backend
83
83
  magick_processor = described_class.new(@file, {
84
- geometry: "50x50#",
85
- backend: :image_magick,
86
- style: :magick_thumb
87
- }, attachment)
84
+ geometry: "50x50#",
85
+ backend: :image_magick,
86
+ style: :magick_thumb,
87
+ }, attachment)
88
88
  magick_result = magick_processor.make
89
89
 
90
90
  # Both should produce valid 50x50 images
@@ -108,20 +108,20 @@ describe Paperclip::Thumbnail do
108
108
 
109
109
  # Large preview with vips (faster for large images)
110
110
  vips_processor = described_class.new(@file, {
111
- geometry: "200x200>",
112
- backend: :vips,
113
- style: :preview
114
- }, attachment)
111
+ geometry: "200x200>",
112
+ backend: :vips,
113
+ style: :preview,
114
+ }, attachment)
115
115
  vips_result = vips_processor.make
116
116
 
117
117
  @file.rewind
118
118
 
119
119
  # Small thumbnail with image_magick
120
120
  magick_processor = described_class.new(@file, {
121
- geometry: "32x32#",
122
- backend: :image_magick,
123
- style: :icon
124
- }, attachment)
121
+ geometry: "32x32#",
122
+ backend: :image_magick,
123
+ style: :icon,
124
+ }, attachment)
125
125
  magick_result = magick_processor.make
126
126
 
127
127
  # Verify dimensions
@@ -186,11 +186,9 @@ describe Paperclip::Thumbnail do
186
186
 
187
187
  context "with vips backend" do
188
188
  before do
189
- begin
190
- require "vips"
191
- rescue LoadError
192
- skip "libvips not installed"
193
- end
189
+ require "vips"
190
+ rescue LoadError
191
+ skip "libvips not installed"
194
192
  end
195
193
 
196
194
  it "resizes image to specified dimensions" do
@@ -216,7 +214,7 @@ describe Paperclip::Thumbnail do
216
214
  # Verify it detects logical dimensions (rotated from 300x200 to 200x300)
217
215
  expect(processor.current_geometry.width).to eq(200)
218
216
  result = processor.make
219
-
217
+
220
218
  cmd = %[identify -format "%wx%h" "#{result.path}"]
221
219
  # Original 300x200 with orientation 6 (90 deg CW).
222
220
  # Post autorot: 200x300.
@@ -225,7 +223,8 @@ describe Paperclip::Thumbnail do
225
223
  end
226
224
 
227
225
  it "strips metadata when requested via convert_options" do
228
- processor = described_class.new(@file, { geometry: "50x50", convert_options: "-strip", backend: :vips }, attachment)
226
+ processor = described_class.new(@file, { geometry: "50x50", convert_options: "-strip", backend: :vips },
227
+ attachment)
229
228
  result = processor.make
230
229
 
231
230
  # identify -verbose shows less output when stripped
@@ -407,10 +406,10 @@ describe Paperclip::Thumbnail do
407
406
  # -strip is cross-platform, should work without warning
408
407
  expect(Paperclip).not_to receive(:log).with(/Warning/)
409
408
  processor = described_class.new(@file, {
410
- geometry: "50x50",
411
- backend: :vips,
412
- convert_options: "-strip",
413
- }, attachment)
409
+ geometry: "50x50",
410
+ backend: :vips,
411
+ convert_options: "-strip",
412
+ }, attachment)
414
413
  processor.make
415
414
  end
416
415
 
@@ -424,10 +423,10 @@ describe Paperclip::Thumbnail do
424
423
  # -density is ImageMagick-only, should warn
425
424
  expect(Paperclip).to receive(:log).with(/Warning.*density.*not supported.*vips/)
426
425
  processor = described_class.new(@file, {
427
- geometry: "50x50",
428
- backend: :vips,
429
- convert_options: "-density 150",
430
- }, attachment)
426
+ geometry: "50x50",
427
+ backend: :vips,
428
+ convert_options: "-density 150",
429
+ }, attachment)
431
430
  processor.make
432
431
  end
433
432
  end
@@ -439,10 +438,10 @@ describe Paperclip::Thumbnail do
439
438
  # Helper to create a thumbnail with specific convert_options
440
439
  def make_thumb_with_options(file, options_string)
441
440
  thumb = Paperclip::Thumbnail.new(file, {
442
- geometry: "100x100",
443
- convert_options: options_string,
444
- backend: :image_magick,
445
- }, attachment)
441
+ geometry: "100x100",
442
+ convert_options: options_string,
443
+ backend: :image_magick,
444
+ }, attachment)
446
445
  thumb.make
447
446
  end
448
447
 
@@ -576,11 +575,11 @@ describe Paperclip::Thumbnail do
576
575
  # Use JPEG to test interlacing (PNG reports format name instead)
577
576
  file = File.new(fixture_file("rotated.jpg"), "rb")
578
577
  thumb = Paperclip::Thumbnail.new(file, {
579
- geometry: "100x100",
580
- convert_options: "-interlace Plane",
581
- backend: :image_magick,
582
- format: :jpg,
583
- }, attachment)
578
+ geometry: "100x100",
579
+ convert_options: "-interlace Plane",
580
+ backend: :image_magick,
581
+ format: :jpg,
582
+ }, attachment)
584
583
  result = thumb.make
585
584
 
586
585
  interlace = `identify -format "%[interlace]" "#{result.path}"`.strip
@@ -602,10 +601,10 @@ describe Paperclip::Thumbnail do
602
601
  # Use a square image for predictable crop results
603
602
  file = File.new(fixture_file("50x50.png"), "rb")
604
603
  thumb = Paperclip::Thumbnail.new(file, {
605
- geometry: "50x50", # Keep original size
606
- convert_options: "-crop 25x25+0+0 +repage",
607
- backend: :image_magick,
608
- }, attachment)
604
+ geometry: "50x50", # Keep original size
605
+ convert_options: "-crop 25x25+0+0 +repage",
606
+ backend: :image_magick,
607
+ }, attachment)
609
608
  result = thumb.make
610
609
 
611
610
  dimensions = `identify -format "%wx%h" "#{result.path}"`.strip
@@ -759,11 +758,9 @@ describe Paperclip::Thumbnail do
759
758
  let(:attachment) { double("Attachment", options: {}) }
760
759
 
761
760
  before do
762
- begin
763
- require "vips"
764
- rescue LoadError
765
- skip "libvips not installed"
766
- end
761
+ require "vips"
762
+ rescue LoadError
763
+ skip "libvips not installed"
767
764
  end
768
765
 
769
766
  # Helper to create a thumbnail with vips backend and specific convert_options
@@ -1211,8 +1208,11 @@ describe Paperclip::Thumbnail do
1211
1208
  end
1212
1209
 
1213
1210
  def width; 100; end
1211
+
1214
1212
  def height; 100; end
1213
+
1215
1214
  def modifier; nil; end
1215
+
1216
1216
  def auto_orient; end
1217
1217
  end
1218
1218
 
@@ -1237,7 +1237,9 @@ describe Paperclip::Thumbnail do
1237
1237
  end
1238
1238
 
1239
1239
  def width; 151; end
1240
+
1240
1241
  def height; 167; end
1242
+
1241
1243
  def modifier; nil; end
1242
1244
  end
1243
1245
 
@@ -1403,7 +1405,7 @@ describe Paperclip::Thumbnail do
1403
1405
  @file,
1404
1406
  geometry: "50x50",
1405
1407
  frame_index: 5,
1406
- format: :jpg
1408
+ format: :jpg,
1407
1409
  )
1408
1410
  end
1409
1411
 
@@ -1415,11 +1417,9 @@ describe Paperclip::Thumbnail do
1415
1417
 
1416
1418
  context "with vips backend" do
1417
1419
  before do
1418
- begin
1419
- require "vips"
1420
- rescue LoadError
1421
- skip "libvips not installed"
1422
- end
1420
+ require "vips"
1421
+ rescue LoadError
1422
+ skip "libvips not installed"
1423
1423
  end
1424
1424
 
1425
1425
  it "preserves animation when output is GIF" do
@@ -1431,7 +1431,8 @@ describe Paperclip::Thumbnail do
1431
1431
  end
1432
1432
 
1433
1433
  it "collapses animation when animated: false is set" do
1434
- processor = Paperclip::Thumbnail.new(@file, { geometry: "50x50", format: :gif, animated: false, backend: :vips })
1434
+ processor = Paperclip::Thumbnail.new(@file,
1435
+ { geometry: "50x50", format: :gif, animated: false, backend: :vips })
1435
1436
  dst = processor.make
1436
1437
  cmd = %[identify -format "%wx%h," "#{dst.path}"]
1437
1438
  frames = `#{cmd}`.chomp.split(",").reject(&:empty?)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jr-paperclip
3
3
  version: !ruby/object:Gem::Version
4
- version: 8.0.0.beta.1
4
+ version: 8.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jukka Rautanen
@@ -389,7 +389,6 @@ extra_rdoc_files: []
389
389
  files:
390
390
  - ".github/FUNDING.yml"
391
391
  - ".github/ISSUE_TEMPLATE/bug_report.md"
392
- - ".github/ISSUE_TEMPLATE/custom.md"
393
392
  - ".github/ISSUE_TEMPLATE/feature_request.md"
394
393
  - ".github/workflows/reviewdog.yml"
395
394
  - ".github/workflows/tests.yml"
@@ -533,6 +532,7 @@ files:
533
532
  - spec/paperclip/matchers/validate_attachment_size_matcher_spec.rb
534
533
  - spec/paperclip/media_type_spoof_detector_spec.rb
535
534
  - spec/paperclip/meta_class_spec.rb
535
+ - spec/paperclip/migration_guide_example_spec.rb
536
536
  - spec/paperclip/paperclip_missing_attachment_styles_spec.rb
537
537
  - spec/paperclip/paperclip_spec.rb
538
538
  - spec/paperclip/plural_cache_spec.rb
@@ -673,6 +673,7 @@ test_files:
673
673
  - spec/paperclip/matchers/validate_attachment_size_matcher_spec.rb
674
674
  - spec/paperclip/media_type_spoof_detector_spec.rb
675
675
  - spec/paperclip/meta_class_spec.rb
676
+ - spec/paperclip/migration_guide_example_spec.rb
676
677
  - spec/paperclip/paperclip_missing_attachment_styles_spec.rb
677
678
  - spec/paperclip/paperclip_spec.rb
678
679
  - spec/paperclip/plural_cache_spec.rb
@@ -1,10 +0,0 @@
1
- ---
2
- name: Custom issue template
3
- about: Describe this issue template's purpose here.
4
- title: ''
5
- labels: ''
6
- assignees: ''
7
-
8
- ---
9
-
10
-