11use crate :: core:: { Edition , Shell , Workspace } ;
22use crate :: util:: errors:: CargoResult ;
3+ use crate :: util:: important_paths:: find_root_manifest_for_wd;
34use crate :: util:: { existing_vcs_repo, FossilRepo , GitRepo , HgRepo , PijulRepo } ;
45use crate :: util:: { restricted_names, Config } ;
56use anyhow:: { anyhow, Context as _} ;
@@ -772,12 +773,11 @@ fn mk(config: &Config, opts: &MkOptions<'_>) -> CargoResult<()> {
772773 if let Some ( registry) = opts. registry {
773774 let mut array = toml_edit:: Array :: default ( ) ;
774775 array. push ( registry) ;
775- array. decor_mut ( ) . set_suffix ( "\n \n # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html" ) ;
776776 manifest[ "package" ] [ "publish" ] = toml_edit:: value ( array) ;
777- } else {
778- manifest[ "package" ] [ "edition" ] . as_value_mut ( ) . expect ( "edition is a string value" ) . decor_mut ( ) . set_suffix ( "\n \n # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html" ) ;
779777 }
780- manifest[ "dependencies" ] = toml_edit:: Item :: Table ( toml_edit:: Table :: new ( ) ) ;
778+ let mut dep_table = toml_edit:: Table :: default ( ) ;
779+ dep_table. decor_mut ( ) . set_prefix ( "\n # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html\n \n " ) ;
780+ manifest[ "dependencies" ] = toml_edit:: Item :: Table ( dep_table) ;
781781
782782 // Calculate what `[lib]` and `[[bin]]`s we need to append to `Cargo.toml`.
783783 for i in & opts. source_files {
@@ -795,15 +795,35 @@ fn mk(config: &Config, opts: &MkOptions<'_>) -> CargoResult<()> {
795795 . push ( bin) ;
796796 }
797797 } else if i. relative_path != "src/lib.rs" {
798- manifest[ "lib" ] [ "name" ] = toml_edit:: value ( i. target_name . clone ( ) ) ;
799- manifest[ "lib" ] [ "path" ] = toml_edit:: value ( i. relative_path . clone ( ) ) ;
798+ let mut lib = toml_edit:: Table :: new ( ) ;
799+ lib[ "name" ] = toml_edit:: value ( i. target_name . clone ( ) ) ;
800+ lib[ "path" ] = toml_edit:: value ( i. relative_path . clone ( ) ) ;
801+ manifest[ "lib" ] = toml_edit:: Item :: Table ( lib) ;
802+ }
803+ }
804+
805+ let manifest_path = path. join ( "Cargo.toml" ) ;
806+ if let Ok ( root_manifest_path) = find_root_manifest_for_wd ( & manifest_path) {
807+ let root_manifest = paths:: read ( & root_manifest_path) ?;
808+ // Sometimes the root manifest is not a valid manifest, so we only try to parse it if it is.
809+ // This should not block the creation of the new project. It is only a best effort to
810+ // inherit the workspace package keys.
811+ if let Ok ( workspace_document) = root_manifest. parse :: < toml_edit:: Document > ( ) {
812+ if let Some ( workspace_package_keys) = workspace_document
813+ . get ( "workspace" )
814+ . and_then ( |workspace| workspace. get ( "package" ) )
815+ . and_then ( |package| package. as_table ( ) )
816+ {
817+ update_manifest_with_inherited_workspace_package_keys (
818+ opts,
819+ & mut manifest,
820+ workspace_package_keys,
821+ )
822+ }
800823 }
801824 }
802825
803- paths:: write (
804- & path. join ( "Cargo.toml" ) ,
805- format ! ( "{}" , manifest. to_string( ) ) ,
806- ) ?;
826+ paths:: write ( & manifest_path, format ! ( "{}" , manifest. to_string( ) ) ) ?;
807827
808828 // Create all specified source files (with respective parent directories) if they don't exist.
809829 for i in & opts. source_files {
@@ -862,3 +882,58 @@ mod tests {
862882
863883 Ok ( ( ) )
864884}
885+
886+ fn update_manifest_with_inherited_workspace_package_keys (
887+ opts : & MkOptions < ' _ > ,
888+ manifest : & mut toml_edit:: Document ,
889+ workspace_package_keys : & toml_edit:: Table ,
890+ ) {
891+ if workspace_package_keys. is_empty ( ) {
892+ return ;
893+ }
894+
895+ let remove_package_key = |key : & str , manifest : & mut toml_edit:: Document | {
896+ let package = manifest[ "package" ]
897+ . as_table_mut ( )
898+ . expect ( "package is a table" ) ;
899+ package. remove ( key) ;
900+ } ;
901+
902+ let set_workspace_inherited_package_key = |key : & str , manifest : & mut toml_edit:: Document | {
903+ let package = manifest[ "package" ]
904+ . as_table_mut ( )
905+ . expect ( "package is a table" ) ;
906+ let mut table = toml_edit:: Table :: new ( ) ;
907+ table. set_dotted ( true ) ;
908+ table[ "workspace" ] = toml_edit:: value ( true ) ;
909+ package. insert ( key, toml_edit:: Item :: Table ( table) ) ;
910+ } ;
911+
912+ let remove_and_inherit_package_key = |key : & str , manifest : & mut toml_edit:: Document | {
913+ remove_package_key ( key, manifest) ;
914+ set_workspace_inherited_package_key ( key, manifest) ;
915+ } ;
916+
917+ // Try inherit the edition from the workspace if it is not specified.
918+ if opts. edition . is_none ( ) && workspace_package_keys. contains_key ( "edition" ) {
919+ remove_and_inherit_package_key ( "edition" , manifest) ;
920+ }
921+
922+ // Try inherit the version from the workspace.
923+ if workspace_package_keys. contains_key ( "version" ) {
924+ remove_and_inherit_package_key ( "version" , manifest) ;
925+ }
926+
927+ // Try inherit the publish from the workspace if it is not specified.
928+ if opts. registry . is_none ( ) && workspace_package_keys. contains_key ( "publish" ) {
929+ remove_and_inherit_package_key ( "publish" , manifest) ;
930+ }
931+
932+ // Inherit other keys from the workspace.
933+ for ( key, _) in workspace_package_keys
934+ . iter ( )
935+ . filter ( |( key, _) | ![ "edition" , "version" , "publish" ] . contains ( key) )
936+ {
937+ set_workspace_inherited_package_key ( key, manifest) ;
938+ }
939+ }
0 commit comments