Repository: tauri-apps/tauri
File: crates/tauri-cli/src/build.rs (Rust)

Code before:
  let app_settings = interface.app_settings();

  if !options.no_bundle && (config_.bundle.active || options.bundles.is_some()) {
    crate::bundle::bundle(
      &options.into(),
      verbosity,
      ci,
      &interface,
      &app_settings,
      config_,
      &out_dir,
    )?;
  }

  Ok(())
}

pub fn setup(
  interface: &AppInterface,
  options: &mut Options,
  config: ConfigHandle,
  mobile: bool,
) -> Result<()> {
  let tauri_path = tauri_dir();

  log::info!("Looking up installed plugins to check incompatible versions...");
  let installed_plugins = crate::info::plugins::installed_plugins(
    frontend_dir(),
    tauri_path,
    PackageManager::from_project(frontend_dir()),
  );
  let incompatible_plugins = installed_plugins.incompatible();
  if !incompatible_plugins.is_empty() {
    let incompatible_text = incompatible_plugins
      .iter()
      .map(|p| {
        format!(
          "{} (v{}) : {} (v{})",
          p.crate_name, p.crate_version, p.npm_name, p.npm_version
        )
      })
      .collect::<Vec<_>>()
      .join("\n");
    if options.ignore_version_mismatches {
      log::error!("Found version mismatched Tauri packages. Make sure the NPM and crate versions are on the same major/minor releases:\n{}", incompatible_text);
    } else {
      anyhow::bail!("Found version mismatched Tauri packages. Make sure the NPM and crate versions are on the same major/minor releases:\n{}", incompatible_text);
    }
  }

  set_current_dir(tauri_path).with_context(|| "failed to change current working directory")?;

Review comment (bug):
I'm still a bit concerned about this blocking the build process, is it possible that we do this in another thread as well?

This is the time I got in the `plugin-workspace`'s API example in debug build

```
        Info Looking up installed plugins to check incompatible versions...
[crates\tauri-cli\src\build.rs:166:3] start.elapsed() = 1.4956269s
```

Code after:
  let app_settings = interface.app_settings();

  if !options.no_bundle && (config_.bundle.active || options.bundles.is_some()) {
    crate::bundle::bundle(
      &options.into(),
      verbosity,
      ci,
      &interface,
      &app_settings,
      config_,
      &out_dir,
    )?;
  }

  Ok(())
}

pub fn setup(
  interface: &AppInterface,
  options: &mut Options,
  config: ConfigHandle,
  mobile: bool,
) -> Result<()> {
  let tauri_path = tauri_dir();

  // TODO: Maybe optimize this to run in parallel in the future
  // see https://github.com/tauri-apps/tauri/pull/13993#discussion_r2280697117
  log::info!("Looking up installed tauri packages to check mismatched versions...");
  if let Err(error) = check_mismatched_packages(frontend_dir(), tauri_path) {
    if options.ignore_version_mismatches {
      log::error!("{error}");
    } else {
      return Err(error);
    }
  }

  set_current_dir(tauri_path).with_context(|| "failed to change current working directory")?;

  let config_guard = config.lock().unwrap();
  let config_ = config_guard.as_ref().unwrap();

  let bundle_identifier_source = config_
    .find_bundle_identifier_overwriter()
    .unwrap_or_else(|| "tauri.conf.json".into());

  if config_.identifier == "com.tauri.dev" {
    anyhow::bail!(
      "You must change the bundle identifier in `{bundle_identifier_source} identifier`. The default value `com.tauri.dev` is not allowed as it must be unique across applications.",
    );
  }