Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ability to use a local folder to fulfill a dependency #439

Merged
merged 13 commits into from Jun 19, 2020

Conversation

mosteo
Copy link
Member

@mosteo mosteo commented Jun 9, 2020

This PR implements the pinning of dependencies to folders. These folders then act as a wildcard for any version; that is, the dependency will be always satisfied. I chose this approach instead of associating a version to the folder because both opam and cargo work like this, and for crates in progress the version is actually not a concern.

On terminology and internals: for Alire users, both pinning to a version or a folder is presented under the concept of pins (because the idea is to fix a dependency to something concrete). Internally, there are separate concepts, "pin to a version" (already implemented) and "linked to a folder" (new in this PR), and the term softlink/link is used for new types/subprograms that involve these new user pins.

Given the lack of version of these linked crates, internally we don't rely on placeholder releases. Instead, links are represented with a new Alire.Externals.Softlinks type and the solver is aware of them, which has the added benefit of the solver not needing to blindly try releases until finding the good one; instead, links are reused from the solution the solver receives as a basis.

There are two ways of pinning a dependency to a folder: right away at the time of adding the dependency (alr with crate --url path) or later with the pin command (alr pin crate --url path). I named the switch --url instead of --dir because in the foreseeable future we may want to support a remote repository or archive instead (as opam does).

When adding and linking simultaneously, the dependency needs not to exist in the index, which is convenient to rely on unindexed dependencies:
alr with unindexed_crate --url /path/to/working/version

See the new tests for examples of usage. In essence:

$ alr init --bin xxx
$ cd xxx
$ alr with libhello --url ../libhello
Requested changes:                                            

   ✓ libhello * (added)

Changes to dependency solution:

   ⊙ libhello file:/tmp/a/libhello (pinned)

Do you want to proceed?
[Y] Yes  [N] No  (default is Yes) 
Using default: Yes
$ alr with --solve
Dependencies (direct):
   libhello*
Dependencies (external):
   libhello* (direct,linked,target=/tmp/a/libhello)
Dependencies (graph):
   xxx=0.0.0 --> libhello*
┌───────────┐     ┌───────────┐
│ xxx=0.0.0 │ ──> │ libhello* │
└───────────┘     └───────────┘
$ alr setenv
export GPR_PROJECT_PATH="/tmp/a/libhello"
export ALIRE="True"

Goes on top of #437, fixes parts of #240

@mosteo mosteo force-pushed the feat/softlinks branch 3 times, most recently from b51f2a1 to d8f62f5 Compare Jun 9, 2020
@mosteo mosteo marked this pull request as ready for review Jun 9, 2020
@mosteo mosteo force-pushed the feat/softlinks branch 2 times, most recently from 432d935 to 7280720 Compare Jun 17, 2020
mosteo added 12 commits Jun 18, 2020
The placeholder `linked` fulfilment is now properly implemented to
hold/load/save the information about a directory to be used to fulfill a
dependency.
Add a Alire.Solutions.Linking subprogram that includes a linked dependency into
a solution.
When a softlink for the dependency being solved exists in the starting
solution, that dependency can be considered fulfilled without further ado.
A dependency can now be added simultaneously with a target directory that
fulfils it. Minimal check of the folder existing is performed; the buildability
of the whole is now the responsibility of the user.
This is the delayed counterpart to `alr with --url`; i.e., users can add the
dependency normally with `alr with` and later decide to pin it to a folder with
`alr pin`, without needing to remove it completely first with `alr with --del`.

We present pinning to versions and to folders to users under the same idea of
pinning. Internally, alr distinguishes between pinning (to versions) and
linking (to URLs). Currently only local paths can be used for links, but in the
future we may add remote files to fetch or repositories to clone.
The logic of collecting all necessary paths has been moved from Alr.Build_Env
to Alire.Roots.Project_Paths. A Root was already necessary to collect the
paths, and furthermore the root has all the necessary information: the root
release and the complete solution, which includes releases and linked dirs.

To make Roots self-contained, the platform properties are copied during startup
to Alire.Root. This is a temporary measure until these properties are
refactored from Alr into Alire.
Information shown for external (lacking a release) dependencies is more
comprehensive now, showing transitivity, pin information, hinting status.
src/alire/alire-pinning.ads Show resolved Hide resolved
src/alr/alr-commands-pin.adb Outdated Show resolved Hide resolved
@Fabien-Chouteau
Copy link
Member

Fabien-Chouteau commented Jun 19, 2020

So when pinning to a directory, only the GPR_PROJECT_PATH and current directory for actions change. How do you see the URL thing working? One time download or re-download for every alr command?

@Fabien-Chouteau
Copy link
Member

Fabien-Chouteau commented Jun 19, 2020

Awesome feature by the way :)

@mosteo
Copy link
Member Author

mosteo commented Jun 19, 2020

only the GPR_PROJECT_PATH and current directory for actions change

I'm not sure what you mean by actions here... A linked dir won't have actions.

How do you see the URL thing working? One time download or re-download for every alr command?

My current idea is that a remote source archive would be downloaded once, when added. A repository could be pulled for changes via alr update.

@Fabien-Chouteau
Copy link
Member

Fabien-Chouteau commented Jun 19, 2020

I'm not sure what you mean by actions here... A linked dir won't have actions.

The actions that can be defined in the crate toml:

[[general.actions.'case(os)'.linux]]
type = "post-fetch"
command = ["make"]

My current idea is that a remote source archive would be downloaded once, when added. A repository could be pulled for changes via alr update.

Sounds good 👍

@mosteo
Copy link
Member Author

mosteo commented Jun 19, 2020

The actions that can be defined in the crate toml:

A linked folder does not go through fetch or compile steps, so no actions will be run for it. For the root release in the workspace, the compile actions will run normally from its own folder.

@mosteo mosteo merged commit dcd7b66 into alire-project:master Jun 19, 2020
@mosteo mosteo deleted the feat/softlinks branch Jun 19, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants