rbuchberger / jekyll_picture_tag

Easy responsive images for Jekyll.
https://rbuchberger.github.io/jekyll_picture_tag/
BSD 3-Clause "New" or "Revised" License
620 stars 104 forks source link

undefined method `width' for nil:NilClass #243

Open kinoute opened 3 years ago

kinoute commented 3 years ago

Hello,

I'm trying to use this plugin to first, add width and height attributes to my post images automatically, and secondly to generate responsive images.

Unfortunately, I struggle to make it work: even when I use the picture tag alone, without any preset, I'm getting this error:

bundle exec jekyll serve --livereload --trace
Configuration file: /Users/kinoute/Sites/kinoute.github.io/_config.yml
            Source: /Users/kinoute/Sites/kinoute.github.io
       Destination: /Users/kinoute/Sites/kinoute.github.io/_site
 Incremental build: disabled. Enable with --incremental
      Generating...
       Jekyll Feed: Generating feed for posts
  Liquid Exception: undefined method `width' for nil:NilClass in /Users/kinoute/Sites/kinoute.github.io/_posts/2022-01-01-ok.md
bundler: failed to load command: jekyll (/usr/local/lib/ruby/gems/2.6.0/bin/jekyll)
Traceback (most recent call last):
    61: from /usr/local/opt/ruby@2.6/bin/bundle:23:in `<main>'
    60: from /usr/local/opt/ruby@2.6/bin/bundle:23:in `load'
    59: from /usr/local/lib/ruby/gems/2.6.0/gems/bundler-2.2.14/exe/bundle:37:in `<top (required)>'
    58: from /usr/local/lib/ruby/gems/2.6.0/gems/bundler-2.2.14/lib/bundler/friendly_errors.rb:130:in `with_friendly_errors'
    57: from /usr/local/lib/ruby/gems/2.6.0/gems/bundler-2.2.14/exe/bundle:49:in `block in <top (required)>'
    56: from /usr/local/lib/ruby/gems/2.6.0/gems/bundler-2.2.14/lib/bundler/cli.rb:24:in `start'
    55: from /usr/local/lib/ruby/gems/2.6.0/gems/bundler-2.2.14/lib/bundler/vendor/thor/lib/thor/base.rb:485:in `start'
    54: from /usr/local/lib/ruby/gems/2.6.0/gems/bundler-2.2.14/lib/bundler/cli.rb:30:in `dispatch'
    53: from /usr/local/lib/ruby/gems/2.6.0/gems/bundler-2.2.14/lib/bundler/vendor/thor/lib/thor.rb:392:in `dispatch'
    52: from /usr/local/lib/ruby/gems/2.6.0/gems/bundler-2.2.14/lib/bundler/vendor/thor/lib/thor/invocation.rb:127:in `invoke_command'
    51: from /usr/local/lib/ruby/gems/2.6.0/gems/bundler-2.2.14/lib/bundler/vendor/thor/lib/thor/command.rb:27:in `run'
    50: from /usr/local/lib/ruby/gems/2.6.0/gems/bundler-2.2.14/lib/bundler/cli.rb:494:in `exec'
    49: from /usr/local/lib/ruby/gems/2.6.0/gems/bundler-2.2.14/lib/bundler/cli/exec.rb:28:in `run'
    48: from /usr/local/lib/ruby/gems/2.6.0/gems/bundler-2.2.14/lib/bundler/cli/exec.rb:63:in `kernel_load'
    47: from /usr/local/lib/ruby/gems/2.6.0/gems/bundler-2.2.14/lib/bundler/cli/exec.rb:63:in `load'
    46: from /usr/local/lib/ruby/gems/2.6.0/bin/jekyll:23:in `<top (required)>'
    45: from /usr/local/lib/ruby/gems/2.6.0/bin/jekyll:23:in `load'
    44: from /usr/local/lib/ruby/gems/2.6.0/gems/jekyll-4.2.0/exe/jekyll:15:in `<top (required)>'
    43: from /usr/local/lib/ruby/gems/2.6.0/gems/mercenary-0.4.0/lib/mercenary.rb:21:in `program'
    42: from /usr/local/lib/ruby/gems/2.6.0/gems/mercenary-0.4.0/lib/mercenary/program.rb:44:in `go'
    41: from /usr/local/lib/ruby/gems/2.6.0/gems/mercenary-0.4.0/lib/mercenary/command.rb:221:in `execute'
    40: from /usr/local/lib/ruby/gems/2.6.0/gems/mercenary-0.4.0/lib/mercenary/command.rb:221:in `each'
    39: from /usr/local/lib/ruby/gems/2.6.0/gems/mercenary-0.4.0/lib/mercenary/command.rb:221:in `block in execute'
    38: from /usr/local/lib/ruby/gems/2.6.0/gems/jekyll-4.2.0/lib/jekyll/commands/serve.rb:86:in `block (2 levels) in init_with_program'
    37: from /usr/local/lib/ruby/gems/2.6.0/gems/jekyll-4.2.0/lib/jekyll/command.rb:91:in `process_with_graceful_fail'
    36: from /usr/local/lib/ruby/gems/2.6.0/gems/jekyll-4.2.0/lib/jekyll/command.rb:91:in `each'
    35: from /usr/local/lib/ruby/gems/2.6.0/gems/jekyll-4.2.0/lib/jekyll/command.rb:91:in `block in process_with_graceful_fail'
    34: from /usr/local/lib/ruby/gems/2.6.0/gems/jekyll-4.2.0/lib/jekyll/commands/build.rb:36:in `process'
    33: from /usr/local/lib/ruby/gems/2.6.0/gems/jekyll-4.2.0/lib/jekyll/commands/build.rb:65:in `build'
    32: from /usr/local/lib/ruby/gems/2.6.0/gems/jekyll-4.2.0/lib/jekyll/command.rb:28:in `process_site'
    31: from /usr/local/lib/ruby/gems/2.6.0/gems/jekyll-4.2.0/lib/jekyll/site.rb:80:in `process'
    30: from /usr/local/lib/ruby/gems/2.6.0/gems/jekyll-4.2.0/lib/jekyll/site.rb:210:in `render'
    29: from /usr/local/lib/ruby/gems/2.6.0/gems/jekyll-4.2.0/lib/jekyll/site.rb:530:in `render_docs'
    28: from /usr/local/lib/ruby/gems/2.6.0/gems/jekyll-4.2.0/lib/jekyll/site.rb:530:in `each_value'
    27: from /usr/local/lib/ruby/gems/2.6.0/gems/jekyll-4.2.0/lib/jekyll/site.rb:531:in `block in render_docs'
    26: from /usr/local/lib/ruby/gems/2.6.0/gems/jekyll-4.2.0/lib/jekyll/site.rb:531:in `each'
    25: from /usr/local/lib/ruby/gems/2.6.0/gems/jekyll-4.2.0/lib/jekyll/site.rb:532:in `block (2 levels) in render_docs'
    24: from /usr/local/lib/ruby/gems/2.6.0/gems/jekyll-4.2.0/lib/jekyll/site.rb:547:in `render_regenerated'
    23: from /usr/local/lib/ruby/gems/2.6.0/gems/jekyll-4.2.0/lib/jekyll/renderer.rb:63:in `run'
    22: from /usr/local/lib/ruby/gems/2.6.0/gems/jekyll-4.2.0/lib/jekyll/renderer.rb:80:in `render_document'
    21: from /usr/local/lib/ruby/gems/2.6.0/gems/jekyll-4.2.0/lib/jekyll/renderer.rb:131:in `render_liquid'
    20: from /usr/local/lib/ruby/gems/2.6.0/gems/jekyll-4.2.0/lib/jekyll/liquid_renderer/file.rb:36:in `render!'
    19: from /usr/local/lib/ruby/gems/2.6.0/gems/jekyll-4.2.0/lib/jekyll/liquid_renderer/file.rb:70:in `measure_time'
    18: from /usr/local/lib/ruby/gems/2.6.0/gems/jekyll-4.2.0/lib/jekyll/liquid_renderer/file.rb:37:in `block in render!'
    17: from /usr/local/lib/ruby/gems/2.6.0/gems/jekyll-4.2.0/lib/jekyll/liquid_renderer/file.rb:63:in `measure_bytes'
    16: from /usr/local/lib/ruby/gems/2.6.0/gems/jekyll-4.2.0/lib/jekyll/liquid_renderer/file.rb:38:in `block (2 levels) in render!'
    15: from /usr/local/lib/ruby/gems/2.6.0/gems/jekyll-4.2.0/lib/jekyll/liquid_renderer/file.rb:59:in `measure_counts'
    14: from /usr/local/lib/ruby/gems/2.6.0/gems/jekyll-4.2.0/lib/jekyll/liquid_renderer/file.rb:39:in `block (3 levels) in render!'
    13: from /usr/local/lib/ruby/gems/2.6.0/gems/liquid-4.0.3/lib/liquid/template.rb:220:in `render!'
    12: from /usr/local/lib/ruby/gems/2.6.0/gems/liquid-4.0.3/lib/liquid/template.rb:207:in `render'
    11: from /usr/local/lib/ruby/gems/2.6.0/gems/liquid-4.0.3/lib/liquid/template.rb:242:in `with_profiling'
    10: from /usr/local/lib/ruby/gems/2.6.0/gems/liquid-4.0.3/lib/liquid/template.rb:208:in `block in render'
     9: from /usr/local/lib/ruby/gems/2.6.0/gems/liquid-4.0.3/lib/liquid/block_body.rb:91:in `render'
     8: from /usr/local/lib/ruby/gems/2.6.0/gems/liquid-4.0.3/lib/liquid/block_body.rb:103:in `render_node_to_output'
     7: from /usr/local/lib/ruby/gems/2.6.0/gems/jekyll_picture_tag-2.0.0/lib/jekyll_picture_tag.rb:71:in `render'
     6: from /usr/local/lib/ruby/gems/2.6.0/gems/jekyll_picture_tag-2.0.0/lib/jekyll_picture_tag/output_formats/basic.rb:10:in `to_s'
     5: from /usr/local/lib/ruby/gems/2.6.0/gems/jekyll_picture_tag-2.0.0/lib/jekyll_picture_tag/output_formats/img.rb:15:in `base_markup'
     4: from /usr/local/lib/ruby/gems/2.6.0/gems/jekyll_picture_tag-2.0.0/lib/jekyll_picture_tag/output_formats/basic.rb:21:in `build_base_img'
     3: from /usr/local/lib/ruby/gems/2.6.0/gems/jekyll_picture_tag-2.0.0/lib/jekyll_picture_tag/output_formats/basic.rb:79:in `build_fallback_image'
     2: from /usr/local/lib/ruby/gems/2.6.0/gems/jekyll_picture_tag-2.0.0/lib/jekyll_picture_tag/output_formats/basic.rb:121:in `checked_fallback_width'
     1: from /usr/local/lib/ruby/gems/2.6.0/gems/jekyll_picture_tag-2.0.0/lib/jekyll_picture_tag/images/source_image.rb:41:in `width'
/usr/local/lib/ruby/gems/2.6.0/gems/jekyll_picture_tag-2.0.0/lib/jekyll_picture_tag/images/source_image.rb:80:in `raw_width': undefined method `width' for nil:NilClass (NoMethodError)

Here Is the post:

---
layout: post
title: "ok"
description: ""
date: 2021-03-18 00:00:00 +0000
tags: [Rails]
typora-copy-images-to: ../assets/images/${filename}/
typora-root-url: ../../kinoute.github.io
---

{% picture /assets/images/2019-05-28-multilabel-model-create-dataset/main-area.png %}

The image appears and no error is raised when using ![](/assets/images/2019-05-28-multilabel-model-create-dataset/main-area.png).

rbuchberger commented 3 years ago

That's a headscratcher. Do you have libvips installed?

kinoute commented 3 years ago

Yes, running macOS 10.14 Mojave:

brew info vips
vips: stable 8.10.5 (bottled)
Image processing library
https://github.com/libvips/libvips
/usr/local/Cellar/vips/8.10.5_2 (167 files, 13.7MB) *
  Poured from bottle on 2021-03-29 at 16:57:37
From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/vips.rb
License: LGPL-2.1-or-later
==> Dependencies
Build: pkg-config ✔
Required: cfitsio ✔, fftw ✔, fontconfig ✔, gettext ✔, giflib ✔, glib ✔, imagemagick ✔, libexif ✔, libgsf ✔, libheif ✔, libimagequant ✔, libmatio ✔, libpng ✔, librsvg ✔, libspng ✔, libtiff ✔, little-cms2 ✔, mozjpeg ✔, openexr ✔, openslide ✔, orc ✔, pango ✔, poppler ✔, webp ✔
==> Analytics
install: 4,205 (30 days), 14,662 (90 days), 50,862 (365 days)
install-on-request: 4,118 (30 days), 13,692 (90 days), 40,471 (365 days)
build-error: 0 (30 days)
rbuchberger commented 3 years ago

Something's going wrong with vips loading the image file... Here's the code that's failing:

    def image
      @image ||= Vips::Image.new_from_file(name)
    end

It's returning nil when it should be returning an image, which is what's breaking things. We're already making sure the file exists, so I can't think of why that would be happening.

Is there some unique configuration here? Can you try it on a brand new jekyll site?

kinoute commented 3 years ago

https://github.com/kinoute/reproduce-responsive-error

ruby 2.6.6p146 (2020-03-31 revision 67876) [x86_64-darwin18]

rbuchberger commented 3 years ago

Works for me, which says it has to do with the environment. I don't have a mac to test on, but I'll look into setting up a vm or a docker container or something.

With version 2 we switched from an imagemagick backend to a libvips backend, which brought a lot of performance gain but also seems to cause a lot of issues like this one. It's looking more and more like I'll have to add the imagemagick version back and make it an option to switch between the two.

~/development/tmp
$ asdf shell ruby 2.6.6

~/development/tmp
$ ruby --version
ruby 2.6.6p146 (2020-03-31 revision 67876) [x86_64-linux]

~/development/tmp
$ git clone https://github.com/kinoute/reproduce-responsive-error
Cloning into 'reproduce-responsive-error'...
remote: Enumerating objects: 13, done.
remote: Counting objects: 100% (13/13), done.
remote: Compressing objects: 100% (12/12), done.
remote: Total 13 (delta 0), reused 13 (delta 0), pack-reused 0
Receiving objects: 100% (13/13), 10.83 KiB | 3.61 MiB/s, done.

~/development/tmp
$ cd reproduce-responsive-error

~/development/tmp/reproduce-responsive-error master
$ bundle install
Fetching gem metadata from https://rubygems.org/..........
Resolving dependencies...
Using public_suffix 4.0.6
Using bundler 2.2.15
Using rouge 3.26.0
Using concurrent-ruby 1.1.8
Using eventmachine 1.2.7
Using http_parser.rb 0.6.0
Using ffi 1.15.0
Using forwardable-extended 2.6.0
Using mime-types-data 3.2021.0225
Using objective_elements 1.1.2
Using rainbow 3.0.0
Using addressable 2.7.0
Using pathutil 0.16.2
Using i18n 1.8.9
Using unicode-display_width 1.7.0
Using rb-fsevent 0.10.4
Using em-websocket 0.5.2
Using liquid 4.0.3
Using mercenary 0.4.0
Using mime-types 3.3.1
Using colorator 1.1.0
Using safe_yaml 1.0.5
Using sassc 2.4.0
Using terminal-table 2.0.0
Using jekyll-sass-converter 2.1.0
Using ruby-vips 2.0.17
Using rexml 3.2.4
Using rb-inotify 0.10.1
Fetching kramdown 2.3.1
Fetching listen 3.5.0
Installing listen 3.5.0
Using jekyll-watch 2.2.1
Installing kramdown 2.3.1
Using kramdown-parser-gfm 1.1.0
Using jekyll 4.2.0
Fetching jekyll-feed 0.15.1
Fetching jekyll-seo-tag 2.7.1
Fetching jekyll_picture_tag 2.0.0
Installing jekyll-feed 0.15.1
Installing jekyll-seo-tag 2.7.1
Fetching minima 2.5.1
Installing jekyll_picture_tag 2.0.0
Installing minima 2.5.1
Bundle complete! 7 Gemfile dependencies, 37 gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.

~/development/tmp/reproduce-responsive-error master* 6s
$ bundle exec jekyll build
Configuration file: /home/robert/development/tmp/reproduce-responsive-error/_config.yml
            Source: /home/robert/development/tmp/reproduce-responsive-error
       Destination: /home/robert/development/tmp/reproduce-responsive-error/_site
 Incremental build: disabled. Enable with --incremental
      Generating...
       Jekyll Feed: Generating feed for posts
Jekyll Picture Tag Warning: /images/apple-touch-icon.png is smaller than the requested fallback width of 800px. Using 180 px instead.
Generating new image file: /images/apple-touch-icon-180-a9dda6879.png
Jekyll Picture Tag Warning: /images/apple-touch-icon.png
is 180px wide (after cropping, if applicable),
smaller than at least one size in the set [400, 600, 800, 1000].
Will not enlarge.
                    done in 0.338 seconds.
 Auto-regeneration: disabled. Use --watch to enable.

~/development/tmp/reproduce-responsive-error master* 2s
$ cd _site

~/development/tmp/reproduce-responsive-error/_site master*
$ ls
about  assets  generated  images  jekyll  404.html  feed.xml  index.html
rbuchberger commented 3 years ago

Until we can work out a better solution, might I suggest a docker container? Something like the following:

FROM jekyll/jekyll:4

RUN apk add vips imagemagick
WORKDIR /tmp
ENV BUNDLER_VERSION 2.2.12
ENV NOKOGIRI_USE_SYSTEM_LIBRARIES 1
ADD ./Gemfile /tmp/
ADD ./Gemfile.lock /tmp/

RUN gem install bundler -i /usr/gem -v 2.2.12
RUN bundle install

COPY . ./

CMD ["jekyll", "build"]

docker build -t mysite . && docker run -v $(pwd):/tmp -t mysite:latest

kinoute commented 3 years ago

I was actually trying to do the same thing with an official Ruby image and indeed, it doesn't raise an error. Weird. I will try to see what versions and dependencies of libvips are used in both and compare, maybe that will say something..

rbuchberger commented 3 years ago

Let me know what you figure out. I'm sorry to say I'm not really smart on package management and the like, but if this is an issue that affects all mac users then I definitely want a better solution than 'use docker'.

kinoute commented 3 years ago

FYI, I switched back to 1.14.0 and without libvips, it does work.

rbuchberger commented 3 years ago

Glad to hear that. I've pushed some updates, can you try with 2.0.2? At the very least, the error message should be less useless.

kinoute commented 3 years ago

No changes with 2.0.2. The error message remains identical

rbuchberger commented 3 years ago

Damn, ok. Are you using the apple-shipped system version of ruby? Per this discussion I've been having with the ruby-vips maintainer, the homebrew version might be necessary.

kinoute commented 3 years ago

Yeah, I installed Ruby 2.6 through Homebrew. I really think this error is out of your scope: with only irb, I get nil as well doing only this:

require "vips"
=> true
irb(main):002:0> img = Vips::Image.new_from_file("apple-touch-icon.png")
=> nil
jcupitt commented 3 years ago

Hi, libvips maintainer here, could you perhaps be running an older libvips? I pushed 8.10.6 to homebrew a couple of days ago and it ought to improve PNG loading.

I see:

$ irb
irb(main):001:0> require "vips"
=> true
irb(main):002:0> x = Vips::Image.new_from_file("apple-touch-icon.png")
irb(main):003:0> x
=> #<Image 180x180 uchar, 4 bands, srgb>
irb(main):004:0> 

Background: we've just switched PNG load libraries. The new load library should be better, but it can be stricter about refusing to load out of spec PNGs. libvips 8.10.6 has tweaks to try to make it a bit more lenient. The next libspng version (due next week) ought to be more generous still.

kinoute commented 3 years ago

@jcupitt I already have 8.10.6 installed. When reinstalling it, I got this message from Homebrew though:

Warning: vips dependency gcc was built with a different C++ standard library (libstdc++ from clang). This may cause problems at runtime.