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.
Functionality-wise, this is close to what @bobeff has done with local develop files, but I'll describe the reasoning behind his design:
1) The "include" feature of the develop files makes it easy to manage large number of developed packages.
If every project had to reference all of its "develop mode" dependencies with separate links, the number of required links would have been N^2. Extracting some modules in a library would require you to create multiple links to the new library in all existing packages.
In contrast, the include feature makes it easy to create a single develop file that lists all of your libraries. With this file included in all of your top-level projects, both adding a new library or a new top-level project consist of a single operation.
Now, it's true that the scheme suggested above manages to reuse the entire
nimbledeps
directory and thus creates a similar setup, but this gets us to point 2)2) You are not forced into a all-or-nothing decision regarding your dependencies.
In a more mature eco-system, a typical large project may have hundreds of dependencies. As an example, Lighthouse, our competing Ethereum 2 client implemented in Rust, has over 500 dependencies. From these, only 30 or so are packages developed by the Lighthouse team and thus are good candidates for the develop mode. In other words, I think most users will prefer to explicitly specify which packages are put in develop mode (either manually or through a script) than to create a directory with hundreds of third-party packages produced by a command such as
nimble develop --deps
.The description above doesn't specify how the locally developed packages (e.g.
ws
) are discovered from the top-level project (e.g.karax
), but I assume that there will be additional links in the shared./nimbledeps/
folder. This graph of links can be equivalent to the tree of includes with the ".develop files" feature, but it may require the user to re-arrange the directory structure as she discovers new shared packages, new packages to be put in develop mode and so on. I feel the incremental steps with the.develop
files are smoother and more natural to handle through the CLI or through manual editing of the contents of the.develop
files.3) Nimble should help the developer deal with the daily
git pull
.When you run
git pull
every morning, you'll discover that most of your "develop mode" packages need to be updated (the lockfile of your top-level projects will point to new git revisions). This daily update must be handled in a highly interactive way because there are plenty of situations that require a decision from the user (e.g. a local dependency that must be updated may be in a dirty state, you may have started work on a diverging branch, etc).The links in the nimbledeps directory don't carry enough semantic information for Nimble to be absolutely certain that the packages are actually in "develop mode". Without this explicit knowledge, it would be more difficult for Nimble to provide a highly specialized UI for all the complicated scenarios that may arise with the develop mode when you build, pull or push your code.