-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add installExt
to hldiff.nimble
#1
Comments
I agree it should install the source, too. Sorry about that. I don't find nimble easy/nice to drive, personally. I think tools that mandate a specific directory layout to operate are lame. Case in point, if I just add that So, It looks like from https://github.com/nim-lang/nimble#hybrids that I will have to rename |
I tried that I'm happy to set it up however it can work and install both binaries and both sources, but this experience is only solidifying in my mind how brittle nimble tends to be. I can probably also provide an If we need to we can drop the |
I guess I figured it out. Let me know if this still doesn't work for you. |
For what it's worth, I did get it to build (but not install) an |
I cloned the Git repo ( commit 814175d ) . If I run
The Nimble version is 0.11.4. I tried different reorganizations but didn't get it to work. One of the approaches was running However, to my surprise Correction: It only seems to succeed. The |
If I do |
Ok, I can confirm that this works for me, too. I had assumed that Anyway, here's the output of the Nimble package installation:
So it seems we have a setup that works at the moment, but with the Nimble warning and the messages from |
I'm quite disappointed that people find Nimble's package directory structure errors so confusing. I spent a lot of time making the errors as informative as possible. Let me now explain how I fix the current structure of this package, based on the errors that Nimble gives and hopefully we can gain some insight into the confusion:
You might ask why is this rigmarole necessary? Well, in the state that this package is before my changes above, the source code will be installed like so:
Which means that The reason this is how it works is a lot to do with the constraints that Nim has imposed on Nimble. Is it perfect? No. Will it stay like this? maybe not. Is it necessary currently to preserve semblance of sanity when many tens/hundreds/thousands of packages are installed/dependend on? Yes. CC @genotrance (you may find the above explanation helpful, and it should be taken into consideration for future directions with how Nimble installs packages). |
No. Just no. Before any of this issue being opened both were in You have a nimble file. It can specify practically anything, such as that namespace translation. In light of that alone any mandated project directory structure at all is logically unnecessary. Full stop. The only question becomes what is easier for users - more complex nimble files or complex package structuring rules. Both have pros and cons and there are many examples in the wild of both. Notably the things that do "whole systems" do make-like things, from BSD ports to Gentoo ebuilds to etc. Prog. lang things avoiding system integration concerns even at the level of So...Sanity is sometimes { all the time? :-) } subjective. Some people might say that you forcing me to have client code But I only care mildly about this if I have to tell people "It's this way because nimble sucks. Bug dom96 or genotrance or whoever". I do not mean to turn this into some big debate about package management, but I have seen you routinely act as if you were boxed into exactly one high level design concept, and I think that is just patently false or at the very least argued very poorly when so many examples in the wild going other ways exist. I personally literally never use nimble "as a client" except to test how others might get my code/programs. I doubt I will ever like it -- even a little -- as a client or an author. Sorry. I only set it up for people more patient with its failings to have an easier time. So, thanks very much @dom96 for taking the time to help me do that for @sschwarzer in this case and good evening to all! |
Oh boy, your response feels very antagonistic to me. I hope my comment didn't come off the same way. If it did, it was not my intention.
I'm not sure I understand, are you suggesting that Nimble could have moved the files around to make them namespaced automatically? Right now Nimble will install files as-is, and I know a lot of people that swear by those semantics. For your code, before this issue was opened, this means that The only way to fix this is to:
Am I missing something? My preference would have been for the last solution, but like I say above it wasn't approved. So I compromised on the first one. I sense that you feel that there is a very obvious solution to this that would solve all these problems and be absolutely perfect. So which solution is that? Based on what you're saying, I guess you mean that you should be able to tell Nimble how it should move files around in order to make them fit the package structure? Something like onInstall:
mv("src/edits.nim", "src/hldiff/edits.nim") Is this your preferred solution? To me it is hardly different to the current structure enforcement rules. The whole
I have been boxed, as I explained above. The other examples in the wild that I've seen require the language compiler to implement additional features, which is precisely the kind of concessions that I was not allowed |
To me it is very different, better, and only the tip of the iceberg. |
And I don't mean to be antagonistic per se, but I am not a nimble fan, cannot pretend to be, never expect to be, and I mostly just hear excuses rather than valid rebuttals. If you lack other examples, you should maybe look at the BSD ports setup or Portage rather than Rust or Python. C compilers have no special features for any of this stuff other than -I/-L paths. Yet somehow the BSD ports tree exists. |
Yes, Nimble seems to be hard to use in some packaging scenarios.
I guess that's a part of the problem. In my opinion, for our case there should be a hint or warning, not an error. An error goes too far, restricting the package maintainer too much. Personally, I read the error message but it seems I couldn't comprehend that the message was what was actually meant. I didn't expect at all that Nimble would deliberately prevent me from installing two modules when I was able to install one (as seen from the In my opinion, it would already be helpful to turn this error into a warning and add background information for the warning. This information should be from the perspective of the package maintainer (who runs
maybe use
(This message is just a rough idea, it surely can be improved.)
Yes, please. If it was only an oddity for the cloned package structure that would be kind of ok, but at the moment this affects also all users of the installed package. As a user, if I do an onInstall:
mv("src/edits.nim", "src/hldiff/edits.nim") I don't know if Nimble should use/allow a free-form package structure and move commands, but it may help. I think at the moment the dependencies between the Nimble file and package structure are relatively complex. (*) @dom96 you may not notice this as a long-time maintainer of Nimble, but it is a problem. I have the impression the current design is more complicated than it has to be. The usability isn't good. (*) In one forum thread I praised |
If you read this issue in sequence, the following happened:-
Nim doesn't import packages in their own namespace - i.e. The Nimble requirement is simply to not export modules into the global namespace unless the package name matches the module name. If package structure is not followed, a user could use two packages such that The package needs to consistently work regardless of nimble - Nim is handling the importing here. If two users ship the same package name, it is amply evident you cannot use both at the same time unless you put them in separate namespaces/subdirs. Recommending users only globally export modules that match the package name is reasonable independent of nimble since the errors are more tedious to debug and work around. It is arguable whether Nimble should enforce package structure but a free for all is just delegating the headache elsewhere. There could be better solutions and we are open to suggestions - it could be documented better, better error messages or what not and while I have been bitten by these issues first hand, I don't think Nimble is wrong in its aspiration. There are other issues around package structure as well that need resolution collectively. Note also that these are still only warnings, not errors, so it is worth saying that you can very well run into module conflicts today since you have package authors who ignore these warnings. cc @Araq |
Just for clarification, for others reading the issue. |
This rigidity & pettiness of Additionally, nimble does not own The Code Universe (and the less flexible it is the more likely it owns less). Someone can always create a conflict with Having the usual name collision resolution mechanism of qualifying (in this case with a package name/directory name) should also be able to be done in a purely Indeed, having this ability to package-qualify imports is independently motivated by people wanting to make dependency on external to the current package explicit in the code not just the Ok...If they aren't merely "library modules" but have binary executables whose names collide then there could be trouble, but guess what - there already is. In this package both Even if you hate the above idea for whatever reasons, there is an important abstract point here neglected now by multiple parties for reasons I don't get at all: There is no fundamental problem with packages exporting multiple modules from their top level because they were always namespaced anyway - by the package name. There might still be a problem with multiple versions of the same package or colliding package names, but A) those are independent concerns and B) I don't know the current nimble does anything smart with that situation anyway. I continue to think that this is not the best venue to discuss every problem with nimble, but I will keep responding if others do. |
Delegating something tricky to the person publishing a package feels like the correct division of labor to me. The lazy package author then gets just as much support. The picky one can ignore those library routines or write their own and has all the power they can/should have. The names of the library routines could even clarify what kind of package it is - library, binaries, hybrid, single multiple. A tiny, eentsy amount of explicitness could probably both simplify the task nimble has to actually do and empower picky package authors. (More concretely there could just be an That's just an example. I think there are a lot of possibilities to factor the entire agenda differently and it is not very constrained by the compiler. |
So I'm afraid you've lost me after this paragraph, and even this paragraph I find ambiguous. What sort of "usual name collision resolution mechanism of qualifying" do you have in mind? The only way I can imagine would be to have Nimble wrap your package inside a That is a perfectly fine solution btw which we may adopt. The only disadvantage that I find with it is that it will break packages that expose pkgname.nim and want it to be imported via |
I need to digest the responses as well but one note worth mention is that the package search implementation is not isolated within nimble. No doubt nimble could handle everything within itself and avoid some issues but many Nim programmers use To support this, Nim has a bunch of code to search
All directories in
Given how things work today, I don't know how you can disambiguate dependencies with just the .nimble file since Nim does the importing and doesn't look at the .nimble file. |
I am thinking:
So, ok...maybe the nim compiler would need to have yet one more way to search for/apply Anyway, with that setup, you can A) be warned by nimble at install time that there is a collision with So, the notification of conflict is the same - the compiler barking -- and the disambiguation by parent-namespace qualifying is the same. Just as with You might need a Indeed, with a nimble-maintained With the current nimble set up at install time you might need to put pkgclone/src/*.nim into the top-level of the pkgs/pkgname directory, but that doesn't seem hard. That would fit with the current style of "you tell me what to move" not "you do the moving". |
Ooh, nice idea. I think we might want to implement this even if to just get rid of the The idea you have about disambiguating by package name also sounds like it could work, but personally I don't think it's the right approach. I personally like knowing which package a certain module comes from, and yes, I realise this is inconsistent with how modules in Nim work (and to be honest, I would love for each function call to be prefixed by the module name by default if it wasn't for how UFCS/operators work in Nim). |
It's just more internally consistent with how name ambiguity and disambiguation works with Nim in general, but with my idea import'ers absolutely have the option either way, whichever they like. For single-*.nim source file packages I suspect It's possible a new Also, multi-module packages could just put all their files at the top-level of the git repo. No need for I don't see any real backward compatibility concerns, or at least no more contortions than are present now, but I haven't really analyzed it deeply. I've more thought "what could be from scratch". |
Since in this new model the nim compiler needs to know basically nothing about package management ( My own interest has less to do with multi-user sharability and more to do with the triplet: (a network-shared Regardless of any of this, it still makes sense for the compiler to just provide "general path search/config search facilities" where anyone could write a |
I feel like having to reply here but I cannot add much to the discussion. I have brought up similar ideas as @c-blake in the past so I mostly agree with him. I also wrote a couple of Nimble RFCs about how to improve the situation. One minor point that hasn't been mentioned, the problem starts with the fact that "simple" package import statements were supposed to look like |
I think just having the "parent level or pkgs/" before any of the |
Maybe I was unclear, but the only time This mess got started by nimble translating package structures into install structures. For old multi-module packages unwilling to restructure there may be a need to translate to the installed structure. But for a new package or a package willing to re-structure, it could be just like a Delegating such translation from whatever a package author wants to canonical for- Maybe the initial mistake was putting/leaving a Anyway, it would be fabulous if we could recover from this mistake someday, somehow. Thanks for listening and best wishes to all! |
How would this work when you have multiple versions of the same package installed?
Pretty sure Cargo didn't exist in 2012 |
How does it work now? I mean, how can I select which one to Anyway, because of that avoidance, it will be very rare/only impact very few "importees". So, for those rare cases you could always install second & later versions under |
Once again, here is what to do:
This setup naturally allows for lock files, is far less complex to implement than today's Nimble, is more flexible and less annoying. |
I'd bet @disruptek approves of @Araq's ideas as they sounds closer to (a subset of) @dom96 - I just did a Presumably people wanting one specific version of a dependency just do an So, this notion of multiple installed versions seems theoretical at best { even without @Araq's better idea that bypasses it completely and also makes for a far more controlled build environment and makes all this due diligence besides the point :-) }. |
@c-blake you're misunderstanding. You let either Nimble or Nim choose the package version, you don't put that version in the import statement ever. Nim by default chooses the latest version that's installed in The imports are always Now Araq's proposal above goes many steps further and outside what we are discussing. I have always and will continue to champion for the ability to quickly write scripts, forcing local deps on people will prevent that use case since it will require a But offering it as an option is perfectly fine by me, and we can see how popular it becomes. In fact, @genotrance already implemented a basic version of it in Nimble. |
Noting multiple points here to help drive towards a solution:
I'm writing down a solution that extends on Araq's suggestion that solves all of these requirements. I'll note that down next but in the interim, please review that the above covers all the concerns. |
In terms of quick scripts, I just nimble installed jester in 3 seconds. It only has 2 deps. Not running @genotrance - that's a pretty good list. I'll personally probably never use nimble except to test compatibility for client codes as long as it installs binary executables into $HOME for reasons already stated. It seems to me that packages are mostly libraries or at least "dependency" is "dependency on the library parts". Don't know if that helps. There could be deps on a code generator binary, I guess. What I find most objectionable is that (even as a non-user/total avoider of learning anything related to this complex ball of nimbleness because it seems like a morass of poorly justified complexity) it pushes package authors to put things into Anyway, I eagerly await @genotrance's ideas. (Which he can post over at nimble if he wants with some link back to here.) |
I would just add that useful changes have grown out of experiences like this. Nimble has some legacy to deal with, but it's definitely improving: @genotrance has really hit the nail on its head with his idea of using the package manager as the source of unidirectional logic; the pm sets up the environment for subsequent tooling, and what comes next does not feed back into the pm. Coupled with the idea that My bias is obviously towards having as little package management as possible, but as Nimble has grown to support local dependencies and (soon) lockfiles, it has liberated me to pursue other development in Nimph, which was really only designed to validate compiler configuration. So there's less lock-in than there was, and people's taste seems to be trending in the right direction. Have heart! |
So, in terms of how theoretical vs. practical the "multiple installed versions problem" is, I did a different analysis and one of the packages involved is even @disruptek & @genotrance. I realize all of this metadata is just "the first 8 years of nimble" or whatnot, but it's at least something. I think it often really helps to study how people actually use your tool to prioritize. Correct me if I am wrong, but unless there is a So, almost nobody uses this So, 4/1333 is a pretty small fraction and the people like @disruptek are probably doing those version ceiling fence posts are probably doing the "abundance of caution" thing to cite how USA lawyers always talk..but it may be overabundant. ;-) There is no Some other data that might shed light on how "real" the problems being prioritized are - top level module name collisions are also very rare in the 749/1333 The 101 Anyway, to me this little investigation suggests that there is probably very little to zero need for multiple versions. The latest tagged release is enough, just dropping/ignoring So, I mean, one can always box oneself into a corner trying to solve an overly hard problem. I think @Araq's idea is great for just separating concerns, boom, done and don't exactly understand the resistance to it. In light of all the above quantitative facts and that resistance, there could also maybe be just a "mode" like Another relevant analysis would be the distribution of sizes (in package count or in bytes) of the transitive closure of per-package dependency graphs. @Araq's proposal may be far less expensive on average than you might at first "guess". And if you do it his way and someone wants to just fire up a text editor then they can just "cd top-level" and start editing a |
I think what's intended here is "use a compiler that is compatible with 1.0.x". If Nim followed semantic versioning, a ceiling of "< 2.0.0" would actually make sense. However, since Nim does not use semantic versioning and the "LTS" version is 1.0.x, the ceiling should be "< 1.1". So while the actual ceiling 2.0.0 doesn't make sense for the current Nim versioning approach that doesn't mean specifying a ceiling for the compiler is generally useless, IMHO on the contrary. Just wanted to mention this. In particular, I don't want to start a discussion on Nim versioning here. :-) |
A fair point :-) but the only version ceilings actually used for the Nim compiler are "2.0.0" (in Either way, I think disallowing Anyway, I'm just trying to scope what/how bad these actual problems are based on what people do/did with facts that are less subjective/theoretical. It's obviously easy to say everyone has misused tools/languages for years to discredit that, but misuse of features is also often an argument against them. |
Oh, and I guess I forgot to even check And forcing people to do that |
Huh? Nim 1.2 does not break compatibility as far as I'm aware. At least as long as adding new features doesn't count. So in essence, Nim does follow semantic versioning.
The fact of the matter is that Nim is so immature and the depth of packages is so low that this investigation does not yield a representative sample of the sorts of issues that will become prevalent into the future. I appreciate your efforts but I don't really think they prove much. I actually think that we should start having a conversation about supporting the ability to import two different versions of the same package inside a single compiled program. The deeper the dependency tree and the more packages are used the more common this scenario will become, and then you'll really run into painful situations when Nimble tells you "Sorry, but Jester needs httpbeast 2.0, but prologue needs Jester 1.0.0". |
This is already a problem; Nimph breaks with I think what is ultimately needed long-term is scoped imports, but I haven't exhausted all my ideas for working around this. |
@dom96 - what about the idea of saying you lose the "shallow optimization" that seems important to you once that gets "too hard" and just do deep dependencies as per @Araq? Most of my investigations could be framed as trying to suss out how often that shallow optimization would work. @disruptek - is there something I can do to make |
I haven't caught up again with the many posts but please read this link for info on minimum version selection. Today nimble picks the latest but it should really move to this algorithm in the future. |
Do we have a ticket for this? I remember ultimately convincing you but I think we just decided to go with |
We may want to discuss this urgently, as Minimal Version Selection can be a replacement for lock files. Perhaps we should adopt it and say screw it to lock files altogether? |
Some comments:
At the time of our discussion, I hadn't read this and related articles. It makes total sense for our ecosystem. The question is how to deploy this without breaking users. It might warrant building all packages and opening upstream PRs to update the required versions. People have been lazy since nimble installs the latest so this will require some education, support and new discipline. MVS warrants simplifying the addition and updating of deps and versions in the .nimble file so that would have to be done as well.
The writing is on the wall. Go has already implemented this it seems. It warrants more investigation and discussion for sure. |
Well, you can use Nimph to test packages. |
Well, ok. I just got rid of all my Re: module name collisions these are collisions after squashing Maybe I was trying to simplify too much at once for |
I'm in favor of issuing a warning, at least, for That said, there are plenty of packages that don't specify version requirements or, if they do, the required package may not be tagged. Are these not |
My only problem with MVS is this statement:
This is definitely not true for Nim. For example,
This assumes that modules follow semantic versioning, but AFAICT, we don't enforce this at all, and in nimble version is a string that can be whatever instead of following a concrete format. And even if we were to enforce it, here's a scenario where it gets hairy:
Under the MVS, to compile B, these packages will be installed: A-1.0.0, A-2.0.0 (major bump is considered to be a different module), C-1.2.0. Now here's the problem: On the Nim side, there's no distinction between Go completely dodged this problem by making the major version is a part of the import identifier, but I don't think we can realistically apply that to current Nim. |
Cue @Araq and "relative import paths". 😉 |
That is precisely the problem. Like I said above, Nim does not support two different versions of the same package in a single compiled program. I only see two solutions to this:
|
I was told that 1.4 would (probably) make orc the default memory management. If that's the case, there's a problem with
The message about a possible reimplementation is relatively new I think; I can't remember having seen it, only that it wasn't supported. So there's hope. :-) I'm not sure what will happen regarding So maybe I was too hasty here. |
I've posted a detailed problem statement and solution for this discussion on the nimble wiki. https://github.com/nim-lang/nimble/wiki/Package-structure-and-Interop Please review and share your thoughts on the forum and thanks in advance. |
Over my dead body. Lock files are superior. |
Since hldiff is described as "A port of Python difflib to compute diffs and (re)highlight diff output intraline", I assume it should be a hybrid package.
Installing hldiff 0.1 or head with
nimble install hldiff
, however, installs only the binaries, not the.nim
source files.There was a change in Nimble a while ago that requires that hybrid packages need an
installExt = @["nim"]
line to install the Nim source files. See https://github.com/nim-lang/nimble/blob/master/changelog.markdown#090---19092018 and nim-lang/nimble#561 .The text was updated successfully, but these errors were encountered: