Following is the RFC for providing project local dependencies in Nimble. This is being tracked in issue 131 and discussed in the Nim forum.
Definitions:
local deps mode- this RFC to enable project local dependencies where$prj/nimbledepsis used by Nimble on a per project basisuser deps mode- current Nimble behavior of using~/.nimblesince dependencies are usable across projects for a specific userglobal deps mode- tracked in issue 80 where a system-wide folder can be used to store dependencies across users and projects. It is not covered in this RFC.
Motivations:
- The main value of
local deps modeis to provide dependency isolation from other projects. Isolation simply makes development easier and avoids any conflicts caused by mixing dependencies across projects. local deps modeis simply a mode of operation during development and is not expected to be checked into source control. The intention is not to push vendoring or an alternative for lock files. It is not aimed at solving any distribution related challenges or enabling reproducible builds.- If a user wants
local deps modefor a particular project, it implies they want complete isolation. As a result, Nimble will no longer consideruserorglobaldependencies and commands will all act as if$prj/nimbledepsis the only directory Nimble uses. - Once a working configuration is reached regardless of
deps mode, the user could then generate a lock file that improves on distribution. That design will be discussed separately and not distract this RFC. - This RFC mainly describes Nimble behavior at this time. The changes required for Nim to understand
local deps modewill be addressed later.
All behaviors below that drive actual code changes are highlighted with *.
Behavior:
- All nimble commands will highlight when in
local deps modeso that it is amply clear to the user* - An explicit
--nimbleDir:xxxoverrideslocal deps mode. - If
$prj/nimbledepsdirectory exists, setlocal deps modeby forcingnimbleDir = $prj/nimbledeps* - Else, continue in default
user deps mode
Command-line behavior in local deps mode:
nimble install- Install all the project's dependencies into
$prj/nimbledeps - Build binaries if applicable
- Do not copy the project itself into
$prj/nimbledeps- inform user*
- Install all the project's dependencies into
nimble install -d | --depsOnly- install all the project's dependencies into$prj/nimbledepsnimble install url|pkg- install dependency into$prj/nimbledepsnimble uninstall pkg- remove pkg from$prj/nimbledepsnimble uninstall pkg -i- remove pkg and packages that depend on it from$prj/nimbledepsnimble build- install deps into$prj/nimbledepsin the processDeps stepnimble develop- Install all deps into
$prj/nimbledepsin the processDeps step - Do not create any links to itself it in
$prj/nimbledeps- inform user*
- Install all deps into
nimble develop prj2- Clone
prj2into sub-directory withinprj1and add a link into$prj/nimbledeps
- Clone
nimble develop prj2 --nimbleDir:$prj1/nimbledeps- Clone
prj2into directory outsideprj1and link into$prj1/nimbledeps
- Clone
- To use an existing project
$prj2as a dependency inlocal deps modeproject$prj1:cd $prj2nimble develop --nimbleDir:$prj1/nimbledeps
local deps mode is a mode of operation during development and not for influencing distribution. While it is not recommended, users can save local deps mode in source control by:
- Checking in
$prj/nimbledeps/empty.txt - Checking in
$prj/nimbledeps/*- vendoring or poor man's lock files - Need to verify that
nimble installof such a project does not break - Nimble should not get confused what the truenimbleDiris when processing such deps
No changes:
- All commands will continue to run like they do today when in
user deps mode - Dependencies will need to be added to the
.nimblefile in therequiressection per usual to get installed from scratch regardless ofdeps mode
Caveats:
- Checking in
$prj/nimbledeps/*into source control will work as expected for the project when checked back out but if the project is itself installed by a parent project, these checked-in deps should not be inherited. The dependencies will get pulled from~/.nimbleor$prj/nimbledepsof that parent project depending on its configuration. This is similar to how lock files work for libraries. - If a project with local deps has a dep which builds binaries, it will install into
$prj/nimbledepswhich means the binaries will not be in~/.nimble/bin, typically in$PATH. User is expected to add$prj/nimbledeps/binto the$PATH.
Replies to some of the comments here.
This is being addressed in two ways - one is for nimble to be vocal about local deps mode in every command so that user knows where deps are being installed and coming from.
Second, local deps is opt in - you need to do something for it to be in effect. If you checkout someone else's project that uses local deps, nimble will remind you as noted above.
nimble uninstallof a package that other packages depend on fails altogether and displays the list. You need to use-ito force remove it and all the others too.As I have noted above,
nimble installandnimble developcan be made to behave in a variety of ways depending on this change. Some of them are not compatible with~/.nimbleat all which means a project with local deps cannot then be used by other global projects on the system. This is highlighted by @disruptek's last comment. Maybe that's okay but it isn't obvious. We need a clear definition of how things change with this feature.Whatever it is, it needs to be obvious and consistent. If you want to install or link (develop) in
~/.nimblethen deps also need to be installed in~/.nimble. It could mean that these commands do both project local and~/.nimblemanagement simultaneously but seems wasteful and confusing. Maybe there should be a flag to force~/.nimblewhen local deps are in effect. Perhaps a--useror something. This seems more sensible since it will be a less frequently used and could do fine with requiring the user to be deliberate.I don't want to mix up
--globalin this proposal cause there's a different issue for that.