Browse Source

`dx doctor` command

Jonathan Kelley 1 day ago
parent
commit
5987dc38dd

+ 7 - 13
packages/cli/src/build/request.rs

@@ -803,7 +803,6 @@ impl BuildRequest {
                 self.write_executable(ctx, &artifacts.exe, &mut artifacts.assets)
                     .await
                     .context("Failed to write executable")?;
-
                 self.write_frameworks(ctx, &artifacts.direct_rustc)
                     .await
                     .context("Failed to write frameworks")?;
@@ -3101,15 +3100,6 @@ impl BuildRequest {
         })
     }
 
-    /// Return the version of the wasm-bindgen crate if it exists
-    fn wasm_bindgen_version(&self) -> Option<String> {
-        self.workspace
-            .krates
-            .krates_by_name("wasm-bindgen")
-            .next()
-            .map(|krate| krate.krate.version.to_string())
-    }
-
     /// Return the platforms that are enabled for the package
     ///
     /// Ideally only one platform is enabled but we need to be able to
@@ -3414,6 +3404,7 @@ impl BuildRequest {
         let post_bindgen_wasm = self.wasm_bindgen_wasm_output_file();
         let should_bundle_split: bool = self.wasm_split;
         let bindgen_version = self
+            .workspace
             .wasm_bindgen_version()
             .expect("this should have been checked by tool verification");
 
@@ -4013,9 +4004,12 @@ __wbg_init({{module_or_path: "/{}/{wasm_path}"}}).then((wasm) => {{
         }
 
         // Wasm bindgen
-        let krate_bindgen_version = self.wasm_bindgen_version().ok_or(anyhow::anyhow!(
-            "failed to detect wasm-bindgen version, unable to proceed"
-        ))?;
+        let krate_bindgen_version =
+            self.workspace
+                .wasm_bindgen_version()
+                .ok_or(anyhow::anyhow!(
+                    "failed to detect wasm-bindgen version, unable to proceed"
+                ))?;
 
         WasmBindgen::verify_install(&krate_bindgen_version).await?;
 

+ 0 - 26
packages/cli/src/cli/clean.rs

@@ -1,26 +0,0 @@
-use anyhow::bail;
-
-use super::*;
-use crate::Result;
-
-/// Clean build artifacts.
-///
-/// Simply runs `cargo clean`
-#[derive(Clone, Debug, Parser)]
-pub(crate) struct Clean {}
-
-impl Clean {
-    /// todo(jon): we should add a config option that just wipes target/dx and target/dioxus-client instead of doing a full clean
-    pub(crate) async fn clean(self) -> Result<StructuredOutput> {
-        let output = tokio::process::Command::new("cargo")
-            .arg("clean")
-            .output()
-            .await?;
-
-        if !output.status.success() {
-            bail!("Cargo clean failed.");
-        }
-
-        Ok(StructuredOutput::Success)
-    }
-}

+ 213 - 0
packages/cli/src/cli/doctor.rs

@@ -0,0 +1,213 @@
+use super::*;
+use crate::{Result, Workspace};
+use anyhow::{bail, Context};
+use itertools::Itertools;
+
+/// Perform a system analysis to verify the system install is working correctly.
+#[derive(Clone, Debug, Parser)]
+pub(crate) struct Doctor {}
+
+impl Doctor {
+    pub async fn doctor(self) -> Result<StructuredOutput> {
+        let Ok(workspace) = Workspace::current().await else {
+            bail!("dx doctor must be run within a cargo workspace!")
+        };
+
+        let rustc_version = &workspace.rustc_version;
+        let rustc_sysroot = &workspace.sysroot.to_string_lossy();
+        let rustlib = workspace.sysroot.join("lib").join("rustlib");
+
+        // wasm-opt
+        let wasm_opt_location = crate::wasm_opt::installed_location();
+        let wasm_opt_message = match wasm_opt_location.clone() {
+            Some(path) => path.to_string_lossy().to_string(),
+            None => "not installed".into(),
+        };
+
+        // wasm-bindgen
+        let wbg_version = workspace.wasm_bindgen_version();
+        let wbg_version_msg = match wbg_version.clone() {
+            Some(msg) => msg,
+            None => "not required".to_string(),
+        };
+        let wasm_bindgen_location = match wbg_version {
+            Some(vers) => match crate::wasm_bindgen::WasmBindgen::new(&vers).get_binary_path() {
+                Ok(path) => path.to_string_lossy().to_string(),
+                Err(err) => err.to_string().lines().join(""),
+            },
+            None => "not required".to_string(),
+        };
+
+        // extensions
+        fn has_dioxus_ext(editor_dir: &str) -> anyhow::Result<PathBuf> {
+            let home = dirs::home_dir().context("no home dir")?;
+            let exts = home.join(editor_dir).join("extensions");
+            for dir in exts.read_dir()?.flatten() {
+                if dir
+                    .file_name()
+                    .to_string_lossy()
+                    .contains("dioxuslabs.dioxus-")
+                {
+                    return Ok(dir.path());
+                }
+            }
+
+            bail!("not found")
+        }
+
+        // Editors
+        let vscode_ext = has_dioxus_ext(".vscode");
+        let vscode_ext_msg = match vscode_ext.as_ref() {
+            Ok(path) => path.to_string_lossy().to_string(),
+            Err(_) => "not found".to_string(),
+        };
+        let cursor_ext = has_dioxus_ext(".cursor");
+        let cursor_ext_msg = match cursor_ext.as_ref() {
+            Ok(path) => path.to_string_lossy().to_string(),
+            Err(_) => "not found".to_string(),
+        };
+
+        // Tailwind
+        let mut tailwindcss = "not found".to_string();
+        if let Ok(path) = crate::tailwind::TailwindCli::v3().get_binary_path() {
+            tailwindcss = path.display().to_string();
+        }
+        if let Ok(path) = crate::tailwind::TailwindCli::v4().get_binary_path() {
+            tailwindcss = path.display().to_string();
+        }
+
+        let mut adb = "not found".to_string();
+        let mut ndk = "not found".to_string();
+        let mut sdk = "not found".to_string();
+        let mut java_home = "not found".to_string();
+        let mut emulator = "not found".to_string();
+        if let Some(rf) = workspace.android_tools.as_deref() {
+            if rf.adb.exists() {
+                adb = rf.adb.display().to_string();
+            }
+            if rf.ndk.exists() {
+                ndk = rf.ndk.display().to_string();
+            }
+            if let Some(jh) = rf.java_home.as_ref() {
+                java_home = jh.display().to_string();
+            }
+            if rf.sdk().exists() {
+                sdk = rf.sdk().display().to_string();
+            }
+            if let Some(jh) = rf.java_home.as_ref() {
+                java_home = jh.display().to_string();
+            }
+            if rf.emulator().exists() {
+                emulator = rf.emulator().display().to_string();
+            }
+        };
+
+        let mut simulator_location = "not found".to_string();
+        let mut xcode_install = "not found".to_string();
+        if let Some(xcode) = workspace.xcode.as_ref() {
+            let sim_location = xcode.join("Applications").join("Simulator.app");
+            if sim_location.exists() {
+                simulator_location = sim_location.display().to_string();
+            }
+            if xcode.exists() {
+                xcode_install = xcode.display().to_string();
+            }
+        }
+
+        // toolchains
+        let mut has_wasm32_unknown_unknown = "❌";
+        let mut has_aarch64_android_linux = "❌";
+        let mut has_i686_linux_android = "❌";
+        let mut has_armv7_linux_androideabi = "❌";
+        let mut has_x86_64_android_linux = "❌";
+        let mut has_x86_64_apple_ios = "❌";
+        let mut has_aarch64_apple_ios = "❌";
+        let mut has_aarch64_apple_ios_sim = "❌";
+        let mut has_aarch64_apple_darwin = "❌";
+        if rustlib.join("wasm32-unknown-unknown").exists() {
+            has_wasm32_unknown_unknown = "✅";
+        }
+        if rustlib.join("aarch64-linux-android").exists() {
+            has_aarch64_android_linux = "✅";
+        }
+        if rustlib.join("i686-linux-android").exists() {
+            has_i686_linux_android = "✅";
+        }
+        if rustlib.join("armv7-linux-androideabi").exists() {
+            has_armv7_linux_androideabi = "✅";
+        }
+        if rustlib.join("x86_64-linux-android").exists() {
+            has_x86_64_android_linux = "✅";
+        }
+        if rustlib.join("x86_64-apple-ios").exists() {
+            has_x86_64_apple_ios = "✅";
+        }
+        if rustlib.join("aarch64-apple-ios").exists() {
+            has_aarch64_apple_ios = "✅";
+        }
+        if rustlib.join("aarch64-apple-ios-sim").exists() {
+            has_aarch64_apple_ios_sim = "✅";
+        }
+        if rustlib.join("aarch64-apple-darwin").exists() {
+            has_aarch64_apple_darwin = "✅";
+        }
+
+        // Things to know
+        // - current rust version and rust-related things
+        // - installed toolchains
+        // -
+        use crate::styles::*;
+        println!(
+            r#"|
+| {LINK_STYLE}Setup{LINK_STYLE:#}
+|  {GLOW_STYLE}Web{GLOW_STYLE:#}: wasm-bindgen, wasm-opt, and TailwindCSS are downloaded automatically
+|  {GLOW_STYLE}iOS{GLOW_STYLE:#}: Install iOS SDK and developer tools and through XCode
+|  {GLOW_STYLE}Android{GLOW_STYLE:#}: Install Android Studio, NDK, and then set ANDROID_HOME and ANDROID_NDK_HOME
+|  {GLOW_STYLE}macOS{GLOW_STYLE:#}: all tools should be installed by default
+|  {GLOW_STYLE}Windows{GLOW_STYLE:#}: install the webview2 binary
+|  {GLOW_STYLE}Linux{GLOW_STYLE:#}: Install libwebkit2gtk-4.1-dev libgtk-3-dev libasound2-dev libudev-dev libayatana-appindicator3-dev libxdo-dev libglib2.0-dev
+|
+| {LINK_STYLE}Rust{LINK_STYLE:#}
+|  Rustc version: {HINT_STYLE}{rustc_version}{HINT_STYLE:#}
+|  Rustc sysroot: {HINT_STYLE}{rustc_sysroot}{HINT_STYLE:#}
+|
+| {LINK_STYLE}Devtools{LINK_STYLE:#}
+|  VSCode Extension: {HINT_STYLE}{vscode_ext_msg}{HINT_STYLE:#}
+|  Cursor Extension: {HINT_STYLE}{cursor_ext_msg}{HINT_STYLE:#}
+|  TailwindCSS: {HINT_STYLE}{tailwindcss}{HINT_STYLE:#}
+|
+| {LINK_STYLE}Web{LINK_STYLE:#}
+|  wasm-opt: {HINT_STYLE}{wasm_opt_message}{HINT_STYLE:#}
+|  wasm-bindgen: {HINT_STYLE}{wasm_bindgen_location}{HINT_STYLE:#}
+|  wasm-bindgen version: {HINT_STYLE}{wbg_version_msg}{HINT_STYLE:#}
+|
+| {LINK_STYLE}iOS{LINK_STYLE:#}
+|  XCode: {HINT_STYLE}{xcode_install}{HINT_STYLE:#}
+|  Simulator: {HINT_STYLE}{simulator_location}{HINT_STYLE:#}
+|
+| {LINK_STYLE}Android{LINK_STYLE:#}
+|  sdk: {HINT_STYLE}{sdk}{HINT_STYLE:#}
+|  ndk: {HINT_STYLE}{ndk}{HINT_STYLE:#}
+|  adb: {HINT_STYLE}{adb}{HINT_STYLE:#}
+|  emulator: {HINT_STYLE}{emulator}{HINT_STYLE:#}
+|  java_home: {HINT_STYLE}{java_home}{HINT_STYLE:#}
+|
+| {LINK_STYLE}Toolchains{LINK_STYLE:#}
+|  {HINT_STYLE}{has_wasm32_unknown_unknown}{HINT_STYLE:#} wasm32-unknown-unknown {HINT_STYLE}(web){HINT_STYLE:#}
+|  {HINT_STYLE}{has_aarch64_android_linux}{HINT_STYLE:#} aarch64-android-linux {HINT_STYLE}(android){HINT_STYLE:#}
+|  {HINT_STYLE}{has_i686_linux_android}{HINT_STYLE:#} i686-linux-android {HINT_STYLE}(android){HINT_STYLE:#}
+|  {HINT_STYLE}{has_armv7_linux_androideabi}{HINT_STYLE:#} armv7-linux-androideabi {HINT_STYLE}(android){HINT_STYLE:#}
+|  {HINT_STYLE}{has_x86_64_android_linux}{HINT_STYLE:#} x86_64-android-linux {HINT_STYLE}(android){HINT_STYLE:#}
+|  {HINT_STYLE}{has_x86_64_apple_ios}{HINT_STYLE:#} x86_64-apple-ios {HINT_STYLE}(iOS){HINT_STYLE:#}
+|  {HINT_STYLE}{has_aarch64_apple_ios}{HINT_STYLE:#} aarch64-apple-ios {HINT_STYLE}(iOS){HINT_STYLE:#}
+|  {HINT_STYLE}{has_aarch64_apple_ios_sim}{HINT_STYLE:#} aarch64-apple-ios-sim {HINT_STYLE}(iOS){HINT_STYLE:#}
+|  {HINT_STYLE}{has_aarch64_apple_darwin}{HINT_STYLE:#} aarch64-apple-darwin {HINT_STYLE}(iOS){HINT_STYLE:#}
+|
+| Get help: {LINK_STYLE}https://discord.gg/XgGxMSkvUM{LINK_STYLE:#}
+| More info: {LINK_STYLE}https://dioxuslabs.com/learn/0.6/{LINK_STYLE:#}
+|"#
+        );
+
+        Ok(StructuredOutput::Success)
+    }
+}

+ 6 - 5
packages/cli/src/cli/mod.rs

@@ -3,9 +3,9 @@ pub(crate) mod build;
 pub(crate) mod build_assets;
 pub(crate) mod bundle;
 pub(crate) mod check;
-pub(crate) mod clean;
 pub(crate) mod config;
 pub(crate) mod create;
+pub(crate) mod doctor;
 pub(crate) mod init;
 pub(crate) mod link;
 pub(crate) mod platform_override;
@@ -75,9 +75,9 @@ pub(crate) enum Commands {
     #[clap(name = "init")]
     Init(init::Init),
 
-    /// Clean output artifacts.
-    #[clap(name = "clean")]
-    Clean(clean::Clean),
+    /// Diagnose installed tools and system configuration.
+    #[clap(name = "doctor")]
+    Doctor(doctor::Doctor),
 
     /// Translate a source file into Dioxus code.
     #[clap(name = "translate")]
@@ -121,7 +121,6 @@ impl Display for Commands {
             Commands::Serve(_) => write!(f, "serve"),
             Commands::New(_) => write!(f, "create"),
             Commands::Init(_) => write!(f, "init"),
-            Commands::Clean(_) => write!(f, "clean"),
             Commands::Config(_) => write!(f, "config"),
             Commands::Autoformat(_) => write!(f, "fmt"),
             Commands::Check(_) => write!(f, "check"),
@@ -129,6 +128,7 @@ impl Display for Commands {
             Commands::Run(_) => write!(f, "run"),
             Commands::SelfUpdate(_) => write!(f, "self-update"),
             Commands::Tools(_) => write!(f, "tools"),
+            Commands::Doctor(_) => write!(f, "doctor"),
         }
     }
 }
@@ -169,4 +169,5 @@ pub mod styles {
     pub(crate) const NOTE_STYLE: Style = AnsiColor::Green.on_default();
     pub(crate) const LINK_STYLE: Style = AnsiColor::Blue.on_default();
     pub(crate) const ERROR_STYLE: Style = AnsiColor::Red.on_default();
+    pub(crate) const HINT_STYLE: Style = clap::builder::styling::Ansi256Color(244).on_default();
 }

+ 1 - 1
packages/cli/src/main.rs

@@ -56,13 +56,13 @@ async fn main() {
         Commands::Config(opts) => opts.config().await,
         Commands::Autoformat(opts) => opts.autoformat().await,
         Commands::Check(opts) => opts.check().await,
-        Commands::Clean(opts) => opts.clean().await,
         Commands::Build(opts) => opts.build().await,
         Commands::Serve(opts) => opts.serve().await,
         Commands::Bundle(opts) => opts.bundle().await,
         Commands::Run(opts) => opts.run().await,
         Commands::SelfUpdate(opts) => opts.self_update().await,
         Commands::Tools(BuildTools::BuildAssets(opts)) => opts.run().await,
+        Commands::Doctor(opts) => opts.doctor().await,
     };
 
     // Provide a structured output for third party tools that can consume the output of the CLI

+ 1 - 1
packages/cli/src/serve/output.rs

@@ -675,7 +675,7 @@ impl Output {
                 if client.build.platform == Platform::Web {
                     "Serving at: ".gray()
                 } else {
-                    "ServerFns at: ".gray()
+                    "Server at: ".gray()
                 },
                 address,
             ])),

+ 1 - 1
packages/cli/src/tailwind.rs

@@ -151,7 +151,7 @@ impl TailwindCli {
         Ok(proc)
     }
 
-    fn get_binary_path(&self) -> anyhow::Result<PathBuf> {
+    pub fn get_binary_path(&self) -> anyhow::Result<PathBuf> {
         if CliSettings::prefer_no_downloads() {
             which::which("tailwindcss").map_err(|_| anyhow!("Missing tailwindcss@{}", self.version))
         } else {

+ 17 - 19
packages/cli/src/wasm_bindgen.rs

@@ -4,7 +4,7 @@ use flate2::read::GzDecoder;
 use std::path::{Path, PathBuf};
 use tar::Archive;
 use tempfile::TempDir;
-use tokio::{fs, process::Command};
+use tokio::process::Command;
 
 pub(crate) struct WasmBindgen {
     version: String,
@@ -100,7 +100,7 @@ impl WasmBindgen {
 
     /// Run the bindgen command with the current settings
     pub(crate) async fn run(&self) -> Result<std::process::Output> {
-        let binary = self.get_binary_path().await?;
+        let binary = self.get_binary_path()?;
 
         let mut args = Vec::new();
 
@@ -253,7 +253,7 @@ impl WasmBindgen {
         })?;
 
         // Get the final binary location.
-        let binary_path = self.get_binary_path().await?;
+        let binary_path = self.get_binary_path()?;
 
         // Download then extract wasm-bindgen-cli.
         let bytes = reqwest::get(url).await?.bytes().await?;
@@ -300,11 +300,10 @@ impl WasmBindgen {
             .output()
             .await?;
 
-        fs::copy(
+        std::fs::copy(
             tempdir.path().join(self.downloaded_bin_name()),
-            self.get_binary_path().await?,
-        )
-        .await?;
+            self.get_binary_path()?,
+        )?;
 
         Ok(())
     }
@@ -336,11 +335,10 @@ impl WasmBindgen {
         tracing::info!("Copying into path: {}", tempdir.path().display());
 
         // copy the wasm-bindgen out of the tempdir to the final location
-        fs::copy(
+        std::fs::copy(
             tempdir.path().join("bin").join(self.downloaded_bin_name()),
-            self.get_binary_path().await?,
+            self.get_binary_path()?,
         )
-        .await
         .context("failed to copy wasm-bindgen binary")?;
 
         Ok(())
@@ -352,7 +350,7 @@ impl WasmBindgen {
             self.version
         );
 
-        let binary = self.get_binary_path().await?;
+        let binary = self.get_binary_path()?;
         let output = Command::new(binary)
             .args(["--version"])
             .output()
@@ -381,7 +379,7 @@ impl WasmBindgen {
         );
 
         let binary_name = self.installed_bin_name();
-        let path = self.install_dir().await?.join(binary_name);
+        let path = self.install_dir()?.join(binary_name);
 
         if !path.exists() {
             self.install().await?;
@@ -390,20 +388,20 @@ impl WasmBindgen {
         Ok(())
     }
 
-    async fn get_binary_path(&self) -> anyhow::Result<PathBuf> {
+    pub fn get_binary_path(&self) -> anyhow::Result<PathBuf> {
         if CliSettings::prefer_no_downloads() {
             which::which("wasm-bindgen")
                 .map_err(|_| anyhow!("Missing wasm-bindgen-cli@{}", self.version))
         } else {
             let installed_name = self.installed_bin_name();
-            let install_dir = self.install_dir().await?;
+            let install_dir = self.install_dir()?;
             Ok(install_dir.join(installed_name))
         }
     }
 
-    async fn install_dir(&self) -> anyhow::Result<PathBuf> {
+    fn install_dir(&self) -> anyhow::Result<PathBuf> {
         let bindgen_dir = Workspace::dioxus_home_dir().join("wasm-bindgen/");
-        fs::create_dir_all(&bindgen_dir).await?;
+        std::fs::create_dir_all(&bindgen_dir)?;
         Ok(bindgen_dir)
     }
 
@@ -501,7 +499,7 @@ mod test {
 
     /// Helper to test that the installed binary actually exists.
     async fn verify_installation(binary: &WasmBindgen) {
-        let path = binary.install_dir().await.unwrap();
+        let path = binary.install_dir().unwrap();
         let name = binary.installed_bin_name();
         let binary_path = path.join(name);
         assert!(
@@ -513,9 +511,9 @@ mod test {
     /// Delete the installed binary. The temp folder should be automatically deleted.
     async fn reset_test() {
         let binary = WasmBindgen::new(VERSION);
-        let path = binary.install_dir().await.unwrap();
+        let path = binary.install_dir().unwrap();
         let name = binary.installed_bin_name();
         let binary_path = path.join(name);
-        let _ = tokio::fs::remove_file(binary_path).await;
+        let _ = std::fs::remove_file(binary_path);
     }
 }

+ 20 - 1
packages/cli/src/wasm_opt.rs

@@ -200,7 +200,7 @@ async fn find_latest_wasm_opt_download_url() -> anyhow::Result<String> {
 }
 
 /// Get the path to the wasm-opt binary, downloading it if necessary
-async fn get_binary_path() -> anyhow::Result<PathBuf> {
+pub async fn get_binary_path() -> anyhow::Result<PathBuf> {
     let install_dir = install_dir();
     let install_path = installed_bin_path(&install_dir);
 
@@ -223,6 +223,25 @@ async fn get_binary_path() -> anyhow::Result<PathBuf> {
     Ok(install_path)
 }
 
+pub fn installed_location() -> Option<PathBuf> {
+    let install_dir = install_dir();
+    let install_path = installed_bin_path(&install_dir);
+
+    if install_path.exists() {
+        return Some(install_path);
+    }
+
+    if CliSettings::prefer_no_downloads() {
+        if let Ok(existing) = which::which("wasm-opt") {
+            return Some(existing);
+        } else {
+            return None;
+        }
+    }
+
+    None
+}
+
 fn install_dir() -> PathBuf {
     Workspace::dioxus_home_dir().join("binaryen")
 }

+ 18 - 3
packages/cli/src/workspace.rs

@@ -21,6 +21,7 @@ pub struct Workspace {
     pub(crate) ignore: Gitignore,
     pub(crate) cargo_toml: cargo_toml::Manifest,
     pub(crate) android_tools: Option<Arc<AndroidTools>>,
+    pub(crate) xcode: Option<PathBuf>,
 }
 
 impl Workspace {
@@ -109,6 +110,13 @@ impl Workspace {
 
         let android_tools = crate::build::get_android_tools();
 
+        let xcode = Command::new("xcode-select")
+            .arg("-p")
+            .output()
+            .await
+            .ok()
+            .map(|s| String::from_utf8_lossy(&s.stdout).trim().to_string().into());
+
         let workspace = Arc::new(Self {
             krates,
             settings,
@@ -118,6 +126,7 @@ impl Workspace {
             ignore,
             cargo_toml,
             android_tools,
+            xcode,
         });
 
         tracing::debug!(
@@ -254,6 +263,14 @@ impl Workspace {
         self.gcc_ld_dir().join("wasm-ld")
     }
 
+    /// Return the version of the wasm-bindgen crate if it exists
+    pub fn wasm_bindgen_version(&self) -> Option<String> {
+        self.krates
+            .krates_by_name("wasm-bindgen")
+            .next()
+            .map(|krate| krate.krate.version.to_string())
+    }
+
     // wasm-ld: ./rustup/toolchains/nightly-x86_64-unknown-linux-gnu/bin/wasm-ld
     // rust-lld: ./rustup/toolchains/nightly-x86_64-unknown-linux-gnu/bin/rust-lld
     fn gcc_ld_dir(&self) -> PathBuf {
@@ -475,9 +492,7 @@ impl Workspace {
 
     /// Returns the path to the dioxus home directory, used to install tools and other things
     pub(crate) fn dioxus_home_dir() -> PathBuf {
-        dirs::data_local_dir()
-            .map(|f| f.join("dioxus/"))
-            .unwrap_or_else(|| dirs::home_dir().unwrap().join(".dioxus"))
+        dirs::home_dir().unwrap().join(".dioxus")
     }
 }