diff --git a/src/alire/alire-index_on_disk-git.ads b/src/alire/alire-index_on_disk-git.ads index 9e3277b14..d1562307f 100644 --- a/src/alire/alire-index_on_disk-git.ads +++ b/src/alire/alire-index_on_disk-git.ads @@ -8,7 +8,8 @@ package Alire.Index_On_Disk.Git is function New_Handler (Origin : URL; Name : Restricted_Name; Parent : Any_Path) return Index with - Pre => AAA.Strings.Has_Prefix (Origin, "git+"); + Pre => AAA.Strings.Has_Prefix (Origin, "git+") or + AAA.Strings.Has_Prefix (Origin, "git@"); overriding function Add (This : Index) return Outcome; diff --git a/src/alire/alire-index_on_disk.adb b/src/alire/alire-index_on_disk.adb index 1260a19e0..336fa0fde 100644 --- a/src/alire/alire-index_on_disk.adb +++ b/src/alire/alire-index_on_disk.adb @@ -217,12 +217,27 @@ package body Alire.Index_On_Disk is return Process_Local_Index (Origin (Origin'First + File_Prefix'Length .. Origin'Last)); elsif Origin (Origin'First) = '/' - or else not AAA.Strings.Contains (Origin, "+") + or else not (AAA.Strings.Contains (Origin, "@") + or AAA.Strings.Contains (Origin, "+")) then return Process_Local_Index (Origin); end if; - -- Process other paths as VCS's + -- Process "git+ssh://" as git over ssh and suggest for "ssh://" + + if AAA.Strings.Has_Prefix (Origin, SSH_Prefix) then + Result := Outcome_Failure + ("ssh:// URLs are not valid index origins. " + & "You may want git+" & Origin & " instead."); + return New_Invalid_Index; + elsif AAA.Strings.Has_Prefix (Origin, "git+" & SSH_Prefix) then + Result := Outcome_Success; + return Index_On_Disk.Git + .New_Handler (Origin, Name, Parent) + .With_Priority (Priority); + end if; + + -- Process other paths as VCSs case VCSs.Kind (Origin) is when VCSs.VCS_Git => diff --git a/src/alire/alire-index_on_disk.ads b/src/alire/alire-index_on_disk.ads index da33535c7..7d273dbd1 100644 --- a/src/alire/alire-index_on_disk.ads +++ b/src/alire/alire-index_on_disk.ads @@ -22,6 +22,7 @@ package Alire.Index_On_Disk is File_Prefix : constant String := "file://"; HTTP_Prefix : constant String := "http"; + SSH_Prefix : constant String := "ssh://"; subtype Priorities is Integer; -- Lower is loaded before diff --git a/src/alire/alire-origins.adb b/src/alire/alire-origins.adb index 9fa6be0f1..fd7cd8474 100644 --- a/src/alire/alire-origins.adb +++ b/src/alire/alire-origins.adb @@ -400,16 +400,13 @@ package body Alire.Origins is use AAA.Strings; use all type URI.Schemes; Scheme : constant URI.Schemes := URI.Scheme (URL); - Transformed : constant Alire.URL := VCSs.Git.Transform_To_Public (URL); VCS_URL : constant String := (if Contains (URL, "+file://") then Tail (URL, '+') -- strip the VCS proto only elsif Contains (URL, "+file:") then Tail (URL, ':') -- Remove file: w.o. // that confuses git - elsif Has_Prefix (URL, "git@") and then - Transformed /= URL -- known and transformable - then - Transformed + elsif Scheme = URI.Pure_Git then + URL elsif Scheme in URI.VCS_Schemes then Tail (URL, '+') -- remove prefix vcs+ elsif Scheme in URI.HTTP then -- A plain URL... check VCS @@ -425,15 +422,7 @@ package body Alire.Origins is begin case Scheme is - when Pure_Git => - if Transformed /= URL then - return New_VCS (Transformed, Commit); - else - Raise_Checked_Error - ("Attempting to use a private git@ URL with an unknown host: " - & Utils.TTY.URL (URL)); - end if; - when Git | HTTP => + when Pure_Git | Git | HTTP => if Commit'Length /= Git_Commit'Length then Raise_Checked_Error ("invalid git commit id, " & diff --git a/src/alire/alire-vcss.adb b/src/alire/alire-vcss.adb index f7c59f930..90d4cb276 100644 --- a/src/alire/alire-vcss.adb +++ b/src/alire/alire-vcss.adb @@ -35,7 +35,8 @@ package body Alire.VCSs is ---------- function Kind (Origin : URL) return Kinds is - (if Has_Prefix (Origin, "git+") then VCS_Git + (if Has_Prefix (Origin, "git+") or Has_Prefix (Origin, "git@") + then VCS_Git else VCS_Unknown); ---------- @@ -50,7 +51,7 @@ package body Alire.VCSs is --------------------- function Repo_And_Commit (Origin : URL) return String - is (if Contains (Origin, "+http") + is (if Contains (Origin, "+http") or else Has_Prefix (Origin, "git+") then Tail (Origin, '+') elsif Has_Prefix (Origin, "file://") then Origin (Origin'First + 7 .. Origin'Last) diff --git a/src/alr/alr-commands-index.adb b/src/alr/alr-commands-index.adb index 6908e469b..a5a470e33 100644 --- a/src/alr/alr-commands-index.adb +++ b/src/alr/alr-commands-index.adb @@ -208,6 +208,13 @@ package body Alr.Commands.Index is & " case a pull operation will be performed on them." & " An index initially set up with a specific commit will" & " not be updated.") + .New_Line + .Append ("URL can be one of:") + .Append ("- Plain absolute path: /path/to/index") + .Append ("- Explicit path: file://path/to/index") + .Append ("- git over HTTP/HTTPS: git+https://github.com/org/repo") + .Append ("- git over SSH: git+ssh://user@host.com:/path/to/repo") + .Append ("- git user over SSH: git@github.com:/org/repo") ); --------------------- diff --git a/testsuite/tests/index/git-ssh-remote/test.py b/testsuite/tests/index/git-ssh-remote/test.py new file mode 100644 index 000000000..d442c3f2b --- /dev/null +++ b/testsuite/tests/index/git-ssh-remote/test.py @@ -0,0 +1,33 @@ +from drivers.alr import init_local_crate, run_alr + +ORG="github.com:/alire-project" +INDEX_REPO="test-index" +CRATE_REPO="libhello" +SSH_IMPLICIT_INDEX = f"git@{ORG}/{INDEX_REPO}" +SSH_EXPLICIT_INDEX = f"git+ssh://{SSH_IMPLICIT_INDEX}" + +# Test that we can add an index using implicit ssh +run_alr("index", "--name", "implicit", "--add", SSH_EXPLICIT_INDEX) +run_alr("index", "--check") +run_alr("index", "--update-all") # Check pulling + +# Remove so it can be re-added +run_alr("index", "--del", "implicit") + +# Test that we can add an index using explicit ssh +run_alr("index", "--name", "explicit", "--add", SSH_EXPLICIT_INDEX) +run_alr("index", "--check") +run_alr("index", "--update-all") + +# Test that we can pin a crate using implicit ssh +init_local_crate() +run_alr("with", "libhello", "--use", f"git@{ORG}/{CRATE_REPO}") +run_alr("update") # Check pulling pin + +# Remove and re-pin using explicit ssh +run_alr("with", "--del", "libhello") +run_alr("with", "libhello", "--use", f"git+ssh://git@{ORG}/{CRATE_REPO}") +run_alr("update") + + +print("SUCCESS") diff --git a/testsuite/tests/index/git-ssh-remote/test.yaml b/testsuite/tests/index/git-ssh-remote/test.yaml new file mode 100644 index 000000000..b61eac805 --- /dev/null +++ b/testsuite/tests/index/git-ssh-remote/test.yaml @@ -0,0 +1,9 @@ +driver: python-script +indexes: + compiler_only_index: {} + +# We cannot run this test without ssh keys, so not intended for remote use. +# Also, it requires going on-line. +control: + - [SKIP, "skip_local", "Local developer-only tests disabled"] + - [SKIP, "skip_network", "Network-requiring tests disabled"]