tauri_build/codegen/
context.rs1use anyhow::{Context, Result};
6use std::{
7 env::var,
8 fs::{create_dir_all, File},
9 io::{BufWriter, Write},
10 path::{Path, PathBuf},
11};
12use tauri_codegen::{context_codegen, ContextData};
13use tauri_utils::config::FrontendDist;
14
15#[cfg_attr(docsrs, doc(cfg(feature = "codegen")))]
18#[derive(Debug)]
19pub struct CodegenContext {
20 config_path: PathBuf,
21 out_file: PathBuf,
22 capabilities: Option<Vec<PathBuf>>,
23}
24
25impl Default for CodegenContext {
26 fn default() -> Self {
27 Self {
28 config_path: PathBuf::from("tauri.conf.json"),
29 out_file: PathBuf::from("tauri-build-context.rs"),
30 capabilities: None,
31 }
32 }
33}
34
35impl CodegenContext {
36 pub fn new() -> Self {
38 Self::default()
39 }
40
41 #[must_use]
47 pub fn config_path(mut self, config_path: impl Into<PathBuf>) -> Self {
48 self.config_path = config_path.into();
49 self
50 }
51
52 #[must_use]
64 pub fn out_file(mut self, filename: PathBuf) -> Self {
65 self.out_file = filename;
66 self
67 }
68
69 #[must_use]
71 pub fn capability<P: AsRef<Path>>(mut self, path: P) -> Self {
72 self
73 .capabilities
74 .get_or_insert_with(Default::default)
75 .push(path.as_ref().to_path_buf());
76 self
77 }
78
79 pub(crate) fn try_build(self) -> Result<PathBuf> {
84 let (config, config_parent) = tauri_codegen::get_config(&self.config_path)?;
85
86 match &config.build.frontend_dist {
88 Some(FrontendDist::Directory(p)) => {
89 let dist_path = config_parent.join(p);
90 if dist_path.exists() {
91 println!("cargo:rerun-if-changed={}", dist_path.display());
92 }
93 }
94 Some(FrontendDist::Files(files)) => {
95 for path in files {
96 println!(
97 "cargo:rerun-if-changed={}",
98 config_parent.join(path).display()
99 );
100 }
101 }
102 _ => (),
103 }
104 for icon in &config.bundle.icon {
105 println!(
106 "cargo:rerun-if-changed={}",
107 config_parent.join(icon).display()
108 );
109 }
110 if let Some(tray_icon) = config.app.tray_icon.as_ref().map(|t| &t.icon_path) {
111 println!(
112 "cargo:rerun-if-changed={}",
113 config_parent.join(tray_icon).display()
114 );
115 }
116
117 #[cfg(target_os = "macos")]
118 {
119 let info_plist_path = config_parent.join("Info.plist");
120 if info_plist_path.exists() {
121 println!("cargo:rerun-if-changed={}", info_plist_path.display());
122 }
123
124 if let Some(plist_path) = &config.bundle.macos.info_plist {
125 let info_plist_path = config_parent.join(plist_path);
126 if info_plist_path.exists() {
127 println!("cargo:rerun-if-changed={}", info_plist_path.display());
128 }
129 }
130 }
131
132 let code = context_codegen(ContextData {
133 dev: crate::is_dev(),
134 config,
135 config_parent,
136 root: quote::quote!(::tauri),
139 capabilities: self.capabilities,
140 assets: None,
141 test: false,
142 })?;
143
144 let out = var("OUT_DIR")
146 .map(PathBuf::from)
147 .map(|path| path.join(&self.out_file))
148 .with_context(|| "unable to find OUT_DIR during tauri-build")?;
149
150 let parent = out.parent().with_context(|| {
152 "`Codegen` could not find the parent to `out_file` while creating the file"
153 })?;
154 create_dir_all(parent)?;
155
156 let mut file = File::create(&out).map(BufWriter::new).with_context(|| {
157 format!(
158 "Unable to create output file during tauri-build {}",
159 out.display()
160 )
161 })?;
162
163 writeln!(file, "{code}").with_context(|| {
164 format!(
165 "Unable to write tokenstream to out file during tauri-build {}",
166 out.display()
167 )
168 })?;
169
170 Ok(out)
171 }
172}