relsqui / doily

A script for managing daily writing.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Organize optional pieces.

relsqui opened this issue · comments

Let's nip some spaghetti in the bud. Stuff like the git repository and the streak counter aren't part of the main function of doily, so they can very reasonably live in their own files. This is true of most of the other enhancements in the issue tracker, too. So how should we organize them? Questions:

  • How to turn on/off these extra pieces. Right now this information lives in top-level booleans in the config directory; if we're going to add arbitrary ones, it might make more sense to have instead a list of options to turn on. This keeps the config file readable and makes it way easier to maintain.
  • How to call them from the main script. No good having a nice generalized opt-in list in the config file if we have to manually test for and call each one by name from the main script. We can use the list of options to choose what to source and what functions to call, but we still need to know when to call them.
    • So far it looks like most of them are no more complicated than "do this before writing" (prompt (#9), timestamp (#8)) or "do this after writing" (git, streak counting).
    • One exception is the word counter (#5), which is really wants to be its own command. See notes in that issue.
  • Where to put configuration for the options! git, for example, can automate commit messages or not, and the writing prompts will have lots of choices. Asking the user to go fiddle with a million files by hand seems excessive.

Here's one way this could look:

  • Add a /plugins directory and put files with extra options in there.
  • Add a section to the config where you can list the plugins you want to turn on, by name. (Probably just a space-separated list, there's no reason to allow spaces in plugin names.)
  • Standardize the interface for those plugins so that we can automatically call them at predetermined hook points (e.g. my_plugin::pre_write()).
    • Have one of the hooks be defining a command-line option, so that the word counter can implement doily --word-count or whatever.
  • Use an option to drop the user into doily config file automatically (in the same way that it already drops them into daily files). This has a couple of benefits:
    • We can store the config files in a standard place without making the user type out the weird path.
    • We can easily have separate config files for particular plugins.

Normally this would be the point at which I decide that this is getting out of hand for a bash script, but most of it is still just filesystem manipulation and calling external commands ...

07:52:16 <@relsqui> lemme see if I understand what you were describing?
07:52:47 < elly> go for it
07:53:23 <@relsqui> so doily's config could sprout some directories like
commands/ and hooks/pre-write and hooks/post-write. if you want to add a
piece, you can add files to those directories
07:53:28 < elly> yup
07:53:33 <@relsqui> for the commands, doing something like `doily foo`
would just go look in doily/commands for foo
07:53:34 <@relsqui> and do the thing
07:53:35 < elly> or even just symlink to other places, if you like
07:53:39 <@relsqui> sure
07:53:52 < elly> right, 'doily' would be like 'hm, foo isn't a builtin,
does commands/foo exist? if so, run that'
07:54:02 <@relsqui> for the hooks, at a given place in the main script,
it would look in hooks/pre-write for any files matching the name of an
enabled plugin
07:54:04 <@relsqui> and run any
07:54:24 <@relsqui> and then same for post and if anything else comes up
07:54:24 < elly> yeah, I think so
07:54:52 <@relsqui> honestly I'm not sure I need to have any builtin commands
that aren't just ... in the commands dir
07:54:58 <@relsqui> I haven't implemented any yet so they can't be that
important :P
07:55:13 < elly> heh :)
07:55:32 <@relsqui> do you agree with having the enabling just be a list in
the main config file?
07:56:02 < elly> that sounds fine to me, yeah
07:56:12  * relsqui thinks
07:56:16 < elly> just lines like "load plugin-name" or something
07:56:29 <@relsqui> oh, yeah, I wasn't even thinking about it that way
07:56:40 <@relsqui> but that's probably better :)

More notes from the same conversation:

  • Don't forget to keep track of and alert the user to requirements of plugins, like git.
  • installing plugins can itself be a command (doily install foo)

As I plan this more, I realize how many moving pieces it's going to have to have. They're not all getting into the first milestone. For 0.1.0 I just want to have the proper directory structure in, and then I can work on implementing important commands and so forth.

First pass at built-in commands:

  • config (takes optional plugin name)
  • help (takes optional plugin name)
  • version (... could also take optional plugin name, I guess)
  • un/install (requires plugin name)
  • separately, un/load (plugin)?
  • list (show installed plugins)

Could do something to list available plugins but that definitely seems excessive for starters.

Edit: search would be another good one. It's syntactic sugar for grep, but most of these are syntactic sugar for something.

Hokay, here's my current thought for the directory hierarchy. For systemwide install:

/usr/local/
    bin/
        doily
        # The main executable.
    lib/
        doily/
            commands/
                ...
                # Standalone command plugins (like "wordcount")
             hooks/
                 pre_write/
                     ...
                     # Plugin code which should execute before writing.
                 post_write/
                     ...
                     # Plugin code which should execute after writing.
    etc/
        doily/
             default.conf
             # The default configuration file.

Because plugins can put files in more than one of those places, there probably needs to be a script somewhere which keeps track of what plugins are installed and what files belong to them. Possibly, what that should actually be is a single plugin file for each one which is stored in a single directory (lib/doily/plugins?) and linked to exactly the places that are appropriate for that file. Then the plugin file can have functions with predetermined names that do each thing. For example:

# my_plugin.sh

NAME="my_plugin"
VERSION="1.0.0"
DESCRIPTION="Demonstrates a possible plugin template."
AUTHOR="Some Rando <somerando@example.com>"

my_plugin::pre_write() {
    echo "Do some stuff before writing."
}

Hmm, I guess it needs some way to indicate what commands it provides if it provides them, though. Also, either both the constants and the function need to be namespaced or neither does. Neither is probably safer, but then the calling (main) script needs to be sending the info of what it should be doing, which will require a little boilerplate to hear and act on, but nothing too complicated. It also might mean that metadata should be tracked somewhere else, though? Need to ruminate on that more.

Wait, maybe it doesn't need to say what commands it provides, the calling code can just go through and try 'em. And the metadata can be callable from outside the same way as anything else. Neat.

This being bash, the boilerplate code can also live in one (provided) file and get sourced.

This issue is now encompassing several things, not all of which belong in the milestone, so let me split them up. The parts seem to be:

  • Change the directory structure (to what will hopefully be final)
    • This belongs in the milestone since it's good groundwork to have early
    • It makes installing tricky, so it brings the install script into the milestone too, so this counts as #13.
  • Finding and running plugins automatically (#20)
    • This doesn't need to be in the milestone
    • So instead, the code calls can stay manual, like they are right now
  • Built-in commands (#21)
    • Nope nope nope
    • Stick with the current interface for now
  • Plugin-specific configuration (including requirements) (this is part of #20 too)
    • Nope
  • Plugin installation (same)
    • Still nope

I'll split these out into their own issues and come back and add numbers.

Another thing plugins should have: the version of Doily that they're currently compatible with (which might be equivalent to their own version but doesn't have to be).

Also, I forgot to type up the directory structure plan for user-only installs. This might not actually change much from the current setup, since the user needs all those files and the XDG spec doesn't really plan for executables. :P

Okay, I think everything here has been broken up into more specific issues, so I'm closing it.