@@ -39,9 +39,9 @@ def run_codegen() -> None:
3939 raise SystemExit (error .returncode ) from None
4040
4141
42- def get_rust_analyzer_version ( ) -> str :
42+ def get_min_rust_analyzer_version ( manifest : str ) -> str :
4343 """Get the minimum version of all ra_ap dependencies from `Cargo.toml`."""
44- dependencies = tomllib .loads (RUST_EXTRACTOR_MANIFEST . read_text () )["dependencies" ]
44+ dependencies = tomllib .loads (manifest )["dependencies" ]
4545 return min (
4646 (
4747 version
@@ -62,7 +62,7 @@ def fetch(url: str) -> bytes:
6262
6363
6464def get_compatible_rust_toolchain (rust_analyzer_version : str ) -> str :
65- """Get the latest Rust toolchain that precedes our version of rust-analyzer."""
65+ """Get the latest Rust toolchain released no later than rust-analyzer."""
6666 # Get the release date of the rust-analyzer version
6767 crate_url = f"https://crates.io/api/v1/crates/ra_ap_syntax/{ rust_analyzer_version } "
6868 crate = json .loads (fetch (crate_url ))
@@ -72,12 +72,13 @@ def get_compatible_rust_toolchain(rust_analyzer_version: str) -> str:
7272 # ```
7373 # static.rust-lang.org/dist/YYYY-MM-DD/channel-rust-stable.toml
7474 # ```
75- # where `YYYY-MM-DD` is the last that is earlier than the rust-analyzer release.
75+ # where `YYYY-MM-DD` is no later than the rust-analyzer release date.
76+ manifests = (
77+ fetch ("https://static.rust-lang.org/manifests.txt" ).decode ().splitlines ()
78+ )
7679 rust_manifest = next (
7780 manifest
78- for manifest in reversed (
79- fetch ("https://static.rust-lang.org/manifests.txt" ).decode ().splitlines ()
80- )
81+ for manifest in reversed (manifests )
8182 if manifest .endswith ("/channel-rust-stable.toml" )
8283 and manifest .split ("/" )[2 ] <= rust_analyzer_release
8384 )
@@ -86,7 +87,7 @@ def get_compatible_rust_toolchain(rust_analyzer_version: str) -> str:
8687 return manifest ["pkg" ]["rust" ]["version" ].split ()[0 ]
8788
8889
89- def update_fixed_rust_toolchain (version : str ) -> None :
90+ def update_fixed_rust_toolchain_versions (version : str ) -> None :
9091 """Change the fixed toolchain in the places where it's hardcoded"""
9192 toolchain_rs = TOOLCHAIN_RS .read_text ()
9293 prefix = 'const FIXED_RUST_TOOLCHAIN: &str = "'
@@ -108,31 +109,29 @@ def update_fixed_rust_toolchain(version: str) -> None:
108109 )
109110
110111
111- def align_rust_analyzer_versions () -> None :
112- """Align ra_ap dependencies and update the lockfile when versions differ .
112+ def align_rust_analyzer_versions (manifest : str ) -> tuple [ str , bool ] :
113+ """Align ra_ap dependency versions in a Cargo manifest .
113114
114115 rust-analyzer crates may be published gradually, so this selects the newest
115116 version that is available for every ra_ap dependency.
116117 """
117- manifest = RUST_EXTRACTOR_MANIFEST .read_text ()
118118 dependencies = {
119119 name : version
120120 for name , version in tomllib .loads (manifest )["dependencies" ].items ()
121121 if name .startswith ("ra_ap_" )
122122 }
123123 if len (set (dependencies .values ())) == 1 :
124124 # All the `ra_ap_` dependencies agree
125- return
125+ return manifest , False
126126
127- version = get_rust_analyzer_version ( )
127+ version = get_min_rust_analyzer_version ( manifest )
128128
129129 for name , old_version in dependencies .items ():
130130 manifest = manifest .replace (
131131 f'{ name } = "{ old_version } "' ,
132132 f'{ name } = "{ version } "' ,
133133 )
134- RUST_EXTRACTOR_MANIFEST .write_text (manifest )
135- run ("cargo" , "update" )
134+ return manifest , True
136135
137136
138137def commit_all (title : str ) -> None :
@@ -152,20 +151,26 @@ def main() -> None:
152151 raise RuntimeError ("the working tree must be clean" )
153152
154153 print_step (1 , "Update dependencies" )
155- old_rust_analyzer_version = get_rust_analyzer_version ()
154+ manifest = RUST_EXTRACTOR_MANIFEST .read_text ()
155+ old_rust_analyzer_version = get_min_rust_analyzer_version (manifest )
156156 run ("cargo" , "upgrade" , "--incompatible" , "--pinned" )
157- new_rust_analyzer_version = get_rust_analyzer_version ()
157+ # Re-read the (potentially) changed manifest
158+ manifest = RUST_EXTRACTOR_MANIFEST .read_text ()
159+ new_rust_analyzer_version = get_min_rust_analyzer_version (manifest )
158160 if new_rust_analyzer_version == old_rust_analyzer_version :
159161 run ("git" , "restore" , "." )
160162 print ("No new rust-analyzer version available." )
161163 return
162164
163- align_rust_analyzer_versions ()
165+ aligned_manifest , manifest_changed = align_rust_analyzer_versions (manifest )
166+ if manifest_changed :
167+ RUST_EXTRACTOR_MANIFEST .write_text (aligned_manifest )
168+ run ("cargo" , "update" )
164169 commit_all ("Cargo: Upgrade dependencies" )
165170
166171 print_step (2 , "Update the fixed Rust toolchain used by the extractor" )
167172 rust_toolchain = get_compatible_rust_toolchain (new_rust_analyzer_version )
168- update_fixed_rust_toolchain (rust_toolchain )
173+ update_fixed_rust_toolchain_versions (rust_toolchain )
169174 commit_all ("Rust: Update fixed toolchain" )
170175
171176 print_step (3 , "Regenerate vendored bazel files" )
0 commit comments