1- #![ allow( dead_code) ]
1+ use std:: {
2+ collections:: BTreeMap ,
3+ fs:: { create_dir_all, remove_dir_all, File } ,
4+ io:: Write ,
5+ path:: { Path , PathBuf } ,
6+ } ;
27
3- use std:: { convert:: TryFrom , path:: PathBuf } ;
8+ use crate :: helpers:: Logger ;
9+ use handlebars:: { to_json, Handlebars } ;
10+ use include_dir:: { include_dir, Dir } ;
11+ use serde:: Deserialize ;
412
5- pub enum ForceType {
6- All ,
7- Config ,
8- Template ,
13+ const TEMPLATE_DIR : Dir = include_dir ! ( "./templates" ) ;
14+
15+ #[ derive( Deserialize ) ]
16+ struct ManifestPackage {
17+ version : String ,
918}
1019
11- impl TryFrom < & str > for ForceType {
12- type Error = anyhow:: Error ;
13- fn try_from ( value : & str ) -> Result < Self , Self :: Error > {
14- match value. to_lowercase ( ) . as_str ( ) {
15- "all" => Ok ( Self :: All ) ,
16- "conf" => Ok ( Self :: Config ) ,
17- "template" => Ok ( Self :: Template ) ,
18- _ => Err ( anyhow:: anyhow!( "Invalid `force` value." ) ) ,
19- }
20- }
20+ #[ derive( Deserialize ) ]
21+ struct Manifest {
22+ package : ManifestPackage ,
2123}
2224
2325pub struct Init {
24- force : Option < ForceType > ,
26+ force : bool ,
2527 directory : PathBuf ,
2628 tauri_path : Option < PathBuf > ,
2729 app_name : Option < String > ,
@@ -33,7 +35,7 @@ pub struct Init {
3335impl Default for Init {
3436 fn default ( ) -> Self {
3537 Self {
36- force : None ,
38+ force : false ,
3739 directory : std:: env:: current_dir ( ) . expect ( "failed to read cwd" ) ,
3840 tauri_path : None ,
3941 app_name : None ,
@@ -49,8 +51,8 @@ impl Init {
4951 Default :: default ( )
5052 }
5153
52- pub fn force ( mut self , force : ForceType ) -> Self {
53- self . force = Some ( force ) ;
54+ pub fn force ( mut self ) -> Self {
55+ self . force = true ;
5456 self
5557 }
5658
@@ -85,6 +87,101 @@ impl Init {
8587 }
8688
8789 pub fn run ( self ) -> crate :: Result < ( ) > {
88- unimplemented ! ( )
90+ let logger = Logger :: new ( "tauri:init" ) ;
91+ let template_target_path = self . directory . join ( "src-tauri" ) ;
92+ if template_target_path. exists ( ) && !self . force {
93+ logger. warn ( format ! (
94+ "Tauri dir ({:?}) not empty. Run `init --force template` to overwrite." ,
95+ template_target_path
96+ ) ) ;
97+ } else {
98+ let ( tauri_dep, tauri_build_dep) = if let Some ( tauri_path) = self . tauri_path {
99+ (
100+ format ! (
101+ "{{ path = {:?} }}" ,
102+ resolve_tauri_path( & tauri_path, "tauri" )
103+ ) ,
104+ format ! (
105+ "{{ path = {:?} }}" ,
106+ resolve_tauri_path( & tauri_path, "core/tauri-build" )
107+ ) ,
108+ )
109+ } else {
110+ let tauri_manifest: Manifest =
111+ toml:: from_str ( include_str ! ( "../../../tauri/Cargo.toml" ) ) . unwrap ( ) ;
112+ let tauri_build_manifest: Manifest =
113+ toml:: from_str ( include_str ! ( "../../../core/tauri-build/Cargo.toml" ) ) . unwrap ( ) ;
114+ (
115+ format ! ( r#"{{ version = "{}" }}"# , tauri_manifest. package. version) ,
116+ format ! (
117+ r#"{{ version = "{}" }}"# ,
118+ tauri_build_manifest. package. version
119+ ) ,
120+ )
121+ } ;
122+
123+ let _ = remove_dir_all ( & template_target_path) ;
124+ let handlebars = Handlebars :: new ( ) ;
125+
126+ let mut data = BTreeMap :: new ( ) ;
127+ data. insert ( "tauri_dep" , to_json ( tauri_dep) ) ;
128+ data. insert ( "tauri_build_dep" , to_json ( tauri_build_dep) ) ;
129+ data. insert (
130+ "dist_dir" ,
131+ to_json ( self . dist_dir . unwrap_or_else ( || "../dist" . to_string ( ) ) ) ,
132+ ) ;
133+ data. insert (
134+ "dev_path" ,
135+ to_json (
136+ self
137+ . dev_path
138+ . unwrap_or_else ( || "http://localhost:4000" . to_string ( ) ) ,
139+ ) ,
140+ ) ;
141+ data. insert (
142+ "app_name" ,
143+ to_json ( self . app_name . unwrap_or_else ( || "Tauri App" . to_string ( ) ) ) ,
144+ ) ;
145+ data. insert (
146+ "window_title" ,
147+ to_json ( self . window_title . unwrap_or_else ( || "Tauri" . to_string ( ) ) ) ,
148+ ) ;
149+
150+ render_template ( & handlebars, & data, & TEMPLATE_DIR , & self . directory ) ?;
151+ }
152+
153+ Ok ( ( ) )
154+ }
155+ }
156+
157+ fn render_template < P : AsRef < Path > > (
158+ handlebars : & Handlebars ,
159+ data : & BTreeMap < & str , serde_json:: Value > ,
160+ dir : & Dir ,
161+ out_dir : P ,
162+ ) -> crate :: Result < ( ) > {
163+ create_dir_all ( out_dir. as_ref ( ) . join ( dir. path ( ) ) ) ?;
164+ for file in dir. files ( ) {
165+ let mut output_file = File :: create ( out_dir. as_ref ( ) . join ( file. path ( ) ) ) ?;
166+ if let Some ( utf8) = file. contents_utf8 ( ) {
167+ handlebars
168+ . render_template_to_write ( utf8, & data, & mut output_file)
169+ . expect ( "Failed to render template" ) ;
170+ } else {
171+ output_file. write_all ( file. contents ( ) ) ?;
172+ }
173+ }
174+ for dir in dir. dirs ( ) {
175+ render_template ( handlebars, data, dir, out_dir. as_ref ( ) ) ?;
176+ }
177+ Ok ( ( ) )
178+ }
179+
180+ fn resolve_tauri_path < P : AsRef < Path > > ( path : P , crate_name : & str ) -> PathBuf {
181+ let path = path. as_ref ( ) ;
182+ if path. is_absolute ( ) {
183+ path. join ( crate_name)
184+ } else {
185+ PathBuf :: from ( ".." ) . join ( path) . join ( crate_name)
89186 }
90187}
0 commit comments