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.
If
uninstallisn't going to by default remove things that depend on the uninstall target, it should at least warn the user, or maybe prompt for permission to remove the orphaned packages. Also, this behavior suggests the need for a command to remove or list orphaned packages. Personally, I'd prefer if it just logged notice and went ahead and removed the orphans by default, and a special flag was required to keep them.