1- use crate :: constants:: DAEMON_STATE ;
2- use crate :: util:: string_as_section;
31use crate :: {
2+ constants:: DAEMON_STATE ,
43 nvim:: BufferDirection ,
54 state:: State ,
6- types:: { Client , Platform } ,
7- Result ,
5+ types:: { Client , Platform , SimDevice } ,
6+ util:: string_as_section,
7+ Error , Result ,
8+ } ;
9+ use {
10+ tap:: Pipe ,
11+ tokio:: { sync:: OwnedMutexGuard , task:: JoinHandle } ,
12+ tokio_stream:: StreamExt ,
13+ xcodebuild:: { parser:: BuildSettings , runner} ,
814} ;
9- use tap:: Pipe ;
10- use tokio:: sync:: OwnedMutexGuard ;
11- use tokio:: task:: JoinHandle ;
12- use tokio_stream:: StreamExt ;
13- use xcodebuild:: parser:: BuildSettings ;
14- use xcodebuild:: runner;
15-
16- mod macos;
17- mod simctl;
1815
1916pub struct Runner {
2017 pub client : Client ,
@@ -35,3 +32,107 @@ impl Runner {
3532 }
3633 }
3734}
35+
36+ /// MacOS Runner
37+ impl Runner {
38+ pub async fn run_as_macos_app ( self , settings : BuildSettings ) -> Result < JoinHandle < Result < ( ) > > > {
39+ let nvim = self . state . clients . get ( & self . client . pid ) ?;
40+ let ref mut logger = nvim. new_logger ( "Run" , & self . target , & self . direction ) ;
41+
42+ logger. log_title ( ) . await ?;
43+ logger. open_win ( ) . await ?;
44+
45+ tokio:: spawn ( async move {
46+ let program = settings. path_to_output_binary ( ) ?;
47+ let mut stream = runner:: run ( & program) . await ?;
48+
49+ tracing:: debug!( "Running binary {program:?}" ) ;
50+
51+ use xcodebuild:: runner:: ProcessUpdate :: * ;
52+ // NOTE: This is required so when neovim exist this should also exit
53+ while let Some ( update) = stream. next ( ) . await {
54+ let state = DAEMON_STATE . clone ( ) ;
55+ let state = state. lock ( ) . await ;
56+ let nvim = state. clients . get ( & self . client . pid ) ?;
57+ let mut logger = nvim. new_logger ( "Run" , & self . target , & self . direction ) ;
58+
59+ // NOTE: NSLog get directed to error by default which is odd
60+ match update {
61+ Stdout ( msg) => {
62+ logger. log ( msg) . await ?;
63+ }
64+ Error ( msg) | Stderr ( msg) => {
65+ logger. log ( format ! ( "[Error] {msg}" ) ) . await ?;
66+ }
67+ Exit ( ref code) => {
68+ let success = code == "0" ;
69+ let msg = string_as_section ( if success {
70+ "" . into ( )
71+ } else {
72+ format ! ( "Panic {code}" )
73+ } ) ;
74+
75+ logger. log ( msg) . await ?;
76+ logger. set_status_end ( success, true ) . await ?;
77+ }
78+ }
79+ }
80+ Ok ( ( ) )
81+ } )
82+ . pipe ( Ok )
83+ }
84+ }
85+
86+ /// Simctl Runner
87+ impl Runner {
88+ pub async fn run_with_simctl ( self , settings : BuildSettings ) -> Result < JoinHandle < Result < ( ) > > > {
89+ let nvim = self . state . clients . get ( & self . client . pid ) ?;
90+ let mut logger = nvim. new_logger ( "Run" , & self . target , & self . direction ) ;
91+
92+ let app_id = settings. product_bundle_identifier ;
93+ let path_to_app = settings. metal_library_output_dir ;
94+
95+ tracing:: debug!( "{app_id}: {:?}" , path_to_app) ;
96+
97+ logger. log_title ( ) . await ?;
98+ logger. open_win ( ) . await ?;
99+
100+ let mut device = get_device ( & self . state , self . udid ) ?;
101+
102+ // NOTE: This is required so when neovim exist this should also exit
103+ let state = DAEMON_STATE . clone ( ) . lock_owned ( ) . await ;
104+
105+ tokio:: spawn ( async move {
106+ let nvim = state. clients . get ( & self . client . pid ) ?;
107+ let ref mut logger = nvim. new_logger ( "Run" , & self . target , & self . direction ) ;
108+
109+ logger. set_running ( ) . await ?;
110+
111+ device. try_boot ( logger) . await ?;
112+ device. try_install ( & path_to_app, & app_id, logger) . await ?;
113+ device. try_launch ( & app_id, logger) . await ?;
114+
115+ let mut state = DAEMON_STATE . clone ( ) . lock_owned ( ) . await ;
116+
117+ // TODO(simctl): device might change outside state
118+ state. devices . insert ( device) ;
119+
120+ // TODO: Remove and replace with app logs
121+ logger. set_status_end ( true , false ) . await ?;
122+
123+ state. sync_client_state ( ) . await ?;
124+
125+ Ok ( ( ) )
126+ } )
127+ . pipe ( Ok )
128+ }
129+ }
130+
131+ fn get_device < ' a > ( state : & ' a OwnedMutexGuard < State > , udid : Option < String > ) -> Result < SimDevice > {
132+ if let Some ( udid) = udid {
133+ state. devices . iter ( ) . find ( |d| d. udid == udid) . cloned ( )
134+ } else {
135+ None
136+ }
137+ . ok_or_else ( || Error :: Run ( "udid not found!!" . to_string ( ) ) )
138+ }
0 commit comments