pragdave / earmark

Markdown parser for Elixir
Other
860 stars 135 forks source link

configuration :sys_interface not set for :earmark (Earmark.from_file!/2) #450

Closed thorsten-de closed 2 years ago

thorsten-de commented 2 years ago

Using Earmark.from_file!/2 with regular markdown files (*.md) results in following error:

    (elixir 1.13.4) lib/application.ex:683: Application.fetch_env!/2
    (earmark 1.4.26) lib/earmark/internal.ex:86: Earmark.Internal.include/2
    (earmark 1.4.26) lib/earmark/internal.ex:101: Earmark.Internal.from_file!/2

This happens when used both at compile-time and at runtime in IEx. So far, there is no mention about it, so I guessed it is a configuration error on my side. Bootstrapping a new mix app and including the current earmark from hex yields the same results. Am I missing something?

P.S: Renaming the file to .md.eex works just fine, as Internal.include/2 doesn't delegate to SysInterface for .eex files.

RobertDober commented 2 years ago

Thank you for reporting this I'll have a look when ASAP (which might be ALAP, alas)

RobertDober commented 2 years ago

@thorsten-de guess I need a little bit more info here, please provide me with the complete input and output of your problelm

A quick check was ok for me

iex(1)> Earmark.version
"1.4.26"
iex(2)> Earmark.from_file!("README.md")
inside: "README.md"
device: #PID<0.230.0>
"<!--\nDO NOT EDIT THIS FILE\n\nIt has been generated from the template `README.md.eex` by Extractly (https://github.com/RobertDober/extractly.git)\n\nand any changes you make in this file will most likely be lost\n\n-->\n<h1>\nEarmark—A Pure Elixir Markdown Processor</h1>\n<p>\n<a href=\"https://github.com/pragdave/earmark/actions/workflows/ci.yml\">  <img src=\"https://github.com/pragdave/earmark/actions/workflows/ci.yml/badge.svg\" alt=\"CI\" />\n</a>\n<a href=\"https://coveralls.io/github/pragdave/earmark?branch=master\">  <img src=\"https://coveralls.io/repos/github/pragdave/earmark/badge.svg?branch=master\" alt=\"Coverage Status\" />\n</a>\n<a href=\"https://hex.pm/packages/earmark\">  <img src=\"https://img.shields.io/hexpm/v/earmark.svg\" alt=\"Hex.pm\" />\n</a>\n<a href=\"https://hex.pm/packages/earmark\">  <img src=\"https://img.shields.io/hexpm/dw/earmark.svg\" alt=\"Hex.pm\" />\n</a>\n<a href=\"https://hex.pm/packages/earmark\">  <img src=\"https://img.shields.io/hexpm/dt/earmark.svg\" alt=\"Hex.pm\" />\n</a></p>\n<p>\n<strong>N.B.</strong></p>\n<p>\nThis README contains the docstrings and doctests from the code by means of <a href=\"https://hex.pm/packages/extractly\">extractly</a>\nand the following code examples are therefore verified with <code class=\"inline\">ExUnit</code> doctests.</p>\n<h2>\nTable Of Content</h2>\n<ul>\n  <li>\n<a href=\"#table-of-content\">Table Of Content</a>  </li>\n  <li>\n<a href=\"#options\">Options</a>    <ul>\n      <li>\n<a href=\"#earmarkcliimplementation\">Earmark.Cli.Implementation</a>      </li>\n      <li>\n<a href=\"#earmarkoptions\">Earmark.Options</a>      </li>\n      <li>\n<a href=\"#earmarkoptionsmake_options1\">Earmark.Options.make_options/1</a>      </li>\n      <li>\n<a href=\"#earmarkoptionsrelative_filename2\">Earmark.Options.relative_filename/2</a>      </li>\n      <li>\n<a href=\"#earmarkoptionswith_postprocessor2\">Earmark.Options.with_postprocessor/2</a>      </li>\n      <li>\n<a href=\"#earmarkinternal\">Earmark.Internal</a>      </li>\n      <li>\n<a href=\"#earmarkinternalas_ast2\">Earmark.Internal.as_ast!/2</a>      </li>\n      <li>\n<a href=\"#earmarkinternalfrom_file2\">Earmark.Internal.from_file!/2</a>      </li>\n      <li>\n<a href=\"#earmarkinternalinclude2\">Earmark.Internal.include/2</a>      </li>\n      <li>\n<a href=\"#earmarktransform\">Earmark.Transform</a>        <ul>\n          <li>\n<a href=\"#structure-conserving-transformers\">Structure Conserving Transformers</a>          </li>\n          <li>\n<a href=\"#postprocessors-and-convenience-functions\">Postprocessors and Convenience Functions</a>          </li>\n          <li>\n<a href=\"#structure-modifying-transformers\">Structure Modifying Transformers</a>          </li>\n        </ul>\n      </li>\n    </ul>\n  </li>\n  <li>\n<a href=\"#contributing\">Contributing</a>  </li>\n  <li>\n<a href=\"#author\">Author</a>  </li>\n</ul>\n<h2>\nOptions</h2>\n<h3>\nEarmark.Cli.Implementation</h3>\n<p>\nFunctional (with the exception of reading input files with <code class=\"inline\">Earmark.File</code>) interface to the CLI\nreturning the device and the string to be output.</p>\n<h3>\nEarmark.Options</h3>\n<p>\nThis is a superset of the options that need to be passed into <code class=\"inline\">EarmarkParser.as_ast/2</code></p>\n<p>\nThe following options are proper to <code class=\"inline\">Earmark</code> only and therefore explained in detail</p>\n<ul>\n  <li>\n    <p>\n<code class=\"inline\">compact_output</code>: boolean indicating to avoid indentation and minimize whitespace    </p>\n  </li>\n  <li>\n    <p>\n<code class=\"inline\">eex</code>: Allows usage of an <code class=\"inline\">EEx</code> template to be expanded to markdown before conversion    </p>\n  </li>\n  <li>\n    <p>\n<code class=\"inline\">file</code>: Name of file passed in from the CLI    </p>\n  </li>\n  <li>\n    <p>\n<code class=\"inline\">line</code>: 1 but might be set to an offset for better error messages in some integration cases    </p>\n  </li>\n  <li>\n    <p>\n<code class=\"inline\">smartypants</code>: boolean use <a href=\"https://daringfireball.net/projects/smartypants/\">Smarty Pants</a> in the output    </p>\n  </li>\n  <li>\n    <p>\n<code class=\"inline\">ignore_strings</code>, <code class=\"in" <> ...
iex(3)> 
thorsten-de commented 2 years ago

That's interesting and maybe I am missing something obvious in my configuration, since if it wouldn't work at all, this issue should have been already reported.

So, this is my dev environment:

I added earmark to my mix.exs:

  defp deps do
    [
      {:earmark, "~>1.4"}
    ]
  end

And running mix -S iex there is:

Erlang/OTP 24 [erts-12.3.2.2] [source] [64-bit] [smp:128:24] [ds:128:24:10] [async-threads:1] [jit]

Interactive Elixir (1.13.4) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> Earmark.version  
"1.4.26"
iex(2)> Earmark.from_file!("README.md")
** (ArgumentError) could not fetch application environment :sys_interface for application :earmark because configuration at :sys_interface was not set
    (elixir 1.13.4) lib/application.ex:683: Application.fetch_env!/2
    (earmark 1.4.26) lib/earmark/internal.ex:86: Earmark.Internal.include/2
    (earmark 1.4.26) lib/earmark/internal.ex:101: Earmark.Internal.from_file!/2
iex(2)> Earmark.from_file!("BAD.md")         
** (ArgumentError) could not fetch application environment :sys_interface for application :earmark because configuration at :sys_interface was not set
    (elixir 1.13.4) lib/application.ex:683: Application.fetch_env!/2
    (earmark 1.4.26) lib/earmark/internal.ex:86: Earmark.Internal.include/2
    (earmark 1.4.26) lib/earmark/internal.ex:101: Earmark.Internal.from_file!/2
iex(2)> 

It seems to me, that there is no :sys_interface configured when I use earmark, but I couldn't figure out the reason for this. Looking in the deps folder, there is SysInterface.Implementation, and your output confirms it is used in general.

By the way, cloning earmark and running your inputs works for me. You configured the :sys_interface in config/config.exs. If I configure my project's config file in the same way, it works fine, of course:

import Config
config :earmark, sys_interface: Earmark.SysInterface.Implementation

But from a user perspective, I don't want to have to know about a particular implementation, or at least it should be documented. As far as I know, a library's config file is not evaluated:

Also note that the config/config.exs of a library is not evaluated when the library is used as a dependency, as configuration is always meant to configure the current project. https://hexdocs.pm/elixir/1.13.4/Config.html

RobertDober commented 2 years ago

oh I see I need to test this in an application that uses Earmark, not Earmark by itself, ty for the details.

and I agree with you, needs to work, I'll try to get some time for this.

RobertDober commented 2 years ago

But from a user perspective, I don't want to have to know about a particular implementation, or at least it should be
documented. As far as I know, a library's config file is not evaluated:

goes without saying

RobertDober commented 2 years ago

fixed in 1.4.27 which I just released