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/nimbledeps
is used by Nimble on a per project basisuser deps mode
- current Nimble behavior of using~/.nimble
since 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 mode
is to provide dependency isolation from other projects. Isolation simply makes development easier and avoids any conflicts caused by mixing dependencies across projects. local deps mode
is 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 mode
for a particular project, it implies they want complete isolation. As a result, Nimble will no longer consideruser
orglobal
dependencies and commands will all act as if$prj/nimbledeps
is 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 mode
will be addressed later.
All behaviors below that drive actual code changes are highlighted with *
.
Behavior:
- All nimble commands will highlight when in
local deps mode
so that it is amply clear to the user*
- An explicit
--nimbleDir:xxx
overrideslocal deps mode
. - If
$prj/nimbledeps
directory exists, setlocal deps mode
by 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/nimbledeps
nimble install url|pkg
- install dependency into$prj/nimbledeps
nimble uninstall pkg
- remove pkg from$prj/nimbledeps
nimble uninstall pkg -i
- remove pkg and packages that depend on it from$prj/nimbledeps
nimble build
- install deps into$prj/nimbledeps
in the processDeps stepnimble develop
- Install all deps into
$prj/nimbledeps
in the processDeps step - Do not create any links to itself it in
$prj/nimbledeps
- inform user*
- Install all deps into
nimble develop prj2
- Clone
prj2
into sub-directory withinprj1
and add a link into$prj/nimbledeps
- Clone
nimble develop prj2 --nimbleDir:$prj1/nimbledeps
- Clone
prj2
into directory outsideprj1
and link into$prj1/nimbledeps
- Clone
- To use an existing project
$prj2
as a dependency inlocal deps mode
project$prj1
:cd $prj2
nimble 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 install
of such a project does not break - Nimble should not get confused what the truenimbleDir
is 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
.nimble
file in therequires
section 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~/.nimble
or$prj/nimbledeps
of 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/nimbledeps
which means the binaries will not be in~/.nimble/bin
, typically in$PATH
. User is expected to add$prj/nimbledeps/bin
to the$PATH
.
Replying to this separately. I think this is a legitimate question.
npm uses project local deps by default. You need to specify
-g | --global
to be explicit about using the global repo. Nimble doesn't have this-g
feature (being tracked in issue 80). It instead uses a per-user global. Now this is definitely cooler since the user is able to manage this repo in any way he chooses unlike npm's global which requires admin/root. pip allows a global location that needs admin as well as a per user site-packages but resorts to virtual envs to provide isolation.The problem local deps alleviate is that a project only has real control over its immediate dependencies. If a dependency pulls in additional dependencies, there is a likelihood of packages conflicts causing issues. Isolating each project's dependencies into a local dep directory definitely reduces these conflicts. It does not completely eliminate them since
A -> B -> C@v1
andA -> D -> C@v2
is still possible but at least you can manage that for a specific project without having to worry about other stuff in~/.nimble
.So in some sense, yes, local deps are for making development easier by providing project isolation.
--nimbleDir
and--path
can be used today but requires a bunch of manual work. This proposal is just to make this easier. It is not a supplement for lock files but perhaps a foundation. There is also the question of how to inform Nim of local deps and that will be the next step of this proposal.Lock files solve a distribution issue so that other users can achieve reproducible builds. Once a user has a working configuration,
~/.nimble
based or local deps based, he can generate and check in a lock file. That design should be discussed separately and not distract this proposal. There are other steps as well to make life better such asnimble install
adding entries into .nimble and perhaps others.