|
2 | 2 |
|
3 | 3 | import json
|
4 | 4 | import logging
|
| 5 | +import os |
| 6 | +import sys |
5 | 7 | import tempfile
|
6 | 8 | import uuid
|
7 | 9 |
|
@@ -753,3 +755,91 @@ def test_content_hash_with_legacy_is_compatible(
|
753 | 755 | content_hash = locker._get_content_hash()
|
754 | 756 |
|
755 | 757 | assert (content_hash == old_content_hash) or fresh
|
| 758 | + |
| 759 | + |
| 760 | +def test_lock_file_resolves_file_url_symlinks(root: ProjectPackage): |
| 761 | + """ |
| 762 | + Create directories and file structure as follows: |
| 763 | +
|
| 764 | + d1/ |
| 765 | + d1/testsymlink -> d1/d2/d3 |
| 766 | + d1/d2/d3/lock_file |
| 767 | + d1/d4/source_file |
| 768 | +
|
| 769 | + Using the testsymlink as the Locker.lock file path should correctly resolve to |
| 770 | + the real physical path of the source_file when calculating the relative path |
| 771 | + from the lock_file, i.e. "../../d4/source_file" instead of the unresolved path |
| 772 | + from the symlink itself which would have been "../d4/source_file" |
| 773 | +
|
| 774 | + See https://github.com/python-poetry/poetry/issues/5849 |
| 775 | + """ |
| 776 | + with tempfile.TemporaryDirectory() as d1: |
| 777 | + symlink_path = Path(d1).joinpath("testsymlink") |
| 778 | + with tempfile.TemporaryDirectory(dir=d1) as d2, tempfile.TemporaryDirectory( |
| 779 | + dir=d1 |
| 780 | + ) as d4, tempfile.TemporaryDirectory(dir=d2) as d3, tempfile.NamedTemporaryFile( |
| 781 | + dir=d4 |
| 782 | + ) as source_file, tempfile.NamedTemporaryFile( |
| 783 | + dir=d3 |
| 784 | + ) as lock_file: |
| 785 | + lock_file.close() |
| 786 | + try: |
| 787 | + os.symlink(Path(d3), symlink_path) |
| 788 | + except OSError: |
| 789 | + if sys.platform == "win32": |
| 790 | + # os.symlink requires either administrative privileges or developer |
| 791 | + # mode on Win10, throwing an OSError if neither is active. |
| 792 | + # Test is not possible in that case. |
| 793 | + return |
| 794 | + raise |
| 795 | + locker = Locker(str(symlink_path) + os.sep + Path(lock_file.name).name, {}) |
| 796 | + |
| 797 | + package_local = Package( |
| 798 | + "local-package", |
| 799 | + "1.2.3", |
| 800 | + source_type="file", |
| 801 | + source_url=source_file.name, |
| 802 | + source_reference="develop", |
| 803 | + source_resolved_reference="123456", |
| 804 | + ) |
| 805 | + packages = [ |
| 806 | + package_local, |
| 807 | + ] |
| 808 | + |
| 809 | + locker.set_lock_data(root, packages) |
| 810 | + |
| 811 | + with locker.lock.open(encoding="utf-8") as f: |
| 812 | + content = f.read() |
| 813 | + |
| 814 | + expected = f"""\ |
| 815 | +[[package]] |
| 816 | +name = "local-package" |
| 817 | +version = "1.2.3" |
| 818 | +description = "" |
| 819 | +category = "main" |
| 820 | +optional = false |
| 821 | +python-versions = "*" |
| 822 | +
|
| 823 | +[package.source] |
| 824 | +type = "file" |
| 825 | +url = "{ |
| 826 | + Path( |
| 827 | + os.path.relpath( |
| 828 | + Path(source_file.name).resolve().as_posix(), |
| 829 | + Path(Path(lock_file.name).parent).resolve().as_posix(), |
| 830 | + ) |
| 831 | + ).as_posix() |
| 832 | +}" |
| 833 | +reference = "develop" |
| 834 | +resolved_reference = "123456" |
| 835 | +
|
| 836 | +[metadata] |
| 837 | +lock-version = "1.1" |
| 838 | +python-versions = "*" |
| 839 | +content-hash = "115cf985d932e9bf5f540555bbdd75decbb62cac81e399375fc19f6277f8c1d8" |
| 840 | +
|
| 841 | +[metadata.files] |
| 842 | +local-package = [] |
| 843 | +""" |
| 844 | + |
| 845 | + assert content == expected |
0 commit comments