Hacker News new | ask | show | jobs
by imhoguy 1906 days ago
TL;DR

This unfortunate chain of events is rooted in licensing violation: https://github.com/minad/mimemagic/issues/97

Mimemagic got its MIME tables source generated from `freedesktop.org.xml` file, which is licensed under GPL2, and the resulting source was released under permissive MIT license. All prior 0.3.6 mimemagic versions violated the GPL2 license.

The author of mimemagic couldn't change the pre-0.3.6 versions so they simply deleted them.

Unfortunately "the fix" has broken the dependent projects and such have to either:

1) upgrade to GPL2 compatible mimemagic 0.3.6 or 0.4.0, which conflicts with MIT licensed projects like Rails or

2) build/use other MIME resolving library with has permissive license or

3) fork mimemagic under MIT and implement dynamic loading of `freedesktop.org.xml` which wouldn't violate the license.

1 comments

Since the xml file is not included in the source, and was just a reference for a rb source file's lookup table, it just feels weird that 3 fixes the violation.
I think the pedantic interpretation of the GPL “depends on” clause is that burning a content-hash of a GPLed release of a work into your work, such that your work retrieves and installs the GPLed work-release by its content-hash (or retrieves the work-release by name + version and then verifies it by content hash — as a Bundler Gemfile.lock does), is “depending on” the GPLed release of the upstream work. Due to the explicitness of the reference, the only release that the downstream project could be depending on, is a GPLed release. (Remember, GPLed code releases need to embed the GPL license somewhere, so there’s no posssibility of a byte-for-byte identical dep being created by coincidence that isn’t GPLed.)

Meanwhile, just saying “I’ll take whatever is in the environment at [path]” is a more plugin-like approach: a GPLed database could be placed there, but a differently-licensed database could be there instead. Because you’re not making any explicit reference to any particular release of any particular work, you aren’t infected by the copyright/licensing of the particular work/release that happens to be there.

It’s a lot like the case-law of the DMCA’s “tool used for breaking copyright” clause: if the tool has features that exclusively help to break copyright, with no other uses, then it’s in violation of the DMCA; while if all features of the tool have other potential use-cases, then it doesn’t.

In both cases, it’s a question of whether there’s a “reasonable doubt” on what exactly the project was aiming to achieve / link against. If the project is explicit and removes all doubt, then it’s in violation.

Then you add a step for adding the content hash as an environment variable in the installation instructions, and include the actual content hash as an _example_ (wink wink) in the documentation.
I don't think Bundler/Bundler-like project lockfiles work that way; lockfiles generally need to be static artifacts checked into source control, so that their transitive dependencies can be resolved and the whole tree of dependencies can be inter-constrained. Swapping the dep out for a different one would require you to re-lock everything.

And, even taking one step back and not having a lockfile, and instead using the dependency version-constraints spec file (the Gemfile) — constraint specs are still generally not really dynamic formats. "Runtime", for them, is compile-time; and usually you can't execute code in them, because the runtime needs to load and resolve them before any of your library's code gets to run. If your app depends on the Rails gem, Rails doesn't get any opportunity during dependency-resolution to run code that decides what its transitive dependencies will be.

(One exception to this general rule in package ecosystems, is Python, due to the existence of setup.py files. This exception is why `pipenv install` in a large Python project takes upwards of 15 minutes: nothing can be parallelized — or ever truly locked down to a specific version — because each dependency gets to run arbitrary, not-guaranteed-deterministic code during installation to decide what its own transitive dependencies will be.)

You could probably create some sort of shim library that dynamically downloads your actual library at runtime — first rewriting its transitive deps, and then loading it as a dep through low-level use of the runtime packaging machinery... but at that point it's a lot easier to just actually load the database itself by dynamic reference.

IANAL but it explicitly states it is derivative from the XML file: https://github.com/minad/mimemagic/blob/master/lib/mimemagic...