fn build_server(
    dir: PathBuf,
    spinners: &MultiProgress,
    did_build: bool,
    exec: Arc<Mutex<String>>,
    is_release: bool,
    is_standalone: bool,
    integration: Integration,
) -> Result<
    ThreadHandle<impl FnOnce() -> Result<i32, ExecutionError>, Result<i32, ExecutionError>>,
    ExecutionError,
> {
    // If we're using the Actix Web integration, warn that it's unstable
    // A similar warning is emitted for snooping on it
    // TODO Remove this once Actix Web v4.0.0 goes stable
    if integration == Integration::ActixWeb {
        println!("WARNING: The Actix Web integration uses a beta version of Actix Web, and is considered unstable. It is not recommended for production usage.")
    }

    let num_steps = match did_build {
        true => 4,
        false => 2,
    };
    let target = dir.join(".perseus/server");

    // Server building message
    let sb_msg = format!(
        "{} {} Building server",
        style(format!("[{}/{}]", num_steps - 1, num_steps))
            .bold()
            .dim(),
        BUILDING_SERVER
    );

    // We'll parallelize the building of the server with any build commands that are currently running
    // We deliberately insert the spinner at the end of the list
    let sb_spinner = spinners.insert(num_steps - 1, ProgressBar::new_spinner());
    let sb_spinner = cfg_spinner(sb_spinner, &sb_msg);
    let sb_target = target;
    let sb_thread =
        spawn_thread(move || {
            let (stdout, _stderr) = handle_exit_code!(run_stage(
                vec![&format!(
                    // This sets Cargo to tell us everything, including the executable path to the server
                    "{} build --message-format json {} {}",
                    env::var("PERSEUS_CARGO_PATH").unwrap_or_else(|_| "cargo".to_string()),
                    // Enable the appropriate integration
                    format!(
                        "--features integration-{} {} --no-default-features",
                        integration.to_string(),
                        // We'll also handle whether or not it's standalone because that goes under the `--features` flag
                        if is_standalone {
                            "--features standalone"
                        } else {
                            ""
                        }
                    ),
                    if is_release { "--release" } else { "" },
                )],
                &sb_target,
                &sb_spinner,
                &sb_msg
            )?);

            let msgs: Vec<&str> = stdout.trim().split('\n').collect();
            // If we got to here, the exit code was 0 and everything should've worked
            // The last message will just tell us that the build finished, the second-last one will tell us the executable path
            let msg = msgs.get(msgs.len() - 2);
            let msg = match msg {
                // We'll parse it as a Serde `Value`, we don't need to know everything that's in there
                Some(msg) => serde_json::from_str::<serde_json::Value>(msg)
                    .map_err(|err| ExecutionError::GetServerExecutableFailed { source: err })?,
                None => return Err(ExecutionError::ServerExectutableMsgNotFound),
            };
            let server_exec_path = msg.get("executable");
            let server_exec_path = match server_exec_path {
            // We'll parse it as a Serde `Value`, we don't need to know everything that's in there
            Some(server_exec_path) => match server_exec_path.as_str() {
                Some(server_exec_path) => server_exec_path,
                None => return Err(ExecutionError::ParseServerExecutableFailed {
                    err: "expected 'executable' field to be string".to_string()
                }),
            },
            None => return Err(ExecutionError::ParseServerExecutableFailed {
                err: "expected 'executable' field in JSON map in second-last message, not present"
                    .to_string()
            }),
        };

            // And now the main thread needs to know about this
            let mut exec_val = exec.lock().unwrap();
            *exec_val = server_exec_path.to_string();

            Ok(0)
        });

    Ok(sb_thread)
}
/// Builds the server for the app, program arguments having been interpreted. This needs to know if we've built as part of this process
/// so it can show an accurate progress count. This also takes a `MultiProgress` so it can be used truly atomically (which will have
/// build spinners already on it if necessary). This also takes a `Mutex<String>` to inform the caller of the path of the server
/// executable.
Builds the server for the app, program arguments having been interpreted. This needs to know if we've built as part of this process
so it can show an accurate progress count. This also takes a `MultiProgress` so it can be used truly atomically (which will have
build spinners already on it if necessary). This also takes a `Mutex` to inform the caller of the path of the server
executable.
Builds the server for the app program arguments having been interpreted . This needs to know if we ' ve built as part of this process so it can show an accurate progress count . This also takes a ` MultiProgress ` so it can be used truly atomically ( which will have build spinners already on it if necessary ) . This also takes a ` Mutex ` to inform the caller of the path of the server executable .
fn build_server(
    dir: PathBuf,
    spinners: &MultiProgress,
    did_build: bool,
    exec: Arc<Mutex<String>>,
    is_release: bool,
    is_standalone: bool,
    integration: Integration,
) -> Result<
    ThreadHandle<impl FnOnce() -> Result<i32, ExecutionError>, Result<i32, ExecutionError>>,
    ExecutionError,
> {
    // If we're using the Actix Web integration, warn that it's unstable
    // A similar warning is emitted for snooping on it
    // TODO Remove this once Actix Web v4.0.0 goes stable
    if integration == Integration::ActixWeb {
        println!("WARNING: The Actix Web integration uses a beta version of Actix Web, and is considered unstable. It is not recommended for production usage.")
    }
    let num_steps = match did_build {
        true => 4,
        false => 2,
    };
    let target = dir.join(".perseus/server");
    // Server building message
    let sb_msg = format!(
        "{} {} Building server",
        style(format!("[{}/{}]", num_steps - 1, num_steps))
            .bold()
            .dim(),
        BUILDING_SERVER
    );
    // We'll parallelize the building of the server with any build commands that are currently running
    // We deliberately insert the spinner at the end of the list
    let sb_spinner = spinners.insert(num_steps - 1, ProgressBar::new_spinner());
    let sb_spinner = cfg_spinner(sb_spinner, &sb_msg);
    let sb_target = target;
    let sb_thread =
        spawn_thread(move || {
            let (stdout, _stderr) = handle_exit_code!(run_stage(
                vec![&format!(
                    // This sets Cargo to tell us everything, including the executable path to the server
                    "{} build --message-format json {} {}",
                    env::var("PERSEUS_CARGO_PATH").unwrap_or_else(|_| "cargo".to_string()),
                    // Enable the appropriate integration
                    format!(
                        "--features integration-{} {} --no-default-features",
                        integration.to_string(),
                        // We'll also handle whether or not it's standalone because that goes under the `--features` flag
                        if is_standalone {
                            "--features standalone"
                        } else {
                            ""
                        }
                    ),
                    if is_release { "--release" } else { "" },
                )],
                &sb_target,
                &sb_spinner,
                &sb_msg
            )?);
            let msgs: Vec<&str> = stdout.trim().split('\n').collect();
            // If we got to here, the exit code was 0 and everything should've worked
            // The last message will just tell us that the build finished, the second-last one will tell us the executable path
            let msg = msgs.get(msgs.len() - 2);
            let msg = match msg {
                // We'll parse it as a Serde `Value`, we don't need to know everything that's in there
                Some(msg) => serde_json::from_str::<serde_json::Value>(msg)
                    .map_err(|err| ExecutionError::GetServerExecutableFailed { source: err })?,
                None => return Err(ExecutionError::ServerExectutableMsgNotFound),
            };
            let server_exec_path = msg.get("executable");
            let server_exec_path = match server_exec_path {
            // We'll parse it as a Serde `Value`, we don't need to know everything that's in there
            Some(server_exec_path) => match server_exec_path.as_str() {
                Some(server_exec_path) => server_exec_path,
                None => return Err(ExecutionError::ParseServerExecutableFailed {
                    err: "expected 'executable' field to be string".to_string()
                }),
            },
            None => return Err(ExecutionError::ParseServerExecutableFailed {
                err: "expected 'executable' field in JSON map in second-last message, not present"
                    .to_string()
            }),
        };
            // And now the main thread needs to know about this
            let mut exec_val = exec.lock().unwrap();
            *exec_val = server_exec_path.to_string();
            Ok(0)
        });
    Ok(sb_thread)
}
fn build_server ( dir : PathBuf , spinners : & MultiProgress , did_build : bool , exec : Arc < Mutex < String > > , is_release : bool , is_standalone : bool , integration : Integration , ) -> Result < ThreadHandle < impl FnOnce ( ) -> Result < i32 , ExecutionError > , Result < i32 , ExecutionError > > , ExecutionError , > { // If we're using the Actix Web integration, warn that it's unstable // A similar warning is emitted for snooping on it // TODO Remove this once Actix Web v4.0.0 goes stable if integration == Integration :: ActixWeb { println ! ( " " ) } let num_steps = match did_build { true => 4 , false => 2 , } ; let target = dir . join ( " " ) ; // Server building message let sb_msg = format ! ( " " style ( format ( " " num_steps 1 num_steps ) ) bold ( ) dim ( ) BUILDING_SERVER ) ; // We'll parallelize the building of the server with any build commands that are currently running // We deliberately insert the spinner at the end of the list let sb_spinner = spinners . insert ( num_steps - 1 , ProgressBar :: new_spinner ( ) ) ; let sb_spinner = cfg_spinner ( sb_spinner , & sb_msg ) ; let sb_target = target ; let sb_thread = spawn_thread ( move | | { let ( stdout , _stderr ) = handle_exit_code ! ( run_stage ( vec [ format ( // This sets Cargo to tell us everything, including the executable path to the server " " env var ( " " ) unwrap_or_else ( " " to_string ( ) ) // Enable the appropriate integration format ( " " integration to_string ( ) // We'll also handle whether or not it's standalone because that goes under the `--features` flag if is_standalone { " " } else { " " } ) if is_release { " " } else { " " } ) ] sb_target sb_spinner sb_msg ) ) ; let msgs : Vec < & str > = stdout . trim ( ) . split ( '\n' ) . collect ( ) ; // If we got to here, the exit code was 0 and everything should've worked // The last message will just tell us that the build finished, the second-last one will tell us the executable path let msg = msgs . get ( msgs . len ( ) - 2 ) ; let msg = match msg { // We'll parse it as a Serde `Value`, we don't need to know everything that's in there Some ( msg ) => serde_json :: from_str :: < serde_json :: Value > ( msg ) . map_err ( | err | ExecutionError :: GetServerExecutableFailed { source : err } ) ? , None => return Err ( ExecutionError :: ServerExectutableMsgNotFound ) , } ; let server_exec_path = msg . get ( " " ) ; let server_exec_path = match server_exec_path { // We'll parse it as a Serde `Value`, we don't need to know everything that's in there Some ( server_exec_path ) => match server_exec_path . as_str ( ) { Some ( server_exec_path ) => server_exec_path , None => return Err ( ExecutionError :: ParseServerExecutableFailed { err : " " . to_string ( ) } ) , } , None => return Err ( ExecutionError :: ParseServerExecutableFailed { err : " " . to_string ( ) } ) , } ; // And now the main thread needs to know about this let mut exec_val = exec . lock ( ) . unwrap ( ) ; * exec_val = server_exec_path . to_string ( ) ; Ok ( 0 ) } ) ; Ok ( sb_thread ) }
Builds the server for the app, program arguments having been interpreted.
Builds the server for the app program arguments having been interpreted .
dir
PathBuf
spinners
&MultiProgress
did_build
bool
exec
Arc<Mutex<String>>
is_release
bool
is_standalone
bool
integration
Integration
dir
PathBuf
spinners
&MultiProgress
did_build
bool
exec
Arc<Mutex<String>>
is_release
bool
is_standalone
bool
integration
Integration