<commit_before>#[macro_use]
extern crate imgui;

extern crate stratis_server as server;
extern crate stratis_shared as shared;

use shared::client::{Client};
use shared::events::Event;
use shared::interface::Interface;

use imgui::{Ui,ImString,ImStr};

use std::thread;
use std::sync::mpsc::{Receiver};
use std::sync::{Arc, Mutex};

#[allow(unused_must_use,unused_variables,unused_assignments)]
fn main() {
    let ip_addr = "127.0.0.1:9996";

    // load in client and connect to server
    let client;
    let rx: Receiver<Event>;
    if let Some((mut c, rx_)) = Client::load_file("client.key") { //assumes client key is an admin user
        c.connect(ip_addr);
        client = Arc::new(Mutex::new(c));
        rx = rx_;
        Client::login(&client);
    }
    else {
        let (mut c, rx_) = Client::default();
        Client::save(&c,"client.key");
        c.connect(ip_addr);
        c.register();
        client = Arc::new(Mutex::new(c));
        rx = rx_;
        Client::login(&client);
    }

    let handler = client.clone();
    thread::spawn(move || {
        Client::handler(handler); // TODO: match server handler call syntax
    });

    let mut ifc = Interface::init("stratis console", [800,600]);
    let mut app = AppState::default();

    'main: loop {
        if !ifc.render(None, |ui| {
            let client = &*client.lock().expect("Client mutex poisoned");
            app.render(&ui,
                       client);
        }) { break 'main }

        ifc.maybe_sleep()
    }
}

struct AppState {
    player_idx: i32,
}

impl Default for AppState {
    fn default() -> AppState {
        AppState {
            player_idx: -1,
        }
    }
}

impl AppState {
    fn render(&mut self, ui: &Ui, client: &Client) {
        ui.main_menu_bar(|| {
            ui.menu(im_str!("Connected:{:?}",client.stream.is_some()))
                .enabled(false)
                .build(|| {})
        });

        ui.window(im_str!("Players"))
            .build(|| {
                let players: Vec<ImString> =
                    client.player_cache.iter().map(|p| {
                        im_str!("{:}", p.0).to_owned()
                    }).collect();

                let players: Vec<&ImStr> = players.iter().map(|p|p.as_ref()).collect();

                ui.list_box(im_str!("UIDS"),
                            &mut self.player_idx,
                            &players[..],
                            50i32);
            });
    }
}
<commit_msg>remove unused<commit_after>#[macro_use]
extern crate imgui;

extern crate stratis_server as server;
extern crate stratis_shared as shared;

use shared::client::{Client};
use shared::events::Event;
use shared::interface::Interface;

use imgui::{Ui,ImString,ImStr};

use std::sync::mpsc::{Receiver};
use std::sync::{Arc, Mutex};

#[allow(unused_must_use,unused_variables,unused_assignments)]
fn main() {
    let ip_addr = "127.0.0.1:9996";

    // load in client and connect to server
    let client;
    let rx: Receiver<Event>;
    if let Some((mut c, rx_)) = Client::load_file("client.key") { //assumes client key is an admin user
        c.connect(ip_addr);
        client = Arc::new(Mutex::new(c));
        rx = rx_;
        Client::login(&client);
    }
    else {
        let (mut c, rx_) = Client::default();
        Client::save(&c,"client.key");
        c.connect(ip_addr);
        c.register();
        client = Arc::new(Mutex::new(c));
        rx = rx_;
        Client::login(&client);
    }

    let mut ifc = Interface::init("stratis console", [800,600]);
    let mut app = AppState::default();

    'main: loop {
        if !ifc.render(None, |ui| {
            let client = &*client.lock().expect("Client mutex poisoned");
            app.render(&ui,
                       client);
        }) { break 'main }

        ifc.maybe_sleep()
    }
}

struct AppState {
    player_idx: i32,
}

impl Default for AppState {
    fn default() -> AppState {
        AppState {
            player_idx: -1,
        }
    }
}

impl AppState {
    fn render(&mut self, ui: &Ui, client: &Client) {
        ui.main_menu_bar(|| {
            ui.menu(im_str!("Connected:{:?}",client.stream.is_some()))
                .enabled(false)
                .build(|| {})
        });

        ui.window(im_str!("Players"))
            .build(|| {
                let players: Vec<ImString> =
                    client.player_cache.iter().map(|p| {
                        im_str!("{:}", p.0).to_owned()
                    }).collect();

                let players: Vec<&ImStr> = players.iter().map(|p|p.as_ref()).collect();

                ui.list_box(im_str!("UIDS"),
                            &mut self.player_idx,
                            &players[..],
                            50i32);
            });
    }
}
<|endoftext|>


<commit_before>//! Handle process life-time and message passing for proc-macro client

use crossbeam_channel::{bounded, Receiver, Sender};
use ra_tt::Subtree;

use crate::msg::{ErrorCode, Message, Request, Response, ResponseError};
use crate::rpc::{ExpansionResult, ExpansionTask, ListMacrosResult, ListMacrosTask, ProcMacroKind};

use io::{BufRead, BufReader};
use std::{
    convert::{TryFrom, TryInto},
    ffi::OsStr,
    io::{self, Write},
    path::{Path, PathBuf},
    process::{Child, Command, Stdio},
    sync::{Arc, Weak},
};

#[derive(Debug, Default)]
pub(crate) struct ProcMacroProcessSrv {
    inner: Option<Weak<Sender<Task>>>,
}

#[derive(Debug)]
pub(crate) struct ProcMacroProcessThread {
    // XXX: drop order is significant
    sender: Arc<Sender<Task>>,
    handle: jod_thread::JoinHandle<()>,
}

struct Task {
    req: Request,
    result_tx: Sender<Option<Response>>,
}

struct Process {
    path: PathBuf,
    child: Child,
}

impl Drop for Process {
    fn drop(&mut self) {
        let _ = self.child.kill();
    }
}

impl Process {
    fn run(
        process_path: PathBuf,
        args: impl IntoIterator<Item = impl AsRef<OsStr>>,
    ) -> Result<Process, io::Error> {
        let child = Command::new(&process_path)
            .args(args)
            .stdin(Stdio::piped())
            .stdout(Stdio::piped())
            .stderr(Stdio::null())
            .spawn()?;

        Ok(Process { path: process_path, child })
    }

    fn restart(&mut self) -> Result<(), io::Error> {
        let _ = self.child.kill();
        self.child = Command::new(&self.path)
            .stdin(Stdio::piped())
            .stdout(Stdio::piped())
            .stderr(Stdio::null())
            .spawn()?;
        Ok(())
    }

    fn stdio(&mut self) -> Option<(impl Write, impl BufRead)> {
        let stdin = self.child.stdin.take()?;
        let stdout = self.child.stdout.take()?;
        let read = BufReader::new(stdout);

        Some((stdin, read))
    }
}

impl ProcMacroProcessSrv {
    pub fn run(
        process_path: PathBuf,
        args: impl IntoIterator<Item = impl AsRef<OsStr>>,
    ) -> io::Result<(ProcMacroProcessThread, ProcMacroProcessSrv)> {
        let process = Process::run(process_path, args)?;

        let (task_tx, task_rx) = bounded(0);
        let handle = jod_thread::spawn(move || {
            client_loop(task_rx, process);
        });

        let task_tx = Arc::new(task_tx);
        let srv = ProcMacroProcessSrv { inner: Some(Arc::downgrade(&task_tx)) };
        let thread = ProcMacroProcessThread { handle, sender: task_tx };

        Ok((thread, srv))
    }

    pub fn find_proc_macros(
        &self,
        dylib_path: &Path,
    ) -> Result<Vec<(String, ProcMacroKind)>, ra_tt::ExpansionError> {
        let task = ListMacrosTask { lib: dylib_path.to_path_buf() };

        let result: ListMacrosResult = self.send_task(Request::ListMacro(task))?;
        Ok(result.macros)
    }

    pub fn custom_derive(
        &self,
        dylib_path: &Path,
        subtree: &Subtree,
        derive_name: &str,
    ) -> Result<Subtree, ra_tt::ExpansionError> {
        let task = ExpansionTask {
            macro_body: subtree.clone(),
            macro_name: derive_name.to_string(),
            attributes: None,
            lib: dylib_path.to_path_buf(),
        };

        let result: ExpansionResult = self.send_task(Request::ExpansionMacro(task))?;
        Ok(result.expansion)
    }

    pub fn send_task<R>(&self, req: Request) -> Result<R, ra_tt::ExpansionError>
    where
        R: TryFrom<Response, Error = &'static str>,
    {
        let sender = match &self.inner {
            None => return Err(ra_tt::ExpansionError::Unknown("No sender is found.".to_string())),
            Some(it) => it,
        };

        let (result_tx, result_rx) = bounded(0);
        let sender = match sender.upgrade() {
            None => {
                return Err(ra_tt::ExpansionError::Unknown("Proc macro process is closed.".into()))
            }
            Some(it) => it,
        };
        sender.send(Task { req: req.into(), result_tx }).unwrap();
        let res = result_rx
            .recv()
            .map_err(|_| ra_tt::ExpansionError::Unknown("Proc macro thread is closed.".into()))?;

        match res {
            Some(Response::Error(err)) => {
                return Err(ra_tt::ExpansionError::ExpansionError(err.message));
            }
            Some(res) => Ok(res.try_into().map_err(|err| {
                ra_tt::ExpansionError::Unknown(format!(
                    "Fail to get response, reason : {:#?} ",
                    err
                ))
            })?),
            None => Err(ra_tt::ExpansionError::Unknown("Empty result".into())),
        }
    }
}

fn client_loop(task_rx: Receiver<Task>, mut process: Process) {
    let (mut stdin, mut stdout) = match process.stdio() {
        None => return,
        Some(it) => it,
    };

    for task in task_rx {
        let Task { req, result_tx } = task;

        match send_request(&mut stdin, &mut stdout, req) {
            Ok(res) => result_tx.send(res).unwrap(),
            Err(_err) => {
                let res = Response::Error(ResponseError {
                    code: ErrorCode::ServerErrorEnd,
                    message: "Server closed".into(),
                });
                result_tx.send(res.into()).unwrap();
                // Restart the process
                if process.restart().is_err() {
                    break;
                }
                let stdio = match process.stdio() {
                    None => break,
                    Some(it) => it,
                };
                stdin = stdio.0;
                stdout = stdio.1;
            }
        }
    }
}

fn send_request(
    mut writer: &mut impl Write,
    mut reader: &mut impl BufRead,
    req: Request,
) -> Result<Option<Response>, io::Error> {
    req.write(&mut writer)?;
    Ok(Response::read(&mut reader)?)
}
<commit_msg>Migrate to Result<T, io::Error> -> io::Result<T><commit_after>//! Handle process life-time and message passing for proc-macro client

use crossbeam_channel::{bounded, Receiver, Sender};
use ra_tt::Subtree;

use crate::msg::{ErrorCode, Message, Request, Response, ResponseError};
use crate::rpc::{ExpansionResult, ExpansionTask, ListMacrosResult, ListMacrosTask, ProcMacroKind};

use io::{BufRead, BufReader};
use std::{
    convert::{TryFrom, TryInto},
    ffi::OsStr,
    io::{self, Write},
    path::{Path, PathBuf},
    process::{Child, Command, Stdio},
    sync::{Arc, Weak},
};

#[derive(Debug, Default)]
pub(crate) struct ProcMacroProcessSrv {
    inner: Option<Weak<Sender<Task>>>,
}

#[derive(Debug)]
pub(crate) struct ProcMacroProcessThread {
    // XXX: drop order is significant
    sender: Arc<Sender<Task>>,
    handle: jod_thread::JoinHandle<()>,
}

struct Task {
    req: Request,
    result_tx: Sender<Option<Response>>,
}

struct Process {
    path: PathBuf,
    child: Child,
}

impl Drop for Process {
    fn drop(&mut self) {
        let _ = self.child.kill();
    }
}

impl Process {
    fn run(
        process_path: PathBuf,
        args: impl IntoIterator<Item = impl AsRef<OsStr>>,
    ) -> io::Result<Process> {
        let child = Command::new(&process_path)
            .args(args)
            .stdin(Stdio::piped())
            .stdout(Stdio::piped())
            .stderr(Stdio::null())
            .spawn()?;

        Ok(Process { path: process_path, child })
    }

    fn restart(&mut self) -> io::Result<()> {
        let _ = self.child.kill();
        self.child = Command::new(&self.path)
            .stdin(Stdio::piped())
            .stdout(Stdio::piped())
            .stderr(Stdio::null())
            .spawn()?;
        Ok(())
    }

    fn stdio(&mut self) -> Option<(impl Write, impl BufRead)> {
        let stdin = self.child.stdin.take()?;
        let stdout = self.child.stdout.take()?;
        let read = BufReader::new(stdout);

        Some((stdin, read))
    }
}

impl ProcMacroProcessSrv {
    pub fn run(
        process_path: PathBuf,
        args: impl IntoIterator<Item = impl AsRef<OsStr>>,
    ) -> io::Result<(ProcMacroProcessThread, ProcMacroProcessSrv)> {
        let process = Process::run(process_path, args)?;

        let (task_tx, task_rx) = bounded(0);
        let handle = jod_thread::spawn(move || {
            client_loop(task_rx, process);
        });

        let task_tx = Arc::new(task_tx);
        let srv = ProcMacroProcessSrv { inner: Some(Arc::downgrade(&task_tx)) };
        let thread = ProcMacroProcessThread { handle, sender: task_tx };

        Ok((thread, srv))
    }

    pub fn find_proc_macros(
        &self,
        dylib_path: &Path,
    ) -> Result<Vec<(String, ProcMacroKind)>, ra_tt::ExpansionError> {
        let task = ListMacrosTask { lib: dylib_path.to_path_buf() };

        let result: ListMacrosResult = self.send_task(Request::ListMacro(task))?;
        Ok(result.macros)
    }

    pub fn custom_derive(
        &self,
        dylib_path: &Path,
        subtree: &Subtree,
        derive_name: &str,
    ) -> Result<Subtree, ra_tt::ExpansionError> {
        let task = ExpansionTask {
            macro_body: subtree.clone(),
            macro_name: derive_name.to_string(),
            attributes: None,
            lib: dylib_path.to_path_buf(),
        };

        let result: ExpansionResult = self.send_task(Request::ExpansionMacro(task))?;
        Ok(result.expansion)
    }

    pub fn send_task<R>(&self, req: Request) -> Result<R, ra_tt::ExpansionError>
    where
        R: TryFrom<Response, Error = &'static str>,
    {
        let sender = match &self.inner {
            None => return Err(ra_tt::ExpansionError::Unknown("No sender is found.".to_string())),
            Some(it) => it,
        };

        let (result_tx, result_rx) = bounded(0);
        let sender = match sender.upgrade() {
            None => {
                return Err(ra_tt::ExpansionError::Unknown("Proc macro process is closed.".into()))
            }
            Some(it) => it,
        };
        sender.send(Task { req: req.into(), result_tx }).unwrap();
        let res = result_rx
            .recv()
            .map_err(|_| ra_tt::ExpansionError::Unknown("Proc macro thread is closed.".into()))?;

        match res {
            Some(Response::Error(err)) => {
                return Err(ra_tt::ExpansionError::ExpansionError(err.message));
            }
            Some(res) => Ok(res.try_into().map_err(|err| {
                ra_tt::ExpansionError::Unknown(format!(
                    "Fail to get response, reason : {:#?} ",
                    err
                ))
            })?),
            None => Err(ra_tt::ExpansionError::Unknown("Empty result".into())),
        }
    }
}

fn client_loop(task_rx: Receiver<Task>, mut process: Process) {
    let (mut stdin, mut stdout) = match process.stdio() {
        None => return,
        Some(it) => it,
    };

    for task in task_rx {
        let Task { req, result_tx } = task;

        match send_request(&mut stdin, &mut stdout, req) {
            Ok(res) => result_tx.send(res).unwrap(),
            Err(_err) => {
                let res = Response::Error(ResponseError {
                    code: ErrorCode::ServerErrorEnd,
                    message: "Server closed".into(),
                });
                result_tx.send(res.into()).unwrap();
                // Restart the process
                if process.restart().is_err() {
                    break;
                }
                let stdio = match process.stdio() {
                    None => break,
                    Some(it) => it,
                };
                stdin = stdio.0;
                stdout = stdio.1;
            }
        }
    }
}

fn send_request(
    mut writer: &mut impl Write,
    mut reader: &mut impl BufRead,
    req: Request,
) -> io::Result<Option<Response>> {
    req.write(&mut writer)?;
    Ok(Response::read(&mut reader)?)
}
<|endoftext|>


<commit_before>use std::fs::{self, File};
use std::io::prelude::*;
use std::env;
use tempdir::TempDir;

use support::{execs, paths, cargo_dir};
use support::paths::CargoPathExt;
use hamcrest::{assert_that, existing_file, existing_dir, is_not};

use cargo::util::{process, ProcessBuilder};

fn setup() {
}

fn my_process(s: &str) -> ProcessBuilder {
    let mut p = process(s).unwrap();
    p.cwd(&paths::root()).env("HOME", &paths::home());
    return p;
}

fn cargo_process(s: &str) -> ProcessBuilder {
    let mut p = process(&cargo_dir().join("cargo")).unwrap();
    p.arg(s).cwd(&paths::root()).env("HOME", &paths::home());
    return p;
}

test!(simple_lib {
    assert_that(cargo_process("new").arg("foo").arg("--vcs").arg("none")
                                    .env("USER", "foo"),
                execs().with_status(0));

    assert_that(&paths::root().join("foo"), existing_dir());
    assert_that(&paths::root().join("foo/Cargo.toml"), existing_file());
    assert_that(&paths::root().join("foo/src/lib.rs"), existing_file());
    assert_that(&paths::root().join("foo/.gitignore"), is_not(existing_file()));

    assert_that(cargo_process("build").cwd(&paths::root().join("foo")),
                execs().with_status(0));
});

test!(simple_bin {
    assert_that(cargo_process("new").arg("foo").arg("--bin")
                                    .env("USER", "foo"),
                execs().with_status(0));

    assert_that(&paths::root().join("foo"), existing_dir());
    assert_that(&paths::root().join("foo/Cargo.toml"), existing_file());
    assert_that(&paths::root().join("foo/src/main.rs"), existing_file());

    assert_that(cargo_process("build").cwd(&paths::root().join("foo")),
                execs().with_status(0));
    assert_that(&paths::root().join(&format!("foo/target/debug/foo{}",
                                             env::consts::EXE_SUFFIX)),
                existing_file());
});

test!(simple_git {
    let td = TempDir::new("cargo").unwrap();
    assert_that(cargo_process("new").arg("foo").cwd(td.path().clone())
                                    .env("USER", "foo"),
                execs().with_status(0));

    assert_that(td.path(), existing_dir());
    assert_that(&td.path().join("foo/Cargo.toml"), existing_file());
    assert_that(&td.path().join("foo/src/lib.rs"), existing_file());
    assert_that(&td.path().join("foo/.git"), existing_dir());
    assert_that(&td.path().join("foo/.gitignore"), existing_file());

    assert_that(cargo_process("build").cwd(&td.path().clone().join("foo")),
                execs().with_status(0));
});

test!(no_argument {
    assert_that(cargo_process("new"),
                execs().with_status(1)
                       .with_stderr("\
Invalid arguments.

Usage:
    cargo new [options] <path>
    cargo new -h | --help
"));
});

test!(existing {
    let dst = paths::root().join("foo");
    fs::create_dir(&dst).unwrap();
    assert_that(cargo_process("new").arg("foo"),
                execs().with_status(101)
                       .with_stderr(format!("Destination `{}` already exists\n",
                                            dst.display())));
});

test!(invalid_characters {
    assert_that(cargo_process("new").arg("foo.rs"),
                execs().with_status(101)
                       .with_stderr("Invalid character `.` in crate name: `foo.rs`"));
});

test!(rust_prefix_stripped {
    assert_that(cargo_process("new").arg("rust-foo").env("USER", "foo"),
                execs().with_status(0)
                       .with_stdout("note: package will be named `foo`; use --name to override"));
    let toml = paths::root().join("rust-foo/Cargo.toml");
    let mut contents = String::new();
    File::open(&toml).unwrap().read_to_string(&mut contents).unwrap();
    assert!(contents.contains(r#"name = "foo""#));
});

test!(bin_disables_stripping {
    assert_that(cargo_process("new").arg("rust-foo").arg("--bin").env("USER", "foo"),
                execs().with_status(0));
    let toml = paths::root().join("rust-foo/Cargo.toml");
    let mut contents = String::new();
    File::open(&toml).unwrap().read_to_string(&mut contents).unwrap();
    assert!(contents.contains(r#"name = "rust-foo""#));
});

test!(explicit_name_not_stripped {
    assert_that(cargo_process("new").arg("foo").arg("--name").arg("rust-bar").env("USER", "foo"),
                execs().with_status(0));
    let toml = paths::root().join("foo/Cargo.toml");
    let mut contents = String::new();
    File::open(&toml).unwrap().read_to_string(&mut contents).unwrap();
    assert!(contents.contains(r#"name = "rust-bar""#));
});

test!(finds_author_user {
    // Use a temp dir to make sure we don't pick up .cargo/config somewhere in
    // the hierarchy
    let td = TempDir::new("cargo").unwrap();
    assert_that(cargo_process("new").arg("foo").env("USER", "foo")
                                    .cwd(td.path().clone()),
                execs().with_status(0));

    let toml = td.path().join("foo/Cargo.toml");
    let mut contents = String::new();
    File::open(&toml).unwrap().read_to_string(&mut contents).unwrap();
    assert!(contents.contains(r#"authors = ["foo"]"#));
});

test!(finds_author_user_escaped {
    // Use a temp dir to make sure we don't pick up .cargo/config somewhere in
    // the hierarchy
    let td = TempDir::new("cargo").unwrap();
    assert_that(cargo_process("new").arg("foo").env("USER", "foo \"bar\"")
                                    .cwd(td.path().clone()),
                execs().with_status(0));

    let toml = td.path().join("foo/Cargo.toml");
    let mut contents = String::new();
    File::open(&toml).unwrap().read_to_string(&mut contents).unwrap();
    assert!(contents.contains(r#"authors = ["foo \"bar\""]"#));
});

test!(finds_author_username {
    // Use a temp dir to make sure we don't pick up .cargo/config somewhere in
    // the hierarchy
    let td = TempDir::new("cargo").unwrap();
    assert_that(cargo_process("new").arg("foo")
                                    .env_remove("USER")
                                    .env("USERNAME", "foo")
                                    .cwd(td.path().clone()),
                execs().with_status(0));

    let toml = td.path().join("foo/Cargo.toml");
    let mut contents = String::new();
    File::open(&toml).unwrap().read_to_string(&mut contents).unwrap();
    assert!(contents.contains(r#"authors = ["foo"]"#));
});

test!(finds_author_git {
    my_process("git").args(&["config", "--global", "user.name", "bar"])
                     .exec().unwrap();
    my_process("git").args(&["config", "--global", "user.email", "baz"])
                     .exec().unwrap();
    assert_that(cargo_process("new").arg("foo").env("USER", "foo"),
                execs().with_status(0));

    let toml = paths::root().join("foo/Cargo.toml");
    let mut contents = String::new();
    File::open(&toml).unwrap().read_to_string(&mut contents).unwrap();
    assert!(contents.contains(r#"authors = ["bar <baz>"]"#));
});

test!(author_prefers_cargo {
    my_process("git").args(&["config", "--global", "user.name", "bar"])
                     .exec().unwrap();
    my_process("git").args(&["config", "--global", "user.email", "baz"])
                     .exec().unwrap();
    let root = paths::root();
    fs::create_dir(&root.join(".cargo")).unwrap();
    File::create(&root.join(".cargo/config")).unwrap().write_all(br#"
        [cargo-new]
        name = "new-foo"
        email = "new-bar"
        git = false
    "#).unwrap();

    assert_that(cargo_process("new").arg("foo").env("USER", "foo"),
                execs().with_status(0));

    let toml = paths::root().join("foo/Cargo.toml");
    let mut contents = String::new();
    File::open(&toml).unwrap().read_to_string(&mut contents).unwrap();
    assert!(contents.contains(r#"authors = ["new-foo <new-bar>"]"#));
    assert!(!root.join("foo/.gitignore").c_exists());
});

test!(git_prefers_command_line {
    let root = paths::root();
    let td = TempDir::new("cargo").unwrap();
    fs::create_dir(&root.join(".cargo")).unwrap();
    File::create(&root.join(".cargo/config")).unwrap().write_all(br#"
        [cargo-new]
        vcs = "none"
        name = "foo"
        email = "bar"
    "#).unwrap();

    assert_that(cargo_process("new").arg("foo").arg("--vcs").arg("git")
                                    .cwd(td.path())
                                    .env("USER", "foo"),
                execs().with_status(0));
    assert!(td.path().join("foo/.gitignore").c_exists());
});

test!(subpackage_no_git {
    assert_that(cargo_process("new").arg("foo").env("USER", "foo"),
                execs().with_status(0));

    let subpackage = paths::root().join("foo").join("components");
    fs::create_dir(&subpackage).unwrap();
    assert_that(cargo_process("new").arg("foo/components/subcomponent")
                                    .env("USER", "foo"),
                execs().with_status(0));

    assert_that(&paths::root().join("foo/components/subcomponent/.git"),
                 is_not(existing_file()));
    assert_that(&paths::root().join("foo/components/subcomponent/.gitignore"),
                 is_not(existing_file()));
});

test!(unknown_flags {
    assert_that(cargo_process("new").arg("foo").arg("--flag"),
                execs().with_status(1)
                       .with_stderr("\
Unknown flag: '--flag'

Usage:
    cargo new [..]
    cargo new [..]
"));
});
<commit_msg>Auto merge of #1756 - tshepang:match-names-below, r=alexcrichton<commit_after>use std::fs::{self, File};
use std::io::prelude::*;
use std::env;
use tempdir::TempDir;

use support::{execs, paths, cargo_dir};
use support::paths::CargoPathExt;
use hamcrest::{assert_that, existing_file, existing_dir, is_not};

use cargo::util::{process, ProcessBuilder};

fn setup() {
}

fn my_process(s: &str) -> ProcessBuilder {
    let mut p = process(s).unwrap();
    p.cwd(&paths::root()).env("HOME", &paths::home());
    return p;
}

fn cargo_process(s: &str) -> ProcessBuilder {
    let mut p = process(&cargo_dir().join("cargo")).unwrap();
    p.arg(s).cwd(&paths::root()).env("HOME", &paths::home());
    return p;
}

test!(simple_lib {
    assert_that(cargo_process("new").arg("foo").arg("--vcs").arg("none")
                                    .env("USER", "foo"),
                execs().with_status(0));

    assert_that(&paths::root().join("foo"), existing_dir());
    assert_that(&paths::root().join("foo/Cargo.toml"), existing_file());
    assert_that(&paths::root().join("foo/src/lib.rs"), existing_file());
    assert_that(&paths::root().join("foo/.gitignore"), is_not(existing_file()));

    assert_that(cargo_process("build").cwd(&paths::root().join("foo")),
                execs().with_status(0));
});

test!(simple_bin {
    assert_that(cargo_process("new").arg("foo").arg("--bin")
                                    .env("USER", "foo"),
                execs().with_status(0));

    assert_that(&paths::root().join("foo"), existing_dir());
    assert_that(&paths::root().join("foo/Cargo.toml"), existing_file());
    assert_that(&paths::root().join("foo/src/main.rs"), existing_file());

    assert_that(cargo_process("build").cwd(&paths::root().join("foo")),
                execs().with_status(0));
    assert_that(&paths::root().join(&format!("foo/target/debug/foo{}",
                                             env::consts::EXE_SUFFIX)),
                existing_file());
});

test!(simple_git {
    let td = TempDir::new("cargo").unwrap();
    assert_that(cargo_process("new").arg("foo").cwd(td.path().clone())
                                    .env("USER", "foo"),
                execs().with_status(0));

    assert_that(td.path(), existing_dir());
    assert_that(&td.path().join("foo/Cargo.toml"), existing_file());
    assert_that(&td.path().join("foo/src/lib.rs"), existing_file());
    assert_that(&td.path().join("foo/.git"), existing_dir());
    assert_that(&td.path().join("foo/.gitignore"), existing_file());

    assert_that(cargo_process("build").cwd(&td.path().clone().join("foo")),
                execs().with_status(0));
});

test!(no_argument {
    assert_that(cargo_process("new"),
                execs().with_status(1)
                       .with_stderr("\
Invalid arguments.

Usage:
    cargo new [options] <path>
    cargo new -h | --help
"));
});

test!(existing {
    let dst = paths::root().join("foo");
    fs::create_dir(&dst).unwrap();
    assert_that(cargo_process("new").arg("foo"),
                execs().with_status(101)
                       .with_stderr(format!("Destination `{}` already exists\n",
                                            dst.display())));
});

test!(invalid_characters {
    assert_that(cargo_process("new").arg("foo.rs"),
                execs().with_status(101)
                       .with_stderr("Invalid character `.` in crate name: `foo.rs`"));
});

test!(rust_prefix_stripped {
    assert_that(cargo_process("new").arg("rust-foo").env("USER", "foo"),
                execs().with_status(0)
                       .with_stdout("note: package will be named `foo`; use --name to override"));
    let toml = paths::root().join("rust-foo/Cargo.toml");
    let mut contents = String::new();
    File::open(&toml).unwrap().read_to_string(&mut contents).unwrap();
    assert!(contents.contains(r#"name = "foo""#));
});

test!(bin_disables_stripping {
    assert_that(cargo_process("new").arg("rust-foo").arg("--bin").env("USER", "foo"),
                execs().with_status(0));
    let toml = paths::root().join("rust-foo/Cargo.toml");
    let mut contents = String::new();
    File::open(&toml).unwrap().read_to_string(&mut contents).unwrap();
    assert!(contents.contains(r#"name = "rust-foo""#));
});

test!(explicit_name_not_stripped {
    assert_that(cargo_process("new").arg("foo").arg("--name").arg("rust-bar").env("USER", "foo"),
                execs().with_status(0));
    let toml = paths::root().join("foo/Cargo.toml");
    let mut contents = String::new();
    File::open(&toml).unwrap().read_to_string(&mut contents).unwrap();
    assert!(contents.contains(r#"name = "rust-bar""#));
});

test!(finds_author_user {
    // Use a temp dir to make sure we don't pick up .cargo/config somewhere in
    // the hierarchy
    let td = TempDir::new("cargo").unwrap();
    assert_that(cargo_process("new").arg("foo").env("USER", "foo")
                                    .cwd(td.path().clone()),
                execs().with_status(0));

    let toml = td.path().join("foo/Cargo.toml");
    let mut contents = String::new();
    File::open(&toml).unwrap().read_to_string(&mut contents).unwrap();
    assert!(contents.contains(r#"authors = ["foo"]"#));
});

test!(finds_author_user_escaped {
    // Use a temp dir to make sure we don't pick up .cargo/config somewhere in
    // the hierarchy
    let td = TempDir::new("cargo").unwrap();
    assert_that(cargo_process("new").arg("foo").env("USER", "foo \"bar\"")
                                    .cwd(td.path().clone()),
                execs().with_status(0));

    let toml = td.path().join("foo/Cargo.toml");
    let mut contents = String::new();
    File::open(&toml).unwrap().read_to_string(&mut contents).unwrap();
    assert!(contents.contains(r#"authors = ["foo \"bar\""]"#));
});

test!(finds_author_username {
    // Use a temp dir to make sure we don't pick up .cargo/config somewhere in
    // the hierarchy
    let td = TempDir::new("cargo").unwrap();
    assert_that(cargo_process("new").arg("foo")
                                    .env_remove("USER")
                                    .env("USERNAME", "foo")
                                    .cwd(td.path().clone()),
                execs().with_status(0));

    let toml = td.path().join("foo/Cargo.toml");
    let mut contents = String::new();
    File::open(&toml).unwrap().read_to_string(&mut contents).unwrap();
    assert!(contents.contains(r#"authors = ["foo"]"#));
});

test!(finds_author_git {
    my_process("git").args(&["config", "--global", "user.name", "bar"])
                     .exec().unwrap();
    my_process("git").args(&["config", "--global", "user.email", "baz"])
                     .exec().unwrap();
    assert_that(cargo_process("new").arg("foo").env("USER", "foo"),
                execs().with_status(0));

    let toml = paths::root().join("foo/Cargo.toml");
    let mut contents = String::new();
    File::open(&toml).unwrap().read_to_string(&mut contents).unwrap();
    assert!(contents.contains(r#"authors = ["bar <baz>"]"#));
});

test!(author_prefers_cargo {
    my_process("git").args(&["config", "--global", "user.name", "foo"])
                     .exec().unwrap();
    my_process("git").args(&["config", "--global", "user.email", "bar"])
                     .exec().unwrap();
    let root = paths::root();
    fs::create_dir(&root.join(".cargo")).unwrap();
    File::create(&root.join(".cargo/config")).unwrap().write_all(br#"
        [cargo-new]
        name = "new-foo"
        email = "new-bar"
        git = false
    "#).unwrap();

    assert_that(cargo_process("new").arg("foo").env("USER", "foo"),
                execs().with_status(0));

    let toml = paths::root().join("foo/Cargo.toml");
    let mut contents = String::new();
    File::open(&toml).unwrap().read_to_string(&mut contents).unwrap();
    assert!(contents.contains(r#"authors = ["new-foo <new-bar>"]"#));
    assert!(!root.join("foo/.gitignore").c_exists());
});

test!(git_prefers_command_line {
    let root = paths::root();
    let td = TempDir::new("cargo").unwrap();
    fs::create_dir(&root.join(".cargo")).unwrap();
    File::create(&root.join(".cargo/config")).unwrap().write_all(br#"
        [cargo-new]
        vcs = "none"
        name = "foo"
        email = "bar"
    "#).unwrap();

    assert_that(cargo_process("new").arg("foo").arg("--vcs").arg("git")
                                    .cwd(td.path())
                                    .env("USER", "foo"),
                execs().with_status(0));
    assert!(td.path().join("foo/.gitignore").c_exists());
});

test!(subpackage_no_git {
    assert_that(cargo_process("new").arg("foo").env("USER", "foo"),
                execs().with_status(0));

    let subpackage = paths::root().join("foo").join("components");
    fs::create_dir(&subpackage).unwrap();
    assert_that(cargo_process("new").arg("foo/components/subcomponent")
                                    .env("USER", "foo"),
                execs().with_status(0));

    assert_that(&paths::root().join("foo/components/subcomponent/.git"),
                 is_not(existing_file()));
    assert_that(&paths::root().join("foo/components/subcomponent/.gitignore"),
                 is_not(existing_file()));
});

test!(unknown_flags {
    assert_that(cargo_process("new").arg("foo").arg("--flag"),
                execs().with_status(1)
                       .with_stderr("\
Unknown flag: '--flag'

Usage:
    cargo new [..]
    cargo new [..]
"));
});
<|endoftext|>


<commit_before>// Copyright 2018 Syn Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![cfg(feature = "extra-traits")]

extern crate proc_macro2;
extern crate syn;

use proc_macro2::{Literal, Span, TokenStream};
use syn::buffer::TokenBuffer;
use syn::*;

#[macro_use]
mod macros;

fn lit<T: Into<Literal>>(t: T) -> Lit {
    Lit::new(t.into())
}

#[test]
fn test_meta_item_word() {
    run_test("#[foo]", Meta::Word("foo".into()))
}

#[test]
fn test_meta_item_name_value() {
    run_test(
        "#[foo = 5]",
        MetaNameValue {
            ident: "foo".into(),
            eq_token: Default::default(),
            lit: lit(Literal::i32_unsuffixed(5)),
        },
    )
}

#[test]
fn test_meta_item_bool_value() {
    run_test(
        "#[foo = true]",
        MetaNameValue {
            ident: "foo".into(),
            eq_token: Default::default(),
            lit: Lit::Bool(LitBool {
                value: true,
                span: Span::call_site(),
            }),
        },
    );
    run_test(
        "#[foo = false]",
        MetaNameValue {
            ident: "foo".into(),
            eq_token: Default::default(),
            lit: Lit::Bool(LitBool {
                value: false,
                span: Span::call_site(),
            }),
        },
    )
}

#[test]
fn test_meta_item_list_lit() {
    run_test(
        "#[foo(5)]",
        MetaList {
            ident: "foo".into(),
            paren_token: Default::default(),
            nested: punctuated![NestedMeta::Literal(lit(Literal::i32_unsuffixed(5)))],
        },
    )
}

#[test]
fn test_meta_item_list_word() {
    run_test(
        "#[foo(bar)]",
        MetaList {
            ident: "foo".into(),
            paren_token: Default::default(),
            nested: punctuated![NestedMeta::Meta(Meta::Word("bar".into()))],
        },
    )
}

#[test]
fn test_meta_item_list_name_value() {
    run_test(
        "#[foo(bar = 5)]",
        MetaList {
            ident: "foo".into(),
            paren_token: Default::default(),
            nested: punctuated![NestedMeta::Meta(
                MetaNameValue {
                    ident: "bar".into(),
                    eq_token: Default::default(),
                    lit: lit(Literal::i32_unsuffixed(5)),
                }.into(),
            ),],
        },
    )
}

#[test]
fn test_meta_item_list_bool_value() {
    run_test(
        "#[foo(bar = true)]",
        MetaList {
            ident: "foo".into(),
            paren_token: Default::default(),
            nested: punctuated![NestedMeta::Meta(
                MetaNameValue {
                    ident: "bar".into(),
                    eq_token: Default::default(),
                    lit: Lit::Bool(LitBool {
                        value: true,
                        span: Span::call_site()
                    }),
                }.into(),
            ),],
        },
    )
}

#[test]
fn test_meta_item_multiple() {
    run_test(
        "#[foo(word, name = 5, list(name2 = 6), word2)]",
        MetaList {
            ident: "foo".into(),
            paren_token: Default::default(),
            nested: punctuated![
                NestedMeta::Meta(Meta::Word("word".into())),
                NestedMeta::Meta(
                    MetaNameValue {
                        ident: "name".into(),
                        eq_token: Default::default(),
                        lit: lit(Literal::i32_unsuffixed(5)),
                    }.into(),
                ),
                NestedMeta::Meta(
                    MetaList {
                        ident: "list".into(),
                        paren_token: Default::default(),
                        nested: punctuated![NestedMeta::Meta(
                            MetaNameValue {
                                ident: "name2".into(),
                                eq_token: Default::default(),
                                lit: lit(Literal::i32_unsuffixed(6)),
                            }.into(),
                        ),],
                    }.into(),
                ),
                NestedMeta::Meta(Meta::Word("word2".into())),
            ],
        },
    )
}

fn run_test<T: Into<Meta>>(input: &str, expected: T) {
    let tokens = input.parse::<TokenStream>().unwrap();
    let buf = TokenBuffer::new2(tokens);
    let attr = match Attribute::parse_outer(buf.begin()) {
        Ok((e, rest)) => {
            assert!(rest.eof());
            e
        }
        Err(err) => panic!(err),
    };
    assert_eq!(expected.into(), attr.interpret_meta().unwrap());
}
<commit_msg>Fix test_meta_item<commit_after>// Copyright 2018 Syn Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![cfg(feature = "extra-traits")]

extern crate proc_macro2;
extern crate syn;

use proc_macro2::{Literal, Span, TokenStream, Ident};
use syn::buffer::TokenBuffer;
use syn::*;

#[macro_use]
mod macros;

fn lit<T: Into<Literal>>(t: T) -> Lit {
    Lit::new(t.into())
}

fn ident(s: &str) -> Ident {
    Ident::new(s, Span::call_site())
}

#[test]
fn test_meta_item_word() {
    run_test("#[foo]", Meta::Word(ident("foo")))
}

#[test]
fn test_meta_item_name_value() {
    run_test(
        "#[foo = 5]",
        MetaNameValue {
            ident: ident("foo").into(),
            eq_token: Default::default(),
            lit: lit(Literal::i32_unsuffixed(5)),
        },
    )
}

#[test]
fn test_meta_item_bool_value() {
    run_test(
        "#[foo = true]",
        MetaNameValue {
            ident: ident("foo").into(),
            eq_token: Default::default(),
            lit: Lit::Bool(LitBool {
                value: true,
                span: Span::call_site(),
            }),
        },
    );
    run_test(
        "#[foo = false]",
        MetaNameValue {
            ident: ident("foo").into(),
            eq_token: Default::default(),
            lit: Lit::Bool(LitBool {
                value: false,
                span: Span::call_site(),
            }),
        },
    )
}

#[test]
fn test_meta_item_list_lit() {
    run_test(
        "#[foo(5)]",
        MetaList {
            ident: ident("foo").into(),
            paren_token: Default::default(),
            nested: punctuated![NestedMeta::Literal(lit(Literal::i32_unsuffixed(5)))],
        },
    )
}

#[test]
fn test_meta_item_list_word() {
    run_test(
        "#[foo(bar)]",
        MetaList {
            ident: ident("foo").into(),
            paren_token: Default::default(),
            nested: punctuated![NestedMeta::Meta(Meta::Word(ident("bar").into()))],
        },
    )
}

#[test]
fn test_meta_item_list_name_value() {
    run_test(
        "#[foo(bar = 5)]",
        MetaList {
            ident: ident("foo").into(),
            paren_token: Default::default(),
            nested: punctuated![NestedMeta::Meta(
                MetaNameValue {
                    ident: ident("bar").into(),
                    eq_token: Default::default(),
                    lit: lit(Literal::i32_unsuffixed(5)),
                }.into(),
            ),],
        },
    )
}

#[test]
fn test_meta_item_list_bool_value() {
    run_test(
        "#[foo(bar = true)]",
        MetaList {
            ident: ident("foo").into(),
            paren_token: Default::default(),
            nested: punctuated![NestedMeta::Meta(
                MetaNameValue {
                    ident: ident("bar").into(),
                    eq_token: Default::default(),
                    lit: Lit::Bool(LitBool {
                        value: true,
                        span: Span::call_site()
                    }),
                }.into(),
            ),],
        },
    )
}

#[test]
fn test_meta_item_multiple() {
    run_test(
        "#[foo(word, name = 5, list(name2 = 6), word2)]",
        MetaList {
            ident: ident("foo").into(),
            paren_token: Default::default(),
            nested: punctuated![
                NestedMeta::Meta(Meta::Word(ident("word").into())),
                NestedMeta::Meta(
                    MetaNameValue {
                        ident: ident("name").into(),
                        eq_token: Default::default(),
                        lit: lit(Literal::i32_unsuffixed(5)),
                    }.into(),
                ),
                NestedMeta::Meta(
                    MetaList {
                        ident: ident("list").into(),
                        paren_token: Default::default(),
                        nested: punctuated![NestedMeta::Meta(
                            MetaNameValue {
                                ident: ident("name2").into(),
                                eq_token: Default::default(),
                                lit: lit(Literal::i32_unsuffixed(6)),
                            }.into(),
                        ),],
                    }.into(),
                ),
                NestedMeta::Meta(Meta::Word(ident("word2").into())),
            ],
        },
    )
}

fn run_test<T: Into<Meta>>(input: &str, expected: T) {
    let tokens = input.parse::<TokenStream>().unwrap();
    let buf = TokenBuffer::new2(tokens);
    let attr = match Attribute::parse_outer(buf.begin()) {
        Ok((e, rest)) => {
            assert!(rest.eof());
            e
        }
        Err(err) => panic!(err),
    };
    assert_eq!(expected.into(), attr.interpret_meta().unwrap());
}
<|endoftext|>


<commit_before>extern crate sdl2;

use sdl2::pixels::Color;
use sdl2::event::Event;
use sdl2::keyboard::Keycode;

fn main()
{
    let context = sdl2::init().unwrap();
    let video = context.video().unwrap();

    let window = video.window("rrthozopsi", 800, 600)
        .position_centered()
        .opengl()
        .build()
        .unwrap();

    let mut renderer = window.renderer().build().unwrap();

    renderer.set_draw_color(Color::RGB(255, 0, 0));
    renderer.clear();
    renderer.present();

    let mut event_pump = context.event_pump().unwrap();

    'running: loop {
        for event in event_pump.poll_iter() {
            match event {
                Event::Quit {..} | Event::KeyDown { keycode: Some(Keycode::Escape), .. } => {
                    break 'running
                },
                _ => {}
            }
        }
    }
}
<commit_msg>minor changes<commit_after>extern crate sdl2;

use sdl2::event::Event;
use sdl2::keyboard::Keycode;

fn main()
{
    let context = sdl2::init().unwrap();
    let video = context.video().unwrap();

    let window = video.window("rrthozopsi", 800, 600)
        .position_centered()
        .opengl()
        .build()
        .unwrap();

    let mut renderer = window.renderer().build().unwrap();

    renderer.set_draw_color(sdl2::pixels::Color::RGB(0, 0, 0));
    renderer.clear();
    renderer.present();

    let mut event_pump = context.event_pump().unwrap();

    'running: loop {
        for event in event_pump.poll_iter() {
            match event {
                Event::Quit {..} | Event::KeyDown { keycode: Some(Keycode::Escape), .. } => {
                    break 'running
                },
                Event::KeyDown {..} => {
                    renderer.set_draw_color(sdl2::pixels::Color::RGB(255, 0, 0));
                    renderer.clear();
                    renderer.present();
                },
                _ => {}
            }
        }
    }
}
<|endoftext|>


<commit_before>use crate::spec::crt_objects::{self, CrtObjectsFallback};
use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions};

pub fn opts() -> TargetOptions {
    let mut pre_link_args = LinkArgs::new();
    pre_link_args.insert(
        LinkerFlavor::Gcc,
        vec![
            // Tell GCC to avoid linker plugins, because we are not bundling
            // them with Windows installer, and Rust does its own LTO anyways.
            "-fno-use-linker-plugin".to_string(),
            // Always enable DEP (NX bit) when it is available
            "-Wl,--nxcompat".to_string(),
        ],
    );

    let mut late_link_args = LinkArgs::new();
    let mut late_link_args_dynamic = LinkArgs::new();
    let mut late_link_args_static = LinkArgs::new();
    late_link_args.insert(
        LinkerFlavor::Gcc,
        vec![
            "-lmingwex".to_string(),
            "-lmingw32".to_string(),
            "-lmsvcrt".to_string(),
            // mingw's msvcrt is a weird hybrid import library and static library.
            // And it seems that the linker fails to use import symbols from msvcrt
            // that are required from functions in msvcrt in certain cases. For example
            // `_fmode` that is used by an implementation of `__p__fmode` in x86_64.
            // Listing the library twice seems to fix that, and seems to also be done
            // by mingw's gcc (Though not sure if it's done on purpose, or by mistake).
            //
            // See https://github.com/rust-lang/rust/pull/47483
            "-lmsvcrt".to_string(),
            "-luser32".to_string(),
            "-lkernel32".to_string(),
        ],
    );
    late_link_args_dynamic.insert(
        LinkerFlavor::Gcc,
        vec![
            // If any of our crates are dynamically linked then we need to use
            // the shared libgcc_s-dw2-1.dll. This is required to support
            // unwinding across DLL boundaries.
            "-lgcc_s".to_string(),
            "-lgcc".to_string(),
            "-lkernel32".to_string(),
        ],
    );
    late_link_args_static.insert(
        LinkerFlavor::Gcc,
        vec![
            // If all of our crates are statically linked then we can get away
            // with statically linking the libgcc unwinding code. This allows
            // binaries to be redistributed without the libgcc_s-dw2-1.dll
            // dependency, but unfortunately break unwinding across DLL
            // boundaries when unwinding across FFI boundaries.
            "-lgcc_eh".to_string(),
            "-l:libpthread.a".to_string(),
            "-lgcc".to_string(),
            // libpthread depends on libmsvcrt, so we need to link it *again*.
            "-lmsvcrt".to_string(),
            "-lkernel32".to_string(),
        ],
    );

    TargetOptions {
        // FIXME(#13846) this should be enabled for windows
        function_sections: false,
        linker: Some("gcc".to_string()),
        dynamic_linking: true,
        executables: true,
        dll_prefix: String::new(),
        dll_suffix: ".dll".to_string(),
        exe_suffix: ".exe".to_string(),
        staticlib_prefix: "lib".to_string(),
        staticlib_suffix: ".a".to_string(),
        target_family: Some("windows".to_string()),
        is_like_windows: true,
        allows_weak_linkage: false,
        pre_link_args,
        pre_link_objects: crt_objects::pre_mingw(),
        post_link_objects: crt_objects::post_mingw(),
        pre_link_objects_fallback: crt_objects::pre_mingw_fallback(),
        post_link_objects_fallback: crt_objects::post_mingw_fallback(),
        crt_objects_fallback: Some(CrtObjectsFallback::Mingw),
        late_link_args,
        late_link_args_dynamic,
        late_link_args_static,
        abi_return_struct_as_int: true,
        emit_debug_gdb_scripts: false,
        requires_uwtable: true,

        ..Default::default()
    }
}
<commit_msg>Rollup merge of #73184 - mati865:fix-mingw-libs-order, r=petrochenkov<commit_after>use crate::spec::crt_objects::{self, CrtObjectsFallback};
use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions};

pub fn opts() -> TargetOptions {
    let mut pre_link_args = LinkArgs::new();
    pre_link_args.insert(
        LinkerFlavor::Gcc,
        vec![
            // Tell GCC to avoid linker plugins, because we are not bundling
            // them with Windows installer, and Rust does its own LTO anyways.
            "-fno-use-linker-plugin".to_string(),
            // Always enable DEP (NX bit) when it is available
            "-Wl,--nxcompat".to_string(),
        ],
    );

    let mut late_link_args = LinkArgs::new();
    let mut late_link_args_dynamic = LinkArgs::new();
    let mut late_link_args_static = LinkArgs::new();
    late_link_args.insert(
        LinkerFlavor::Gcc,
        vec![
            "-lmsvcrt".to_string(),
            "-lmingwex".to_string(),
            "-lmingw32".to_string(),
            // mingw's msvcrt is a weird hybrid import library and static library.
            // And it seems that the linker fails to use import symbols from msvcrt
            // that are required from functions in msvcrt in certain cases. For example
            // `_fmode` that is used by an implementation of `__p__fmode` in x86_64.
            // Listing the library twice seems to fix that, and seems to also be done
            // by mingw's gcc (Though not sure if it's done on purpose, or by mistake).
            //
            // See https://github.com/rust-lang/rust/pull/47483
            "-lmsvcrt".to_string(),
            "-luser32".to_string(),
            "-lkernel32".to_string(),
        ],
    );
    late_link_args_dynamic.insert(
        LinkerFlavor::Gcc,
        vec![
            // If any of our crates are dynamically linked then we need to use
            // the shared libgcc_s-dw2-1.dll. This is required to support
            // unwinding across DLL boundaries.
            "-lgcc_s".to_string(),
            "-lgcc".to_string(),
            "-lkernel32".to_string(),
        ],
    );
    late_link_args_static.insert(
        LinkerFlavor::Gcc,
        vec![
            // If all of our crates are statically linked then we can get away
            // with statically linking the libgcc unwinding code. This allows
            // binaries to be redistributed without the libgcc_s-dw2-1.dll
            // dependency, but unfortunately break unwinding across DLL
            // boundaries when unwinding across FFI boundaries.
            "-lgcc_eh".to_string(),
            "-l:libpthread.a".to_string(),
            "-lgcc".to_string(),
            // libpthread depends on libmsvcrt, so we need to link it *again*.
            "-lmsvcrt".to_string(),
            "-lkernel32".to_string(),
        ],
    );

    TargetOptions {
        // FIXME(#13846) this should be enabled for windows
        function_sections: false,
        linker: Some("gcc".to_string()),
        dynamic_linking: true,
        executables: true,
        dll_prefix: String::new(),
        dll_suffix: ".dll".to_string(),
        exe_suffix: ".exe".to_string(),
        staticlib_prefix: "lib".to_string(),
        staticlib_suffix: ".a".to_string(),
        target_family: Some("windows".to_string()),
        is_like_windows: true,
        allows_weak_linkage: false,
        pre_link_args,
        pre_link_objects: crt_objects::pre_mingw(),
        post_link_objects: crt_objects::post_mingw(),
        pre_link_objects_fallback: crt_objects::pre_mingw_fallback(),
        post_link_objects_fallback: crt_objects::post_mingw_fallback(),
        crt_objects_fallback: Some(CrtObjectsFallback::Mingw),
        late_link_args,
        late_link_args_dynamic,
        late_link_args_static,
        abi_return_struct_as_int: true,
        emit_debug_gdb_scripts: false,
        requires_uwtable: true,

        ..Default::default()
    }
}
<|endoftext|>


<commit_before>// Copyright 2015 Bobby Powers. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#![feature(convert)]

//extern crate libc;
//use libc::geteuid;

use std::fs;

const PROC_PATH: &'static str = "/proc";

struct CmdInfo {
    name: &'static str,
    pss: f32,
    shared: f32,
    heap: f32,
    swap: f32,
}

fn is_digit(d: u8) -> bool {
    d >= ('0' as u8) && d <= ('9' as u8)
}

fn main() {

    // command line flag parsing

    // unsafe {
    // 	let uid = geteuid();
    // 	if uid != 0 {
    // 	    println!("we aren't root");
    // 	}
    // }

    let mut pids: Vec<i32> = vec!();

    // get a list of all pids
    /*let result =*/ match fs::read_dir(PROC_PATH) {
	Err(err) => {
	    println!("read_dir({}): {}", PROC_PATH, err);
	    return;
	},
	Ok(result) => {
	    for entry in result {
		entry.map(|dent| {
		    fs::metadata(dent.path()).map(|md| {
			if md.is_dir() && is_digit(dent.file_name().to_bytes().unwrap()[0]) {
			    let file_name = dent.file_name();
			    let name = file_name.to_str().unwrap();
			    println!("pid: {}", name);
			}
		    });
		})
	    };
	},
    };

    // get details of all pids (possibly in parallel)

    // sort pid details

    // find total

    // print_results

    println!("Hello, world!");
}
<commit_msg>updates to structure of get_pids<commit_after>// Copyright 2015 Bobby Powers. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#![feature(convert)]

//extern crate libc;
//use libc::geteuid;

use std::fs;

const PROC_PATH: &'static str = "/proc";

struct CmdInfo {
    name: &'static str,
    pss: f32,
    shared: f32,
    heap: f32,
    swap: f32,
}

fn is_digit(d: char) -> bool {
    d >= '0' && d <= '9'
}

fn get_pids() -> Vec<i32> {
    let mut pids: Vec<i32> = vec!();

    match fs::read_dir(PROC_PATH) {
	Err(err) => println!("read_dir({}): {}", PROC_PATH, err),
	Ok(result) => for entry in result {
	    match entry {
		Err(_) => (), // ignore
		Ok(dent) => {
		    if !is_digit(dent.file_name().to_str().unwrap().char_at(0)) {
			continue;
		    }
		    match fs::metadata(dent.path()) {
			Err(_) => (), // ignore
			Ok(md) => {
			    if md.is_dir() {
				pids.push(i32::from_str_radix(dent.file_name().to_str().unwrap(), 10).unwrap());
			    }
			}
		    }
		},
	    }
	},
    };

    return pids;
}

fn cmdinfos_for(pids: Vec<i32>) -> Vec<CmdInfo> {
    let mut infos: Vec<CmdInfo> = Vec::with_capacity(pids.len());

    for pid in pids {
	println!("pid: {}", pid);
    }

    return infos;
}

fn main() {

    // command line flag parsing

    // check euid
    // unsafe {
    // 	let uid = geteuid();
    // 	if uid != 0 {
    // 	    println!("we aren't root");
    // 	}
    // }

    let pids = get_pids();

    // get details of all pids (possibly in parallel)
    let infos = cmdinfos_for(pids);

    // sort pid details

    // find total

    // print_results

    println!("Hello, world!");
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

use crate::build_project::{build_project, build_schema, commit_project, BuildProjectFailure};
use crate::compiler_state::{ArtifactMapKind, CompilerState, ProjectName};
use crate::config::Config;
use crate::errors::{BuildProjectError, Error, Result};
use crate::graphql_asts::GraphQLAsts;
use crate::red_to_green::RedToGreen;
use crate::watchman::FileSource;
use common::{DiagnosticsResult, PerfLogEvent, PerfLogger};
use futures::future::join_all;
use log::{error, info};
use rayon::prelude::*;
use schema::Schema;
use std::{collections::HashMap, sync::Arc};
use tokio::{sync::Notify, task};

pub struct Compiler<TPerfLogger>
where
    TPerfLogger: PerfLogger + 'static,
{
    config: Arc<Config>,
    perf_logger: Arc<TPerfLogger>,
}

impl<TPerfLogger: PerfLogger> Compiler<TPerfLogger> {
    pub fn new(config: Config, perf_logger: Arc<TPerfLogger>) -> Self {
        Self {
            config: Arc::new(config),
            perf_logger,
        }
    }

    pub async fn compile(self) -> Result<CompilerState> {
        let setup_event = self.perf_logger.create_event("compiler_setup");

        let file_source = FileSource::connect(&self.config, &setup_event).await?;
        let mut compiler_state = file_source
            .query(&setup_event, self.perf_logger.as_ref())
            .await?;
        self.build_projects(&mut compiler_state, &setup_event)
            .await?;

        self.perf_logger.complete_event(setup_event);
        Ok(compiler_state)
    }

    pub fn build_schemas(
        &self,
        compiler_state: &CompilerState,
        setup_event: &impl PerfLogEvent,
    ) -> DiagnosticsResult<HashMap<ProjectName, Arc<Schema>>> {
        let timer = setup_event.start("build_schemas");
        let mut schemas = HashMap::new();
        for project_config in self.config.enabled_projects() {
            let schema = build_schema(compiler_state, project_config)?;
            schemas.insert(project_config.name, schema);
        }
        setup_event.stop(timer);
        Ok(schemas)
    }

    pub async fn watch(&self) -> Result<()> {
        let setup_event = self.perf_logger.create_event("compiler_setup");

        let file_source = FileSource::connect(&self.config, &setup_event).await?;

        let (mut compiler_state, mut subscription) = file_source
            .subscribe(&setup_event, self.perf_logger.as_ref())
            .await?;

        let mut red_to_green = RedToGreen::new();

        if self
            .build_projects(&mut compiler_state, &setup_event)
            .await
            .is_err()
        {
            // build_projects should have logged already
            red_to_green.log_error()
        } else {
            info!("Compilation completed.");
        }
        self.perf_logger.complete_event(setup_event);
        info!("Waiting for changes...");

        let pending_file_source_changes = compiler_state.pending_file_source_changes.clone();
        let notify_sender = Arc::new(Notify::new());
        let notify_receiver = notify_sender.clone();
        task::spawn(async move {
            loop {
                if let Some(file_source_changes) = subscription.next_change().await.unwrap() {
                    pending_file_source_changes
                        .write()
                        .unwrap()
                        .push(file_source_changes);
                    notify_sender.notify();
                }
            }
        });

        loop {
            notify_receiver.notified().await;
            // Single change to file sometimes produces 2 watchman change events for the same file
            // wait for 50ms in case there is a subsquent request
            tokio::time::delay_for(std::time::Duration::from_millis(50)).await;
            if compiler_state.has_pending_file_source_changes() {
                let incremental_build_event =
                    self.perf_logger.create_event("incremental_build_event");
                let incremental_build_time =
                    incremental_build_event.start("incremental_build_time");

                let had_new_changes = compiler_state.merge_file_source_changes(
                    &self.config,
                    &incremental_build_event,
                    self.perf_logger.as_ref(),
                    false,
                )?;

                if had_new_changes {
                    info!("Change detected, start compiling...");
                    if self
                        .build_projects(&mut compiler_state, &incremental_build_event)
                        .await
                        .is_err()
                    {
                        // build_projects should have logged already
                        red_to_green.log_error()
                    } else {
                        info!("Compilation completed.");
                        red_to_green.clear_error_and_log(self.perf_logger.as_ref());
                    }
                    incremental_build_event.stop(incremental_build_time);
                    info!("Waiting for changes...");
                } else {
                    incremental_build_event.stop(incremental_build_time);
                }
                self.perf_logger.complete_event(incremental_build_event);
                // We probably don't want the messages queue to grow indefinitely
                // and we need to flush then, as the check/build is completed
                self.perf_logger.flush();
            }
        }
    }

    async fn build_projects(
        &self,
        compiler_state: &mut CompilerState,
        setup_event: &impl PerfLogEvent,
    ) -> Result<()> {
        self.config.error_reporter.build_starts();
        let result = build_projects(
            Arc::clone(&self.config),
            Arc::clone(&self.perf_logger),
            setup_event,
            compiler_state,
        )
        .await;
        self.config.error_reporter.build_finishes();
        match result {
            Ok(()) => {
                compiler_state.complete_compilation();
                self.config.artifact_writer.finalize()?;
                if let Some(post_artifacts_write) = &self.config.post_artifacts_write {
                    if let Err(error) = post_artifacts_write(&self.config) {
                        let error = Error::PostArtifactsError { error };
                        error!("{}", error);
                        return Err(error);
                    }
                }
                Ok(())
            }
            Err(error) => {
                match &error {
                    Error::DiagnosticsError { errors } => {
                        for diagnostic in errors {
                            self.config.error_reporter.report_diagnostic(diagnostic);
                        }
                    }
                    Error::BuildProjectsErrors { errors } => {
                        for error in errors {
                            self.print_project_error(error);
                        }
                    }
                    Error::Cancelled => {
                        info!("Compilation cancelled due to new changes.");
                    }
                    error => {
                        error!("{}", error);
                    }
                }
                if !matches!(error, Error::Cancelled) {
                    error!("Compilation failed.");
                }
                Err(error)
            }
        }
    }

    fn print_project_error(&self, error: &BuildProjectError) {
        match error {
            BuildProjectError::ValidationErrors { errors } => {
                for diagnostic in errors {
                    self.config.error_reporter.report_diagnostic(diagnostic);
                }
            }
            BuildProjectError::PersistErrors { errors } => {
                for error in errors {
                    error!("{}", error);
                }
            }
            _ => {
                error!("{}", error);
            }
        }
    }
}

async fn build_projects<TPerfLogger: PerfLogger + 'static>(
    config: Arc<Config>,
    perf_logger: Arc<TPerfLogger>,
    setup_event: &impl PerfLogEvent,
    compiler_state: &mut CompilerState,
) -> Result<()> {
    let mut graphql_asts = setup_event.time("parse_sources_time", || {
        GraphQLAsts::from_graphql_sources_map(
            &compiler_state.graphql_sources,
            &compiler_state.get_dirty_defintions(&config),
        )
    })?;

    if compiler_state.has_pending_file_source_changes() {
        return Err(Error::Cancelled);
    }

    let build_results: Vec<_> = config
        .par_enabled_projects()
        .filter(|project_config| {
            if let Some(base) = project_config.base {
                if compiler_state.project_has_pending_changes(base) {
                    return true;
                }
            }
            compiler_state.project_has_pending_changes(project_config.name)
        })
        .map(|project_config| {
            build_project(
                &config,
                project_config,
                compiler_state,
                &graphql_asts,
                Arc::clone(&perf_logger),
            )
        })
        .collect();
    let mut results = Vec::new();
    let mut errors = Vec::new();
    for result in build_results {
        match result {
            Ok(result) => results.push(result),
            Err(error) => match error {
                BuildProjectFailure::Error(error) => errors.push(error),
                BuildProjectFailure::Cancelled => {
                    return Err(Error::Cancelled);
                }
            },
        }
    }

    if errors.is_empty() {
        let mut handles = Vec::new();
        for (project_name, schema, programs, artifacts) in results {
            let config = Arc::clone(&config);
            let perf_logger = Arc::clone(&perf_logger);
            let artifact_map = compiler_state
                .artifacts
                .get(&project_name)
                .cloned()
                .unwrap_or_else(|| Arc::new(ArtifactMapKind::Unconnected(Default::default())));
            let removed_definition_names = graphql_asts
                .remove(&project_name)
                .expect("Expect GraphQLAsts to exist.")
                .removed_definition_names;
            let dirty_artifact_paths = compiler_state
                .dirty_artifact_paths
                .get(&project_name)
                .cloned()
                .unwrap_or_default();
            handles.push(task::spawn(async move {
                let project_config = &config.projects[&project_name];
                Ok((
                    project_name,
                    commit_project(
                        &config,
                        project_config,
                        perf_logger,
                        &schema,
                        programs,
                        artifacts,
                        artifact_map,
                        removed_definition_names,
                        dirty_artifact_paths,
                    )
                    .await?,
                    schema,
                ))
            }));
        }
        for commit_result in join_all(handles).await {
            let commit_result: std::result::Result<std::result::Result<_, _>, _> = commit_result;
            let inner_result = commit_result.map_err(|e| Error::JoinError {
                error: e.to_string(),
            })?;
            match inner_result {
                Ok((project_name, next_artifact_map, schema)) => {
                    let next_artifact_map = Arc::new(ArtifactMapKind::Mapping(next_artifact_map));
                    compiler_state
                        .artifacts
                        .insert(project_name, next_artifact_map);
                    compiler_state
                        .schema_cache
                        .insert(project_name, schema.to_owned());
                }
                Err(error) => {
                    errors.push(error);
                }
            }
        }
        Ok(())
    } else {
        Err(Error::BuildProjectsErrors { errors })
    }
}
<commit_msg>fix ignored errors<commit_after>/*
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

use crate::build_project::{build_project, build_schema, commit_project, BuildProjectFailure};
use crate::compiler_state::{ArtifactMapKind, CompilerState, ProjectName};
use crate::config::Config;
use crate::errors::{BuildProjectError, Error, Result};
use crate::graphql_asts::GraphQLAsts;
use crate::red_to_green::RedToGreen;
use crate::watchman::FileSource;
use common::{DiagnosticsResult, PerfLogEvent, PerfLogger};
use futures::future::join_all;
use log::{error, info};
use rayon::prelude::*;
use schema::Schema;
use std::{collections::HashMap, sync::Arc};
use tokio::{sync::Notify, task};

pub struct Compiler<TPerfLogger>
where
    TPerfLogger: PerfLogger + 'static,
{
    config: Arc<Config>,
    perf_logger: Arc<TPerfLogger>,
}

impl<TPerfLogger: PerfLogger> Compiler<TPerfLogger> {
    pub fn new(config: Config, perf_logger: Arc<TPerfLogger>) -> Self {
        Self {
            config: Arc::new(config),
            perf_logger,
        }
    }

    pub async fn compile(self) -> Result<CompilerState> {
        let setup_event = self.perf_logger.create_event("compiler_setup");

        let file_source = FileSource::connect(&self.config, &setup_event).await?;
        let mut compiler_state = file_source
            .query(&setup_event, self.perf_logger.as_ref())
            .await?;
        self.build_projects(&mut compiler_state, &setup_event)
            .await?;

        self.perf_logger.complete_event(setup_event);
        Ok(compiler_state)
    }

    pub fn build_schemas(
        &self,
        compiler_state: &CompilerState,
        setup_event: &impl PerfLogEvent,
    ) -> DiagnosticsResult<HashMap<ProjectName, Arc<Schema>>> {
        let timer = setup_event.start("build_schemas");
        let mut schemas = HashMap::new();
        for project_config in self.config.enabled_projects() {
            let schema = build_schema(compiler_state, project_config)?;
            schemas.insert(project_config.name, schema);
        }
        setup_event.stop(timer);
        Ok(schemas)
    }

    pub async fn watch(&self) -> Result<()> {
        let setup_event = self.perf_logger.create_event("compiler_setup");

        let file_source = FileSource::connect(&self.config, &setup_event).await?;

        let (mut compiler_state, mut subscription) = file_source
            .subscribe(&setup_event, self.perf_logger.as_ref())
            .await?;

        let mut red_to_green = RedToGreen::new();

        if self
            .build_projects(&mut compiler_state, &setup_event)
            .await
            .is_err()
        {
            // build_projects should have logged already
            red_to_green.log_error()
        } else {
            info!("Compilation completed.");
        }
        self.perf_logger.complete_event(setup_event);
        info!("Waiting for changes...");

        let pending_file_source_changes = compiler_state.pending_file_source_changes.clone();
        let notify_sender = Arc::new(Notify::new());
        let notify_receiver = notify_sender.clone();
        task::spawn(async move {
            loop {
                if let Some(file_source_changes) = subscription.next_change().await.unwrap() {
                    pending_file_source_changes
                        .write()
                        .unwrap()
                        .push(file_source_changes);
                    notify_sender.notify();
                }
            }
        });

        loop {
            notify_receiver.notified().await;
            // Single change to file sometimes produces 2 watchman change events for the same file
            // wait for 50ms in case there is a subsquent request
            tokio::time::delay_for(std::time::Duration::from_millis(50)).await;
            if compiler_state.has_pending_file_source_changes() {
                let incremental_build_event =
                    self.perf_logger.create_event("incremental_build_event");
                let incremental_build_time =
                    incremental_build_event.start("incremental_build_time");

                let had_new_changes = compiler_state.merge_file_source_changes(
                    &self.config,
                    &incremental_build_event,
                    self.perf_logger.as_ref(),
                    false,
                )?;

                if had_new_changes {
                    info!("Change detected, start compiling...");
                    if self
                        .build_projects(&mut compiler_state, &incremental_build_event)
                        .await
                        .is_err()
                    {
                        // build_projects should have logged already
                        red_to_green.log_error()
                    } else {
                        info!("Compilation completed.");
                        red_to_green.clear_error_and_log(self.perf_logger.as_ref());
                    }
                    incremental_build_event.stop(incremental_build_time);
                    info!("Waiting for changes...");
                } else {
                    incremental_build_event.stop(incremental_build_time);
                }
                self.perf_logger.complete_event(incremental_build_event);
                // We probably don't want the messages queue to grow indefinitely
                // and we need to flush then, as the check/build is completed
                self.perf_logger.flush();
            }
        }
    }

    async fn build_projects(
        &self,
        compiler_state: &mut CompilerState,
        setup_event: &impl PerfLogEvent,
    ) -> Result<()> {
        self.config.error_reporter.build_starts();
        let result = build_projects(
            Arc::clone(&self.config),
            Arc::clone(&self.perf_logger),
            setup_event,
            compiler_state,
        )
        .await;
        self.config.error_reporter.build_finishes();
        match result {
            Ok(()) => {
                compiler_state.complete_compilation();
                self.config.artifact_writer.finalize()?;
                if let Some(post_artifacts_write) = &self.config.post_artifacts_write {
                    if let Err(error) = post_artifacts_write(&self.config) {
                        let error = Error::PostArtifactsError { error };
                        error!("{}", error);
                        return Err(error);
                    }
                }
                Ok(())
            }
            Err(error) => {
                match &error {
                    Error::DiagnosticsError { errors } => {
                        for diagnostic in errors {
                            self.config.error_reporter.report_diagnostic(diagnostic);
                        }
                    }
                    Error::BuildProjectsErrors { errors } => {
                        for error in errors {
                            self.print_project_error(error);
                        }
                    }
                    Error::Cancelled => {
                        info!("Compilation cancelled due to new changes.");
                    }
                    error => {
                        error!("{}", error);
                    }
                }
                if !matches!(error, Error::Cancelled) {
                    error!("Compilation failed.");
                }
                Err(error)
            }
        }
    }

    fn print_project_error(&self, error: &BuildProjectError) {
        match error {
            BuildProjectError::ValidationErrors { errors } => {
                for diagnostic in errors {
                    self.config.error_reporter.report_diagnostic(diagnostic);
                }
            }
            BuildProjectError::PersistErrors { errors } => {
                for error in errors {
                    error!("{}", error);
                }
            }
            _ => {
                error!("{}", error);
            }
        }
    }
}

async fn build_projects<TPerfLogger: PerfLogger + 'static>(
    config: Arc<Config>,
    perf_logger: Arc<TPerfLogger>,
    setup_event: &impl PerfLogEvent,
    compiler_state: &mut CompilerState,
) -> Result<()> {
    let mut graphql_asts = setup_event.time("parse_sources_time", || {
        GraphQLAsts::from_graphql_sources_map(
            &compiler_state.graphql_sources,
            &compiler_state.get_dirty_defintions(&config),
        )
    })?;

    if compiler_state.has_pending_file_source_changes() {
        return Err(Error::Cancelled);
    }

    let build_results: Vec<_> = config
        .par_enabled_projects()
        .filter(|project_config| {
            if let Some(base) = project_config.base {
                if compiler_state.project_has_pending_changes(base) {
                    return true;
                }
            }
            compiler_state.project_has_pending_changes(project_config.name)
        })
        .map(|project_config| {
            build_project(
                &config,
                project_config,
                compiler_state,
                &graphql_asts,
                Arc::clone(&perf_logger),
            )
        })
        .collect();
    let mut results = Vec::new();
    let mut errors = Vec::new();
    for result in build_results {
        match result {
            Ok(result) => results.push(result),
            Err(error) => match error {
                BuildProjectFailure::Error(error) => errors.push(error),
                BuildProjectFailure::Cancelled => {
                    return Err(Error::Cancelled);
                }
            },
        }
    }

    if errors.is_empty() {
        let mut handles = Vec::new();
        for (project_name, schema, programs, artifacts) in results {
            let config = Arc::clone(&config);
            let perf_logger = Arc::clone(&perf_logger);
            let artifact_map = compiler_state
                .artifacts
                .get(&project_name)
                .cloned()
                .unwrap_or_else(|| Arc::new(ArtifactMapKind::Unconnected(Default::default())));
            let removed_definition_names = graphql_asts
                .remove(&project_name)
                .expect("Expect GraphQLAsts to exist.")
                .removed_definition_names;
            let dirty_artifact_paths = compiler_state
                .dirty_artifact_paths
                .get(&project_name)
                .cloned()
                .unwrap_or_default();
            handles.push(task::spawn(async move {
                let project_config = &config.projects[&project_name];
                Ok((
                    project_name,
                    commit_project(
                        &config,
                        project_config,
                        perf_logger,
                        &schema,
                        programs,
                        artifacts,
                        artifact_map,
                        removed_definition_names,
                        dirty_artifact_paths,
                    )
                    .await?,
                    schema,
                ))
            }));
        }
        for commit_result in join_all(handles).await {
            let commit_result: std::result::Result<std::result::Result<_, _>, _> = commit_result;
            let inner_result = commit_result.map_err(|e| Error::JoinError {
                error: e.to_string(),
            })?;
            match inner_result {
                Ok((project_name, next_artifact_map, schema)) => {
                    let next_artifact_map = Arc::new(ArtifactMapKind::Mapping(next_artifact_map));
                    compiler_state
                        .artifacts
                        .insert(project_name, next_artifact_map);
                    compiler_state
                        .schema_cache
                        .insert(project_name, schema.to_owned());
                }
                Err(error) => {
                    errors.push(error);
                }
            }
        }
    }

    if errors.is_empty() {
        Ok(())
    } else {
        Err(Error::BuildProjectsErrors { errors })
    }
}
<|endoftext|>


<commit_before>//! MIPS

// Building this module (even if unused) for non-fp64 targets such as the Sony
// PSP fails with an LLVM error. There doesn't seem to be a good way to detect
// fp64 support as it is sometimes implied by the target cpu, so
// `#[cfg(target_feature = "fp64")]` will unfortunately not work. This is a
// fairly conservative workaround that only disables MSA intrinsics for the PSP.
#[cfg(not(target_os = "psp"))] mod msa;
#[cfg(not(target_os = "psp"))] pub use self::msa::*;

#[cfg(test)]
use stdarch_test::assert_instr;

/// Generates the trap instruction `BREAK`
#[cfg_attr(test, assert_instr(break))]
#[inline]
pub unsafe fn break_() -> ! {
    crate::intrinsics::abort()
}
<commit_msg>Fix code style<commit_after>//! MIPS

// Building this module (even if unused) for non-fp64 targets such as the Sony
// PSP fails with an LLVM error. There doesn't seem to be a good way to detect
// fp64 support as it is sometimes implied by the target cpu, so
// `#[cfg(target_feature = "fp64")]` will unfortunately not work. This is a
// fairly conservative workaround that only disables MSA intrinsics for the PSP.
#[cfg(not(target_os = "psp"))]
mod msa;
#[cfg(not(target_os = "psp"))]
pub use self::msa::*;

#[cfg(test)]
use stdarch_test::assert_instr;

/// Generates the trap instruction `BREAK`
#[cfg_attr(test, assert_instr(break))]
#[inline]
pub unsafe fn break_() -> ! {
    crate::intrinsics::abort()
}
<|endoftext|>