Skip to content

Commit 91508c0

Browse files
feat: add config option for custom watch folders (#13881)
* feat: add config option for custom watch folders * fix: cargo clippy changes * chore: remove file * fix: ios dev * docs: clarify absolute allowed * refactor: rename variable * fix: review suggestions * fix: resolve paths * fixL use canonicalize * chore: add changefile * chore: add error if cant canonicalize * reformat changelog * Update .changes/additional-watch-folders.md * Update crates/tauri-cli/src/interface/rust.rs Co-authored-by: Tony <[email protected]> * Revert "Update .changes/additional-watch-folders.md" This reverts commit 98186b1. * Also bump `@tauri-apps/cli` * Apparently I'm so used to a higher rust version * Revert "Apparently I'm so used to a higher rust version" This reverts commit ea1d89e. * Need to check for existence for abs paths as well --------- Co-authored-by: Tony <[email protected]> Co-authored-by: Tony <[email protected]>
1 parent fd63f22 commit 91508c0

File tree

8 files changed

+89
-7
lines changed

8 files changed

+89
-7
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
"tauri-cli": minor:feat
3+
"@tauri-apps/cli": minor:feat
4+
"tauri-utils": minor:feat
5+
---
6+
7+
Introduces a new configuration option that allows you to specify custom folders to watch for changes when running `tauri dev`.

crates/tauri-cli/config.schema.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@
7070
"build": {
7171
"description": "The build configuration.",
7272
"default": {
73+
"additionalWatchFolders": [],
7374
"removeUnusedCommands": false
7475
},
7576
"allOf": [
@@ -1880,6 +1881,14 @@
18801881
"description": "Try to remove unused commands registered from plugins base on the ACL list during `tauri build`,\n the way it works is that tauri-cli will read this and set the environment variables for the build script and macros,\n and they'll try to get all the allowed commands and remove the rest\n\n Note:\n - This won't be accounting for dynamically added ACLs when you use features from the `dynamic-acl` (currently enabled by default) feature flag, so make sure to check it when using this\n - This feature requires tauri-plugin 2.1 and tauri 2.4",
18811882
"default": false,
18821883
"type": "boolean"
1884+
},
1885+
"additionalWatchFolders": {
1886+
"description": "Additional paths to watch for changes when running `tauri dev`.",
1887+
"default": [],
1888+
"type": "array",
1889+
"items": {
1890+
"type": "string"
1891+
}
18831892
}
18841893
},
18851894
"additionalProperties": false

crates/tauri-cli/src/dev.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use tauri_utils::{config::RunnerConfig, platform::Target};
2222
use std::{
2323
env::set_current_dir,
2424
net::{IpAddr, Ipv4Addr},
25+
path::PathBuf,
2526
process::{exit, Command, Stdio},
2627
sync::{
2728
atomic::{AtomicBool, Ordering},
@@ -81,6 +82,9 @@ pub struct Options {
8182
/// Disable the file watcher.
8283
#[clap(long)]
8384
pub no_watch: bool,
85+
/// Additional paths to watch for changes.
86+
#[clap(long)]
87+
pub additional_watch_folders: Vec<PathBuf>,
8488

8589
/// Disable the built-in dev server for static files.
8690
#[clap(long)]
@@ -336,6 +340,19 @@ pub fn setup(interface: &AppInterface, options: &mut Options, config: ConfigHand
336340
}
337341
}
338342

343+
if options.additional_watch_folders.is_empty() {
344+
options.additional_watch_folders.extend(
345+
config
346+
.lock()
347+
.unwrap()
348+
.as_ref()
349+
.unwrap()
350+
.build
351+
.additional_watch_folders
352+
.clone(),
353+
);
354+
}
355+
339356
Ok(())
340357
}
341358

crates/tauri-cli/src/interface/rust.rs

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use std::{
1515
};
1616

1717
use anyhow::Context;
18+
use dunce::canonicalize;
1819
use glob::glob;
1920
use ignore::gitignore::{Gitignore, GitignoreBuilder};
2021
use notify::RecursiveMode;
@@ -54,6 +55,7 @@ pub struct Options {
5455
pub args: Vec<String>,
5556
pub config: Vec<ConfigValue>,
5657
pub no_watch: bool,
58+
pub additional_watch_folders: Vec<PathBuf>,
5759
}
5860

5961
impl From<crate::build::Options> for Options {
@@ -66,6 +68,7 @@ impl From<crate::build::Options> for Options {
6668
args: options.args,
6769
config: options.config,
6870
no_watch: true,
71+
additional_watch_folders: Vec::new(),
6972
}
7073
}
7174
}
@@ -93,6 +96,7 @@ impl From<crate::dev::Options> for Options {
9396
args: options.args,
9497
config: options.config,
9598
no_watch: options.no_watch,
99+
additional_watch_folders: options.additional_watch_folders,
96100
}
97101
}
98102
}
@@ -104,6 +108,7 @@ pub struct MobileOptions {
104108
pub args: Vec<String>,
105109
pub config: Vec<ConfigValue>,
106110
pub no_watch: bool,
111+
pub additional_watch_folders: Vec<PathBuf>,
107112
}
108113

109114
#[derive(Debug)]
@@ -209,7 +214,7 @@ impl Interface for Rust {
209214
on_exit(status, reason)
210215
})
211216
});
212-
self.run_dev_watcher(&merge_configs, run)
217+
self.run_dev_watcher(&options.additional_watch_folders, &merge_configs, run)
213218
}
214219
}
215220

@@ -233,7 +238,7 @@ impl Interface for Rust {
233238
} else {
234239
let merge_configs = options.config.iter().map(|c| &c.0).collect::<Vec<_>>();
235240
let run = Arc::new(|_rust: &mut Rust| runner(options.clone()));
236-
self.run_dev_watcher(&merge_configs, run)
241+
self.run_dev_watcher(&options.additional_watch_folders, &merge_configs, run)
237242
}
238243
}
239244

@@ -411,13 +416,31 @@ fn expand_member_path(path: &Path) -> crate::Result<Vec<PathBuf>> {
411416
Ok(res)
412417
}
413418

414-
fn get_watch_folders() -> crate::Result<Vec<PathBuf>> {
419+
fn get_watch_folders(additional_watch_folders: &[PathBuf]) -> crate::Result<Vec<PathBuf>> {
415420
let tauri_path = tauri_dir();
416421
let workspace_path = get_workspace_dir()?;
417422

418423
// We always want to watch the main tauri folder.
419424
let mut watch_folders = vec![tauri_path.to_path_buf()];
420425

426+
// Add the additional watch folders, resolving the path from the tauri path if it is relative
427+
watch_folders.extend(additional_watch_folders.iter().filter_map(|dir| {
428+
let path = if dir.is_absolute() {
429+
dir.to_owned()
430+
} else {
431+
tauri_path.join(dir)
432+
};
433+
434+
let canonicalized = canonicalize(&path).ok();
435+
if canonicalized.is_none() {
436+
log::warn!(
437+
"Additional watch folder '{}' not found, ignoring",
438+
path.display()
439+
);
440+
}
441+
canonicalized
442+
}));
443+
421444
// We also try to watch workspace members, no matter if the tauri cargo project is the workspace root or a workspace member
422445
let cargo_settings = CargoSettings::load(&workspace_path)?;
423446
if let Some(members) = cargo_settings.workspace.and_then(|w| w.members) {
@@ -480,6 +503,7 @@ impl Rust {
480503

481504
fn run_dev_watcher<F: Fn(&mut Rust) -> crate::Result<Box<dyn DevProcess + Send>>>(
482505
&mut self,
506+
additional_watch_folders: &[PathBuf],
483507
merge_configs: &[&serde_json::Value],
484508
run: Arc<F>,
485509
) -> crate::Result<()> {
@@ -489,7 +513,7 @@ impl Rust {
489513
let (tx, rx) = sync_channel(1);
490514
let frontend_path = frontend_dir();
491515

492-
let watch_folders = get_watch_folders()?;
516+
let watch_folders = get_watch_folders(additional_watch_folders)?;
493517

494518
let common_ancestor = common_path::common_path_all(watch_folders.iter().map(Path::new))
495519
.expect("watch_folders should not be empty");

crates/tauri-cli/src/mobile/android/dev.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ use cargo_mobile2::{
3434
target::TargetTrait,
3535
};
3636

37-
use std::env::set_current_dir;
37+
use std::{env::set_current_dir, path::PathBuf};
3838

3939
#[derive(Debug, Clone, Parser)]
4040
#[clap(
@@ -66,6 +66,9 @@ pub struct Options {
6666
/// Disable the file watcher
6767
#[clap(long)]
6868
pub no_watch: bool,
69+
/// Additional paths to watch for changes.
70+
#[clap(long)]
71+
pub additional_watch_folders: Vec<PathBuf>,
6972
/// Open Android Studio instead of trying to run on a connected device
7073
#[clap(short, long)]
7174
pub open: bool,
@@ -113,6 +116,7 @@ impl From<Options> for DevOptions {
113116
config: options.config,
114117
args: options.args,
115118
no_watch: options.no_watch,
119+
additional_watch_folders: options.additional_watch_folders,
116120
no_dev_server_wait: options.no_dev_server_wait,
117121
no_dev_server: options.no_dev_server,
118122
port: options.port,
@@ -265,6 +269,7 @@ fn run_dev(
265269
args: options.args,
266270
config: dev_options.config.clone(),
267271
no_watch: options.no_watch,
272+
additional_watch_folders: options.additional_watch_folders,
268273
},
269274
|options| {
270275
let cli_options = CliOptions {

crates/tauri-cli/src/mobile/ios/dev.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ use cargo_mobile2::{
3232
opts::{NoiseLevel, Profile},
3333
};
3434

35-
use std::env::set_current_dir;
35+
use std::{env::set_current_dir, path::PathBuf};
3636

3737
const PHYSICAL_IPHONE_DEV_WARNING: &str = "To develop on physical phones you need the `--host` option (not required for Simulators). See the documentation for more information: https://v2.tauri.app/develop/#development-server";
3838

@@ -73,6 +73,9 @@ pub struct Options {
7373
/// Disable the file watcher
7474
#[clap(long)]
7575
pub no_watch: bool,
76+
/// Additional paths to watch for changes.
77+
#[clap(long)]
78+
pub additional_watch_folders: Vec<PathBuf>,
7679
/// Open Xcode instead of trying to run on a connected device
7780
#[clap(short, long)]
7881
pub open: bool,
@@ -119,6 +122,7 @@ impl From<Options> for DevOptions {
119122
release_mode: options.release_mode,
120123
args: options.args,
121124
no_watch: options.no_watch,
125+
additional_watch_folders: options.additional_watch_folders,
122126
no_dev_server: options.no_dev_server,
123127
no_dev_server_wait: options.no_dev_server_wait,
124128
port: options.port,
@@ -273,6 +277,7 @@ fn run_dev(
273277
args: options.args,
274278
config: dev_options.config.clone(),
275279
no_watch: options.no_watch,
280+
additional_watch_folders: options.additional_watch_folders,
276281
},
277282
|options| {
278283
let cli_options = CliOptions {

crates/tauri-schema-generator/schemas/config.schema.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@
7070
"build": {
7171
"description": "The build configuration.",
7272
"default": {
73+
"additionalWatchFolders": [],
7374
"removeUnusedCommands": false
7475
},
7576
"allOf": [
@@ -1880,6 +1881,14 @@
18801881
"description": "Try to remove unused commands registered from plugins base on the ACL list during `tauri build`,\n the way it works is that tauri-cli will read this and set the environment variables for the build script and macros,\n and they'll try to get all the allowed commands and remove the rest\n\n Note:\n - This won't be accounting for dynamically added ACLs when you use features from the `dynamic-acl` (currently enabled by default) feature flag, so make sure to check it when using this\n - This feature requires tauri-plugin 2.1 and tauri 2.4",
18811882
"default": false,
18821883
"type": "boolean"
1884+
},
1885+
"additionalWatchFolders": {
1886+
"description": "Additional paths to watch for changes when running `tauri dev`.",
1887+
"default": [],
1888+
"type": "array",
1889+
"items": {
1890+
"type": "string"
1891+
}
18831892
}
18841893
},
18851894
"additionalProperties": false

crates/tauri-utils/src/config.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2892,6 +2892,9 @@ pub struct BuildConfig {
28922892
/// - This feature requires tauri-plugin 2.1 and tauri 2.4
28932893
#[serde(alias = "remove-unused-commands", default)]
28942894
pub remove_unused_commands: bool,
2895+
/// Additional paths to watch for changes when running `tauri dev`.
2896+
#[serde(alias = "additional-watch-directories", default)]
2897+
pub additional_watch_folders: Vec<PathBuf>,
28952898
}
28962899

28972900
#[derive(Debug, PartialEq, Eq)]
@@ -3540,6 +3543,7 @@ mod build {
35403543
let before_bundle_command = quote!(None);
35413544
let features = quote!(None);
35423545
let remove_unused_commands = quote!(false);
3546+
let additional_watch_folders = quote!(Vec::new());
35433547

35443548
literal_struct!(
35453549
tokens,
@@ -3551,7 +3555,8 @@ mod build {
35513555
before_build_command,
35523556
before_bundle_command,
35533557
features,
3554-
remove_unused_commands
3558+
remove_unused_commands,
3559+
additional_watch_folders
35553560
);
35563561
}
35573562
}
@@ -3874,6 +3879,7 @@ mod test {
38743879
before_bundle_command: None,
38753880
features: None,
38763881
remove_unused_commands: false,
3882+
additional_watch_folders: Vec::new(),
38773883
};
38783884

38793885
// create a bundle config

0 commit comments

Comments
 (0)