fn run_events(
        &self,
        events: &[Event],
        cwd: &std::path::Path,
        import_root: &std::path::Path,
        marks: &mut std::collections::HashMap<String, String>,
    ) -> eyre::Result<()> {
        for event in events.iter() {
            match event {
                Event::Import(path) => {
                    let path = import_root.join(path);
                    let mut child_dag = Dag::load(&path)?;
                    child_dag.init = false;
                    child_dag.sleep = child_dag.sleep.or(self.sleep);
                    child_dag.run(cwd).wrap_err_with(|| {
                        format!("Failed when running imported fixcture {}", path.display())
                    })?;
                }
                Event::Tree(tree) => {
                    let output = std::process::Command::new("git")
                        .arg("ls-files")
                        .current_dir(cwd)
                        .ok()?;
                    for relpath in output.stdout.lines() {
                        let relpath = std::path::Path::new(relpath.to_os_str()?);
                        std::process::Command::new("git")
                            .arg("rm")
                            .arg("-f")
                            .arg(relpath)
                            .current_dir(cwd)
                            .ok()
                            .wrap_err_with(|| format!("Failed to remove {}", relpath.display()))?;
                    }
                    for (relpath, content) in tree.tracked.iter() {
                        let path = cwd.join(relpath);
                        if let Some(parent) = path.parent() {
                            std::fs::create_dir_all(parent).wrap_err_with(|| {
                                format!("Failed to create {}", parent.display())
                            })?;
                        }
                        std::fs::write(&path, content.as_bytes())
                            .wrap_err_with(|| format!("Failed to write {}", path.display()))?;
                        if !tree.state.is_tracked() {
                            std::process::Command::new("git")
                                .arg("add")
                                .arg(relpath)
                                .current_dir(cwd)
                                .ok()?;
                        }
                    }
                    if tree.state.is_committed() {
                        // Detach
                        if let Ok(pre_commit) = current_oid(cwd) {
                            checkout(cwd, &pre_commit)?;
                        }

                        let mut p = std::process::Command::new("git");
                        p.arg("commit")
                            .arg("-m")
                            .arg(tree.message.as_deref().unwrap_or("Automated"))
                            .current_dir(cwd);
                        if let Some(author) = tree.author.as_deref() {
                            p.arg("--author").arg(author);
                        }
                        p.ok()?;
                        if let Some(sleep) = self.sleep {
                            std::thread::sleep(sleep);
                        }

                        if let Some(branch) = tree.branch.as_ref() {
                            let _ = std::process::Command::new("git")
                                .arg("branch")
                                .arg("-D")
                                .arg(branch.as_str())
                                .current_dir(cwd)
                                .ok();
                            std::process::Command::new("git")
                                .arg("checkout")
                                .arg("-b")
                                .arg(branch.as_str())
                                .current_dir(cwd)
                                .ok()?;
                        }

                        if let Some(mark) = tree.mark.as_ref() {
                            let commit = current_oid(cwd)?;
                            marks.insert(mark.as_str().to_owned(), commit);
                        }
                    }
                }
                Event::Children(events) => {
                    let start_commit = current_oid(cwd)?;
                    for run in events {
                        checkout(cwd, &start_commit)?;
                        self.run_events(run, cwd, import_root, marks)?;
                    }
                }
                Event::Head(reference) => {
                    let revspec = match &reference {
                        Reference::Mark(mark) => marks
                            .get(mark.as_str())
                            .ok_or_else(|| eyre::eyre!("Reference doesn't exist: {:?}", mark))?
                            .as_str(),
                        Reference::Branch(branch) => branch.as_str(),
                    };
                    checkout(cwd, revspec)?;
                }
            }
        }

        Ok(())
    }
// Note: shelling out to git to minimize programming bugs
shelling out to git to minimize programming bugs
shelling out to git to minimize programming bugs
fn run_events(
        &self,
        events: &[Event],
        cwd: &std::path::Path,
        import_root: &std::path::Path,
        marks: &mut std::collections::HashMap<String, String>,
    ) -> eyre::Result<()> {
        for event in events.iter() {
            match event {
                Event::Import(path) => {
                    let path = import_root.join(path);
                    let mut child_dag = Dag::load(&path)?;
                    child_dag.init = false;
                    child_dag.sleep = child_dag.sleep.or(self.sleep);
                    child_dag.run(cwd).wrap_err_with(|| {
                        format!("Failed when running imported fixcture {}", path.display())
                    })?;
                }
                Event::Tree(tree) => {
                    let output = std::process::Command::new("git")
                        .arg("ls-files")
                        .current_dir(cwd)
                        .ok()?;
                    for relpath in output.stdout.lines() {
                        let relpath = std::path::Path::new(relpath.to_os_str()?);
                        std::process::Command::new("git")
                            .arg("rm")
                            .arg("-f")
                            .arg(relpath)
                            .current_dir(cwd)
                            .ok()
                            .wrap_err_with(|| format!("Failed to remove {}", relpath.display()))?;
                    }
                    for (relpath, content) in tree.tracked.iter() {
                        let path = cwd.join(relpath);
                        if let Some(parent) = path.parent() {
                            std::fs::create_dir_all(parent).wrap_err_with(|| {
                                format!("Failed to create {}", parent.display())
                            })?;
                        }
                        std::fs::write(&path, content.as_bytes())
                            .wrap_err_with(|| format!("Failed to write {}", path.display()))?;
                        if !tree.state.is_tracked() {
                            std::process::Command::new("git")
                                .arg("add")
                                .arg(relpath)
                                .current_dir(cwd)
                                .ok()?;
                        }
                    }
                    if tree.state.is_committed() {
                        // Detach
                        if let Ok(pre_commit) = current_oid(cwd) {
                            checkout(cwd, &pre_commit)?;
                        }
                        let mut p = std::process::Command::new("git");
                        p.arg("commit")
                            .arg("-m")
                            .arg(tree.message.as_deref().unwrap_or("Automated"))
                            .current_dir(cwd);
                        if let Some(author) = tree.author.as_deref() {
                            p.arg("--author").arg(author);
                        }
                        p.ok()?;
                        if let Some(sleep) = self.sleep {
                            std::thread::sleep(sleep);
                        }
                        if let Some(branch) = tree.branch.as_ref() {
                            let _ = std::process::Command::new("git")
                                .arg("branch")
                                .arg("-D")
                                .arg(branch.as_str())
                                .current_dir(cwd)
                                .ok();
                            std::process::Command::new("git")
                                .arg("checkout")
                                .arg("-b")
                                .arg(branch.as_str())
                                .current_dir(cwd)
                                .ok()?;
                        }
                        if let Some(mark) = tree.mark.as_ref() {
                            let commit = current_oid(cwd)?;
                            marks.insert(mark.as_str().to_owned(), commit);
                        }
                    }
                }
                Event::Children(events) => {
                    let start_commit = current_oid(cwd)?;
                    for run in events {
                        checkout(cwd, &start_commit)?;
                        self.run_events(run, cwd, import_root, marks)?;
                    }
                }
                Event::Head(reference) => {
                    let revspec = match &reference {
                        Reference::Mark(mark) => marks
                            .get(mark.as_str())
                            .ok_or_else(|| eyre::eyre!("Reference doesn't exist: {:?}", mark))?
                            .as_str(),
                        Reference::Branch(branch) => branch.as_str(),
                    };
                    checkout(cwd, revspec)?;
                }
            }
        }
        Ok(())
    }
fn run_events ( & self , events : & [ Event ] , cwd : & std :: path :: Path , import_root : & std :: path :: Path , marks : & mut std :: collections :: HashMap < String , String > , ) -> eyre :: Result < ( ) > { for event in events . iter ( ) { match event { Event :: Import ( path ) => { let path = import_root . join ( path ) ; let mut child_dag = Dag :: load ( & path ) ? ; child_dag . init = false ; child_dag . sleep = child_dag . sleep . or ( self . sleep ) ; child_dag . run ( cwd ) . wrap_err_with ( | | { format ! ( " " path display ( ) ) } ) ? ; } Event :: Tree ( tree ) => { let output = std :: process :: Command :: new ( " " ) . arg ( " " ) . current_dir ( cwd ) . ok ( ) ? ; for relpath in output . stdout . lines ( ) { let relpath = std :: path :: Path :: new ( relpath . to_os_str ( ) ? ) ; std :: process :: Command :: new ( " " ) . arg ( " " ) . arg ( " " ) . arg ( relpath ) . current_dir ( cwd ) . ok ( ) . wrap_err_with ( | | format ! ( " " relpath display ( ) ) ) ? ; } for ( relpath , content ) in tree . tracked . iter ( ) { let path = cwd . join ( relpath ) ; if let Some ( parent ) = path . parent ( ) { std :: fs :: create_dir_all ( parent ) . wrap_err_with ( | | { format ! ( " " parent display ( ) ) } ) ? ; } std :: fs :: write ( & path , content . as_bytes ( ) ) . wrap_err_with ( | | format ! ( " " path display ( ) ) ) ? ; if ! tree . state . is_tracked ( ) { std :: process :: Command :: new ( " " ) . arg ( " " ) . arg ( relpath ) . current_dir ( cwd ) . ok ( ) ? ; } } if tree . state . is_committed ( ) { // Detach if let Ok ( pre_commit ) = current_oid ( cwd ) { checkout ( cwd , & pre_commit ) ? ; } let mut p = std :: process :: Command :: new ( " " ) ; p . arg ( " " ) . arg ( " " ) . arg ( tree . message . as_deref ( ) . unwrap_or ( " " ) ) . current_dir ( cwd ) ; if let Some ( author ) = tree . author . as_deref ( ) { p . arg ( " " ) . arg ( author ) ; } p . ok ( ) ? ; if let Some ( sleep ) = self . sleep { std :: thread :: sleep ( sleep ) ; } if let Some ( branch ) = tree . branch . as_ref ( ) { let _ = std :: process :: Command :: new ( " " ) . arg ( " " ) . arg ( " " ) . arg ( branch . as_str ( ) ) . current_dir ( cwd ) . ok ( ) ; std :: process :: Command :: new ( " " ) . arg ( " " ) . arg ( " " ) . arg ( branch . as_str ( ) ) . current_dir ( cwd ) . ok ( ) ? ; } if let Some ( mark ) = tree . mark . as_ref ( ) { let commit = current_oid ( cwd ) ? ; marks . insert ( mark . as_str ( ) . to_owned ( ) , commit ) ; } } } Event :: Children ( events ) => { let start_commit = current_oid ( cwd ) ? ; for run in events { checkout ( cwd , & start_commit ) ? ; self . run_events ( run , cwd , import_root , marks ) ? ; } } Event :: Head ( reference ) => { let revspec = match & reference { Reference :: Mark ( mark ) => marks . get ( mark . as_str ( ) ) . ok_or_else ( | | eyre :: eyre ! ( " " mark ) ) ? . as_str ( ) , Reference :: Branch ( branch ) => branch . as_str ( ) , } ; checkout ( cwd , revspec ) ? ; } } } Ok ( ( ) ) }
Note: shelling out to git to minimize programming bugs
Note : shelling out to git to minimize programming bugs
&self
events
&[Event]
cwd
&std::path::Path
import_root
&std::path::Path
marks
&mut std::collections::HashMap<String, String>
&self
events
&[Event]
cwd
&std::path::Path
import_root
&std::path::Path
marks
&mut std::collections::HashMap<String, String>