1
1
use crate :: core:: { Edition , Shell , Workspace } ;
2
2
use crate :: util:: errors:: CargoResult ;
3
+ use crate :: util:: important_paths:: find_root_manifest_for_wd;
3
4
use crate :: util:: { existing_vcs_repo, FossilRepo , GitRepo , HgRepo , PijulRepo } ;
4
5
use crate :: util:: { restricted_names, Config } ;
5
6
use anyhow:: { anyhow, Context as _} ;
@@ -772,12 +773,11 @@ fn mk(config: &Config, opts: &MkOptions<'_>) -> CargoResult<()> {
772
773
if let Some ( registry) = opts. registry {
773
774
let mut array = toml_edit:: Array :: default ( ) ;
774
775
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" ) ;
776
776
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" ) ;
779
777
}
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) ;
781
781
782
782
// Calculate what `[lib]` and `[[bin]]`s we need to append to `Cargo.toml`.
783
783
for i in & opts. source_files {
@@ -795,15 +795,35 @@ fn mk(config: &Config, opts: &MkOptions<'_>) -> CargoResult<()> {
795
795
. push ( bin) ;
796
796
}
797
797
} 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
+ }
800
823
}
801
824
}
802
825
803
- paths:: write (
804
- & path. join ( "Cargo.toml" ) ,
805
- format ! ( "{}" , manifest. to_string( ) ) ,
806
- ) ?;
826
+ paths:: write ( & manifest_path, format ! ( "{}" , manifest. to_string( ) ) ) ?;
807
827
808
828
// Create all specified source files (with respective parent directories) if they don't exist.
809
829
for i in & opts. source_files {
@@ -862,3 +882,58 @@ mod tests {
862
882
863
883
Ok ( ( ) )
864
884
}
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