def try_path(path: str): """ Pin the parent crate using the given path, that must be equivalent to ".." """ if os.path.isdir("child"): rmtree("child") init_local_crate("child") alr_pin("parent", path=path, manual=False) # This should result in the pin being simplified to ".." assert "parent = { path='..' }\n" in lines_of(alr_manifest()), \ "Unexpected manifest contents: " + content_of(alr_manifest()) os.chdir("..") # We entered during init_local_crate()
def should_work(commit="", branch=""): os.mkdir("nest") os.chdir("nest") for crate in ["xxx", "yyy"]: init_local_crate(crate) alr_pin("zzz", url=url, commit=commit, branch=branch) os.chdir("..") os.chdir("xxx") alr_pin("yyy", path="../yyy") p = run_alr("pin") assert_match( escape("yyy file:../yyy") + ".*\n" + escape("zzz file:alire/cache/pins/zzz") + ".*" + escape(url), p.out) # Clean up for next trial os.chdir("..") os.chdir("..") git_blast("nest")
def should_not_work(commits=["", ""], branches=["", ""], match_error="FAIL"): # Commits and branches must contain two values that go into each crate pin os.mkdir("nest") os.chdir("nest") crates = ["xxx", "yyy"] for i in [0, 1]: init_local_crate(crates[i]) alr_pin("zzz", url=url, commit=commits[i], branch=branches[i]) os.chdir("..") os.chdir("xxx") alr_pin("yyy", path="../yyy", update=False) p = run_alr("pin", complain_on_error=False) assert_match(match_error, p.out) # Clean up for next trial os.chdir("..") os.chdir("..") shutil.rmtree("nest")
def check_equivalent(crate, path="", url="", commit="", branch=""): """ Run manual and auto and compare outputs """ manual = [False, True] p = [None, None] for i in [0, 1]: init_local_crate() # run command alr_pin(crate=crate, path=path, url=url, commit=commit, branch=branch, manual=manual[i]) # get pins output p[i] = run_alr("pin").out if i == 1: assert_eq(p[0], p[1]) # Cleanup os.chdir("..") shutil.rmtree("xxx")
""" Verify that recursive pins work for local paths """ from drivers.alr import run_alr, alr_pin, init_local_crate from drivers.asserts import assert_eq, assert_match import os # We are going to setup xxx --> yyy --> zzz, where xxx and zzz live at the # same level, and yyy is at ./nest/yyy init_local_crate(name="zzz", enter=False) os.mkdir("nest") os.chdir("nest") init_local_crate(name="yyy") alr_pin("zzz", path="../../zzz") os.chdir("..") os.chdir("..") init_local_crate() alr_pin("yyy", path="../nest/yyy") # Should work properly p = run_alr("pin") assert_eq('yyy file:../nest/yyy \n' 'zzz file:../zzz \n', p.out) print('SUCCESS')
""" Verify that pins when there is no lockfile are correctly applied on first run """ from drivers.alr import run_alr, alr_pin, init_local_crate, alr_lockfile from drivers.asserts import assert_eq import os fake_dep = "unobtainium" # Create a crate init_local_crate() # Add a dependency run_alr("with", fake_dep, force=True) # Pin to a local folder os.mkdir(fake_dep) alr_pin(fake_dep, path=fake_dep) # Remove the lockfile os.remove(alr_lockfile()) # Check that the pin is applied on next command run p = run_alr("pin") assert_eq(f"{fake_dep} file:{fake_dep} \n", p.out) print('SUCCESS')
# We are going to setup xxx --> yyy --> zzz, where xxx and zzz live at the # same level, and yyy is at ./nest/yyy. Both yyy and zzz will be git # repositories, so we refer to them by their absolute path (as if they were # remote URLs) # zzz crate/repo init_local_crate(name="zzz", enter=False) path_zzz = os.path.join(os.getcwd(), "zzz") init_git_repo(path_zzz) # yyy crate/repo os.mkdir("nest") os.chdir("nest") init_local_crate(name="yyy") alr_pin("zzz", url=path_zzz) os.chdir("..") path_yyy = os.path.join(os.getcwd(), "yyy") init_git_repo(path_yyy) # xxx crate os.chdir("..") init_local_crate() alr_pin("yyy", url=path_yyy) # Should work properly p = run_alr("pin") # Absolute path to simulate a remote URL is platform dependent: s = dir_separator() assert_match(
# Dependency to be pinned with absolute path init_local_crate(name="dep_absolute") path_absolute = os.getcwd() os.chdir("..") # Dependency to be pinned with portable relative path init_local_crate(name="dep_portable", enter=False) # Dependency to be pinned with bad relative path init_local_crate(name="dep_not_portable", enter=False) # Dependent main crate init_local_crate() # Should not cause error alr_pin("dep_absolute", path=path_absolute) # Should not cause error alr_pin("dep_portable", path="../dep_portable") # Now the update should detect the bad path. This check is only useful on Win if on_windows(): alr_pin("dep_not_portable", path=r"..\dep_not_portable", update=False) p = run_alr("update", complain_on_error=False) assert_match(".*Pin relative paths must use " "forward slashes to be portable.*", p.out) print('SUCCESS')
flags=re.S) # Verify lockfile check_line_in(alr_lockfile(), 'name = "libchild"') check_line_in(alr_lockfile(), f'version = "{version}"') # Create a new "xxx" program project run_alr('init', '--bin', 'xxx') os.chdir('xxx') # Make it depend on child=0.1 (there is also 0.2) run_alr('with', 'libchild=0.1') # Pin it alr_pin('libchild', version="0.1") # To avoid pinning and downgrading (that's a different test), we depend on # a crate that also depends on libchild. This way we can remove the exact # libchild dependency and verify the pin holds run_alr('with', 'libparent') # Remove child dependency run_alr('with', '--del', 'libchild') # But keeping the pin (alr with --del will remove also the pin) alr_pin('libchild', version="0.1") # Verify pinned version is still in the solution, pre-update: p = run_alr('show', '--solve') check_child('0.1.0', p.out, pinned=True)
# Make it depend on libhello, it is auto-narrowed down to ^1 session_file = os.path.join('alire.toml') run_alr('with', 'libhello') check_line_in(session_file, 'libhello = "^1.0.0"') # Add the corresponding "with" line in xxx.gpr. # # TODO: maybe "alr with" should do that automatically? with open('xxx.gpr', 'r') as f: content = f.read() with open('xxx.gpr', 'w') as f: f.write('with "libhello";\n') f.write(content) # Pin the version of libhello and verify pin is there alr_pin('libhello', version='1.0') p = run_alr('pin') assert_eq('libhello 1.0.0\n', p.out) # Build and run "xxx" with open(os.path.join('src', 'xxx.adb'), 'w') as f: f.write(""" with Ada.Text_IO; with libhello; procedure XXX is begin Ada.Text_IO.Put_Line ("This is XXX..."); libhello.Hello_World; end XXX; """)
from drivers.helpers import check_line_in import os import re # Create a new "xxx" program project run_alr('init', '--bin', 'xxx') os.chdir('xxx') # Make it depend on a couple of crates (simplifies checking the solution later) # libparent depends on libchild run_alr('with', 'libparent') # Pin the child alr_pin('libchild', version='0.2') # Remove parent run_alr('with', '--del', 'libparent') # Check pin is there p = run_alr('pin') assert_eq('libchild 0.2.0\n', p.out) # Check that there are no dependencies p = run_alr('with') assert_eq('Dependencies (direct):\n' ' (empty)\n', p.out)
import os from drivers.alr import run_alr, alr_pin, alr_unpin, alr_lockfile from drivers.asserts import assert_eq from drivers.helpers import check_line_in # Create a new "xxx" program project run_alr('init', '--bin', 'xxx') os.chdir('xxx') # Make it depend on libhello run_alr('with', 'libhello') # Pin the version of libhello and verify pin is there alr_pin('libhello', version="1") p = run_alr('pin') assert_eq('libhello 1.0.0\n', p.out) # Update and verify that the pin has survived run_alr('update') p = run_alr('pin') assert_eq('libhello 1.0.0\n', p.out) # Delete lockfile and verify the pin has survived os.remove(alr_lockfile()) p = run_alr('pin') assert_eq('libhello 1.0.0\n', p.out) # Unpin and verify pin is not there alr_unpin('libhello')
""" Check that updating a manifest-pinned crate results in a recoverable error """ import re import os from drivers.alr import run_alr, alr_pin from drivers.asserts import assert_match from glob import glob # Add a dependency and force it missing by pinning it to non-existing version run_alr('init', '--bin', 'xxx') os.chdir('xxx') run_alr('with', 'libhello^1') # This causes libhello=1.1 alr_pin('libhello', version='1') # Downgrade to 1.0 # Check that updating without specific crate does not err run_alr('update') # See that updating the pinned crate errs p = run_alr('update', 'libhello', complain_on_error=False) assert p.status != 0, "should have erred" # Check that force updating the pinned crate does not err run_alr('update', 'libhello', force=True) # Check that the solution is still the expected one p = run_alr('with', '--solve') assert_match('.*Dependencies \(solution\):\n' ' libhello=1.0.0 \(pinned\).*',
Create the same dependency yyy under the given nest path """ os.mkdir(nest) os.chdir(nest) init_local_crate("yyy", enter=False) os.chdir("..") # Two versions of the same crate create_dep("nest1") create_dep("nest2") # Dependent main crate init_local_crate() alr_pin("yyy", path="../nest1/yyy") # Edit the pin path by unpinning/repinning, without running alr in between, # so this is equivalent to just editing the pin alr_unpin("yyy", update=False) alr_pin("yyy", path="../nest2/yyy", update=False) # Now detect changes and show output p = run_alr("pin", quiet=False) assert_eq( """Note: Synchronizing workspace... Dependencies automatically updated as follows: · yyy 0.1.0-dev (path=../nest2/yyy) yyy file:../nest2/yyy \n""", p.out)
import os import re from drivers.alr import run_alr, alr_pin from drivers.asserts import assert_match # Initialize a workspace, enter, and add a regular dependency run_alr('init', '--bin', 'xxx') os.chdir('xxx') # Add a regular solvable dependency run_alr('with', 'libhello') # Add a missing crate run_alr('with', 'unobtanium', force=True) # Pin the missing crate alr_pin('unobtanium', path='/') # Check the solution shows both pinned dir and regular dependency p = run_alr('with', '--solve') # For this match we don't know where the test is temporarily put, so we skip # over some parts of the output assert_match('.*Dependencies \(solution\):.*' 'libhello=1\.0\.0.*' 'Dependencies \(external\):.*' 'unobtanium\* \(direct,linked,.*', p.out, flags=re.S) print('SUCCESS')
from drivers.helpers import dir_separator, with_project # Initialize a workspace, enter, and add a regular dependency run_alr('init', '--bin', 'xxx') os.chdir('xxx') # Prepend the library we want to use to its project file with_project('xxx.gpr', 'libhello') # Verify it doesn't build without it p = run_alr('build', complain_on_error=False) assert p.status != 0, "Build should fail" # Add normally and then pin, check that it builds run_alr('with', 'libhello') alr_pin('libhello', path='../crates/libhello_1.0.0') run_alr('build') # Check the pin shows in the solution p = run_alr('with', '--solve') # For this match we don't know where the test is temporarily put, so we skip # over some parts of the output assert_match( '.*Dependencies \(external\):.*' 'libhello\^1.0.0 \(direct,linked' ',path=../crates/libhello_1.0.0\).*', # relative, always fwd slash p.out, flags=re.S) # Check that unpinning the dependency works and now the dependency is show # as a regular one from the index
""" Verify that pinning a bad path is rejected """ from drivers.alr import run_alr, alr_pin, init_local_crate from drivers.asserts import assert_eq, assert_match init_local_crate() alr_pin("badcrate", path="../bad/path", update=False) # Now the update should detect the bad path p = run_alr("update", complain_on_error=False) assert_match(".*Pin path is not a valid directory:.*", p.out) print('SUCCESS')
from drivers.alr import run_alr, init_local_crate, alr_pin, alr_publish, \ alr_manifest from drivers.helpers import content_of, init_git_repo from drivers.asserts import assert_eq, assert_match from subprocess import run crate = "pinner" # We create a repository with the nested crate that will act as the upstream # remote repository: start_dir = os.getcwd() init_local_crate(crate) # And add the pin directly in the remote alr_pin("unobtanium", path="/") # We can now create the upstream repo os.chdir("..") commit = init_git_repo(crate) os.rename(crate, f"{crate}.upstream") # We clone the project to obtain our local copy assert run(["git", "clone", f"{crate}.upstream", crate]).returncode == 0 # We enter the clone os.chdir(crate) # Verify the pin is there assert_match(".*\[\[pins\]\].*", content_of(alr_manifest()))
from glob import glob # Retrieve a crate run_alr('get', 'hello=1') target = glob('hello*')[0] # Initialize a workspace run_alr('init', '--bin', 'xxx') os.chdir('xxx') # Add dependency as regular crate; this has missing dependencies so we have to # force. This brings in hello=4. run_alr('with', 'hello', force=True) # Pin the hello crate as local dir dependency. The version in the folder is # different to the one we had in the solution, so this should cause a downgrade # but with complete solution. Now hello=1 --> libhello=1.1. alr_pin('hello', path='../' + target) # Verify that hello dependencies are detected and used, and are the ones # corresponding to the linked dir versions. p = run_alr('with', '--solve') assert_match( '''.*Dependencies \(solution\): hello=1\.0\.0 .* libhello=1\.1\.0 .*''', # we skip non-relevant details p.out, flags=re.S) print('SUCCESS')
import os from drivers.alr import run_alr, alr_pin from drivers.asserts import assert_match from glob import glob # Initialize a new crate and add the "hello*" dependency. This is solved as: # xxx=0.0.0 -> hello=1.0.1 --> libhello=1.1.0 run_alr('init', '--bin', 'xxx') os.chdir('xxx') run_alr('with', 'hello>0') # 1st test: pin to an existing version that brings in missing dependencies. # Pinning hello=3 brings in a libhello^3 dependency that is unavailable, so: # xxx=0.0.0 -> hello=3.0.0 --> libhello^3 (missing) alr_pin('hello', version='3') # Check solution is as expected p = run_alr('with', '--solve') assert_match( '.*Dependencies \(solution\):\n' ' hello=3\.0\.0 \(pinned\).*\n' # skip irrelevant origin info '.*Dependencies \(external\):\n' ' libhello\^3\.0.*', p.out, flags=re.S) # 2nd test: directly pin to a missing version (hello=5). This causes libhello # to disappear from the solution, since hello's dependencies are now unknown: # xxx=0.0.0 -> hello=5 (missing) alr_pin('hello', version='5')
""" Verify pin circularity detection """ from drivers.alr import run_alr, alr_pin, alr_unpin, alr_with, init_local_crate from drivers.asserts import assert_eq, assert_match from drivers.helpers import on_windows, dir_separator import os import re import shutil # Obvious self-pinning detection init_local_crate() alr_pin("xxx", path=".", update=False) p = run_alr("pin", complain_on_error=False) assert_match(".*" "ERROR: Pin circularity detected when adding pin xxx --> xxx:\n" "ERROR: Last manifest in the cycle is .*\n", p.out) # A real cycle detection os.chdir("..") # back to top-level shutil.rmtree("xxx") # and restart from scratch # Prepare a cycle init_local_crate("xxx", enter=False) init_local_crate("yyy", enter=False) init_local_crate("zzz") alr_pin("xxx", path="../xxx", update=False)
init_local_crate(name="remote", enter=False) url = os.path.join(os.getcwd(), "remote") head1 = init_git_repo("remote") os.chdir("remote") default_branch = git_branch() # Create a second branch and commit for testing subprocess.run(["git", "checkout", "-b", "devel"]).check_returncode() touch("telltale") subprocess.run(["git", "add", "telltale"]).check_returncode() subprocess.run(["git", "commit", "-m", "branching"]).check_returncode() os.chdir("..") # Now pin to the branch, and verify the telltale file exists in the checkout init_local_crate() alr_pin("remote", url=url, branch="devel") p = run_alr("pin") assert_match("remote file:alire/cache/pins/remote " + re.escape(url) + "#devel\n", # branch in the info matches p.out) # Also verify the file exists assert os.path.exists("alire/cache/pins/remote/telltale"), \ "Missing file in checkout" # Edit pin to point to the default branch, and verify telltale is missing alr_unpin("remote", update=False) alr_pin("remote", url=url, branch=default_branch) p = run_alr("pin") assert_match("remote file:alire/cache/pins/remote " + re.escape(url) + f"#{default_branch}\n",
""" Test pinning to a version """ from drivers.alr import run_alr, alr_pin, alr_with, init_local_crate from drivers.asserts import assert_eq, assert_match init_local_crate() alr_with("hello") # Test pinning to the version currently in the solution alr_pin("hello", manual=False) p = run_alr("pin") assert_eq("hello 1.0.1\n", p.out) # Test pinning to a different explicit version alr_pin("hello", version="1.0", manual=False, force=True) p = run_alr("pin") assert_eq("hello 1.0.0\n", p.out) # Test that trying to use a non-equal restriction fails p = run_alr("pin", "hello^1.0", complain_on_error=False) assert_eq( "ERROR: Plain crate name or crate=version argument expected" " for pinning, but got: hello^1.0\n", p.out) # Test that pinning to a non-existent version is doable but solution is missing p = run_alr("pin", "hello=7.7.7", force=True) p = run_alr("pin") assert_eq("hello 7.7.7\n", p.out) p = run_alr("with", "--solve")
""" from drivers.alr import run_alr, alr_pin, alr_unpin, init_local_crate from drivers.asserts import assert_eq, assert_match import os # We are going to setup xxx --> yyy --> zzz, xxx --> zzz to verify same link # is accepted. init_local_crate(name="zzz", enter=False) os.mkdir("nest") # By nesting yyy, we force different relative paths that os.chdir("nest") # should not be a problem as internally is the same abs path. init_local_crate(name="yyy") alr_pin("zzz", path="../../zzz") os.chdir("..") os.chdir("..") init_local_crate() # This places us at ./xxx alr_pin("yyy", path="../nest/yyy") alr_pin("zzz", path="../zzz") # This is the doubly-linked same crate # Should work properly p = run_alr("pin") assert_eq('yyy file:../nest/yyy \n' 'zzz file:../zzz \n', p.out) # Now we will pin a different zzz from xxx, # so xxx --> ./xxx/zzz conflicts with ./nest/yyy --> ../../zzz alr_unpin("zzz")