HaxeFoundation / haxelib

The Haxe library manager
https://lib.haxe.org/
MIT License
172 stars 78 forks source link

Define lib.name #600

Open Simn opened 1 year ago

Simn commented 1 year ago

We decided (5 minutes ago) that for Haxe 5 it would be nice if libraries namespaced themselves. To ease transition, haxelib should emit both -D name and -D lib.name for the time being. This allows users to move towards the latter, which should then still work fine in Haxe 4 as long as haxelib is up-to-date.

Aurel300 commented 1 year ago

(To be clear this is about namespacing in the -D defines, not about actually namespacing the packages, which would be really good too.)

For slightly more flexibility going forward, maybe the define should actually be lib.<name>.version? Then we could add other info about the library into other "fields".

kLabz commented 1 year ago

This would make for weird #if lib.somelib.version checks instead of #if lib.somelib

Aurel300 commented 1 year ago

Maybe the .version define should contain the version and the shorter one is just a Boolean? Then again the version might as well already be in the shorter define… :shrug:

Simn commented 1 year ago

Doesn't haxelib already define -D name=version anyway? I see no reason to change anything in that regard.

tobil4sk commented 1 year ago

While we're here, there is also another relevant problem I would like to solve, related to #529 and #568.

Haxelib names are case insensitive but defines are case sensitive. This is especially an issue because right now (haxelib 4.1.0), if a library is installed as haxelib, but you use -lib haXeLIB on Windows, it will set -D haXeLIB=... disregarding how the library is actually meant to be capitalised.

This means that #if blocks could be activated or deactivated based on a typo, where someone uses -lib Library instead of -lib library in their hxml. There are many examples of libraries which use capital letters in their names on lib.haxe.org, so this is not an unrealistic situation.

I can think of two possible solutions to this problem:

back2dos commented 1 year ago

Mhh. Now that I've seen the PR, I'm beginning to wonder what's being accomplished with this?

tobil4sk commented 1 year ago

The issue is that currently there is nothing preventing someone creating a haxelib with a name that clashes with a built-in haxe define flag. Setting the flag with the lib. prefix (with the intention of eventually replacing the old flag) avoids this define flag naming issue (so long as the lib. prefix remains reserved for haxelibs).

back2dos commented 1 year ago

Hmm. Seems slightly paranoid and definitely futile. Who in their right mind would want to publish a library that clashes with the compiler's defines? And if such evildoers existed, how does this stop them, given that they can put -D evilFlag into their extraParams.hxml or even do haxe.macro.Compiler.define('evilFlag') in some part of the library code?

To me this feels like red tape. Maybe well intentioned red tape. But still ...

tobil4sk commented 1 year ago

Who in their right mind would want to publish a library that clashes with the compiler's defines

I'm more concerned about this happening unintentionally.

There are a lot of define flags currently: https://haxe.org/manual/compiler-usage-flags.html, some of which already have quite generic names which could easily be used as library names. At least 14 are already package names on npm. Granted, npm has a different culture, but this shows that this is not an unreasonable concern. The list of flags and the list of libraries on haxelib are both constantly growing.

Library authors shouldn't be expected to check the full list of compiler flags to know what library names are safe to use without odd side effects in compilation. New library authors may not even be aware that this haxelib define feature exists.

An alternative solution is adding submission checks to check the name against the list of define flags, but that isn't future proof and doesn't work the other way around, so every time a new compiler flag is added, a haxelib search would also have to be performed to avoid clashes. I think this is pretty limiting, and working around these potential clashes would be pretty awkward. The lib. prefix solves this issue both ways by completely separating the two.

how does this stop them, given that they can put -D evilFlag into their extraParams.hxml

I agree that we can't stop bad actors, but as I said I don't think it is crazy to think that someone could do this by accident. I also think there is a difference between a flag being set explicitly and a flag being set inadvertantly due to an internal feature of haxelib.

back2dos commented 1 year ago

That sounds like a rather hypothetical problem.

Haxelib has something in the order of 1000 libs, npm has over a million. Not sure it makes sense to compare these things, but if we do, then I think this is a bit as if the node team decided to say that in the future one will have to write require('npm.xyz') instead of require('xyz') to avoid naming conflicts between builtin and user modules. They don't - even though node and npm are even run by two separate entities, surrounded by a huge community with a tendency of raising massive shit storms, all of which makes dealing with such issues considerably harder than it would be for us.

Library authors shouldn't be expected to check the full list of compiler flags to know what library names are safe to use without odd side effects in compilation. New library authors may not even be aware that this haxelib define feature exists.

Agreed. Of the concerns brought up here, this one weighs heaviest, by a large margin. The less obstacles we have for new library authors, the better. As you pointed out yourself, this could be prevented by not allowing users to create such libraries.

every time a new compiler flag is added, a haxelib search would also have to be performed to avoid clashes.

If that is really a concern, the CI could check defines.json against haxelib.

That said, defines are not added by newbies. The rate at which generically sounding defines are added has decreased considerably over the years. The vast majority of the existing ones come from the dawn of Haxe, when people were adding new backends at 6am, after drinking all night at a conference, and when namespacing defines wasn't even possible in the first place. A whole lot of those time-honored artifacts would best be namespaced (e.g. file-extension) regardless of this issue, and would then further decrease the risk of any collisions.


I guess there thing that bothers me is that this will be quite awkward in many places. For example library subflags. If in the future it is lib.tink_state should it then be lib.tink_state.debug? I'm really not that fond of double namespacing, but then again sticking to tink_state.debug would seem inconsistent. Also, #if cs becoming #if lib.csharp in the foreseeable future is not such a nice prospect, nor transitioning to constructs like e.g. #if lib.openfl .. #elseif lib.heaps ... #else ....

Obviously, these would be nuisances at best. But personally, I don't think further minimizing an already quite limited risk is worth adding this level of awkwardness.