diff --git a/doc/user-changes.md b/doc/user-changes.md index ec90ca994..06efb7ea4 100644 --- a/doc/user-changes.md +++ b/doc/user-changes.md @@ -6,6 +6,10 @@ stay on top of `alr` new features. ## Release `3.0` +### Gentoo support + +Add Gentoo's Portage support via sudo, if the base package contains a section for gentoo, see libsdl2 for example, emerge will be called if the package is not installed. + ### New `--github` switch for `alr init` command PR [#1972](https://github.com/alire-project/alire/pull/1972) @@ -81,9 +85,9 @@ easily. It takes several optional command line flags: - `--location=` to specify where to install the new binary - `--release=` to download and install a specific version (provided - that Alire builds binaries for this version on your platform) + that Alire builds binaries for this version on your platform) - `--nightly` to install a pre-release version of Alire. - + **Disclaimer**: nightly versions may have incomplete features, unresolved bugs and may delete features or break compatibility without warning. diff --git a/src/alire/alire-origins-deployers-system-portage.adb b/src/alire/alire-origins-deployers-system-portage.adb new file mode 100644 index 000000000..cdab964c8 --- /dev/null +++ b/src/alire/alire-origins-deployers-system-portage.adb @@ -0,0 +1,148 @@ +with Ada.Characters.Latin_1; +with AAA.Strings; use AAA.Strings; + +with Alire.Errors; +with Alire.OS_Lib.Subprocess; +-- with Alire.Utils.Regex; + +package body Alire.Origins.Deployers.System.Portage is + + package L1 renames Ada.Characters.Latin_1; + package Subprocess renames Alire.OS_Lib.Subprocess; + + ----------------------- + -- Already_Installed -- + ----------------------- + + overriding function Already_Installed (This : Deployer) return Boolean + is + -- The following call is faster than using emerge. + Output : constant AAA.Strings.Vector := + Subprocess.Checked_Spawn_And_Capture + ("eix", + Empty_Vector & "-ce" & This.Base.Package_Name, + -- Check the category (A), + -- whether it is installed (I) and + -- match against the exact string (e). + -- i.e. "app-editors/zed" + Valid_Exit_Codes => (1, 0), -- returns 1 when not found + Err_To_Out => True); + + Indicator : constant String := "[I]"; + Line : constant String := AAA.Strings.First_Element (Output); + begin + Trace.Detail ("Already_Installed: " & This.Base.Package_Name); + + if Line'Length >= Indicator'Length then + return + Line (Line'First .. Line'First + Indicator'Length - 1) = Indicator; + end if; + + return False; + end Already_Installed; + + ------------------------- + -- To_Semantic_Version -- + ------------------------- + + function To_Semantic_Version (Gentoo_Version : String) return String is + Tmp : String := Gentoo_Version; + begin + for C in Tmp'Range loop + -- Format: 0.0.0_release-rc9 + if Tmp (C) = L1.Low_Line then + Tmp (C) := L1.Hyphen; + + Trace.Debug ("To_Semantic_Version: " & Tmp); + + return Tmp; + end if; + end loop; + + Trace.Debug ("To_Semantic_Version: " & Tmp); + + return Tmp; + end To_Semantic_Version; + + ------------ + -- Detect -- + ------------ + + overriding + function Detect (This : Deployer) return Version_Outcomes.Outcome + is + function Split_Version (Gentoo_Package_Version : String) return String is + begin + for Index in Gentoo_Package_Version'Range loop + if Gentoo_Package_Version (Index) = L1.Hyphen then + return Gentoo_Package_Version + (Index + 1 .. Gentoo_Package_Version'Last); + end if; + end loop; + + return ""; + end Split_Version; + pragma Unreferenced (Split_Version); + + PortageQ_Output : constant AAA.Strings.Vector := + Subprocess.Checked_Spawn_And_Capture + ("portageq", + Empty_Vector & "best_visible" & "/" & + This.Base.Package_Name, + Valid_Exit_Codes => (0, 1), -- Returned when not found + Err_To_Out => True); + -- portageq should *always* produce zero or one line result. + + Output : constant AAA.Strings.Vector := + Subprocess.Checked_Spawn_And_Capture + ("qatom", + Empty_Vector & "-F%{PVR}" & + First_Element (PortageQ_Output), + Valid_Exit_Codes => (0, 1), -- Returned when not found + Err_To_Out => True); + Gentoo_Version : constant String := First_Element (Output); + + -- Regexp : constant String := + -- "[0-9]+(\.[0-9]+)*[a-z](_[a-z]+[0-9]?)*(-r[0-9]*)*"; + -- From the pms.pdf. + begin + if Gentoo_Version /= "" then + Trace.Debug ("Detect: " & This.Base.Package_Name & " - " & + Gentoo_Version & " - " & To_Semantic_Version (Gentoo_Version) & + " => " & Semantic_Versioning.Parse + (To_Semantic_Version (Gentoo_Version), + Relaxed => True).Image); + + return + Version_Outcomes.New_Result + (Semantic_Versioning.Parse + (To_Semantic_Version (Gentoo_Version), Relaxed => True)); + end if; + + Trace.Debug ("System deployer could not detect: " & This.Base.Image); + return Version_Outcomes.Outcome_Failure ("could not be detected", + Report => False); + end Detect; + + ------------- + -- Install -- + ------------- + + overriding + function Install (This : Deployer) return Outcome is + begin + Trace.Debug ("Install: " & This.Base.Package_Name); + + Subprocess.Checked_Spawn + ("sudo", Empty_Vector & + "emerge" & + "-av" & + This.Base.Package_Name); + + return Outcome_Success; + exception + when E : others => + return Alire.Errors.Get (E); + end Install; + +end Alire.Origins.Deployers.System.Portage; diff --git a/src/alire/alire-origins-deployers-system-portage.ads b/src/alire/alire-origins-deployers-system-portage.ads new file mode 100644 index 000000000..1b63c8a91 --- /dev/null +++ b/src/alire/alire-origins-deployers-system-portage.ads @@ -0,0 +1,18 @@ +package Alire.Origins.Deployers.System.Portage is + + type Deployer is new Deployers.System.Deployer with null record; + + overriding + function Already_Installed (This : Deployer) return Boolean; + + overriding + function Detect (This : Deployer) + return Version_Outcomes.Outcome; + + overriding + function Install (This : Deployer) return Outcome; + + overriding + function Executable_Name (This : Deployer) return String is ("emerge"); + +end Alire.Origins.Deployers.System.Portage; diff --git a/src/alire/alire-origins-deployers-system.adb b/src/alire/alire-origins-deployers-system.adb index 521e2f3d7..e282b8e24 100644 --- a/src/alire/alire-origins-deployers-system.adb +++ b/src/alire/alire-origins-deployers-system.adb @@ -1,4 +1,5 @@ with Alire.Origins.Deployers.System.Apt; +with Alire.Origins.Deployers.System.Portage; with Alire.Origins.Deployers.System.Homebrew; with Alire.Origins.Deployers.System.Macports; with Alire.Origins.Deployers.System.Pacman; @@ -11,6 +12,7 @@ with Alire.Toolchains; with CLIC.User_Input; with GNAT.IO; +-- with System; package body Alire.Origins.Deployers.System is @@ -118,6 +120,9 @@ package body Alire.Origins.Deployers.System is when Platforms.Macports => System.Macports.Deployer'(Deployers.Deployer'(Base => From) with others => <>), + when Platforms.Portage => + System.Portage.Deployer'(Deployers.Deployer'(Base => From) + with others => <>), when Platforms.Packager_Unknown => System.Unknown.Deployer'(Deployers.Deployer'(Base => From) with others => <>) diff --git a/src/alire/alire-platforms.ads b/src/alire/alire-platforms.ads index bf879bd7d..460b61df5 100644 --- a/src/alire/alire-platforms.ads +++ b/src/alire/alire-platforms.ads @@ -44,6 +44,7 @@ package Alire.Platforms with Preelaborate is Suse, Homebrew, Macports, + Gentoo, Distribution_Unknown); subtype Known_Distributions is @@ -61,6 +62,7 @@ package Alire.Platforms with Preelaborate is Zypper, Homebrew, Macports, + Portage, Packager_Unknown); Distro_Manager : constant array (Distributions) of Package_Managers := @@ -71,6 +73,7 @@ package Alire.Platforms with Preelaborate is Suse => Zypper, Homebrew => Homebrew, Macports => Macports, + Gentoo => Portage, Distribution_Unknown => Packager_Unknown); type Toolchains is (System, diff --git a/src/alire/alire-utils-tools.adb b/src/alire/alire-utils-tools.adb index 2e7241c5e..014abe81d 100644 --- a/src/alire/alire-utils-tools.adb +++ b/src/alire/alire-utils-tools.adb @@ -59,7 +59,7 @@ package body Alire.Utils.Tools is return ""; when Msys2 | Debian | Ubuntu | Arch | Centos | Fedora | Rhel | Suse - | Homebrew | Macports => + | Homebrew | Macports | Gentoo => return (case Tool is when Easy_Graph => (if Distribution in Centos | Fedora | Rhel | Suse