From fa6c67da824c8d4d44f0d78da9a3f63e373324f7 Mon Sep 17 00:00:00 2001 From: Simon Wright Date: Tue, 18 Jul 2023 12:37:59 +0100 Subject: [PATCH] Support MacPorts as external provider. (#1404) * src/alire/alire-origins-deployers-system-macports.adb: new. * src/alire/alire-origins-deployers-system-macports.ads: new. * src/alire/alire-origins-deployers-system.adb (context): add Alire.Origins.Deployers.System.Macports. (Platform_Deployer): Platforms.Macports => System.Macports.Deployer. * src/alire/alire-platforms.ads (Distributions): add Macports. (Package_Managers): likewise. (Distro_Manager): Macports => Macports. * src/alire/alire-utils-tools.adb (System_Package_For_Tool): add Macports, same as the other distributions. * src/alire/os_macos/alire-platforms-current__macos.adb: (context): add GNAT.OS_Lib. (Port_Access): new, access to Macports' 'port' executable. (Macports_Present): new, true if 'port' was found. (Detected_Distribution): first, check for Homebrew_Present, then, for Macports_Present. Return the corresponding Distribution if found. --- ...lire-origins-deployers-system-macports.adb | 114 ++++++++++++++++++ ...lire-origins-deployers-system-macports.ads | 15 +++ src/alire/alire-origins-deployers-system.adb | 4 + src/alire/alire-platforms.ads | 3 + src/alire/alire-utils-tools.adb | 2 +- .../alire-platforms-current__macos.adb | 30 +++-- 6 files changed, 160 insertions(+), 8 deletions(-) create mode 100644 src/alire/alire-origins-deployers-system-macports.adb create mode 100644 src/alire/alire-origins-deployers-system-macports.ads diff --git a/src/alire/alire-origins-deployers-system-macports.adb b/src/alire/alire-origins-deployers-system-macports.adb new file mode 100644 index 00000000..8fac68eb --- /dev/null +++ b/src/alire/alire-origins-deployers-system-macports.adb @@ -0,0 +1,114 @@ +with AAA.Strings; use AAA.Strings; + +with Alire.OS_Lib.Subprocess; +with Alire.Errors; + +package body Alire.Origins.Deployers.System.Macports is + + -- Ada.Strings.Unbounded is use-visible via Alire.Origins. + + package Subprocess renames Alire.OS_Lib.Subprocess; + + ----------------------- + -- Already_Installed -- + ----------------------- + + overriding function Already_Installed (This : Deployer) return Boolean + is + Installed : AAA.Strings.Vector; + begin + Trace.Debug ("already_installed? " & This.Base.Package_Name); + + if Subprocess.Unchecked_Spawn_And_Capture + ("port", + Empty_Vector & "echo" & "installed", + Output => Installed, + Err_To_Out => True) /= 0 + then + -- failed. + Trace.Debug ("port failed to find any installed packages"); + return False; + end if; + + -- We get a list of all the installed packages, + -- name {spaces} '@' version + + Trace.Debug (Installed.Length'Image & " installed packages"); + + for P of Installed loop + Trace.Debug ("Checking '" & P & "'"); + if AAA.Strings.Head (P, ' ') = This.Base.Package_Name then + Trace.Debug ("found '" & P & "'"); + return True; + end if; + end loop; + + return False; -- until we've implemented Install + end Already_Installed; + + ------------ + -- Detect -- + ------------ + + -- Returns the package version, if the package exists, whether or + -- not it's installed. + -- + -- If it's not installed, what you get is the version that would + -- be installed. + + overriding + function Detect (This : Deployer) return Version_Outcomes.Outcome + is + Info : AAA.Strings.Vector; + begin + Trace.Debug ("detect? " & This.Base.Package_Name); + + if Subprocess.Unchecked_Spawn_And_Capture + ("port", + Empty_Vector & "info" & "--version" & This.Base.Package_Name, + Output => Info, + Err_To_Out => True) /= 0 + then + -- failed. + Trace.Debug ("port failed to find " & This.Base.Package_Name); + return Version_Outcomes.Outcome_Failure + ("no candidate version found", + Report => False); + end if; + + if Integer (Info.Length) /= 1 then + raise Constraint_Error + with "port info --version returned" & Info.Length'Image & " lines."; + end if; + + Trace.Debug ("port info output: " & Info (Info.First)); + declare + Version : constant String := Trim (Tail (Info (Info.First), ':')); + begin + Trace.Debug (" -> version: '" & Version & "'"); + return Version_Outcomes.New_Result (Semantic_Versioning.Parse + (Version, + Relaxed => True)); + end; + + end Detect; + + ------------- + -- Install -- + ------------- + + overriding + function Install (This : Deployer) return Outcome is + begin + Trace.Debug ("hoping to install: " & This.Base.Image); + Subprocess.Checked_Spawn + ("sudo", + Empty_Vector & "port" & "install" & This.Base.Package_Name); + + return Outcome_Success; + exception + when E : others => + return Alire.Errors.Get (E); + end Install; + +end Alire.Origins.Deployers.System.Macports; diff --git a/src/alire/alire-origins-deployers-system-macports.ads b/src/alire/alire-origins-deployers-system-macports.ads new file mode 100644 index 00000000..7c7fc92d --- /dev/null +++ b/src/alire/alire-origins-deployers-system-macports.ads @@ -0,0 +1,15 @@ +package Alire.Origins.Deployers.System.Macports 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; + +end Alire.Origins.Deployers.System.Macports; diff --git a/src/alire/alire-origins-deployers-system.adb b/src/alire/alire-origins-deployers-system.adb index c094c7aa..efecf97c 100644 --- a/src/alire/alire-origins-deployers-system.adb +++ b/src/alire/alire-origins-deployers-system.adb @@ -1,5 +1,6 @@ with Alire.Origins.Deployers.System.Apt; with Alire.Origins.Deployers.System.Homebrew; +with Alire.Origins.Deployers.System.Macports; with Alire.Origins.Deployers.System.Pacman; with Alire.Origins.Deployers.System.RPM_Wrappers; with Alire.Origins.Deployers.System.Zypper; @@ -108,6 +109,9 @@ package body Alire.Origins.Deployers.System is with others => <>), when Platforms.Homebrew => System.Homebrew.Deployer'(Deployers.Deployer'(Base => From) + with others => <>), + when Platforms.Macports => + System.Macports.Deployer'(Deployers.Deployer'(Base => From) with others => <>)); -- NOTE: add here other native package managers as they get -- implemented. diff --git a/src/alire/alire-platforms.ads b/src/alire/alire-platforms.ads index 4903f98a..13507132 100644 --- a/src/alire/alire-platforms.ads +++ b/src/alire/alire-platforms.ads @@ -42,6 +42,7 @@ package Alire.Platforms with Preelaborate is Fedora, Suse, Homebrew, + Macports, Distro_Unknown); subtype Known_Distributions is @@ -58,6 +59,7 @@ package Alire.Platforms with Preelaborate is Dnf, Zypper, Homebrew, + Macports, Packager_Unknown); Distro_Manager : constant array (Distributions) of Package_Managers := @@ -67,6 +69,7 @@ package Alire.Platforms with Preelaborate is Centos | Fedora => Dnf, Suse => Zypper, Homebrew => Homebrew, + Macports => Macports, Distro_Unknown => Packager_Unknown); type Toolchains is (System, diff --git a/src/alire/alire-utils-tools.adb b/src/alire/alire-utils-tools.adb index 6da9fd24..9d3dc4e9 100644 --- a/src/alire/alire-utils-tools.adb +++ b/src/alire/alire-utils-tools.adb @@ -57,7 +57,7 @@ package body Alire.Utils.Tools is return ""; when Msys2 | Debian | Ubuntu | Arch | Centos | Fedora | Rhel | Suse - | Homebrew => + | Homebrew | Macports => return (case Tool is when Easy_Graph => (if Distribution = Centos or else diff --git a/src/alire/os_macos/alire-platforms-current__macos.adb b/src/alire/os_macos/alire-platforms-current__macos.adb index 3e2c1cc6..e6799136 100644 --- a/src/alire/os_macos/alire-platforms-current__macos.adb +++ b/src/alire/os_macos/alire-platforms-current__macos.adb @@ -1,31 +1,47 @@ with Alire.OS_Lib; +with GNAT.OS_Lib; package body Alire.Platforms.Current is -- macOS implementation - -- Homebrew only at this time (2022-09-13) + -- Homebrew Homebrew_Prefix : constant String := Alire.OS_Lib.Getenv ("HOMEBREW_PREFIX", ""); Homebrew_Present : constant Boolean := Homebrew_Prefix /= ""; + -- MacPorts + Port_Access : constant GNAT.OS_Lib.String_Access + := GNAT.OS_Lib.Locate_Exec_On_Path ("port"); + use type GNAT.OS_Lib.String_Access; + Macports_Present : constant Boolean := Port_Access /= null; + ------------------ -- Distribution -- ------------------ function Detected_Distribution return Platforms.Distributions is - (if Homebrew_Present - then Homebrew - else Distro_Unknown); + begin + if Homebrew_Present + then + return Homebrew; + elsif Macports_Present then + return Macports; + else + return Distro_Unknown; + end if; + end Detected_Distribution; ----------------------- -- Distribution_Root -- ----------------------- function Distribution_Root return Absolute_Path - is (if Homebrew_Present - then Homebrew_Prefix - else "/"); + is (if Homebrew_Present + then Homebrew_Prefix + elsif Macports_Present + then "/opt/local" + else "/"); ---------------------- -- Load_Environment -- -- 2.39.5