|
43 | 43 | import easybuild.tools.systemtools as systemtools |
44 | 44 | from easybuild.framework.easyconfig import CUSTOM |
45 | 45 | from easybuild.framework.extensioneasyblock import ExtensionEasyBlock |
| 46 | +from easybuild.tools import LooseVersion |
46 | 47 | from easybuild.tools.build_log import EasyBuildError, print_warning |
47 | 48 | from easybuild.tools.config import build_option |
48 | 49 | from easybuild.tools.filetools import CHECKSUM_TYPE_SHA256, compute_checksum, copy_dir, extract_file, mkdir |
49 | 50 | from easybuild.tools.filetools import read_file, remove_dir, write_file, which |
| 51 | +from easybuild.tools.modules import get_software_version |
50 | 52 | from easybuild.tools.run import run_shell_cmd |
51 | 53 | from easybuild.tools.toolchain.compiler import OPTARCH_GENERIC |
52 | 54 |
|
53 | 55 | CRATESIO_SOURCE = "https://crates.io/api/v1/crates" |
| 56 | +CRATES_REGISTRY_URL = 'registry+https://github.com/rust-lang/crates.io-index' |
54 | 57 |
|
55 | 58 | CONFIG_TOML_SOURCE_VENDOR = """ |
56 | 59 | [source.vendored-sources] |
|
76 | 79 | replace-with = "vendored-sources" |
77 | 80 | """ |
78 | 81 |
|
| 82 | +CONFIG_LOCK_SOURCE = """ |
| 83 | +[[package]] |
| 84 | +name = "{name}" |
| 85 | +version = "{version}" |
| 86 | +source = "{source}" |
| 87 | +# checksum intentionally not set |
| 88 | +""" |
| 89 | + |
79 | 90 | CARGO_CHECKSUM_JSON = '{{"files": {{}}, "package": "{checksum}"}}' |
80 | 91 |
|
81 | 92 |
|
@@ -610,8 +621,33 @@ def prepare_step(self, *args, **kwargs): |
610 | 621 | self.set_cargo_vars() |
611 | 622 |
|
612 | 623 | def configure_step(self): |
613 | | - """Empty configuration step.""" |
614 | | - pass |
| 624 | + """Create lockfile if it doesn't exist""" |
| 625 | + cargo_lock = 'Cargo.lock' |
| 626 | + if self.crates and os.path.exists('Cargo.toml') and not os.path.exists(cargo_lock): |
| 627 | + root_toml = run_shell_cmd('cargo locate-project --message-format=plain --workspace').output |
| 628 | + cargo_lock_path = os.path.join(os.path.dirname(root_toml), cargo_lock) |
| 629 | + if not os.path.exists(cargo_lock_path): |
| 630 | + rust_version = LooseVersion(get_software_version('Rust')) |
| 631 | + # File format version, oldest supported used for compatibility |
| 632 | + if rust_version <= '1.37': |
| 633 | + version = 1 |
| 634 | + elif rust_version <= '1.81': |
| 635 | + version = 2 |
| 636 | + else: |
| 637 | + version = 3 |
| 638 | + # Use vendored crates to ensure those versions are used |
| 639 | + self.log.info(f"No {cargo_lock} file found, creating one at {cargo_lock_path}") |
| 640 | + content = f'version = {version}\n' |
| 641 | + for crate_info in self.crates: |
| 642 | + if len(crate_info) == 2: |
| 643 | + name, version = crate_info |
| 644 | + source = CRATES_REGISTRY_URL |
| 645 | + else: |
| 646 | + name, version, repo, rev = crate_info |
| 647 | + source = f'git+{repo}?rev={rev}#{rev}' |
| 648 | + |
| 649 | + content += CONFIG_LOCK_SOURCE.format(name=name, version=version, source=source) |
| 650 | + write_file(cargo_lock_path, content) |
615 | 651 |
|
616 | 652 | @property |
617 | 653 | def profile(self): |
@@ -701,7 +737,7 @@ def generate_crate_list(sourcedir): |
701 | 737 | if name == app_name: |
702 | 738 | app_in_cratesio = True # exclude app itself, needs to be first in crates list or taken from pypi |
703 | 739 | else: |
704 | | - if source_url == 'registry+https://github.com/rust-lang/crates.io-index': |
| 740 | + if source_url == CRATES_REGISTRY_URL: |
705 | 741 | crates.append((name, version)) |
706 | 742 | else: |
707 | 743 | # Lock file has revision and branch in the url |
|
0 commit comments