Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Weechat plugin split #25274

Merged
merged 1 commit into from Nov 4, 2017
Merged

Weechat plugin split #25274

merged 1 commit into from Nov 4, 2017

Conversation

lheckemann
Copy link
Member

@lheckemann lheckemann commented Apr 27, 2017

Motivation for this change

#22746

This change moves each language plugin into a separate output, significantly reducing weechat's closure size. It also adds a withPlugins function to weechat, which generates a wrapper for adding the plugins.

This relies on weechat/weechat#971 and so probably shouldn't be merged until the next stable release which will (hopefully!) include that change.

This is probably my biggest nixpkgs change yet, so I'm PRing it now in search of feedback — any input would be highly appreciated! Particularly, the way in which I add the withPlugins function to weechat. This should allow using it like weechat.withPlugins [weechat.ruby weechat.guile], but is there a more elegant way of adding it than the set union I'm doing here? I'd also like to know what people think about the mechanism as a whole, i.e. how this runtime composition is implemented.

Checklist before this can be merged:

  • Search WEECHAT_EXTRA_LIBDIR for plugins weechat/weechat#971 merged and incorporated into a release patch added to expression instead
  • Remove references from main weechat derivation to python and perl packages — these should be in the wrapper as well
  • Document it — but where? This isn't specific to NixOS (so probably not the NixOS manual), nor is it only applicable to people intending to contribute to nixpkgs (so probably not the nixpkgs manual). Do we have an "end-user's guide" to nixpkgs?

Ideas:

  • Potentially handle the plugins in a more unified way; I'll be experimenting with this a bit.
  • Allow managing user config as well as plugins
Things done
  • Tested using sandboxing
    (nix.useSandbox on NixOS,
    or option build-use-sandbox in nix.conf
    on non-NixOS)
  • Built on platform(s)
    • NixOS
    • macOS
    • Linux
  • Tested compilation of all pkgs that depend on this change using nix-shell -p nox --run "nox-review wip"
  • Tested execution of all binary files (usually in ./result/bin/)
  • Fits CONTRIBUTING.md.

@mention-bot
Copy link

@lheckemann, thanks for your PR! By analyzing the history of the files in this pull request, we identified @edolstra, @lovek323 and @aneeshusa to be potential reviewers.

@lheckemann
Copy link
Member Author

I would also appreciate if anyone could comment on whether they think lheckemann@e8bf1f9 is an improvement on this. It has yet to address the issue of plugin-specific environment variables properly, so is also WIP on top of this.

platforms = stdenv.lib.platforms.unix;
};
};
in weechat // {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think more standard way to extend expressions is to rely on .override function. That means that have to specify withPlugins as argument of weechat expression.

When somebody wants to use a customized weechat they will do something like:

custom_weechat = pkgs.weechat.override {
   guileSupport = false;
   withPlugins = [ plugin1, plugin2 ];
};

You can check neovim expression how I did it to conditionally (when configuration is present) return wrapped and configured neovim.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm aware of this; the idea behind the approach I've used here is to take advantage of weechat's modularity to significantly reduce weechat's closure size without the need for rebuilding weechat itself (as is necessary if any of the xSupport flags are passed in). Customising weechat's plugins has already been possible simply by disabling them in the build, but that means that it needs to be rebuilt on the user's end which somewhat dampens the resulting improvement in closure size as all the build deps need to be available (at least initially) and the build takes longer.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

using withPlugins in does not go against reducing weechat's closure size. If you looked at neovim's expression you will see that by default default weechat is returned. if plugins are set you wrap the returning weechat executable. The only things that changes is how you go about customizing this. The preferred way to do this is via .override function.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, that makes sense... so something like d421f4aefcaddf0ec07582ffb62fa6f625dd8f96 ?

(usage: weechat.override {withPlugins = ["perl" "python" "ruby"];})

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@garbas
Copy link
Member

garbas commented Apr 27, 2017

@lheckemann to not wait for upstream you could also point to that PR and add it to the patches list.

@lheckemann
Copy link
Member Author

Of course, I forgot about that!

src = fetchFromGitHub {
owner = "lheckemann";
repo = "weechat";
rev = "546e260fd58e41db20e7bc4ec5585e93fb6994c1";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i this v1.7.1 tag?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, it's master as of yesterday + my patch. I've changed it back to use v1.7.1 plus my patch
368edaf

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry commenting on old code :)

Copy link
Member

@garbas garbas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lheckemann 💯 on the change. I would just squash the commits before we merge this to nixpkgs.

@lheckemann
Copy link
Member Author

Yes, that was my plan. I also still need to fix the perl/python path stuff in the wrapper — currently just weechat will still depend on perl and python, without even bringing in the plugins.

@lheckemann
Copy link
Member Author

It also still needs docs, which I don't know where to put.

@lheckemann
Copy link
Member Author

This definitely isn't ready for merging yet — for instance, fish.py from the official scripts repo doesn't work with it

@garbas
Copy link
Member

garbas commented Apr 28, 2017

@lheckemann I think you can open a new section about weechat at Chapter 10. Package Notes

I'll do a bit of dreaming in this comment and you stop me when I go too far :P Also I'm interested to work on this myself, just for some things I'm too short on my skills.

(1) nixos module: maybe it would be worthwhile to also create a nixos module for weechat. eg

programs.weechat.enable = true;
programs.weechat.plugins = [ ... ];
programs.weechat.<other-options>...

(2) like with plugins it would be nice to have a variable to configure weechat to write logs in location other then $WEECHAT_HOME/logs, we could add this as an argument like withPlugins

(3) configuring weechat: it would be also nice to be able to disallow weechat to write configuration. and create a nice way to configure weechat (eg. like i already do with neovim for example), we could add this as an argument like withPlugins

(4) work on weechat2nix script that will package weechat plugins

@lheckemann
Copy link
Member Author

  1. Not sure how useful this would be, given that weechat doesn't really require any system-wide configuration — most modules, as far as I can tell, exist because they require system-wide settings e.g. programs.zsh for registering it as the users' default shell, programs.cdemu for setting appropriate permissions, etc. A module for weechat, as far as I can tell, wouldn't provide anything that installing an expression wouldn't already.

  2. Yes.

  3. Yes. Generally, separating the state and the config would be nice.

  4. I'm not aware of any plugins that don't ship with weechat. Most extra functionality seems to be implemented through scripts built on the existing language plugins.

@garbas
Copy link
Member

garbas commented May 2, 2017

  1. you're probably right. .override to configure weechat is enough. maybe having a service that would spawn weechat+tmux like i do here

  2. & 3. I would love to poke with weechat's code but this goes beyond my skills.

  3. Sorry for the confusion. I was talking about scripts. instead of using weechat to pull in unknown code we can use nix. That would of-course require us to disable /scripts command.

@lheckemann
Copy link
Member Author

Yeah, I'll have a look at making those changes to weechat in the next few days.

As for script installation, yes I guess that would be the logical next step from there. I'll see what I can do!

@lheckemann
Copy link
Member Author

lheckemann commented May 9, 2017

The python plugin needs some python libraries on its path. I think the right solution would be to allow passing in a python environment as created by python3.withPackages, but I'm not sure how best to expose this. @garbas do you have any ideas for what a nice way to do this would look like? Some ideas so far…

weechat.override { configure = {
  plugins = ["python"];
  environment = {
      PYTHON_HOME = python.withPackages (ps: with ps; [pycrypto dbus-python]);
  };
};}

But I'm not really sure if this is a nice way to do it, particularly because it relies on "magical" values so much. It would be nicer if it could somehow be included in the plugins attribute, something like

weechat.override { configure = {
  plugins = available: [
    (available.python.withPackages (ps: with ps; [pycrypto python-dbus]))
  ];
};}

or even

weechat.override {
  configure = {availablePlugins, ...}: {
    plugins = [availablePlugins.python.withPackages (ps: with ps; [pycrypto python-dbus])];
  };
}

But all of these look rather complicated to use. Any thoughts?

@FRidh
Copy link
Member

FRidh commented May 30, 2017

@lheckemann does the basic package, without plugins, need Python, or is it only needed for a plugin? If it does not build against a Python env, then you can just add the Python env to PATH.

pluginFile = "${weechat.python}/lib/weechat/plugins/python.so";
withPackages = pkgsFun: (python // {
extraEnv = ''
export PYTHONHOME="${pythonPackages.python.withPackages pkgsFun}"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not going to work. python.withPackages uses itself --set PYTHONHOME.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It worked for me.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What python.withPackages does is build an environment containing symlinks to all the packages and a python wrapper which sets PYTHONHOME to the location of the resulting environment. The wrapper won't actually be used by weechat's python plugin, but the python plugin does load the python interpreter as a shared library and at that point the interpreter looks at PYTHONHOME to see where to import stuff from.

ln -s $plugin $out/plugins
done
'';
in writeScriptBin "weechat" ''
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you considered using buildEnv for composition? This does look neat btw.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure how that would work in this case, since the paths are the actual shared libraries and not the derivations.

@lheckemann
Copy link
Member Author

does the basic package, without plugins, need Python, or is it only needed for a plugin? If it does not build against a Python env, then you can just add the Python env to PATH.

The python plugin for weechat requires python obviously. It does not execute python as a process though, it uses the library interface to the interpreter, so I think the approach I'm taking is the right one?

@lheckemann
Copy link
Member Author

That's it documented. If nobody has any further objections, I'll rebase and squash for the actual merge.

@lheckemann lheckemann force-pushed the weechat-plugin-split branch 2 times, most recently from 8415302 to f0291e0 Compare July 8, 2017 20:05
@lheckemann lheckemann changed the title (WIP) Weechat plugin split Weechat plugin split Jul 8, 2017
<section xml:id="sec-weechat">
<title>Weechat</title>
<para>
Weechat can currently be configured to include your choice of plugins.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"You can configure plugins as follows" is shorter and says the same.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Explicitly mentioning that this is an expression to install is more helpful, as some other packages are configured via nixpkgs config settings instead.

@lheckemann lheckemann force-pushed the weechat-plugin-split branch 2 times, most recently from ceefe38 to cb8360a Compare August 12, 2017 14:03
@lheckemann
Copy link
Member Author

@FRidh @garbas ping?

@FRidh
Copy link
Member

FRidh commented Sep 5, 2017

@lheckemann I'd like to give the final word to whoever maintains this

@lheckemann
Copy link
Member Author

Oh yeah, maybe @the-kenny and @lovek323 would like to weigh in as well :)

@disassembler
Copy link
Member

disassembler commented Nov 1, 2017

@lheckemann merge conflicts can you rebase? Also @garbas @the-kenny and @lovek323 we're looking for feedback here. If we don't get a response, I say we go ahead and merge it.

Also add a wrapper generator that allows adding the plugins back
conveniently and corresponding documentation in the package notes
section of the nixpkgs manual.
@jluttine
Copy link
Member

jluttine commented Nov 3, 2017

Would this PR make it possible to use plugins like https://github.com/wee-slack/wee-slack which, for instance, depend on other Python packages?

@lheckemann
Copy link
Member Author

@jluttine yes, see the addition to the manual for details on how. The packages in question do need to be included in nixpkgs though.

@Ma27
Copy link
Member

Ma27 commented Nov 4, 2017

@lheckemann are there any remaining blockers? I've packaged some Weechat plugins for Nixpkgs and I'd try to make them compatible with this in the next time :-)

@lheckemann
Copy link
Member Author

Just approval from maintainers.

@FRidh FRidh merged commit 4bd9b3b into NixOS:master Nov 4, 2017
@lheckemann lheckemann deleted the weechat-plugin-split branch November 4, 2017 08:56
@Ma27
Copy link
Member

Ma27 commented Nov 4, 2017

ah nice :-D
will try to make my weechat derivations compatible with this :-)

@Ma27
Copy link
Member

Ma27 commented Nov 16, 2017

@lheckemann just to ensure that I got this right: your change adds the ability to builda weechat with plugins.
My PR (see #28897) adds an FHS wrapper to make it possible that the scripts inside are buildable with nix. It surely needs some refactoring (I hacked this in ~1h to have an example that can be used for further discussion about this), but in the end it should live happily together with this, right?

@lheckemann
Copy link
Member Author

Yes, in principle: they're concerned with different parts of weechat, mine is for plugins and yours for scripts. I think the "patch weechat to search an alternative path" approach would be nicer than building a FHS env for scripts too, but I don't see any reason the latter approach would be incompatible with this PR either.

@Ma27
Copy link
Member

Ma27 commented Nov 17, 2017 via email

@jluttine
Copy link
Member

I started using this feature and it seems really great. I figured out how to add Python dependencies that some scripts need, but I couldn't figure out how to do the same for Lua dependencies.. There's no lua.withPackages apparently as there is for Python. Any ideas? I'm trying to add cjson Lua package required by this script: https://github.com/torhve/weechat-matrix-protocol-script

@lheckemann
Copy link
Member Author

Yes, it doesn't currently have support for this, largely because lua library support in nixpkgs isn't that great in general as far as I remember. I seem to remember @teto doing some work on that, maybe you can advise?

@teto
Copy link
Member

teto commented Mar 15, 2018

the work is visible here #33903. It works well except for some torch packages. I have yet to understand what's the problem there.

@jluttine
Copy link
Member

Ok, thanks! So at the moment, weechat cannot be used with lua dependencies. (?)

@teto
Copy link
Member

teto commented Mar 15, 2018

Other packages hack their way around via adjusting the LUA_PATH in a wrapper but if you are not hurry, there should be a better way soon :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet