From 28c756a5fc12fd9e8d3ef4b72b9cf0ef30f80af3 Mon Sep 17 00:00:00 2001 From: Alejandro R Mosteo Date: Wed, 8 Jul 2020 15:35:11 +0200 Subject: [PATCH] New `alr with --versions` for version-related info of dependencies (#464) * New `alr with --versions` for version-related info This new version focuses on showing: which constraints were found for each dependency, which version was used to fulfill them, and what's the latest existing version for a crate (hence pointing to possible wanted updates). * Review fixes --- doc/user-changes.md | 18 +++++ src/alire/alire-index.adb | 2 + src/alire/alire-solutions.adb | 76 +++++++++++++++++++ src/alire/alire-solutions.ads | 7 ++ src/alr/alr-commands-withing.adb | 14 +++- src/alr/alr-commands-withing.ads | 3 +- testsuite/tests/with/versions-switch/test.py | 41 ++++++++++ .../tests/with/versions-switch/test.yaml | 3 + 8 files changed, 162 insertions(+), 2 deletions(-) create mode 100644 testsuite/tests/with/versions-switch/test.py create mode 100644 testsuite/tests/with/versions-switch/test.yaml diff --git a/doc/user-changes.md b/doc/user-changes.md index 3c6f218e..e76ee41f 100644 --- a/doc/user-changes.md +++ b/doc/user-changes.md @@ -4,6 +4,24 @@ This document is a development diary summarizing changes in `alr` that notably affect the user experience. It is intended as a one-stop point for users to stay on top of `alr` new features. +### New `alr with --versions` switch + +PR [#464](https://github.com/alire-project/alire/pull/464). + +A new `alr with --versions` switch is available to obtain version-focused +information of dependencies. Namely, the combined dependencies on a crate are +shown, with the release in the solution, and the last known version for the +crate: +``` +CRATE DEPENDENCY SOLVED LATEST +a_project (root) 0.0.0 unknown +hello ^1 1.0.1 4.0.0 +libhello (^1.0) & (~1.0) 1.0.1 2.0.0 +superhello * 1.0.0 1.0.0 +unobtanium * missing unknown +wip * /fake unknown +``` + ### New `alr with --graph` and `alr with --tree` switches PR [#465](https://github.com/alire-project/alire/pull/465). diff --git a/src/alire/alire-index.adb b/src/alire/alire-index.adb index 9107e545..a0732f39 100644 --- a/src/alire/alire-index.adb +++ b/src/alire/alire-index.adb @@ -60,6 +60,8 @@ package body Alire.Index is if Already_Detected.Contains (Name) then Trace.Debug ("Not redoing detection of externals for crate " & (+Name)); + elsif not Exists (Name) then + Trace.Debug ("Skipping external detection for unindexed crate"); else Already_Detected.Insert (Name); Trace.Debug ("Looking for externals for crate: " & (+Name)); diff --git a/src/alire/alire-solutions.adb b/src/alire/alire-solutions.adb index ff43eb71..7b458664 100644 --- a/src/alire/alire-solutions.adb +++ b/src/alire/alire-solutions.adb @@ -600,6 +600,82 @@ package body Alire.Solutions is not Print_Root); end Print_Tree; + -------------------- + -- Print_Versions -- + -------------------- + + procedure Print_Versions (This : Solution; + Root : Roots.Root) is + use all type Dependencies.States.Fulfillments; + Table : Utils.Tables.Table; + begin + Table + .Append (TTY.Bold ("CRATE")) + .Append (TTY.Bold ("DEPENDENCY")) + .Append (TTY.Bold ("SOLVED")) + .Append (TTY.Bold ("LATEST")) + .New_Row; + + for Dep of This.Including (Root.Release, + Root.Environment, + Add_Dependency => True).Required + loop + Table.Append (+Dep.Crate); + + if Dep.Crate = Root.Release.Name then + Table.Append (TTY.Version ("(root)")); + else + Table.Append (TTY.Version (Dep.Versions.Image)); + end if; + + Index.Add_Externals (Dep.Crate, Root.Environment); + -- Detect externals for the crate, in case they add more versions + + declare + Latest_Known : constant Boolean := + Index.Exists (Dep.Crate) and then + not Index.Crate (Dep.Crate).Releases.Is_Empty; + Latest : constant Containers.Release_H := + (if Latest_Known + then Containers.To_Release_H + (Index.Crate (Dep.Crate).Releases.Last_Element) + else Containers.Release_Holders.Empty_Holder); + begin + + -- Print release version, colored according to being latest + + case Dep.Fulfilment is + when Solved => + if not Latest_Known or else + Dep.Release.Version < Latest.Element.Version + then + Table.Append (TTY.Warn (Dep.Release.Version.Image)); + else + Table.Append (TTY.OK (Dep.Release.Version.Image)); + end if; + + when Linked => + Table.Append (TTY.URL (Dep.Link.Path)); + + when others => + Table.Append (TTY.Error ("missing")); + end case; + + -- Display latest crate version, when known + + if Latest_Known then + Table.Append (TTY.Version (Latest.Element.Version.Image)); + else -- For whatever reason the index hasn't a release + Table.Append (TTY.Warn ("unindexed")); + end if; + + Table.New_Row; + end; + end loop; + + Table.Print (Always); + end Print_Versions; + -------------- -- Releases -- -------------- diff --git a/src/alire/alire-solutions.ads b/src/alire/alire-solutions.ads index 9d2842f7..a9553221 100644 --- a/src/alire/alire-solutions.ads +++ b/src/alire/alire-solutions.ads @@ -5,6 +5,7 @@ with Alire.Externals.Softlinks; with Alire.Interfaces; with Alire.Properties; with Alire.Releases; +limited with Alire.Roots; with Alire.TOML_Adapters; limited with Alire.Solutions.Diffs; @@ -290,6 +291,12 @@ package Alire.Solutions is -- Print the solution in tree form. If Print_Root, Root is printed too; -- otherwise the tree is a forest starting at Root direct dependencies. + procedure Print_Versions (This : Solution; + Root : Roots.Root); + -- Print a table with the dependencies in the solutions, showing the wanted + -- dependencies, the solved version, and the latest existing version for a + -- crate. + ----------------- -- Persistence -- ----------------- diff --git a/src/alr/alr-commands-withing.adb b/src/alr/alr-commands-withing.adb index 075a12bb..ceaaded8 100644 --- a/src/alr/alr-commands-withing.adb +++ b/src/alr/alr-commands-withing.adb @@ -444,8 +444,11 @@ package body Alr.Commands.Withing is Check (Cmd.Graph); Check (Cmd.Solve); Check (Cmd.Tree); + Check (Cmd.Versions); + + -- No parameters: give requested info and return. There is still the + -- possibility of a `with --use` that is processed later. - -- No parameters: give current platform dependencies and BAIL OUT if Num_Arguments = 0 then if Flags = 0 or else Cmd.Solve then List (Cmd); @@ -457,6 +460,10 @@ package body Alr.Commands.Withing is Root.Current.Solution.Print_Graph (Root.Current.Release, Platform.Properties); return; + elsif Cmd.Versions then + Requires_Full_Index; + Root.Current.Solution.Print_Versions (Root.Current); + return; end if; end if; @@ -582,6 +589,11 @@ package body Alr.Commands.Withing is Cmd.Tree'Access, "", "--tree", "Show complete dependency tree"); + + Define_Switch (Config, + Cmd.Versions'Access, + "", "--versions", + "Show version status of dependencies"); end Setup_Switches; end Alr.Commands.Withing; diff --git a/src/alr/alr-commands-withing.ads b/src/alr/alr-commands-withing.ads index dcd3f08f..19f0d7d6 100644 --- a/src/alr/alr-commands-withing.ads +++ b/src/alr/alr-commands-withing.ads @@ -21,7 +21,7 @@ package Alr.Commands.Withing is ("[{ [--del] [versions]..." & " | --from ..." & " | [versions] --use } ]" - & " | --tree"); + & " | --solve | --tree | --versions"); private @@ -32,6 +32,7 @@ private Solve : aliased Boolean := False; Tree : aliased Boolean := False; URL : aliased GNAT.Strings.String_Access; + Versions : aliased Boolean := False; end record; end Alr.Commands.Withing; diff --git a/testsuite/tests/with/versions-switch/test.py b/testsuite/tests/with/versions-switch/test.py new file mode 100644 index 00000000..ecd5a52e --- /dev/null +++ b/testsuite/tests/with/versions-switch/test.py @@ -0,0 +1,41 @@ +""" +Check output of with --versions switch +""" + +import os +import re + +from drivers.alr import run_alr +from drivers.asserts import assert_match + +# Initialize project +run_alr('init', '--bin', 'xxx') +os.chdir('xxx') + +# Add dependency on hello^1. Solution is hello=1.0.1 --> libhello=1.1.0 +run_alr('with', 'hello^1') + +# Add dependency on superhello*. Solution is superhello=1.0 --> libhello=1.0.1 +# This implies a downgrade from libhello=1.1.0 to libhello=1.0.1, which is the +# only possible combination of libhello^1.0 & libhello~1.0 +run_alr('with', 'superhello') + +# Add a pinned directory and a missing dependency +run_alr('with', 'wip', '--use', '/fake') +run_alr('with', 'unobtanium', '--force') + +# Check output +p = run_alr('with', '--versions') + +assert_match +(re.escape + ('CRATE DEPENDENCY SOLVED LATEST \n' + 'hello ^1 1.0.1 4.0.0 \n' + 'libhello (^1.0) & (~1.0) 1.0.1 2.0.0 \n' + 'superhello * 1.0.0 1.0.0 \n' + 'unobtanium * missing unindexed\n' + 'wip * ') + '.*fake' + re.escape('unindexed\n' + 'xxx (root) 0.0.0 unindexed\n'), + p.out) + +print('SUCCESS') diff --git a/testsuite/tests/with/versions-switch/test.yaml b/testsuite/tests/with/versions-switch/test.yaml new file mode 100644 index 00000000..476e709f --- /dev/null +++ b/testsuite/tests/with/versions-switch/test.yaml @@ -0,0 +1,3 @@ +driver: python-script +indexes: + solver_index: {} -- 2.39.5