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

Improve URI recognition #1736

Merged
merged 35 commits into from
Oct 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
6ae4742
Improve origin URI recognition
Seb-MCaw Aug 12, 2024
4186694
Fix source archives hosted on GitHub or similar
Seb-MCaw Aug 12, 2024
8672e86
Fix test when ssh command is unavailable
Seb-MCaw Aug 13, 2024
2462ca1
Workaround for GNAT 10 bug
Seb-MCaw Aug 14, 2024
4d63508
Merge branch 'master' into feat/improve-uri-recognition
Seb-MCaw Aug 19, 2024
784c566
Further improve URI recognition
Seb-MCaw Sep 2, 2024
fc0eb73
Fix existing test
Seb-MCaw Sep 17, 2024
88c00d0
Add test for local indexes
Seb-MCaw Sep 17, 2024
d514ecb
Add test for 'clean --cache' command
Seb-MCaw Sep 20, 2024
765144d
Fix on Windows
Seb-MCaw Sep 20, 2024
6732fcd
Fix on MacOS
Seb-MCaw Sep 24, 2024
ce42b78
Clean up local-index-not-found test
Seb-MCaw Sep 25, 2024
967a6fb
Merge branch 'master' into feat/improve-uri-recognition
Seb-MCaw Sep 26, 2024
f840375
Consolidate 'Host' implementations
Seb-MCaw Sep 26, 2024
dd279b2
Fix Fragment for local URLs
Seb-MCaw Sep 26, 2024
1580f00
Fix test
Seb-MCaw Sep 26, 2024
b69cbdb
Improve publishing test
Seb-MCaw Sep 26, 2024
070e672
Fix documentation
Seb-MCaw Sep 26, 2024
ec5f0ff
Remove redundant test
Seb-MCaw Sep 26, 2024
fbdae33
Fix tests
Seb-MCaw Sep 27, 2024
0552004
Merge branch 'master' into feat/improve-uri-recognition
Seb-MCaw Oct 4, 2024
50a30e1
Merge branch 'master' into feat/improve-uri-recognition
Seb-MCaw Oct 7, 2024
14567e5
Merge branch 'master' into feat/improve-uri-recognition
Seb-MCaw Oct 8, 2024
08864dd
Merge branch 'master' into feat/improve-uri-recognition
Seb-MCaw Oct 11, 2024
599264a
Merge branch 'master' into feat/improve-uri-recognition
Seb-MCaw Oct 11, 2024
dc001ef
Fix typos
Seb-MCaw Oct 14, 2024
e6b351f
Switch to US English
Seb-MCaw Oct 14, 2024
17188dc
Merge branch 'master' into feat/improve-uri-recognition
Seb-MCaw Oct 14, 2024
2f3ef61
Merge branch 'master' into feat/improve-uri-recognition
Seb-MCaw Oct 15, 2024
4e9d697
Use crate_dirname
Seb-MCaw Oct 18, 2024
0ab1a01
Use less fragile test for git failure
Seb-MCaw Oct 18, 2024
a52f442
Add clarifying comments
Seb-MCaw Oct 18, 2024
b8a51e6
Merge branch 'master' into feat/improve-uri-recognition
Seb-MCaw Oct 18, 2024
d70e298
Treat http with non-empty userinfo as private
Seb-MCaw Oct 23, 2024
2920bc3
Fix typo
Seb-MCaw Oct 23, 2024
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
9 changes: 8 additions & 1 deletion doc/catalog-format-spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -447,6 +447,13 @@ static, i.e. they cannot depend on the context.
the following fields:

- `url`: mandatory string which points to a source file or repository.
If it points to a repository, this should be apparent from the URL;
the prefixes `git+`, `hg+` or `svn+` can be prepended to the scheme
(e.g. `git+https://`) to make this explicit, though a `.git` suffix or
the hosts `github.com`, `gitlab.com` or `bitbucket.org` will also be
recognized. For crates submitted to the community index, origins should
be publicly accessible (i.e. should not require private ssh keys or
other authentication).

- `hashes`: mandatory string array for source archives. An array
of "kind:digest" fields that specify a hash kind and its value. Kinds
Expand All @@ -466,7 +473,7 @@ static, i.e. they cannot depend on the context.
several crates from the same repository (sometimes referred to as a
*monorepo*).

- `binary`: optional (defauts to false) boolean used to design the origin
- `binary`: optional (defaults to false) boolean used to design the origin
as binary. Binary origins are not compiled and can optionally use dynamic
expressions to narrow down the platform to which they apply. An origin
using a dynamic expression must be tagged as binary; see the
Expand Down
3 changes: 1 addition & 2 deletions src/alire/alire-index_on_disk-directory.adb
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ package body Alire.Index_On_Disk.Directory is

overriding
function Index_Directory (This : Index) return String
is (This.Origin
(This.Origin'First + File_Prefix'Length .. This.Origin'Last));
is (URI.Local_Path (This.Origin));

-----------------
-- New_Handler --
Expand Down
11 changes: 6 additions & 5 deletions src/alire/alire-index_on_disk-directory.ads
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
with Alire.URI;

package Alire.Index_On_Disk.Directory is

-- A local index that is taken from a local filesystem path
Expand All @@ -8,18 +10,17 @@ package Alire.Index_On_Disk.Directory is
function New_Handler (From : URL;
Name : Restricted_Name;
Parent : Any_Path) return Index with
Pre => AAA.Strings.Has_Prefix (From, "file://")
and then
Check_Absolute_Path (From (From'First + 7 .. From'Last));
-- file:// + absolute path
Pre => Alire.URI.URI_Kind (From) in Alire.URI.File
and then Check_Absolute_Path (Alire.URI.Local_Path (From));
-- From must be a "file:" URL with an absolute path

overriding
function Add (This : Index) return Outcome is (Outcome_Success);
-- Nothing to do because general checks are done in Features.Index.Add

overriding
function Index_Directory (This : Index) return String;
-- A file:// index is already on disk, so we reuse its path
-- A "file:" index is already on disk, so we reuse its path

overriding
function Update (This : Index) return Outcome is (Outcome_Success);
Expand Down
8 changes: 5 additions & 3 deletions src/alire/alire-index_on_disk-git.adb
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ package body Alire.Index_On_Disk.Git is
---------

overriding
function Add (This : Index) return Outcome is
(VCSs.Git.Handler.Clone
(VCSs.Repo_And_Commit (This.Origin), This.Index_Directory));
function Add (This : Index) return Outcome
is (VCSs.Git.Handler.Clone
(VCSs.Repo_URL (This.Origin),
This.Index_Directory,
VCSs.Commit (This.Origin)));

-----------------
-- New_Handler --
Expand Down
5 changes: 3 additions & 2 deletions src/alire/alire-index_on_disk-git.ads
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
with Alire.URI;

package Alire.Index_On_Disk.Git is

-- Local management of remote indexes stored in git repositories
Expand All @@ -8,8 +10,7 @@ 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+") or else
AAA.Strings.Has_Prefix (Origin, "git@");
Pre => URI.URI_Kind (Origin) in URI.Git_URIs;

overriding
function Add (This : Index) return Outcome;
Expand Down
125 changes: 65 additions & 60 deletions src/alire/alire-index_on_disk.adb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ with Alire.Index_On_Disk.Git;
with Alire.Index_On_Disk.Loading;
with Alire.TOML_Index;
with Alire.TOML_Keys;
with Alire.VCSs;
with Alire.URI;

with GNAT.OS_Lib;

Expand Down Expand Up @@ -158,95 +158,100 @@ package body Alire.Index_On_Disk is
Priority : Priorities := Default_Priority)
return Index'Class
is
function Process_Local_Index (Path : String) return Index'Class;
-- Check that Path designates a readable directory and create the
-- corresponding index handler for it. If something goes wrong, set
-- Result to contain the corresponding error message and return
-- New_Invalid_Index.
Origin_Kind : constant URI.URI_Kinds := URI.URI_Kind (Origin);

-------------------------
-- Process_Local_Index --
-------------------------
function Abs_Path (This : String) return String;
-- Return the absolute path to which a local origin path/URL points

function Process_Local_Index (Path : String) return Index'Class is
function Is_Valid_Local_Origin (Path : String) return Boolean;
-- Return whether Path designates a readable directory suitable for an
-- index origin (i.e. not inside Alire's config path). If something goes
-- wrong, set Result to contain the corresponding error message.

--------------
-- Abs_Path --
--------------

function Abs_Path (This : String) return String
is (Ada.Directories.Full_Name (URI.Local_Path (Origin)));

---------------------------
-- Is_Valid_Local_Origin --
---------------------------

function Is_Valid_Local_Origin (Path : String) return Boolean is
use GNATCOLL.VFS;
Dir : constant Virtual_File := Create (+Path);
begin
-- Ensure the path exists and is a directory

if not Dir.Is_Directory then
Result := Outcome_Failure ("Not a readable directory: " & Path);
return New_Invalid_Index;
return False;
end if;

-- Ensure the given path is not one of our own configured indexes

if AAA.Strings.Has_Prefix (Path, Parent) then
Result := Outcome_Failure
("Given index path is inside Alire configuration path");
return New_Invalid_Index;
return False;
end if;

-- Ensure the created Index wrapper has absolute path

Result := Outcome_Success;
return Directory.New_Handler
(File_Prefix & Ada.Directories.Full_Name (Path),
Name,
Parent).With_Priority (Priority);
end Process_Local_Index;
return True;
end Is_Valid_Local_Origin;

begin
if not Is_Valid_Name (Name) then
Result := Outcome_Failure (Error_In_Name (Name));
return New_Invalid_Index;
end if;

-- Warn about http[s]:// URLs being not supported and suggest git+http
-- instead.

if AAA.Strings.Has_Prefix (Origin, HTTP_Prefix) then
Result := Outcome_Failure
("HTTP/HTTPS URLs are not valid index origins. "
& "You may want git+" & Origin & " instead.");
return New_Invalid_Index;
end if;

-- Process "file://" URLs and anything that looks like a file name as a
-- local index.

if AAA.Strings.Has_Prefix (Origin, File_Prefix) then
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 AAA.Strings.Contains (Origin, "+"))
if Origin_Kind in URI.Local_URIs
and then not Is_Valid_Local_Origin (URI.Local_Path (Origin))
then
return Process_Local_Index (Origin);
end if;

-- 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.");
-- Result is already set to Outcome_Failure by Is_Valid_Local_Origin
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 =>
case Origin_Kind is
when URI.Local_Other =>
-- Process path or "file:" URL as a local index.
Result := Outcome_Success;
return Index_On_Disk.Git.New_Handler (Origin, Name, Parent)
.With_Priority (Priority);
when VCSs.VCS_Unknown =>
return Index_On_Disk.Directory.New_Handler
(URI.To_URL (Abs_Path (Origin)), Name, Parent)
.With_Priority (Priority);

when URI.Git_URIs =>
-- A recognized Git repo; create a clone in the config directory.
declare
-- Ensure `git+file:` origin is an absolute path
From : constant String :=
(if Origin_Kind in URI.Local_Git
then URI.Make_VCS_Explicit (Abs_Path (Origin), URI.Git)
else Origin);
begin
Result := Outcome_Success;
return Index_On_Disk.Git.New_Handler (From, Name, Parent)
.With_Priority (Priority);
end;

when URI.Hg_URIs | URI.SVN_URIs =>
-- Other VCSs are not currently supported.
Result := Outcome_Failure ("Unknown index kind: " & Origin);
return New_Invalid_Index;

when URI.HTTP_Other | URI.SSH_Other =>
-- Warn that URL is not recognized and suggest 'git+http' or
-- 'git+ssh' instead.
Result := Outcome_Failure
("Unrecognized index URL. Did you mean 'git+"
& Origin & "' instead?");
return New_Invalid_Index;

when others =>
Result := Outcome_Failure ("Unrecognized index URL: " & Origin);
return New_Invalid_Index;
end case;
end New_Handler;

Expand Down
9 changes: 3 additions & 6 deletions src/alire/alire-index_on_disk.ads
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,14 @@ package Alire.Index_On_Disk is
-- Index metadata are stored in the <config>/indexes/<unique_id>/index.toml
-- Actual index is stored in <config>/indexes/<name>/repo

-- URLs given to New_Handler functions must be complete, commit optional:
-- URLs given to New_Handler functions must be complete, optionally with a
-- commit (except for 'file:' URLs, where path can contain literal '#'):
-- E.g.: git+https://path/to/server/and/project[#commit]
-- E.g.: file:///path/to/local/folder
-- E.g.: file:/path/to/local/folder

Checkout_Directory : constant String := "repo";
Metadata_Filename : constant String := "index.toml";

File_Prefix : constant String := "file://";
HTTP_Prefix : constant String := "http";
SSH_Prefix : constant String := "ssh://";

subtype Priorities is Integer; -- Lower is loaded before

Default_Priority : constant := 1;
Expand Down
2 changes: 1 addition & 1 deletion src/alire/alire-origins-deployers-git.adb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ package body Alire.Origins.Deployers.Git is
overriding
function Deploy (This : Deployer; Folder : String) return Outcome is
begin
VCSs.Git.Handler.Clone (This.Base.URL_With_Commit, Folder).Assert;
VCSs.Git.Handler.Clone (This.Base.URL, Folder, This.Base.Commit).Assert;

if Settings.Builtins.Dependencies_Git_Keep_Repository.Get then

Expand Down
2 changes: 1 addition & 1 deletion src/alire/alire-origins-deployers-hg.adb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ package body Alire.Origins.Deployers.Hg is
overriding
function Deploy (This : Deployer; Folder : String) return Outcome is
begin
return VCSs.Hg.Handler.Clone (This.Base.URL_With_Commit, Folder);
return VCSs.Hg.Handler.Clone (This.Base.URL, Folder, This.Base.Commit);
end Deploy;

-----------
Expand Down
2 changes: 1 addition & 1 deletion src/alire/alire-origins-deployers-source_archive.adb
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ package body Alire.Origins.Deployers.Source_Archive is
-- linux also for local files, something funny is going on Windows which
-- is difficult to pinpoint.

if URI.Scheme (This.Base.Archive_URL) in URI.File_Schemes then
if URI.URI_Kind (This.Base.Archive_URL) in URI.Local_Other then
if not Dirs.Exists (Folder) then
Alire.Directories.Create_Tree (Folder);
end if;
Expand Down
2 changes: 1 addition & 1 deletion src/alire/alire-origins-deployers-svn.adb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ package body Alire.Origins.Deployers.SVN is
overriding
function Deploy (This : Deployer; Folder : String) return Outcome is
begin
return VCSs.SVN.Handler.Clone (This.Base.URL_With_Commit, Folder);
return VCSs.SVN.Handler.Clone (This.Base.URL, Folder, This.Base.Commit);
end Deploy;

-----------
Expand Down
8 changes: 4 additions & 4 deletions src/alire/alire-origins-tweaks.adb
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,10 @@ package body Alire.Origins.Tweaks is

function Fix_VCS return Origin is
use Ada.Directories;
URL : constant String := This.URL; -- Doesn't include #commit
URL : constant String := This.URL;
begin
-- Check for "xxx+file://" or return as-is:
if URI.Scheme (URL) not in URI.File_Schemes then
-- Return as-is unless local path:
if URI.URI_Kind (URL) not in URI.Local_URIs then
return This;
end if;

Expand All @@ -55,7 +55,7 @@ package body Alire.Origins.Tweaks is

-- Rebuild the filesystem path as absolute for the VCS in hand:
Absolute.Data.Repo_URL := + -- Unbounded string
(Prefix_File & Full_Name (TOML_Path / Rel_Path));
(Full_Name (TOML_Path / Rel_Path));

return Absolute;
end;
Expand Down
Loading
Loading