1

I have encountered this scenario twice recently, in two different projects and languages:

  1. A python project defined an is_interactive() function that used os.isatty() to know whether it could actively accept user input from a terminal. This function worked in all scenarios except specific older versions of Git-bash for windows, where os.isatty() returned a false negative.

  2. A Rust crate with dependencies on https://www.mingw-w64.org specifically invoked mingw binaries to produce an output, but it appears that something has changed with those binaries since the crate was written, and now they require Linux/cygpath style path inputs.

Both of these situations involve interacting with an outside binary (Git bash, mingw utilities) without any sort of version control, and now some change within the binary conditionally breaks interaction with the software.

Writing unit tests to confirm the external binaries are within some version constraints seems like the wrong way to go.

The projects could clearly identify version requirements in a README, but is there a better way to handle this type of scenario?

4
  • The straightforward solution is to bundle those binaries that you need instead of relying on the exact behaviour of systems outside your control. Any particular reason why you don't want to do that? Commented Apr 15 at 6:12
  • 2
    I am not a maintainer on either of these projects, so any MR I produce would need to be accepted by the project owner. My knee-jerk reaction is that bundling binaries might be acceptable for the Rust crate — it only needs to support Windows. However situation (#1) is a little trickier because it's a development tool intended to support multiple environments and shells, so delivering a bash executable and saying "you must use our shell instead of your system shell" does not seem appropriate (and has the downside of requiring a shell binary for each supported platform.)
    – Rob
    Commented Apr 15 at 7:05
  • 3
    Isn't this just basic dependency management? This is no different from using a library which changes its API, using a web service which changes its API, running on an OS which changes its API, using a framework which changes its API, or even using an internal component which changes its API. Commented Apr 15 at 12:58
  • @JörgWMittag Yes, but I think making the distinction has value because the package managers for most programming languages aren't necessarily suitable for tracking external binaries. I might consider something like a binary repository manager (e.g. artifactory) but maintaining DevOps infrastructure just to build could be cost prohibitive for many projects.
    – Rob
    Commented Apr 16 at 0:25

1 Answer 1

4

I see two possible solutions. The good one, and the not-so-good one:

  1. The good one: those binaries are dependencies and so should be bundled with the project. And in concrete versions. Just like every other dependency. Then you can have full control. This is of course rarely platform independent, and so potentially you will have to keep those libs per supported operating system. Unless you have access to source code. Putting this source code into your project (either directly or through reference) is something worth considering. Generally it is ok idea, but building stuff from source code is not always easy.
  2. The not-so-good one: you could write code that detects the version of the installed software, and the implementation covers all the possible cases. In practice you can limit yourself to some versions. For example, hardly anyone writes code that supports some old version of browsers, like internet explorer. Even though these are still in use.

IMO the not-so-good solution should be used only when the good one is not possible. It is inferior because eventually it becomes a maintanance nightmare.

2
  • 2
    +1, however, I would avoid to prejudice the two alternatives as "good" and "not-so-good". There are cases where #2 is the better of the two alternatives, even when #1 could be possible. #2 might not be implemented in terms of explicit version checking, but in terms of availability-of-a-feature-checking
    – Doc Brown
    Commented Apr 15 at 10:39
  • 1
    +1 Thanks for the input! I'm going to leave this question open a while longer but will probably accept this answer. If the maintainer provides long-term artifacts over public HTTP, what do you think about pulling smaller binaries over the network during builds? It seems like fetching www.source.com/project/name.version.platform.gzip might simplify delivering concrete versions for multiple supported architectures, but maybe it actually introduces complexity?
    – Rob
    Commented Apr 16 at 0:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.