luci

pypi documentation pipeline status updates coveralls codestyle

What luci is about:

  • you add metadata to any type of text file (most likely, but not necessarily, in it’s comments)
  • you point luci to that file
  • luci reads the metadata
  • luci uses that metadata as configuration to (optionally) create a command-line interface for the file in question, and as configuration for a task of your choosing
  • luci executes that task, letting the user specify additional metadata/configuration values via the dynamically created command-line interface (if applicable)

‘What.. ??’, ‘Those words you just said are weird!!’, ‘English much?!?’ – Yes, sorry. I’m having real trouble coming up with a good and simple explanation for all this. Honestly, I’d be happy to settle for only one of the two!

luci is the result of one of those situations where I needed a solution for an issue I had (and which would be even more difficult to explain), and where I decided I saw an interesting enough pattern worth trying to implement a generic solution for. I know, I know, typical over-engineered piece of crap solution looking for problems. I don’t care though.

To illustrate the class of problems luci can help with, here are two quick and dirty…

Examples

A dynamic text emitter

Say you are developing a shell script that processes text via stdin, and for development purposes (testing regular expressions?) you need to pipe in some (changing, but predictable) text input. This can be achieved quickly in a number of ways, but with luci I think it’s especially straightforward. You create a file (let’s call it dev_input):

Now, make it executable (chmod +x dev_input), and put it somewhere into your $PATH. That’s all, now you’ve got an executable that emits templated text (which can be way more complex than this example, you’d just use some of the more advanced bells and whistles of the jinja2 templating engine) that can be controlled via command-line switches:

Check out the collected examples for more details and options.

Make a file ‘updateable’

Say we want to share the file from the last example with our co-workers, and every now and then we update it to add new ‘features’. Of course, we will check it into a git repository. But checking out that repo might or might not be too much overhead for just one file. We could, instead, add the download url to the file’s metadata, and use a luci task to update it. Here’s how the updated file looks like:

Once our co-worker has this file on their machine, and we publish an update, all they need to do is:

❯ luci download /home/markus/.local/bin/dev_input --replace

Again, this is only a very simplistic example to quickly show what luci is about. Check out the full example (and the luci documentation in general) for more details.

luci comes with a few default ‘commands’ (‘lucifiers’ in luci-speak) like the download one. You can easily write your own lucifiers, and that’s where I see luci’s real value, as that let’s you, fairly quickly, create applications and scripts for sorta ‘secondary’ tasks related to the data you commonly work with. In an organized and reproducible way.

Because of it’s generic nature I think examples are best suited to convey the type of problems luci can help solve. Which is why I wrote up some more usage examples.

Obviously, nothing luci does can’t be achieved by writing your own scripts. I honestly have no idea how people feel about embedding task-specific metadata in their files. I think it’s a neat idea in some cases, even if I find it really hard to tell you why I do :-)

Install

❯ pip install luci

I’ll leave it as exercise for the reader to decide whether to use sudo or create a virtualenv or similar for a tidier installation.

Features

  • generic (to a fault)
  • extensible (plugin-architecture, add your own dictlet-finders, dictlet-readers, and lucifiers)
  • dynamic command-line interface generation
  • includes default task implementations (‘lucifiers’) that help with development/debugging (debug, metadata, cat) as well as common generic use-cases (template, download)

ToDo

  • look into performance
  • add more (input) formats in addition to yaml
  • add a few more generic lucifiers
  • enable the use of non-text files, directories, urls etc.
  • tests

License

  • Free software: GNU General Public License v3

Credits

click
used to dynamically create the dictlet command-line interface
jinja2
does all the templating in the background
stevedore
used to manage plugins
cookiecutter
was used to create the initial project layout