February 02
Announcing kameloso IRC bot, 1.0.0.

It's a bot, not a parser library, though the parsing can technically be lifted out and reused.

On GitHub: https://github.com/zorael/kameloso, also https://kameloso.dub.pm.

There's notes to offline users, pasted URL title lookup, logs, automatic mode sets (e.g. +o on join), s/this/that/ substitution, user quotes, !seen, a basic Twitch streamer plugin. Some other legacy features and trivialities like the original venerable echo command. Ideas needed.

Absolute bare minimum required to try it:

git clone https://github.com/zorael/kameloso.git
cd kameloso
dub build
./kameloso --channels "#d,#freenode,##linuxmint"

With no other settings this will just be in client mode as a guest user and won't pollute the channels. (#d alone is too quiet to make a good example.) ./kameloso --writeconfig to set up further, see --help and the readme. Windows Powershell/cmd users may need an extra step to get terminal colours instead of \033[0m everywhere, see the readme.

The MVPs here are definitely UDAs, slices and mixin templates. There are some clever things in there that I'm really proud of, and some blemishes that I've learned to live with.

dscanner --sloc weighs it in at ~11k lines, excluding most tests. Much of it is @safe but it's not @nogc, nor -betterC. Naturally it tries to avoid allocating low-hanging fruit but there's Exceptions, associative and dynamic arrays, string concatenations, closures, and all kinds of convenient D things.

Parsing looks like this (automatically generated unit test): https://github.com/zorael/kameloso/commit/dde05a06

Plugins like this (automatically called module-level function):

@(IRCEvent.Type.CHAN)
@(PrivilegeLevel.anyone)
@(ChannelPolicy.home)
@BotCommand(PrefixPolicy.prefixed, "hello")
@BotCommand(PrefixPolicy.nickname, "poke")
@Description("Sends a hello world to the current channel.")
void onCommandHello(MyPlugin plugin, const IRCEvent event)
{
    plugin.chan(event.channel, "Hello world!");
}

Because of how code.dlang.org and dub deals with versions (announces pre-releases but serves releases), having previously pulled this from there at any point up until now will have landed you with an ancient version. So please don't judge this by any previous builds.

A normal dub build takes 9 seconds with dmd on this laptop (Linux) and eats 4036 Mb of RAM, down from 7800+ Mb. Profiling does not seem to show any particular surprising hotspots anymore. All compilers segfault in various situations[1][2][3].

Feedback appreciated.


[1]: https://issues.dlang.org/show_bug.cgi?id=18026
[2]: https://issues.dlang.org/show_bug.cgi?id=19123
[3]: https://bugzilla.gdcproject.org/show_bug.cgi?id=307