diff --git a/src/alr/alr-commands-pin.adb b/src/alr/alr-commands-pin.adb index 4db19f59b..651da4149 100644 --- a/src/alr/alr-commands-pin.adb +++ b/src/alr/alr-commands-pin.adb @@ -195,21 +195,29 @@ package body Alr.Commands.Pin is else -- Pin to dir, with a warning if it doesn't look like a path - - if Alire.URI.URI_Kind (Cmd.URL.all) not in Alire.URI.Local_URIs - then - Alire.Put_Warning - ("Assuming '" & Cmd.URL.all & "' is a directory " - & "because no branch or commit was specified."); - end if; - - if not Alire.Utils.User_Input.Approve_Dir (Cmd.URL.all) then - Trace.Info ("Abandoned by user."); - return; - end if; - - New_Root.Add_Path_Pin (Crate => Optional_Crate, - Path => Cmd.URL.all); + -- and a subsequent confirmation prompt if it doesn't exist. + + declare + use Alire.URI; + Local : constant Boolean := + URI_Kind (Cmd.URL.all) in Local_URIs; + Path : constant String := + (if Local then Local_Path (Cmd.URL.all) else Cmd.URL.all); + begin + if not Local then + Alire.Put_Warning + ("Assuming '" & Cmd.URL.all & "' is a directory " + & "because no branch or commit was specified."); + end if; + + if not Alire.Utils.User_Input.Approve_Dir (Path) then + Trace.Info ("Abandoned by user."); + return; + end if; + + New_Root.Add_Path_Pin (Crate => Optional_Crate, + Path => Path); + end; end if; diff --git a/src/alr/alr-commands-withing.adb b/src/alr/alr-commands-withing.adb index 9a0965889..cfa157a24 100644 --- a/src/alr/alr-commands-withing.adb +++ b/src/alr/alr-commands-withing.adb @@ -10,6 +10,7 @@ with Alire.Releases; with Alire.Roots.Editable; with Alire.Solutions; with Alire.URI; +with Alire.Utils.User_Input; with Alr.OS_Lib; @@ -210,15 +211,27 @@ package body Alr.Commands.Withing is else -- Pin to local folder, with a warning if it doesn't look like a path + -- and a subsequent confirmation prompt if it doesn't exist. - if Alire.URI.URI_Kind (Cmd.URL.all) not in Alire.URI.Local_URIs then - Alire.Put_Warning ("Assuming '" & Cmd.URL.all & "' is a directory " - & "because no branch or commit was specified."); - end if; + declare + use Alire.URI; + Local : constant Boolean := URI_Kind (Cmd.URL.all) in Local_URIs; + Path : constant String := (if Local then Local_Path (Cmd.URL.all) + else Cmd.URL.all); + begin + if not Local then + Alire.Put_Warning + ("Assuming '" & Cmd.URL.all & "' is a directory because no " + & "branch or commit was specified."); + end if; - Root.Add_Path_Pin - (Crate => Crate, - Path => Cmd.URL.all); + if not Alire.Utils.User_Input.Approve_Dir (Path) then + Trace.Info ("Abandoned by user."); + return; + end if; + + Root.Add_Path_Pin (Crate => Crate, Path => Path); + end; end if; end Add_With_Pin; diff --git a/testsuite/tests/index/git-local/test.py b/testsuite/tests/index/git-local/test.py index 568c9b77a..5a73d98e6 100644 --- a/testsuite/tests/index/git-local/test.py +++ b/testsuite/tests/index/git-local/test.py @@ -3,6 +3,7 @@ """ import os +import re import shutil import subprocess @@ -22,7 +23,7 @@ def run(*args, **kwargs): def check_index_is_configured(name, url, path): assert_match( - rf".*\d+.*{name}.*{url}.*{path}", + rf".*\d+.*{re.escape(name)}.*{re.escape(url)}.*{re.escape(path)}", run_alr("index", "--list").out ) @@ -39,8 +40,9 @@ def check_index_works(): shutil.rmtree(deploy_dir) -# Convert all paths in the index to absolute (relative paths don't work with -# indexes that are git repos) +# Add all necessary paths to the index. We do this now because they need to be +# absolute paths; relative paths don't work for git repo indexes. Note that TOML +# files require backslashes (in windows paths) to be escaped. my_crates_path = os.path.join(TEST_ROOT_DIR, "my_crates") hello_manifest_path = os.path.join( "my_index", "index", "he", "hello", "hello-1.0.1.toml" @@ -48,10 +50,12 @@ def check_index_works(): libhello_manifest_path = os.path.join( "my_index", "index", "li", "libhello", "libhello-1.0.0.toml" ) +hello_path = os.path.join(my_crates_path, "hello").replace("\\", "\\\\") +libhello_path = os.path.join(my_crates_path, "libhello").replace("\\", "\\\\") with open(hello_manifest_path, "a") as f: - f.write(f'url = "file:{os.path.join(my_crates_path, "hello")}"') + f.write(f'url = "file:{hello_path}"\n') with open(libhello_manifest_path, "a") as f: - f.write(f'url = "file:{os.path.join(my_crates_path, "libhello")}"') + f.write(f'url = "file:{libhello_path}"\n') # Test adding my_index as a simple directory index. @@ -85,7 +89,9 @@ def check_index_works(): "index", "--name", "my_index", "--add", "git+file:my_index", complain_on_error=False ) -assert_match(".*repository '.*my_index' does not exist", p.out) +unix_pattern = "repository '.*my_index' does not exist" +windows_pattern = "'.*my_index' does not appear to be a git repository" +assert_match(f".*({unix_pattern}|{windows_pattern})", p.out) # Initialise a normal git repo in the my_index directory. @@ -107,12 +113,12 @@ def check_index_works(): run_alr("index", "--name", "my_index", "--add", "git+file:my_index") check_index_is_configured( "my_index", - rf"git\+file:{MY_INDEX_PATH}", + f"git+file:{MY_INDEX_PATH}", os.path.join(TEST_ROOT_DIR, "alr-config", "indexes", "my_index", "repo") ) os.chdir(os.path.join("alr-config", "indexes", "my_index", "repo")) sp = run(["git", "remote", "show", "origin"], capture_output=True) -assert_match(".*Fetch URL: (?!(git\+)?file:).*my_index", sp.stdout.decode()) +assert_match(r".*Fetch URL: (?!(git\+)?file:).*my_index", sp.stdout.decode()) os.chdir(TEST_ROOT_DIR) check_index_works() run_alr("index", "--del", "my_index") @@ -145,13 +151,13 @@ def check_index_works(): ) check_index_is_configured( "bare_repo_index", - rf"git\+file:{os.path.join(TEST_ROOT_DIR, 'bare_repo_index')}", + f"git+file:{os.path.join(TEST_ROOT_DIR, 'bare_repo_index')}", os.path.join(TEST_ROOT_DIR, "alr-config", "indexes", "bare_repo_index", "repo") ) os.chdir(os.path.join("alr-config", "indexes", "bare_repo_index", "repo")) sp = run(["git", "remote", "show", "origin"], capture_output=True) assert_match( - ".*Fetch URL: (?!(git\+)?file:).*bare_repo_index", + r".*Fetch URL: (?!(git\+)?file:).*bare_repo_index", sp.stdout.decode() ) os.chdir(TEST_ROOT_DIR) @@ -174,7 +180,7 @@ def check_index_works(): run_alr("index", "--name", "my_index", "--add", "git+file:my_index") check_index_is_configured( "my_index", - rf"git\+file:{MY_INDEX_PATH}", + f"git+file:{MY_INDEX_PATH}", os.path.join(TEST_ROOT_DIR, "alr-config", "indexes", "my_index", "repo") ) p = run_alr("get", "hello", quiet=False, complain_on_error=False) @@ -194,7 +200,7 @@ def check_index_works(): run_alr("index", "--name", "my_index", "--add", "git+file:my_index") check_index_is_configured( "my_index", - rf"git\+file:{MY_INDEX_PATH}", + f"git+file:{MY_INDEX_PATH}", os.path.join(TEST_ROOT_DIR, "alr-config", "indexes", "my_index", "repo") ) check_index_works() diff --git a/testsuite/tests/index/local-index-not-found/test.py b/testsuite/tests/index/local-index-not-found/test.py index 4add3de68..2fbd59c10 100644 --- a/testsuite/tests/index/local-index-not-found/test.py +++ b/testsuite/tests/index/local-index-not-found/test.py @@ -10,26 +10,54 @@ from drivers.alr import prepare_indexes, run_alr from drivers.asserts import assert_match +from drivers.helpers import replace_in_file + + +INDEX_DIR = "no-such-directory" + + +# Delete old configuration and indexes, but disable msys2 installation or +# installation will be reattempted. +rm('alr-config', recursive=True) +run_alr("settings", "--global", "--set", "msys2.do_not_install", "true") + + +# Directly configure the non-existent index in Alire's config directory +prepare_indexes( + 'alr-config', '.', {'bad_index': {'dir': INDEX_DIR, 'in_fixtures': False}} +) +# Verify that `alr search` gives a suitable error +p = run_alr("search", "--crates", complain_on_error=False, debug=False) +rel_path = os.path.join('alr-config', 'indexes', 'bad_index', 'index.toml') +separator = re.escape(os.path.sep) +err_msg = ( + f'.*ERROR: Cannot load metadata from .*{re.escape(rel_path)}: ' + f'Not a readable directory: .{separator}{INDEX_DIR}\n' +) +assert_match(err_msg, p.out) + +# Rewrite the url field of the config 'index.toml' file to use a 'file://' URL +replace_in_file(rel_path, "url = '", "url = 'file://") +# Verify this yields the same result +p = run_alr("search", "--crates", complain_on_error=False, debug=False) +assert_match(err_msg, p.out) + +# Repeat both cases, but using the `alr index --add` UI +p = run_alr( + "index", "--add", "no-such-directory", "--name", "bad_index", + complain_on_error=False +) +assert_match(err_msg, p.out) +p = run_alr( + "index", "--add", "file:no-such-directory", "--name", "bad_index", + complain_on_error=False +) +assert_match(err_msg, p.out) +p = run_alr( + "index", "--add", "file://no-such-directory", "--name", "bad_index", + complain_on_error=False +) +assert_match(err_msg, p.out) -for d in ('no-such-directory', - 'file://no-such-directory', ): - - # Delete old configuration and indexes, but disable msys2 installation or - # installation will be reattempted. - rm('alr-config', recursive=True) - run_alr("settings", "--global", "--set", "msys2.do_not_install", "true") - - prepare_indexes('alr-config', '.', - {'bad_index': {'dir': d, 'in_fixtures': False}}) - p = run_alr("search", "--crates", complain_on_error=False, debug=False) - - path_excerpt = os.path.join('alr-config', 'indexes', 'bad_index', - 'index.toml') - separator = re.escape(os.path.sep) - assert_match('ERROR: Cannot load metadata from .*{}:' - ' Not a readable directory: .{}{}' - '\n' - .format(re.escape(path_excerpt), separator, d), - p.out) print('SUCCESS') diff --git a/testsuite/tests/index/local-index-not-found/test.yaml b/testsuite/tests/index/local-index-not-found/test.yaml index 847671162..32c747b3f 100644 --- a/testsuite/tests/index/local-index-not-found/test.yaml +++ b/testsuite/tests/index/local-index-not-found/test.yaml @@ -1,5 +1 @@ driver: python-script -indexes: - bad_index: - dir: file://no-such-directory - in_fixtures: false diff --git a/testsuite/tests/pin/bad-path/test.py b/testsuite/tests/pin/bad-path/test.py index 239d0a33c..0eaf3ac7e 100644 --- a/testsuite/tests/pin/bad-path/test.py +++ b/testsuite/tests/pin/bad-path/test.py @@ -23,6 +23,8 @@ r".*Given path does not exist: \.\./bad/path", p.out ) +# Note that `alr` returns zero because the confirmation prompt abandons the +# operation by default. assert_match( r".*Do you want to continue anyway\?", p.out @@ -32,6 +34,13 @@ p.out ) +# Verify the same result with a `file:` URL. +p = run_alr("pin", "badcrate", "--use", "file:../bad/path") +assert_match( + r".*Given path does not exist: \.\./bad/path", + p.out +) + # Verify that a warning is issued for a path that looks like a remote URL. p = run_alr("pin", "badcrate", "--use", "https://some.host/path", quiet=False) assert_match( diff --git a/testsuite/tests/pin/equivalent/test.py b/testsuite/tests/pin/equivalent/test.py index f88df2de2..7afe0b66a 100644 --- a/testsuite/tests/pin/equivalent/test.py +++ b/testsuite/tests/pin/equivalent/test.py @@ -2,13 +2,14 @@ Verify that using manual edition and `alr pin` result in equivalent outputs """ +import os + +from e3.fs import rm + from drivers.alr import run_alr, alr_pin, init_local_crate from drivers.asserts import assert_eq from drivers.helpers import init_git_repo, git_branch -import os -import shutil - def check_equivalent(crate, path="", url="", commit="", branch=""): """ @@ -33,7 +34,7 @@ def check_equivalent(crate, path="", url="", commit="", branch=""): # Cleanup os.chdir("..") - shutil.rmtree("xxx") + rm("xxx", recursive=True) # Local pinnable crate diff --git a/testsuite/tests/with/equivalent/test.py b/testsuite/tests/with/equivalent/test.py index b13a60429..f05601583 100644 --- a/testsuite/tests/with/equivalent/test.py +++ b/testsuite/tests/with/equivalent/test.py @@ -2,13 +2,14 @@ Verify that using manual edition and `alr with` result in equivalent manifests """ +import os + +from e3.fs import rm + from drivers.alr import run_alr, alr_with, init_local_crate -from drivers.asserts import assert_eq, assert_match +from drivers.asserts import assert_eq from drivers.helpers import init_git_repo, git_branch -import os -import shutil - def check_equivalent(dep="", path="", url="", commit="", branch=""): """ @@ -33,7 +34,7 @@ def check_equivalent(dep="", path="", url="", commit="", branch=""): # Cleanup os.chdir("..") - shutil.rmtree("xxx") + rm("xxx", recursive=True) # Simple with without subset cannot be tested as `alr with` will narrow down diff --git a/testsuite/tests/with/pin-bad-path/test.py b/testsuite/tests/with/pin-bad-path/test.py index dddce459d..21be3a5a3 100644 --- a/testsuite/tests/with/pin-bad-path/test.py +++ b/testsuite/tests/with/pin-bad-path/test.py @@ -9,17 +9,31 @@ # Pin a local path which doesn't exist init_local_crate() -p = run_alr("with", "badcrate", "--use", "../bad/path", complain_on_error=False) +p = run_alr("with", "badcrate", "--use", "../bad/path") assert_match( - r".*Pin path is not a valid directory: .*/bad/path", + r".*Given path does not exist: \.\./bad/path", + p.out +) +# Note that `alr` returns zero because the confirmation prompt abandons the +# operation by default. +assert_match( + r".*Do you want to continue anyway\?", + p.out +) +assert_match( + r".*Using default: No", p.out ) -# Verify that a warning is issued for a path that looks like a remote URL. -p = run_alr( - "with", "badcrate", "--use", "https://some.host/path", - quiet=False, complain_on_error=False +# Verify the same result with a `file:` URL. +p = run_alr("with", "badcrate", "--use", "file:../bad/path") +assert_match( + r".*Given path does not exist: \.\./bad/path", + p.out ) + +# Verify that a warning is issued for a path that looks like a remote URL. +p = run_alr("with", "badcrate", "--use", "https://some.host/path", quiet=False) assert_match( ( r".*Assuming 'https://some\.host/path' is a directory because no " @@ -28,7 +42,7 @@ p.out ) assert_match( - r".*Pin path is not a valid directory: .*/xxx/https:/some.host/path", + r".*Given path does not exist: https://some\.host/path", p.out )