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

Pins in the manifest #743

Merged
merged 25 commits into from
Jun 22, 2021
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
3c07450
Added data structures
mosteo May 12, 2021
05a7614
Pins may appear in manifest, being ignored
mosteo May 13, 2021
b58d2fa
Loading of user pins complete
mosteo May 19, 2021
34c1a40
Pins are downloaded or skipped as needed
mosteo May 19, 2021
e01ff27
Pins are properly pruned, and info displayed
mosteo May 19, 2021
41c2cc5
Added new-format pins to alire.toml for self-build
mosteo May 19, 2021
6f6627b
Allow selective update of pins as for regular deps
mosteo May 20, 2021
b7d6605
Local pins work with new manifest syntax
mosteo May 20, 2021
575e795
Fixed bug in which version pins were not used
mosteo May 21, 2021
09ca589
Make version explicit key in user pin
mosteo May 21, 2021
254b5a3
Fix bug about confirming empty updates
mosteo May 21, 2021
5298c1a
Roots: Conflated dep updating into single Sync
mosteo May 21, 2021
d622f05
Disable tests that rely on `alr pin`
mosteo Jun 14, 2021
aeb52cd
More tests temporarily disabled
mosteo Jun 14, 2021
d71b7aa
Disable code for pin edition in command-line
mosteo Jun 14, 2021
f293ec1
Changes to allow pins to non-dependencies
mosteo Jun 14, 2021
00f1a34
Tests in tests/pin using new pins
mosteo Jun 14, 2021
6d1a2e2
Documentation on new pins
mosteo Jun 16, 2021
674582e
Fix for testcase on Windows using path separators
mosteo Jun 16, 2021
0215202
Spelling fixes, and exclude lockfiles from check
mosteo Jun 16, 2021
ebaba3a
New test for various invalid pin entries in manifest
mosteo Jun 16, 2021
b90150c
Fixes from code self-review
mosteo Jun 16, 2021
9a3174e
Fixes suggested during code review
mosteo Jun 17, 2021
472a849
Fix for missed update when there is no lockfile
mosteo Jun 17, 2021
e3fb579
Test to check pins are applied with no prior lockfile
mosteo Jun 17, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/spellcheck.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ jobs:
github_token: ${{ secrets.github_token }}
reporter: github-pr-review
locale: "US"
exclude: "*.lock*
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,6 @@
path = deps/spdx
url = https://github.com/Fabien-Chouteau/spdx_ada
branch = 319ca7bcc1e2eb1843aad1f64aca3ecba91a2bcc
[submodule "deps/optional"]
path = deps/optional
url = https://github.com/mosteo/optional
1 change: 1 addition & 0 deletions alire.gpr
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ with "ajunitgen";
with "ansi";
with "gnatcoll";
with "minirest";
with "optional";
with "semantic_versioning";
with "simple_logging";
with "uri";
Expand Down
14 changes: 14 additions & 0 deletions alire.lock
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,20 @@ remote = true
commit = "4550aa356d55b9cd55f26acd34701f646021c5ff"
url = "git+https://github.com/mosteo/minirest.git"
[[solution.state]]
crate = "optional"
fulfilment = "linked"
mosteo marked this conversation as resolved.
Show resolved Hide resolved
pinned = false
transitivity = "direct"
versions = "~0.0.0"
[solution.state.link]
kind = "softlink"
path = "file:alire/cache/pins/optional_0.1.0-rc1_30aaee65"
relative = true
remote = true
[solution.state.link.origin]
commit = "30aaee65d89d5a9ca1c71f6d38e4462fae2ef4ce"
url = "git+https://github.com/mosteo/optional.git"
[[solution.state]]
crate = "semantic_versioning"
fulfilment = "linked"
pinned = false
Expand Down
14 changes: 14 additions & 0 deletions alire.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ ajunitgen = "^1.0.1"
ansiada = "~0.1"
gnatcoll = "^21"
minirest = "~0.2"
optional = "~0.0.0"
semantic_versioning = "^2"
simple_logging = "^1.2"
uri_ada = "^1"
Expand All @@ -29,3 +30,16 @@ spdx = "~0.2"
# Building alr requires the explicit setting of this variable
[gpr-set-externals."case(os)"]
macos = { OS = "macOS" }

# Most dependencies require precise versions during the development cycle:
[[pins]]
aaa = { url = "https://github.com/mosteo/aaa.git", commit = "4b4aa047f29a4270c5b5003468617e153977ab97" }
ada_toml = { url = "https://github.com/pmderodat/ada-toml.git", commit = "ade3cc905cef405dbf53e16a54f6fb458482710f" }
ajunitgen = { url = "https://github.com/mosteo/ajunitgen.git", commit = "e5d01db5e7834d15c4066f0a8e33d780deae3cc9" }
ansiada = { url = "https://github.com/mosteo/ansi-ada.git", commit = "acf9afca3afe1f8b8843c061f3cef860d7567307" }
gnatcoll = { url = "https://github.com/alire-project/gnatcoll-core.git", commit = "f3bd1c51d12962879f52733e790b394f5bbfe05f" }
minirest = { url = "https://github.com/mosteo/minirest.git", commit = "4550aa356d55b9cd55f26acd34701f646021c5ff" }
optional = { url = "https://github.com/mosteo/optional.git", commit = "30aaee65d89d5a9ca1c71f6d38e4462fae2ef4ce" }
semantic_versioning = { url = "https://github.com/alire-project/semantic_versioning.git", commit = "82c28f773d0e3126d7cdf6e4ded228d2b733441e" }
simple_logging = { url = "https://github.com/alire-project/simple_logging.git", commit = "02a7de7568af6af7cedd1048901fae8e9477b1d9" }
uri_ada = { url = "https://github.com/mosteo/uri-ada.git", commit = "b61eba59099b3ab39e59e228fe4529927f9e849e" }
1 change: 1 addition & 0 deletions alr_env.gpr
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ aggregate project Alr_Env is
"deps/ansi",
"deps/gnatcoll-slim",
"deps/minirest",
"deps/optional",
"deps/semantic_versioning",
"deps/simple_logging",
"deps/uri-ada",
Expand Down
4 changes: 4 additions & 0 deletions config/alr_config.ads
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
-- Configuration for alr generated by Alire
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this folder not be added to git?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed by #744

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in Alire, but they still should not be checked in here.

package alr_Config is

end alr_Config;
14 changes: 14 additions & 0 deletions config/alr_config.gpr
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
-- Configuration for alr generated by Alire
with "aaa.gpr";
with "ajunitgen.gpr";
with "ansi.gpr";
with "gnatcoll.gpr";
with "minirest.gpr";
with "optional.gpr";
with "semantic_versioning.gpr";
with "simple_logging.gpr";
with "spdx.gpr";
with "uri.gpr";
abstract project alr_Config is

end alr_Config;
5 changes: 5 additions & 0 deletions config/alr_config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/* Configuration for alr generated by Alire */
#ifndef ALR_CONFIG_H
#define ALR_CONFIG_H

#endif
1 change: 1 addition & 0 deletions deps/optional
Submodule optional added at eb929e
1 change: 1 addition & 0 deletions dev/edit.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
gnatstudio -P alr_env &
65 changes: 61 additions & 4 deletions doc/catalog-format-spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ static, i.e. they cannot depend on the context.

```toml
project-files = ["my_project.gpr", "utils/utils_for_my_project.gpr"]

mosteo marked this conversation as resolved.
Show resolved Hide resolved
[project-files.'case(word-size)']
bits-64 = ["my_project.gpr"]
bits-32 = ["my_project32.gpr"]
Expand All @@ -291,7 +291,7 @@ static, i.e. they cannot depend on the context.
```toml
[gpr-set-externals]
BUILD_MODE = "release"

[gpr-set-externals.'case(os)']
linux = { OS = "gnu-linux" } # Compact table syntax is convenient in this case
windows = { OS = "ms-linux" } # to see all enumeration values, one per row.
Expand Down Expand Up @@ -365,11 +365,11 @@ static, i.e. they cannot depend on the context.
[[actions.'case(os)'.linux]]
type = "post-fetch"
command = ["make"]

[[actions.'case(os)'.windows]]
type = "post-fetch"
command = ["cmd", "build"]

[[actions.'case(os)'.'...']]
# An explicit empty case alternative, which is not mandatory
```
Expand Down Expand Up @@ -508,6 +508,63 @@ static, i.e. they cannot depend on the context.
crate_2.var1 = "Debug"
```

## Work-in-progress dependency overrides

It is usual to develop several interdependent crates at the same time. In this scenario, it is often impractical to rely on indexed releases which are not intended to be modified. Instead, one would prefer to use a work-in-progress version of a crate to fulfill some dependency.

Alire provides *pins* to support this use case. Pins are overrides to dependencies, are intended to be used locally, and to be fulfilled by proper dependencies once a crate is ready to be published. The use of pins is based on two ideas:
mosteo marked this conversation as resolved.
Show resolved Hide resolved

* Dependencies are given, as normally, in the `depends-on` array of the manifest, even for those dependencies to be pinned. This way, once the release is ready, pins are simply removed and the actual dependencies are used in their place.
* Dependency overrides, aka *pins*, are given under the `[[pins]]` array of the manifest.

Three kinds of pins are available, all of them with the syntax:

`crate_name = { pin_attributes }`

The specific pin kinds and their attributes are:

* Pins to versions: used to force the use of a particular version of an indexed crate.

* `version`: a string containing a single version to be used.
* `crate_name = { version = "1.2+hotfix-1" }`

* Pins to local crates: a local directory will fulfill the crate dependency, no matter what version is given in its local manifest. "Raw" Ada projects without an Alire manifest can be used too, as long as their project file matches the crate name and it is located in the directory given as override.

* `path`: an absolute or relative path to the crate directory.
* `crate_name = { path = "../my/wip/crate" }`

For the common case of directories containing an Alire manifest, dependencies and pins will be included recursively in the build context.

* Pins to git repositories: the repository will be cloned locally and its directory will be used as in the previous case. Currently, this pin may optionally include a commit to fix the checkout to be used. Otherwise, the default branch will be used, and running `alr update` will refresh the checkout.

* `url`: the URL of a git repository
* `commit` (optional): a complete git commit hash.
* `crate_name = { url = "https://my/repo.git" } # Updatable pin`
* `crate_name = { url = "https://my/repo.git", commit="abcdef..." } # Fixed pin`

### Using pins for crate testing
mosteo marked this conversation as resolved.
Show resolved Hide resolved

Pins are also useful to have a separate test project that depends on your main crate. The recommended setup is as follows:

```
/path/to/my_crate
├── alire.toml
└── my_crate_test
mosteo marked this conversation as resolved.
Show resolved Hide resolved
└── alire.toml
```

I.e., a `my_crate_test` crate is initialized within the main `my_crate`. In the `my_crate_test` manifest, you have a dependency and local relative path pin for `my_crate`:

```toml
# my_crate_test/alire.toml
[[depends-on]]
my_crate = "*" # Any version of the main crate
[[pins]]
my_crate = { path = ".." } # Overridden by the latest sources
```

mosteo marked this conversation as resolved.
Show resolved Hide resolved
Then, `my_crate` is published normally, and `my_crate_test` can be used locally for any kind of testing needed on `my_crate` without polluting `my_crate` manifest with test specifics.

## External releases

The above information applies to regular releases distributed from sources
Expand Down
17 changes: 17 additions & 0 deletions doc/user-changes.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,23 @@ stay on top of `alr` new features.

## Release `1.1`

### Pins stored in the manifest

PR [#743](https://github.com/alire-project/alire/pull/743).

The options to modify pins through the command-line (`with --use`, `alr pin
[--unpin] crate` have been disabled in favor of direct edition of the manifest.
This way, pins are more robust against lockfile format changes. These kinds of
pins exist:

```
[[pins]]
foo = { version = "1.3.2+bugfix" } # Require a specific version
bar = { path = "../my/bar" } # Use a local crate to override a dependency
baz = { url = "https://github.com/baz.git" } # No commit, will use HEAD, will update on `alr update`
gru = { url = "https://gitlab.com/gru.git" commit="123456890abcdef..." } # Explicit commit, won't update
```

### Automatic GPR 'with' now in crate configuration

PR [#740](https://github.com/alire-project/alire/pull/740).
Expand Down
9 changes: 5 additions & 4 deletions src/alire/alire-crate_configuration.adb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ with Alire.Solutions;
with Alire.Releases;
with Alire.Roots;
with Alire.Origins;
with Alire.Warnings;

with Alire.Directories;

Expand All @@ -28,8 +29,8 @@ package body Alire.Crate_Configuration is
begin

if not Solution.Is_Complete then
Trace.Warning ("Generating possibly incomplete configuration"
& " because of missing dependencies");
Warnings.Warn_Once ("Generating possibly incomplete configuration"
& " because of missing dependencies");
end if;

for Rel of Solution.Releases.Including (Root.Release) loop
Expand Down Expand Up @@ -75,8 +76,8 @@ package body Alire.Crate_Configuration is
begin

if not Solution.Is_Complete then
Trace.Warning ("Generating possibly incomplete configuration"
& " because of missing dependencies");
Warnings.Warn_Once ("Generating possibly incomplete configuration"
& " because of missing dependencies");
end if;

for Rel of Solution.Releases.Including (Root.Release) loop
Expand Down
10 changes: 10 additions & 0 deletions src/alire/alire-crates.adb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ with Alire.Origins;
with Alire.Properties.Labeled;
with Alire.TOML_Keys;
with Alire.TOML_Load;
with Alire.User_Pins.Maps;
with Alire.Utils.TTY;

with TOML;
Expand Down Expand Up @@ -144,6 +145,7 @@ package body Alire.Crates is
declare
Unused_Avail : Conditional.Availability;
Unused_Deps : Conditional.Dependencies;
Unused_Pins : User_Pins.Maps.Map;
Properties : Conditional.Properties;
begin
TOML_Load.Load_Crate_Section
Expand All @@ -152,8 +154,16 @@ package body Alire.Crates is
From => From,
Props => Properties,
Deps => Unused_Deps,
Pins => Unused_Pins,
Avail => Unused_Avail);

Assert (Unused_Deps.Is_Empty,
"Unexpected dependencies in external definition");
Assert (Unused_Pins.Is_Empty,
"Unexpected pins in external definition");
Assert (Unused_Avail.Is_Empty,
"Unexpected availability in external definition");

case Policy is
when Policies.Merge_Priorizing_Existing =>
if This.Externals.Properties.Is_Empty then
Expand Down
6 changes: 6 additions & 0 deletions src/alire/alire-dependencies-containers.ads
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
with Ada.Containers.Indefinite_Doubly_Linked_Lists;
with Ada.Containers.Indefinite_Ordered_Sets;

with Optional.Values;

package Alire.Dependencies.Containers with Preelaborate is

package Lists is new
Ada.Containers.Indefinite_Doubly_Linked_Lists (Dependency);

type List is new Lists.List with null record;

package Optionals is new Optional.Values (Dependency, Image);

subtype Optional is Optionals.Optional;

package Sets is new
Ada.Containers.Indefinite_Ordered_Sets (Dependency,
Lexicographical_Sort);
Expand Down
27 changes: 27 additions & 0 deletions src/alire/alire-dependencies-states.ads
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ package Alire.Dependencies.States is

type State (<>) is new Dependency with private;

overriding function "=" (L, R : State) return Boolean;
-- For some unclear reason, the default implementation reports differences
-- for identical states. Suspecting the Indefinite_Holders therein to be
-- the culprits. We override to rely on the same information the user sees,
-- thus avoiding any inconsistent "want to confirm?" empty updates.

------------------
-- Constructors --
------------------
Expand Down Expand Up @@ -61,6 +67,9 @@ package Alire.Dependencies.States is
with Pre => Base.Crate = Using.Name;
-- Uses release to fulfill this dependency in a copy of Base

function Unlinking (Base : State) return State;
-- Unlinks the crate in a copy of Base, becoming Missed

function Unpinning (Base : State) return State;
-- Removes the pin in a copy of Base

Expand Down Expand Up @@ -202,6 +211,13 @@ private
Transitivity : Transitivities := Unknown;
end record;

---------
-- "=" --
---------

overriding function "=" (L, R : State) return Boolean
is (L.Image = R.Image);
mosteo marked this conversation as resolved.
Show resolved Hide resolved

-------------------
-- As_Dependency --
-------------------
Expand Down Expand Up @@ -477,6 +493,17 @@ private
else "")
& ")");

---------------
-- Unlinking --
---------------

function Unlinking (Base : State) return State
is (Base.As_Dependency with
Name_Len => Base.Name_Len,
Fulfilled => (Fulfillment => Missed),
Pinning => Base.Pinning,
Transitivity => Base.Transitivity);

---------------
-- Unpinning --
---------------
Expand Down
12 changes: 9 additions & 3 deletions src/alire/alire-environment.adb
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ package body Alire.Environment is
-- Load --
----------

Already_Warned : Boolean := False;

procedure Load (This : in out Context;
Root : in out Alire.Roots.Root)
is
Expand All @@ -95,17 +97,21 @@ package body Alire.Environment is
-- Warnings when setting up an incomplete environment

if not Solution.Is_Complete then
Trace.Debug ("Generating incomplete environment"
Trace.Debug ("Generating possibly incomplete environment"
& " because of missing dependencies");

-- Normally we would generate a warning, but since that will pollute
-- the output making it unusable, for once we write directly to
-- stderr (unless quiet is in effect):

if not Alire_Early_Elaboration.Switch_Q then
if not Alire_Early_Elaboration.Switch_Q and then not Already_Warned
then
Already_Warned := True;

GNAT.IO.Put_Line
(GNAT.IO.Standard_Error,
TTY.Warn ("warn:") & " Generating incomplete environment"
TTY.Warn ("warn:")
& " Generating possibly incomplete environment"
& " because of missing dependencies");
end if;
end if;
Expand Down
Loading