Structuring Projects: when to include a dependency as a library instead of just calling a command line interface. - eviltoast

Hello fellow rustaceans! Recently, there was a thread about how we can grow this community (how can I link to posts across servers?), where I already talked briefly about this topic, saying that I did not know if it is worthy of a full post here, as most things seem to be pretty professional looking links to talks and blogs. I’ve gotten some encouragement to post it, so here we go:

When to use a library instead of a CLI

I’m working on a little project called Autcrate in my free time, which aims to streamline the release and publishing process (what exactly it does isn’t really important for this discussion). Autocrate uses git to get the path of the current repo, tags and pushes releases, generates a change log from commits and so on.

Up until a week ago, I was just using the git2 library crate, which offers the functionalities of libgit2 for rust. While good, using this crate is much more complicated than for example just executing git push from my program using std::process::command. I am only using the porcelain functionalities of git (as of now), so all functionality could be achieved by calling the CLI interface.

Question

When is it acceptable to use CLI Commands instead of using libraries provided for that same software?

Is it generally better to use API/ABI from libraries, or is it maybe even better to use the CLI interface, reducing the list of dependencies?

Pro and Con of using Commands instead of libraries

Pro Con
Reduces the dependencies of a crate Adds a dependency that cannot be tracked by cargo
Much easier to program for developers The CLI interface is not versioned and might break in the future
Documentation of the CLI interface is often better than of libraries Bad usage of command cannot be detected at compile time
Cli program might not be available depending on architecture or platform

(this is of course not an exhaustive list. I will edit it if something comes up in the thread.)

Edit

Alright then. Thank you for your answers. While using the git CLI would probably be fine, since it’s very stable and available on most systems (especially those for CI/CD), it might change and is at best hacky. I’ll be doing the “right” thing and use libgit2 instead of just calling CLI commands.

  • TehPers@beehaw.org
    link
    fedilink
    English
    arrow-up
    5
    ·
    9 months ago

    I can’t speak for others, but personally, for anything that isn’t intended to be hacky or something like a CI/CD script, I use a library where possible. Specifically with Rust, libraries are statically linked, so there’s no need to worry about the interface/version being different on different machines at runtime, and the machine doesn’t (usually) need to install a dependency for your program. Libraries which wrap a CLI tool and call out to it internally are still useful even if the CLI tool isn’t statically linked since they already have all the glue to connect the code with the CLI tool set up, making it easier to use the tool usually.

    This isn’t always possible of course, but if you’re calling out to something like git which has an extremely stable interface and has had all the features you need for many years, then the benefits of statically linking aren’t nearly as high. Also, sometimes the dependency is just too complex to be a statically linked library (like if you need to call cmake or something). Still, if some kind of popular wrapper library for these exist, I use them where possible so I don’t need to reimplement what the wrapper libraries already have.

    • PlexSheep@feddit.deOP
      link
      fedilink
      arrow-up
      1
      ·
      9 months ago

      Thanks for your answer. As far as I can see it, the git library isn’t too much to add to my dependencies, so I’ll be using that for reasons mentioned in other comments too. I believe it will help my software to become more stable and not have to be lucky with the environment we’re in.