浏览代码

Filter out features that transitively enable a platform when detecting platformless features

Signed-off-by: Nico Burns <nico@nicoburns.com>
Nico Burns 23 小时之前
父节点
当前提交
5446e2656e
共有 2 个文件被更改,包括 29 次插入31 次删除
  1. 18 30
      packages/cli/src/build/request.rs
  2. 11 1
      packages/cli/src/platform.rs

+ 18 - 30
packages/cli/src/build/request.rs

@@ -2967,7 +2967,7 @@ impl BuildRequest {
         //
         if let Some(dxs) = package.dependencies.iter().find(|dep| dep.name == "dioxus") {
             for f in dxs.features.iter() {
-                if let Some(platform) = Platform::autodetect_from_cargo_feature(f) {
+                if let Some(platform) = Platform::from_dx_cargo_feature(f) {
                     platforms.push(platform);
                 }
             }
@@ -2981,12 +2981,8 @@ impl BuildRequest {
         // Check for any enabled features which enable a dioxus platform
         for feature in enabled_features.iter() {
             // If the user directly specified a platform we can just use that.
-            if feature.starts_with("dioxus/") {
-                let dx_feature = feature.trim_start_matches("dioxus/");
-                let auto = Platform::autodetect_from_cargo_feature(dx_feature);
-                if let Some(auto) = auto {
-                    platforms.push(auto);
-                }
+            if let Some(auto) = Platform::from_user_cargo_feature(feature) {
+                platforms.push(auto);
             }
         }
 
@@ -3001,31 +2997,23 @@ impl BuildRequest {
         package: &krates::cm::Package,
         enabled_features: &[String],
     ) -> Vec<String> {
-        enabled_features
-            .iter()
-            .filter(|feature| {
-                // Don't keep features that point to a platform via dioxus/blah
-                if feature.starts_with("dioxus/") {
-                    let dx_feature = feature.trim_start_matches("dioxus/");
-                    if Platform::autodetect_from_cargo_feature(dx_feature).is_some() {
-                        return false;
-                    }
-                }
+        fn feature_enables_platform(package: &krates::cm::Package, feature: &str) -> bool {
+            if Platform::from_user_cargo_feature(feature).is_some() {
+                return true;
+            }
 
-                // Don't keep features that point to a platform via an internal feature
-                if let Some(internal_feature) = package.features.get(*feature) {
-                    for feature in internal_feature {
-                        if feature.starts_with("dioxus/") {
-                            let dx_feature = feature.trim_start_matches("dioxus/");
-                            if Platform::autodetect_from_cargo_feature(dx_feature).is_some() {
-                                return false;
-                            }
-                        }
-                    }
-                }
+            if let Some(sub_features) = package.features.get(feature) {
+                sub_features
+                    .iter()
+                    .any(|sub_feature| feature_enables_platform(package, sub_feature))
+            } else {
+                false
+            }
+        }
 
-                true
-            })
+        enabled_features
+            .iter()
+            .filter(|feature| !feature_enables_platform(package, feature))
             .cloned()
             .collect()
     }

+ 11 - 1
packages/cli/src/platform.rs

@@ -250,7 +250,8 @@ impl Platform {
         }
     }
 
-    pub(crate) fn autodetect_from_cargo_feature(feature: &str) -> Option<Self> {
+    /// Autodetect from a dioxus-crate cargo feature such as "web", "native", etc
+    pub(crate) fn from_dx_cargo_feature(feature: &str) -> Option<Self> {
         match feature {
             "web" => Some(Platform::Web),
             "desktop" | "native" => Platform::TARGET_PLATFORM,
@@ -261,6 +262,15 @@ impl Platform {
         }
     }
 
+    /// Autodetect from a user-crate cargo feature such as "dioxus/web", "dioxus/native", etc
+    pub(crate) fn from_user_cargo_feature(feature: &str) -> Option<Self> {
+        if !feature.starts_with("dioxus/") {
+            return None;
+        }
+        let dx_feature = feature.trim_start_matches("dioxus/");
+        Self::from_dx_cargo_feature(dx_feature)
+    }
+
     pub(crate) fn profile_name(&self, release: bool) -> String {
         let base_profile = match self {
             // TODO: add native profile?