The Crystal Programming Language Forum

Which Crystal version is Kemal 0.26 compatible with?

I am working on a Kemal application locally (on Mac) with Crystal 0.28 and Kemal 0.25.2.

I transferred this application to the server which has Crystal 0.29 installed. If I force the Kemal version to stay at 0.25.2, the code compiles without any issues. However, if I upgrade Kemal to 0.26 then the code does not compile. Gives the following error. Is this a bug in Kemal, or is it expected since Kemal 0.26 works only with Crystal 0.30?

Thank you.

    Kemal.run
      ^~~

in lib/kemal/src/kemal.cr:15: instantiating 'run(Array(String))'

  def self.run(args = ARGV)
  ^~~

in lib/kemal/src/kemal.cr:16: instantiating 'Kemal:Module#run(Nil)'

    self.run(nil, args: args)
         ^~~

in lib/kemal/src/kemal.cr:11: instantiating 'Kemal:Module#run(Nil, Array(String))'

    self.run(port, args) { }
         ^~~

in lib/kemal/src/kemal.cr:65: instantiating 'HTTP::Server#listen()'

    server.listen unless config.env == "test"
           ^~~~~~

in /usr/share/crystal/src/http/server.cr:415: instantiating 'Array(Socket::Server)#each()'

    @sockets.each do |socket|
             ^~~~

in /usr/share/crystal/src/indexable.cr:187: instantiating 'each_index()'

    each_index do |i|
    ^~~~~~~~~~

in /usr/share/crystal/src/indexable.cr:187: instantiating 'each_index()'

    each_index do |i|
    ^~~~~~~~~~

in /usr/share/crystal/src/http/server.cr:415: instantiating 'Array(Socket::Server)#each()'

    @sockets.each do |socket|
             ^~~~

in /usr/share/crystal/src/http/server.cr:428: expanding macro

            spawn handle_client(_io)
            ^

in macro 'spawn' /usr/share/crystal/src/concurrent.cr:97, line 11:

   1.
   2.
   3.
   4.     ->(
   5.
   6.         __arg0 : typeof(_io),
   7.
   8.
   9.       ) {
  10.       spawn(name: nil) do
> 11.         handle_client(
  12.
  13.             __arg0,
  14.
  15.
  16.         )
  17.       end
  18.
  19.       }.call(_io)
  20.
  21.

instantiating 'handle_client(IO+)'
in /usr/share/crystal/src/http/server.cr:462: instantiating 'HTTP::Server::RequestProcessor#process(IO+, IO+)'

    @processor.process(io, io)
               ^~~~~~~

in /usr/share/crystal/src/http/server/request_processor.cr:16: instantiating 'process(IO+, IO+, IO::FileDescriptor)'

  def process(input, output, error = STDERR)
  ^~~~~~~

in /usr/share/crystal/src/http/server/request_processor.cr:39: instantiating '(HTTP::Handler | Proc(HTTP::Server::Context, Nil))#call(HTTP::Server::Context)'

          @handler.call(context)
                   ^~~~

in /usr/share/crystal/src/http/server/handlers/compress_handler.cr:12: expanding macro

    {% if flag?(:without_zlib) %}
    ^

in macro 'macro_140567668562560' /usr/share/crystal/src/http/server/handlers/compress_handler.cr:12, line 12:

   1.
   2.       request_headers = context.request.headers
   3.
   4.       if request_headers.includes_word?("Accept-Encoding", "gzip")
   5.         context.response.headers["Content-Encoding"] = "gzip"
   6.         context.response.output = Gzip::Writer.new(context.response.output, sync_close: true)
   7.       elsif request_headers.includes_word?("Accept-Encoding", "deflate")
   8.         context.response.headers["Content-Encoding"] = "deflate"
   9.         context.response.output = Flate::Writer.new(context.response.output, sync_close: true)
  10.       end
  11.
> 12.       call_next(context)
  13.

instantiating 'call_next(HTTP::Server::Context)'
in /usr/share/crystal/src/http/server/handler.cr:26: instantiating '(HTTP::Handler | Proc(HTTP::Server::Context, Nil))#call(HTTP::Server::Context)'

      next_handler.call(context)
                   ^~~~

in /usr/share/crystal/src/http/server/handlers/error_handler.cr:15: instantiating 'call_next(HTTP::Server::Context)'

      call_next(context)
      ^~~~~~~~~

in /usr/share/crystal/src/http/server/handler.cr:26: instantiating '(HTTP::Handler | Proc(HTTP::Server::Context, Nil))#call(HTTP::Server::Context)'

      next_handler.call(context)
                   ^~~~

in /usr/share/crystal/src/http/server/handlers/log_handler.cr:11: instantiating 'Time.class#measure()'

    elapsed = Time.measure { call_next(context) }
                   ^~~~~~~

in /usr/share/crystal/src/http/server/handlers/log_handler.cr:11: instantiating 'Time.class#measure()'

    elapsed = Time.measure { call_next(context) }
                   ^~~~~~~

in /usr/share/crystal/src/http/server/handlers/log_handler.cr:11: instantiating 'call_next(HTTP::Server::Context)'

    elapsed = Time.measure { call_next(context) }
                             ^~~~~~~~~

in /usr/share/crystal/src/http/server/handler.cr:26: instantiating '(HTTP::Handler | Proc(HTTP::Server::Context, Nil))#call(HTTP::Server::Context)'

      next_handler.call(context)
                   ^~~~

in lib/kemal/src/kemal/static_file_handler.cr:24: undefined method 'decode' for URI.class

      request_path = URI.decode(original_path)

You can go to that tag in GitHub and check the contents of shard.yaml:

It says crystal: 0.30.0.

The compiler doesn’t check that, but it probably means that it works with Crystal 0.30.0.

Got it! Thank you so much.

What about for package such as will/crystal-pg which does not specify the crystal version? Is there a way to find out?

Thank you.

I guess the only way to finding out is trying it. I think the latest version supports crystal 0.30.0

Thank you. Just wanted to make sure I was not missing another better way.