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