@@ -153,7 +153,7 @@ def _clean_line(line: str, expected_end: Union[str, None]) -> str:
153153 return line [:idx ].strip ()
154154
155155
156- def parse_toml (file : Path ) -> Dict [str , str ]:
156+ def parse_toml (file_or_content : Union [ Path , str ] ) -> Dict [str , str ]:
157157 """Minimally parse a TOML file into sections, keys and values
158158
159159 Values will be the raw strings (including quotes for string-typed values)"""
@@ -163,7 +163,7 @@ def parse_toml(file: Path) -> Dict[str, str]:
163163 pending_value = None
164164 expected_end = None
165165 current_section = None
166- content = read_file (file )
166+ content = read_file (file_or_content ) if isinstance ( file_or_content , Path ) else file_or_content
167167 num = raw_line = None
168168 start_end = {
169169 '[' : ']' ,
@@ -196,7 +196,7 @@ def parse_toml(file: Path) -> Dict[str, str]:
196196 result [current_section ][pending_key ] = pending_value .strip ()
197197 pending_key = None
198198 except Exception as e :
199- raise ValueError (f'Failed to parse { file } , error { e } at line { num } : { raw_line } ' )
199+ raise ValueError (f'Failed to parse { file_or_content } , error { e } at line { num } : { raw_line } ' )
200200 return result
201201
202202
@@ -236,6 +236,35 @@ def get_workspace_members(cargo_toml: Dict[str, str]):
236236 return has_package , members
237237
238238
239+ def merge_sub_crate (cargo_toml_path : Path , workspace_toml : Dict [str , str ]):
240+ """Resolve workspace references in the Cargo.toml file"""
241+ # Lines such as 'authors.workspace = true' must be replaced by 'authors = <value from workspace.package>'
242+ content : str = read_file (cargo_toml_path )
243+ SUFFIX = '.workspace'
244+ if SUFFIX not in content :
245+ return
246+ cargo_toml = parse_toml (content )
247+ lines = content .splitlines ()
248+
249+ def do_replacement (section , workspace_section ):
250+ if not section or not workspace_section :
251+ return
252+
253+ for key , value in section .items ():
254+ if key .endswith (SUFFIX ) and value == 'true' :
255+ real_key = key [:- len (SUFFIX )]
256+ value = workspace_section [real_key ]
257+ idx = next (idx for idx , line in enumerate (lines ) if key in line )
258+ lines [idx ] = f'{ real_key } = { value } '
259+
260+ do_replacement (cargo_toml .get ('package' ), workspace_toml .get ('workspace.package' ))
261+ do_replacement (cargo_toml .get ('dependencies' ), workspace_toml .get ('workspace.dependencies' ))
262+ do_replacement (cargo_toml .get ('build-dependencies' ), workspace_toml .get ('workspace.dependencies' ))
263+ do_replacement (cargo_toml .get ('dev-dependencies' ), workspace_toml .get ('workspace.dependencies' ))
264+
265+ write_file (cargo_toml_path , '\n ' .join (lines ))
266+
267+
239268def get_checksum (src , log ):
240269 """Get the checksum from an extracted source"""
241270 checksum = src ['checksum' ]
@@ -502,6 +531,8 @@ def _setup_offline_config(self, git_sources):
502531 # Use copy_dir to resolve symlinks that might point to the parent folder
503532 copy_dir (tmp_crate_dir / member , target_path , symlinks = False )
504533 cargo_pkg_dirs .append (target_path )
534+ self .log .info (f'Resolving workspace values for crate { member } ' )
535+ merge_sub_crate (target_path / 'Cargo.toml' , parsed_toml )
505536 if has_package :
506537 # Remove the copied crate folders
507538 for member in members :
0 commit comments