jgm/gitit

Removing dynamic plugins

zaxtax opened this issue · 15 comments

I've noticed that the bundled plugins are severely bit-rotted. The code for dynamically loading plugins is very brittle and does not play well with the sandboxed method Haskell libraries are installed these days.

@jgm would you be opposed to a PR that ripped out dynamic plugin capabilities and replaced it with something more akin to a contrib library or just bundled the existing plugins in a way that they are compiled with the rest of the package?

jgm commented

I'm open to this. I'm not sure what the best way would be.

One advantage to the dynamically loaded plugins is that compiled plugins are probably going to be quite large (since they link to Gitit itself). (That could be mitigated with dynamic linking, but that's not the default at least with stack.)

I've compared the size of the gitit binary with and without compiled plugins and the difference is negligible. If we are concerned about binary size I've had reasonable success using upx and strip reducing the gitit binary size from 222M to 42M.

jgm commented

Oh, I see -- do you mean you're including the plugins in the main binary? I had thought you meant compiling them separately.

jgm commented

Part of the idea of the plugins directory was to give examples showing how people could create their own dynamically loadable plugins -- this objective wouldn't be met just by providing some baked in ones.

I'm happy with either suggestion. I am suggesting including the existing plugins in the main binary as the simplest way to prevent and reverse bit-rot. It also doesn't seem totally unreasonable as it seems the main way people are running gitit is installing it from source. If you are creating your own plugins, you are probably skilled enough to patch gitit to bundle the plugin.

jgm commented

On the other hand, if you can patch gitit, then you don't really need plugins. You can just patch your transformation into the main content transformer chain.

I like the idea of having something like pandoc filters but optionally configurable. Right now, I'm doing what @jefdaj does for his plugins since the mechanism is really hard to get working with the way cabal sandboxes packages these days. In my current setup, effectively Network.Gitit.Plugins is where I include my plugins and not gitit.conf.

jgm commented

So, is the main problem that without a global cabal package store, the current dynamic loading mechanism can't find the dependencies? Or is the problem installing the dependencies in the first place? If it's the first problem, we might be able to do something like

export GHC_PACKAGE_PATH=`stack path --snapshot-pkg-db`:
gitit

It's the first problem. There is a way to fix this by explicitly adding gitit to

~/.ghc/x86_64-linux-8.10.2/environments/default which is a bit hacky

The larger issue is that either solution is fairly brittle, and it doesn't solve the bit-rot problem that the included plugins in the repo don't even compile as they were built to work with an older version of pandoc.

I think the simplest solution would bundle all the plugins as compiled modules and the configuration file would change to just select amongst those already included in the package. If a user wanted to add their own plugin they would use the bundled ones as examples and modify the codebase to add them. This also has the advantage that it's a small step from there to push it upstream where it's visible to all other users of gitit.

jgm commented

The whole idea of plugins, though, was that you don't need to recompile the gitit code base to use them. I'd prefer to keep that. It would be helpful to hear from others who use gitit plugins, to see how they deal with these issues.

Certainly. In the meanwhile, let me fix up the existing plugins. Whatever gets decided that needs to happen regardless.

jgm commented

That would be great!

Just to throw in my 2 cents: I also compile my plugins into the main gitit binary. My feeling is that in gitit's current state (i.e., many people building from source; I had to for FreeBSD), anyone who can both compile the software and knows enough Haskell to write a basic plugin probably has enough knowledge (and likely won't mind) compiling the plugin directly into the binary.