diff options
Diffstat (limited to 'crate_universe/src/context/crate_context.rs')
-rw-r--r-- | crate_universe/src/context/crate_context.rs | 173 |
1 files changed, 106 insertions, 67 deletions
diff --git a/crate_universe/src/context/crate_context.rs b/crate_universe/src/context/crate_context.rs index 36435230..1f56e4d0 100644 --- a/crate_universe/src/context/crate_context.rs +++ b/crate_universe/src/context/crate_context.rs @@ -27,7 +27,7 @@ pub struct CrateDependency { #[derive(Debug, Default, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize, Clone)] #[serde(default)] -pub struct TargetAttributes { +pub(crate) struct TargetAttributes { /// The module name of the crate (notably, not the package name). // // This must be the first field of `TargetAttributes` to make it the @@ -35,17 +35,17 @@ pub struct TargetAttributes { // by. The `Ord` impl controls the order of multiple rules of the same type // in the same BUILD file. In particular, this makes packages with multiple // bin crates generate those `rust_binary` targets in alphanumeric order. - pub crate_name: String, + pub(crate) crate_name: String, /// The path to the crate's root source file, relative to the manifest. - pub crate_root: Option<String>, + pub(crate) crate_root: Option<String>, /// A glob pattern of all source files required by the target - pub srcs: Glob, + pub(crate) srcs: Glob, } #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize, Clone)] -pub enum Rule { +pub(crate) enum Rule { /// `rust_library` Library(TargetAttributes), @@ -63,58 +63,58 @@ pub enum Rule { /// [core rules of `rules_rust`](https://bazelbuild.github.io/rules_rust/defs.html). #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[serde(default)] -pub struct CommonAttributes { +pub(crate) struct CommonAttributes { #[serde(skip_serializing_if = "Select::is_empty")] - pub compile_data: Select<BTreeSet<Label>>, + pub(crate) compile_data: Select<BTreeSet<Label>>, #[serde(skip_serializing_if = "BTreeSet::is_empty")] - pub compile_data_glob: BTreeSet<String>, + pub(crate) compile_data_glob: BTreeSet<String>, #[serde(skip_serializing_if = "Select::is_empty")] - pub crate_features: Select<BTreeSet<String>>, + pub(crate) crate_features: Select<BTreeSet<String>>, #[serde(skip_serializing_if = "Select::is_empty")] - pub data: Select<BTreeSet<Label>>, + pub(crate) data: Select<BTreeSet<Label>>, #[serde(skip_serializing_if = "BTreeSet::is_empty")] - pub data_glob: BTreeSet<String>, + pub(crate) data_glob: BTreeSet<String>, #[serde(skip_serializing_if = "Select::is_empty")] - pub deps: Select<BTreeSet<CrateDependency>>, + pub(crate) deps: Select<BTreeSet<CrateDependency>>, #[serde(skip_serializing_if = "Select::is_empty")] - pub extra_deps: Select<BTreeSet<Label>>, + pub(crate) extra_deps: Select<BTreeSet<Label>>, #[serde(skip_serializing_if = "Select::is_empty")] - pub deps_dev: Select<BTreeSet<CrateDependency>>, + pub(crate) deps_dev: Select<BTreeSet<CrateDependency>>, - pub edition: String, + pub(crate) edition: String, #[serde(skip_serializing_if = "Option::is_none")] - pub linker_script: Option<String>, + pub(crate) linker_script: Option<String>, #[serde(skip_serializing_if = "Select::is_empty")] - pub proc_macro_deps: Select<BTreeSet<CrateDependency>>, + pub(crate) proc_macro_deps: Select<BTreeSet<CrateDependency>>, #[serde(skip_serializing_if = "Select::is_empty")] - pub extra_proc_macro_deps: Select<BTreeSet<Label>>, + pub(crate) extra_proc_macro_deps: Select<BTreeSet<Label>>, #[serde(skip_serializing_if = "Select::is_empty")] - pub proc_macro_deps_dev: Select<BTreeSet<CrateDependency>>, + pub(crate) proc_macro_deps_dev: Select<BTreeSet<CrateDependency>>, #[serde(skip_serializing_if = "Select::is_empty")] - pub rustc_env: Select<BTreeMap<String, String>>, + pub(crate) rustc_env: Select<BTreeMap<String, String>>, #[serde(skip_serializing_if = "Select::is_empty")] - pub rustc_env_files: Select<BTreeSet<String>>, + pub(crate) rustc_env_files: Select<BTreeSet<String>>, #[serde(skip_serializing_if = "Select::is_empty")] - pub rustc_flags: Select<Vec<String>>, + pub(crate) rustc_flags: Select<Vec<String>>, - pub version: String, + pub(crate) version: String, #[serde(skip_serializing_if = "Vec::is_empty")] - pub tags: Vec<String>, + pub(crate) tags: Vec<String>, } impl Default for CommonAttributes { @@ -147,21 +147,21 @@ impl Default for CommonAttributes { // https://bazelbuild.github.io/rules_rust/cargo.html#cargo_build_script #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[serde(default)] -pub struct BuildScriptAttributes { +pub(crate) struct BuildScriptAttributes { #[serde(skip_serializing_if = "Select::is_empty")] - pub compile_data: Select<BTreeSet<Label>>, + pub(crate) compile_data: Select<BTreeSet<Label>>, #[serde(skip_serializing_if = "Select::is_empty")] - pub data: Select<BTreeSet<Label>>, + pub(crate) data: Select<BTreeSet<Label>>, #[serde(skip_serializing_if = "BTreeSet::is_empty")] - pub data_glob: BTreeSet<String>, + pub(crate) data_glob: BTreeSet<String>, #[serde(skip_serializing_if = "Select::is_empty")] - pub deps: Select<BTreeSet<CrateDependency>>, + pub(crate) deps: Select<BTreeSet<CrateDependency>>, #[serde(skip_serializing_if = "Select::is_empty")] - pub extra_deps: Select<BTreeSet<Label>>, + pub(crate) extra_deps: Select<BTreeSet<Label>>, // TODO: refactor a crate with a build.rs file from two into three bazel // rules in order to deduplicate link_dep information. Currently as the @@ -181,40 +181,40 @@ pub struct BuildScriptAttributes { // normal dependencies. This could be handled a special rule, or just using // a `filegroup`. #[serde(skip_serializing_if = "Select::is_empty")] - pub link_deps: Select<BTreeSet<CrateDependency>>, + pub(crate) link_deps: Select<BTreeSet<CrateDependency>>, #[serde(skip_serializing_if = "Select::is_empty")] - pub extra_link_deps: Select<BTreeSet<Label>>, + pub(crate) extra_link_deps: Select<BTreeSet<Label>>, #[serde(skip_serializing_if = "Select::is_empty")] - pub build_script_env: Select<BTreeMap<String, String>>, + pub(crate) build_script_env: Select<BTreeMap<String, String>>, #[serde(skip_serializing_if = "Select::is_empty")] - pub rundir: Select<String>, + pub(crate) rundir: Select<String>, #[serde(skip_serializing_if = "Select::is_empty")] - pub extra_proc_macro_deps: Select<BTreeSet<Label>>, + pub(crate) extra_proc_macro_deps: Select<BTreeSet<Label>>, #[serde(skip_serializing_if = "Select::is_empty")] - pub proc_macro_deps: Select<BTreeSet<CrateDependency>>, + pub(crate) proc_macro_deps: Select<BTreeSet<CrateDependency>>, #[serde(skip_serializing_if = "Select::is_empty")] - pub rustc_env: Select<BTreeMap<String, String>>, + pub(crate) rustc_env: Select<BTreeMap<String, String>>, #[serde(skip_serializing_if = "Select::is_empty")] - pub rustc_flags: Select<Vec<String>>, + pub(crate) rustc_flags: Select<Vec<String>>, #[serde(skip_serializing_if = "Select::is_empty")] - pub rustc_env_files: Select<BTreeSet<String>>, + pub(crate) rustc_env_files: Select<BTreeSet<String>>, #[serde(skip_serializing_if = "Select::is_empty")] - pub tools: Select<BTreeSet<Label>>, + pub(crate) tools: Select<BTreeSet<Label>>, #[serde(skip_serializing_if = "Option::is_none")] - pub links: Option<String>, + pub(crate) links: Option<String>, #[serde(skip_serializing_if = "BTreeSet::is_empty")] - pub toolchains: BTreeSet<Label>, + pub(crate) toolchains: BTreeSet<Label>, } impl Default for BuildScriptAttributes { @@ -242,66 +242,78 @@ impl Default for BuildScriptAttributes { } } -#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize)] -#[serde(default)] -pub struct CrateContext { +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub(crate) struct CrateContext { /// The package name of the current crate - pub name: String, + pub(crate) name: String, /// The full version of the current crate - pub version: String, + pub(crate) version: semver::Version, /// The package URL of the current crate - pub package_url: Option<String>, + #[serde(default)] + pub(crate) package_url: Option<String>, /// Optional source annotations if they were discoverable in the /// lockfile. Workspace Members will not have source annotations and /// potentially others. - pub repository: Option<SourceAnnotation>, + #[serde(default)] + pub(crate) repository: Option<SourceAnnotation>, /// A list of all targets (lib, proc-macro, bin) associated with this package - pub targets: BTreeSet<Rule>, + #[serde(default)] + pub(crate) targets: BTreeSet<Rule>, /// The name of the crate's root library target. This is the target that a dependent /// would get if they were to depend on `{crate_name}`. - pub library_target_name: Option<String>, + #[serde(default)] + pub(crate) library_target_name: Option<String>, /// A set of attributes common to most [Rule] types or target types. - pub common_attrs: CommonAttributes, + #[serde(default)] + pub(crate) common_attrs: CommonAttributes, /// Optional attributes for build scripts. This field is only populated if /// a build script (`custom-build`) target is defined for the crate. #[serde(skip_serializing_if = "Option::is_none")] - pub build_script_attrs: Option<BuildScriptAttributes>, + #[serde(default)] + pub(crate) build_script_attrs: Option<BuildScriptAttributes>, /// The license used by the crate - pub license: Option<String>, + #[serde(default)] + pub(crate) license: Option<String>, /// The SPDX licence IDs - pub license_ids: BTreeSet<String>, + /// #[serde(default)] + pub(crate) license_ids: BTreeSet<String>, - // The license file - pub license_file: Option<String>, + /// The license file + #[serde(default)] + pub(crate) license_file: Option<String>, /// Additional text to add to the generated BUILD file. #[serde(skip_serializing_if = "Option::is_none")] - pub additive_build_file_content: Option<String>, + #[serde(default)] + pub(crate) additive_build_file_content: Option<String>, /// If true, disables pipelining for library targets generated for this crate #[serde(skip_serializing_if = "std::ops::Not::not")] - pub disable_pipelining: bool, + #[serde(default)] + pub(crate) disable_pipelining: bool, /// Extra targets that should be aliased. #[serde(skip_serializing_if = "BTreeMap::is_empty")] - pub extra_aliased_targets: BTreeMap<String, String>, + #[serde(default)] + pub(crate) extra_aliased_targets: BTreeMap<String, String>, /// Transition rule to use instead of `alias`. #[serde(skip_serializing_if = "Option::is_none")] - pub alias_rule: Option<AliasRule>, + #[serde(default)] + pub(crate) alias_rule: Option<AliasRule>, } impl CrateContext { - pub fn new( + pub(crate) fn new( annotation: &CrateAnnotation, packages: &BTreeMap<PackageId, Package>, source_annotations: &BTreeMap<PackageId, SourceAnnotation>, @@ -311,7 +323,7 @@ impl CrateContext { include_build_scripts: bool, ) -> Self { let package: &Package = &packages[&annotation.node.id]; - let current_crate_id = CrateId::new(package.name.clone(), package.version.to_string()); + let current_crate_id = CrateId::new(package.name.clone(), package.version.clone()); let new_crate_dep = |dep: Dependency| -> CrateDependency { let pkg = &packages[&dep.package_id]; @@ -322,7 +334,7 @@ impl CrateContext { let target = sanitize_module_name(&dep.target_name); CrateDependency { - id: CrateId::new(pkg.name.clone(), pkg.version.to_string()), + id: CrateId::new(pkg.name.clone(), pkg.version.clone()), target, alias: dep.alias, } @@ -450,7 +462,7 @@ impl CrateContext { } } - let license_file = package.license_file.as_ref().map(|path| path.to_string()); + let license_file = Self::locate_license_file(package); let package_url: Option<String> = match package.repository { Some(..) => package.repository.clone(), @@ -460,7 +472,7 @@ impl CrateContext { // Create the crate's context and apply extra settings CrateContext { name: package.name.clone(), - version: package.version.to_string(), + version: package.version.clone(), license: package.license.clone(), license_ids, license_file, @@ -650,6 +662,33 @@ impl CrateContext { self } + fn locate_license_file(package: &Package) -> Option<String> { + if let Some(license_file_path) = &package.license_file { + return Some(license_file_path.to_string()); + } + let package_root = package + .manifest_path + .as_std_path() + .parent() + .expect("Every manifest should have a parent directory"); + if package_root.exists() { + let mut paths: Vec<_> = package_root + .read_dir() + .unwrap() + .map(|r| r.unwrap()) + .collect(); + paths.sort_by_key(|dir| dir.path()); + for path in paths { + if let Some(file_name) = path.file_name().to_str() { + if file_name.to_uppercase().starts_with("LICENSE") { + return Some(file_name.to_string()); + } + } + } + } + None + } + /// Determine whether or not a crate __should__ include a build script /// (build.rs) if it happens to have one. fn crate_includes_build_script( @@ -801,7 +840,7 @@ mod test { let mut pairred_extras = BTreeMap::new(); pairred_extras.insert( - CrateId::new("common".to_owned(), "0.1.0".to_owned()), + CrateId::new("common".to_owned(), semver::Version::new(0, 1, 0)), PairedExtras { package_id, crate_extra: CrateAnnotations { |