|
1 | 1 | use crate::core::{Edition, Shell, Workspace};
|
2 | 2 | use crate::util::errors::CargoResult;
|
| 3 | +use crate::util::toml::parse_document; |
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 _};
|
@@ -866,15 +867,117 @@ mod tests {
|
866 | 867 | }
|
867 | 868 | }
|
868 | 869 | }
|
869 |
| - |
870 |
| - if let Err(e) = Workspace::new(&path.join("Cargo.toml"), config) { |
871 |
| - crate::display_warning_with_error( |
872 |
| - "compiling this new package may not work due to invalid \ |
| 870 | + match Workspace::new(&path.join("Cargo.toml"), config) { |
| 871 | + Ok(ws) => { |
| 872 | + // Because we only inherit the package field of workspace for valid members of workspace, |
| 873 | + // we did not inherit it directly above. |
| 874 | + let root_manifest = paths::read(ws.root_manifest())?; |
| 875 | + let workspace_document = |
| 876 | + parse_document(root_manifest.as_str(), ws.root_manifest(), config)?; |
| 877 | + if let Some(workspace_package_keys) = workspace_document |
| 878 | + .get("workspace") |
| 879 | + .and_then(|workspace| workspace.get("package")) |
| 880 | + .and_then(|package| package.as_table()) |
| 881 | + { |
| 882 | + // We create a new manifest with the inherited package field. |
| 883 | + // We do not use the existing manifest because we do not want |
| 884 | + // to couple those two write operations together. |
| 885 | + // Moreover, if we want to add the package as a member of the workspace automatically, |
| 886 | + // we can directly reuse this function. |
| 887 | + return create_manifest_with_inherited_workspace_package_fields( |
| 888 | + opts, |
| 889 | + path, |
| 890 | + name, |
| 891 | + cargotoml_path_specifier.as_str(), |
| 892 | + workspace_package_keys, |
| 893 | + ); |
| 894 | + } |
| 895 | + } |
| 896 | + Err(e) => { |
| 897 | + crate::display_warning_with_error( |
| 898 | + "compiling this new package may not work due to invalid \ |
873 | 899 | workspace configuration",
|
874 |
| - &e, |
875 |
| - &mut config.shell(), |
876 |
| - ); |
| 900 | + &e, |
| 901 | + &mut config.shell(), |
| 902 | + ); |
| 903 | + } |
877 | 904 | }
|
878 | 905 |
|
879 | 906 | Ok(())
|
880 | 907 | }
|
| 908 | + |
| 909 | +fn create_manifest_with_inherited_workspace_package_fields( |
| 910 | + opts: &MkOptions<'_>, |
| 911 | + path: &Path, |
| 912 | + name: &str, |
| 913 | + cargotoml_path_specifier: &str, |
| 914 | + workspace_package_keys: &toml::value::Table, |
| 915 | +) -> CargoResult<()> { |
| 916 | + if workspace_package_keys.is_empty() { |
| 917 | + return Ok(()); |
| 918 | + } |
| 919 | + // Try inherit the edition from the workspace if it is not specified. |
| 920 | + let edition = match opts.edition { |
| 921 | + Some(edition) => { |
| 922 | + format!("edition = {}", toml::Value::String(edition.to_string())) |
| 923 | + } |
| 924 | + None => { |
| 925 | + if workspace_package_keys.contains_key("edition") { |
| 926 | + format!("edition.workspace = {}", toml::Value::Boolean(true)) |
| 927 | + } else { |
| 928 | + format!( |
| 929 | + "edition = {}", |
| 930 | + toml::Value::String(Edition::LATEST_STABLE.to_string()) |
| 931 | + ) |
| 932 | + } |
| 933 | + } |
| 934 | + }; |
| 935 | + // Try inherit the version from the workspace if it is not specified. |
| 936 | + let version = if workspace_package_keys.contains_key("version") { |
| 937 | + format!("version.workspace = {}", toml::Value::Boolean(true)) |
| 938 | + } else { |
| 939 | + "version = \"0.1.0\"".to_string() |
| 940 | + }; |
| 941 | + // Try inherit the publish from the workspace if it is not specified. |
| 942 | + let publish = match opts.registry { |
| 943 | + Some(registry) => format!( |
| 944 | + "publish = {}\n", |
| 945 | + toml::Value::Array(vec!(toml::Value::String(registry.to_string()))) |
| 946 | + ), |
| 947 | + None => { |
| 948 | + if workspace_package_keys.contains_key("publish") { |
| 949 | + format!("publish.workspace = {}\n", toml::Value::Boolean(true)) |
| 950 | + } else { |
| 951 | + "".to_string() |
| 952 | + } |
| 953 | + } |
| 954 | + }; |
| 955 | + // Inherit other keys from the workspace. |
| 956 | + let workspace_package_fields = workspace_package_keys |
| 957 | + .iter() |
| 958 | + .filter(|(key, _)| *key != "edition" && *key != "version" && *key != "publish") |
| 959 | + .map(|(key, _)| format!("{}.workspace = {}", key, toml::Value::Boolean(true))) |
| 960 | + .collect::<Vec<String>>(); |
| 961 | + paths::write( |
| 962 | + &path.join("Cargo.toml"), |
| 963 | + format!( |
| 964 | + r#"[package] |
| 965 | +name = "{}" |
| 966 | +{} |
| 967 | +{} |
| 968 | +{}{} |
| 969 | +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html |
| 970 | +
|
| 971 | +[dependencies] |
| 972 | +{}"#, |
| 973 | + name, |
| 974 | + version, |
| 975 | + edition, |
| 976 | + publish, |
| 977 | + workspace_package_fields.join("\n"), |
| 978 | + cargotoml_path_specifier |
| 979 | + ) |
| 980 | + .as_bytes(), |
| 981 | + )?; |
| 982 | + return Ok(()); |
| 983 | +} |
0 commit comments