Only new behavior is captured, everything else should work per usual.
Nimble recently added the ability to work with project local dependencies. Simply by creating a nimbledeps
directory in the project is sufficient to go into this mode. Once this directory exists, all information that typically goes into ~/.nimble
is stored here, unaffected by any other projects or global changes.
This feature is being extended with a new -l | --local
flag which sets up a project in localdeps mode. For most cases, all it does is creates a nimbledeps
directory if it doesn't already exist.
E.g. nimble -l init
will initialize a project in localdeps mode.
This flag is only useful when initially working with a project or a pre-existing project folder. Once the nimbledeps
folder is setup, the flag is redundant.
The nimble develop pkg
command clones a new project so setting it up in localdeps mode requires some additional code changes.
Using nimble develop -l karax
for example will result in the following actions:
git clone https://github.com/pragmagic/karax karax
cd karax
mkdir nimbledeps
After this, nimble will setup all dependencies in ./karax/nimbledeps
since project is now in localdeps mode.
Larger Nim projects require code changes to dependencies as well. This requires the user to check out each dependency separately in nimble develop
mode.
This workflow can be simplified with a new -d | --deps
flag for nimble develop
which will also set up all dependencies in develop mode.
Running nimble develop -d karax
will result in the following directory structure:
./dotenv/...
./karax/...
./ws/...
The top level project karax
and all its dependencies will be checked out with git clone
at #head
as sibling directories. This also means all requires
statements with version specific information will be only used to identify dependencies but not their actual versions since you develop on #head
.
By default, nimble will use ~/.nimble
and link all packages per usual.
If -l | --local
is also specified, the project and all dependencies will be set up in project local dependency mode.
Running nimble develop -l -d karax
will result in the following directory structure:
./nimbledeps/... # contains all project local nimble metadata
./dotenv/nimbledeps/nimble.nimble-link # links to ../../nimbledeps
./dotenv/...
./karax/nimbledeps/nimble.nimble-link # links to ../../nimbledeps
./karax/...
./ws/nimbledeps/nimble.nimble-link # links to ../../nimbledeps
./ws/...
This enables project isolation and the project and each dependency can be developed while being linked to their dependencies.
Any nimble commands to add/remove dependencies will work the same whether within the parent directory, the top level project ./karax
or in a dependency directory.
Let's not overvalue the "reduction of new code" and instead aim for a design with the best long-term properties.
I feel the main drawback of the local deps feature is that it tries to create a new proper way to use Nimble in which you can opt-in, but it still leaves other default behaviors that can lead you to problems down the road. Many users will fall into the trap of using the global cache for develop links or they will run with a single non-shared localdeps folder. Instead, @bobeff's approach aims to solve the problems with the global cache, so even the unexperienced users can get the best possible experience out of the box.
I'll address few particular critiques:
1) The
.develop
file clutters your working copyI would say the same is even more true for the
localdeps
folder. I can name dozens of less sophisticated tools that can suffer from a large number of files in your project folder (e.g. text editors with less sophisticated "Find in files" features will give less relevant results; The Ctrl+P file navigation feature in a text editor can get slower; build systems that watch your project tree for modifications can run into file descriptor limits, etc). Hard disk space is indeed cheap nowadays, but if we can get a working system that needs only the global cache, why shouldn't we?2) Links can do exactly the same as
.develop
filesThis is not strictly true. The shared
nimbledeps
folder is roughly equivalent to having a shared.develop
file that you include in your top-level projects. But in each top-level project's.develop
file you can also easily temporary redirect the path only of a particular package. I can recall many situations where I needed to test how some new version of a particular component interoperates with an older working version of the same code and this extra flexibility of the.develop
files makes it easier to setup small experiments like these.You are also saying that having a link implies the so called "develop mode", but is this true? In the scheme you proposed, the entire shared
nimbledeps
directory is linked in each project. Shouldn't this imply that all of the packages in that directory are in develop mode, even the third party ones? It's true that metadata additions can address this.3) Minimal version selection makes the lockfiles unnecessary
Again, this might look beneficial if the goal is to keep Nimble as small as possible, but it cuts into the flexibility that the lockfiles provide for the authors of libraries and for creating test setups. When @bobeff is so close to shipping the feature, why shouldn't we help him make the last few steps instead of pursuing alternative directions that will be more taxing for the end users and will require more development time at this point?
With lockfiles in place, it's clear that the interaction between Nim and Nimble will need to change somehow in order to provide the precise package selection in the presence of multiple package versions installed side-by-side (i.e. these are the
nim.cfg
plans). This gives us a chance to rethink some of the key operations concerning the global cache and allows us to solve the problems without introducing unnecessary fragmentation in the user experience (different users using Nimble in a different way, leading to "it works on my machine" type of problems)