fn do_for_each_command(args: &Args, projects: &GlProjects) -> Result<()> {
    let (tx, rx) = channel();
    if projects.projects.is_empty() {
        log::warn!("There is no projects in the manifest");
        return Ok(());
    }

    let pool = ThreadPool::new(args.jobs);

    // Increment by one to make sure we don't terminate
    // until all threads has been handled by the thread pool.
    let pending = Arc::new(Mutex::new(AtomicUsize::new(1)));
    let projects = projects.projects.clone();
    for (name, project) in projects {
        match &args.command {
            Command::Sync { projects } => {
                let filtered_projects = !projects.is_empty();
                if !filtered_projects || projects.iter().any(|p| *p == name) {
                    let tx2 = tx.clone();
                    let p2 = pending.clone();
                    p2.lock().unwrap().fetch_add(1, Ordering::Relaxed);
                    // Add function to the thread pool.
                    pool.execute(move || {
                        // Only sync projects that has auto_sync set to true
                        // or sync if projects was explicit selected.
                        if project.auto_sync || filtered_projects {
                            log::info!("Sync: {}", name);
                            if let Err(e) = Git::sync(&name, &project) {
                                tx2.send(ThreadError(name.clone(), e)).ok();
                            }
                        }
                        p2.lock().unwrap().fetch_sub(1, Ordering::Relaxed);
                    });
                }
            }
            Command::ForEach { args, timeout_ms } => {
                let timeout_ms = *timeout_ms;
                let args = args.clone();
                let tx2 = tx.clone();
                let p2 = pending.clone();
                p2.lock().unwrap().fetch_add(1, Ordering::Relaxed);
                // Add function to the thread pool.
                pool.execute(move || {
                    if let Err(e) = process::spawn_shell_and_wait(
                        &name,
                        &project.path,
                        args,
                        std::time::Duration::from_millis(timeout_ms),
                    ) {
                        tx2.send(ThreadError(name.clone(), e)).ok();
                    }
                    p2.lock().unwrap().fetch_sub(1, Ordering::Relaxed);
                });
            }
            Command::Changed { ls_files } => match Git::open(&project.path) {
                Ok(repo) => {
                    let files = repo.changed()?;
                    if !files.is_empty() {
                        println!("{}", name);

                        if *ls_files {
                            println!("{}", files);
                        }
                    }
                }
                Err(e) => {
                    log::error!("{} Make sure sync has been run", e);
                }
            },
            _ => panic!("Command: {:#?} not implemented", args.command),
        }
    }
    // All projects are now pushed decrement by one
    // and then wait until all Projects has done it's job.
    pending.lock().unwrap().fetch_sub(1, Ordering::Relaxed);
    let mut errors = vec![];
    while *pending.lock().unwrap().get_mut() > 0 {
        match rx.try_recv() {
            Ok(e) => {
                log::error!("Project: {}: {}", e.0, e.1);
                errors.push(e);
            }
            Err(_) => {
                // timeout or channel endpoint terminated
                std::thread::sleep(std::time::Duration::from_millis(100));
            }
        }
    }

    // We need to empty any errors coming from threads.
    // If there are error messages left.
    while let Ok(e) = rx.try_recv() {
        log::error!("Project: {}: {}", e.0.bold(), e.1);
        errors.push(e);
    }

    if !errors.is_empty() {
        eprintln!();
        let mut summary = format!(
            "The following {} has errors:\n\n",
            if errors.len() == 1 {
                String::from("project")
            } else {
                format!("{} projects", errors.len())
            }
        );
        for e in errors.iter() {
            summary += &format!("{}\n", e.0);
        }
        return Err(Error::Summary(summary));
    }
    Ok(())
}
///
/// Run command on every project in the manifest.
///
/// # Error
/// return GlRepo::Error on failure.
///
Run command on every project in the manifest.
Run command on every project in the manifest .
fn do_for_each_command(args: &Args, projects: &GlProjects) -> Result<()> {
    let (tx, rx) = channel();
    if projects.projects.is_empty() {
        log::warn!("There is no projects in the manifest");
        return Ok(());
    }
    let pool = ThreadPool::new(args.jobs);
    // Increment by one to make sure we don't terminate
    // until all threads has been handled by the thread pool.
    let pending = Arc::new(Mutex::new(AtomicUsize::new(1)));
    let projects = projects.projects.clone();
    for (name, project) in projects {
        match &args.command {
            Command::Sync { projects } => {
                let filtered_projects = !projects.is_empty();
                if !filtered_projects || projects.iter().any(|p| *p == name) {
                    let tx2 = tx.clone();
                    let p2 = pending.clone();
                    p2.lock().unwrap().fetch_add(1, Ordering::Relaxed);
                    // Add function to the thread pool.
                    pool.execute(move || {
                        // Only sync projects that has auto_sync set to true
                        // or sync if projects was explicit selected.
                        if project.auto_sync || filtered_projects {
                            log::info!("Sync: {}", name);
                            if let Err(e) = Git::sync(&name, &project) {
                                tx2.send(ThreadError(name.clone(), e)).ok();
                            }
                        }
                        p2.lock().unwrap().fetch_sub(1, Ordering::Relaxed);
                    });
                }
            }
            Command::ForEach { args, timeout_ms } => {
                let timeout_ms = *timeout_ms;
                let args = args.clone();
                let tx2 = tx.clone();
                let p2 = pending.clone();
                p2.lock().unwrap().fetch_add(1, Ordering::Relaxed);
                // Add function to the thread pool.
                pool.execute(move || {
                    if let Err(e) = process::spawn_shell_and_wait(
                        &name,
                        &project.path,
                        args,
                        std::time::Duration::from_millis(timeout_ms),
                    ) {
                        tx2.send(ThreadError(name.clone(), e)).ok();
                    }
                    p2.lock().unwrap().fetch_sub(1, Ordering::Relaxed);
                });
            }
            Command::Changed { ls_files } => match Git::open(&project.path) {
                Ok(repo) => {
                    let files = repo.changed()?;
                    if !files.is_empty() {
                        println!("{}", name);
                        if *ls_files {
                            println!("{}", files);
                        }
                    }
                }
                Err(e) => {
                    log::error!("{} Make sure sync has been run", e);
                }
            },
            _ => panic!("Command: {:#?} not implemented", args.command),
        }
    }
    // All projects are now pushed decrement by one
    // and then wait until all Projects has done it's job.
    pending.lock().unwrap().fetch_sub(1, Ordering::Relaxed);
    let mut errors = vec![];
    while *pending.lock().unwrap().get_mut() > 0 {
        match rx.try_recv() {
            Ok(e) => {
                log::error!("Project: {}: {}", e.0, e.1);
                errors.push(e);
            }
            Err(_) => {
                // timeout or channel endpoint terminated
                std::thread::sleep(std::time::Duration::from_millis(100));
            }
        }
    }
    // We need to empty any errors coming from threads.
    // If there are error messages left.
    while let Ok(e) = rx.try_recv() {
        log::error!("Project: {}: {}", e.0.bold(), e.1);
        errors.push(e);
    }
    if !errors.is_empty() {
        eprintln!();
        let mut summary = format!(
            "The following {} has errors:\n\n",
            if errors.len() == 1 {
                String::from("project")
            } else {
                format!("{} projects", errors.len())
            }
        );
        for e in errors.iter() {
            summary += &format!("{}\n", e.0);
        }
        return Err(Error::Summary(summary));
    }
    Ok(())
}
fn do_for_each_command ( args : & Args , projects : & GlProjects ) -> Result < ( ) > { let ( tx , rx ) = channel ( ) ; if projects . projects . is_empty ( ) { log :: warn ! ( " " ) ; return Ok ( ( ) ) ; } let pool = ThreadPool :: new ( args . jobs ) ; // Increment by one to make sure we don't terminate // until all threads has been handled by the thread pool. let pending = Arc :: new ( Mutex :: new ( AtomicUsize :: new ( 1 ) ) ) ; let projects = projects . projects . clone ( ) ; for ( name , project ) in projects { match & args . command { Command :: Sync { projects } => { let filtered_projects = ! projects . is_empty ( ) ; if ! filtered_projects || projects . iter ( ) . any ( | p | * p == name ) { let tx2 = tx . clone ( ) ; let p2 = pending . clone ( ) ; p2 . lock ( ) . unwrap ( ) . fetch_add ( 1 , Ordering :: Relaxed ) ; // Add function to the thread pool. pool . execute ( move | | { // Only sync projects that has auto_sync set to true // or sync if projects was explicit selected. if project . auto_sync || filtered_projects { log :: info ! ( " " name ) ; if let Err ( e ) = Git :: sync ( & name , & project ) { tx2 . send ( ThreadError ( name . clone ( ) , e ) ) . ok ( ) ; } } p2 . lock ( ) . unwrap ( ) . fetch_sub ( 1 , Ordering :: Relaxed ) ; } ) ; } } Command :: ForEach { args , timeout_ms } => { let timeout_ms = * timeout_ms ; let args = args . clone ( ) ; let tx2 = tx . clone ( ) ; let p2 = pending . clone ( ) ; p2 . lock ( ) . unwrap ( ) . fetch_add ( 1 , Ordering :: Relaxed ) ; // Add function to the thread pool. pool . execute ( move | | { if let Err ( e ) = process :: spawn_shell_and_wait ( & name , & project . path , args , std :: time :: Duration :: from_millis ( timeout_ms ) , ) { tx2 . send ( ThreadError ( name . clone ( ) , e ) ) . ok ( ) ; } p2 . lock ( ) . unwrap ( ) . fetch_sub ( 1 , Ordering :: Relaxed ) ; } ) ; } Command :: Changed { ls_files } => match Git :: open ( & project . path ) { Ok ( repo ) => { let files = repo . changed ( ) ? ; if ! files . is_empty ( ) { println ! ( " " name ) ; if * ls_files { println ! ( " " files ) ; } } } Err ( e ) => { log :: error ! ( " " e ) ; } } , _ => panic ! ( " " args command ) , } } // All projects are now pushed decrement by one // and then wait until all Projects has done it's job. pending . lock ( ) . unwrap ( ) . fetch_sub ( 1 , Ordering :: Relaxed ) ; let mut errors = vec ! [ ] ; while * pending . lock ( ) . unwrap ( ) . get_mut ( ) > 0 { match rx . try_recv ( ) { Ok ( e ) => { log :: error ! ( " " e 0 e 1 ) ; errors . push ( e ) ; } Err ( _ ) => { // timeout or channel endpoint terminated std :: thread :: sleep ( std :: time :: Duration :: from_millis ( 100 ) ) ; } } } // We need to empty any errors coming from threads. // If there are error messages left. while let Ok ( e ) = rx . try_recv ( ) { log :: error ! ( " " e 0 bold ( ) e 1 ) ; errors . push ( e ) ; } if ! errors . is_empty ( ) { eprintln ! ( ) ; let mut summary = format ! ( " \n \n " if errors len ( ) 1 { String from ( " " ) } else { format ( " " errors len ( ) ) } ) ; for e in errors . iter ( ) { summary += & format ! ( " \n " e 0 ) ; } return Err ( Error :: Summary ( summary ) ) ; } Ok ( ( ) ) }
Run command on every project in the manifest.
Run command on every project in the manifest .
args
&Args
projects
&GlProjects
args
&Args
projects
&GlProjects
error
return GlRepo::Error on failure.
return GlRepo :: Error on failure .