<commit_before>use std::fs::{File, create_dir_all, set_permissions, Permissions, remove_file};
use std::fs::{symlink_metadata};
use std::io::Write;
use std::os::unix::fs::PermissionsExt;
use std::path::Path;

use regex::Regex;
use scan_dir::{ScanDir};

use config::builders::Builder;
use config::builders::Builder as B;
use config::builders::Source as S;
use config::read_config;
use container::util::{clean_dir, copy_dir};
use super::super::path_util::ToRelative;
use super::commands::ubuntu;
use super::commands::alpine;
use super::commands::generic;
use super::commands::pip;
use super::commands::npm;
use super::commands::vcs;
use super::commands::download;
use super::tarcmd;
use version::short_version;
use builder::distrib::{DistroBox};
use builder::guard::Guard;
use builder::error::StepError;
use path_util::PathExt;
use file_util::{create_dir, shallow_copy};


pub trait BuildCommand {
    fn build(&self, ctx: &mut Guard, build: bool) -> Result<(), StepError>;
}


impl BuildCommand for Builder {
    fn build(&self, guard: &mut Guard, build: bool)
        -> Result<(), StepError>
    {
        use builder::error::StepError as E;
        match self {
            &B::Install(ref pkgs) => {
                guard.ctx.packages.extend(pkgs.clone().into_iter());
                for i in pkgs.iter() {
                    guard.ctx.build_deps.remove(i);
                }
                if build {
                    try!(guard.distro.install(&mut guard.ctx, pkgs));
                }
            }
            &B::BuildDeps(ref pkgs) => {
                for i in pkgs.iter() {
                    if !guard.ctx.packages.contains(i) {
                        guard.ctx.build_deps.insert(i.clone());
                    }
                }
                if build {
                    try!(guard.distro.install(&mut guard.ctx, pkgs));
                }
            }
            &B::Container(ref name) => {
                let cont = guard.ctx.config.containers.get(name)
                    .expect("Subcontainer not found");  // TODO
                for b in cont.setup.iter() {
                    try!(b.build(guard, false)
                        .map_err(|e| E::SubStep(b.clone(), Box::new(e))));
                }
                if build {
                    let version = try!(short_version(&cont, &guard.ctx.config)
                        .map_err(|(s, e)| format!("step {}: {}", s, e)));
                    let path = Path::new("/vagga/base/.roots")
                        .join(format!("{}.{}", name, version)).join("root");
                    try_msg!(copy_dir(&path, &Path::new("/vagga/root")),
                        "Error copying dir {p:?}: {err}", p=path);
                }
            }
            &B::SubConfig(ref sconfig) => {
                let path = match sconfig.source {
                    S::Container(ref container) => {
                        let cont = guard.ctx.config.containers.get(container)
                            .expect("Subcontainer not found");  // TODO
                        let version = try!(short_version(&cont, &guard.ctx.config)
                            .map_err(|(s, e)| format!("step {}: {}", s, e)));
                        Path::new("/vagga/base/.roots")
                            .join(format!("{}.{}", container, version))
                            .join("root").join(&sconfig.path)
                    }
                    S::Git(ref _git) => {
                        unimplemented!();
                    }
                    S::Directory => {
                        Path::new("/work").join(&sconfig.path)
                    }
                };
                let subcfg = try!(read_config(&path));
                let cont = subcfg.containers.get(&sconfig.container)
                    .expect("Subcontainer not found");  // TODO
                for b in cont.setup.iter() {
                    try!(b.build(guard, build)
                        .map_err(|e| E::SubStep(b.clone(), Box::new(e))));
                }
            }
            &B::Text(ref files) => {
                if build {
                    for (path, text) in files.iter() {
                        let realpath = Path::new("/vagga/root")
                            .join(path.rel());
                        try!(File::create(&realpath)
                            .and_then(|mut f| f.write_all(text.as_bytes()))
                            .map_err(|e| format!("Can't create file: {}", e)));
                        try!(set_permissions(&realpath,
                            Permissions::from_mode(0o755))
                            .map_err(|e| format!("Can't chmod file: {}", e)));
                    }
                }
            }
            &B::Copy(ref cinfo) => {
                if build {
                    let ref src = cinfo.source;
                    let dest = Path::new("/vagga/root").join(cinfo.path.rel());
                    let typ = try!(symlink_metadata(src)
                        .map_err(|e| E::Write(src.into(), e)));
                    if typ.is_dir() {
                        try!(create_dir(&dest, false)
                            .map_err(|e| E::Write(dest.clone(), e)));
                        let re = try!(Regex::new(&cinfo.ignore_regex));
                        try!(ScanDir::all().walk(src, |iter| {
                            for (entry, _) in iter {
                                let fpath = entry.path();
                                // We know that directory is inside
                                // the source
                                let path = fpath.rel_to(src).unwrap();
                                // We know that it's decodable
                                let strpath = path.to_str().unwrap();
                                if re.is_match(strpath) {
                                    continue;
                                }
                                let fdest = dest.join(path);
                                println!("Entry {:?} / {:?} / {} -> {:?}", fpath,
                                    strpath,
                                    re.is_match(strpath),
                                    fdest);
                                try!(shallow_copy(&fpath, &fdest)
                                    .map_err(|e| E::Write(fdest, e)));
                            }
                            Ok(())
                        }).map_err(E::ScanDir).and_then(|x| x));
                    } else {
                        try!(shallow_copy(&cinfo.source, &dest)<commit_msg>Remove debugging print<commit_after>use std::fs::{File, create_dir_all, set_permissions, Permissions, remove_file};
use std::fs::{symlink_metadata};
use std::io::Write;
use std::os::unix::fs::PermissionsExt;
use std::path::Path;

use regex::Regex;
use scan_dir::{ScanDir};

use config::builders::Builder;
use config::builders::Builder as B;
use config::builders::Source as S;
use config::read_config;
use container::util::{clean_dir, copy_dir};
use super::super::path_util::ToRelative;
use super::commands::ubuntu;
use super::commands::alpine;
use super::commands::generic;
use super::commands::pip;
use super::commands::npm;
use super::commands::vcs;
use super::commands::download;
use super::tarcmd;
use version::short_version;
use builder::distrib::{DistroBox};
use builder::guard::Guard;
use builder::error::StepError;
use path_util::PathExt;
use file_util::{create_dir, shallow_copy};


pub trait BuildCommand {
    fn build(&self, ctx: &mut Guard, build: bool) -> Result<(), StepError>;
}


impl BuildCommand for Builder {
    fn build(&self, guard: &mut Guard, build: bool)
        -> Result<(), StepError>
    {
        use builder::error::StepError as E;
        match self {
            &B::Install(ref pkgs) => {
                guard.ctx.packages.extend(pkgs.clone().into_iter());
                for i in pkgs.iter() {
                    guard.ctx.build_deps.remove(i);
                }
                if build {
                    try!(guard.distro.install(&mut guard.ctx, pkgs));
                }
            }
            &B::BuildDeps(ref pkgs) => {
                for i in pkgs.iter() {
                    if !guard.ctx.packages.contains(i) {
                        guard.ctx.build_deps.insert(i.clone());
                    }
                }
                if build {
                    try!(guard.distro.install(&mut guard.ctx, pkgs));
                }
            }
            &B::Container(ref name) => {
                let cont = guard.ctx.config.containers.get(name)
                    .expect("Subcontainer not found");  // TODO
                for b in cont.setup.iter() {
                    try!(b.build(guard, false)
                        .map_err(|e| E::SubStep(b.clone(), Box::new(e))));
                }
                if build {
                    let version = try!(short_version(&cont, &guard.ctx.config)
                        .map_err(|(s, e)| format!("step {}: {}", s, e)));
                    let path = Path::new("/vagga/base/.roots")
                        .join(format!("{}.{}", name, version)).join("root");
                    try_msg!(copy_dir(&path, &Path::new("/vagga/root")),
                        "Error copying dir {p:?}: {err}", p=path);
                }
            }
            &B::SubConfig(ref sconfig) => {
                let path = match sconfig.source {
                    S::Container(ref container) => {
                        let cont = guard.ctx.config.containers.get(container)
                            .expect("Subcontainer not found");  // TODO
                        let version = try!(short_version(&cont, &guard.ctx.config)
                            .map_err(|(s, e)| format!("step {}: {}", s, e)));
                        Path::new("/vagga/base/.roots")
                            .join(format!("{}.{}", container, version))
                            .join("root").join(&sconfig.path)
                    }
                    S::Git(ref _git) => {
                        unimplemented!();
                    }
                    S::Directory => {
                        Path::new("/work").join(&sconfig.path)
                    }
                };
                let subcfg = try!(read_config(&path));
                let cont = subcfg.containers.get(&sconfig.container)
                    .expect("Subcontainer not found");  // TODO
                for b in cont.setup.iter() {
                    try!(b.build(guard, build)
                        .map_err(|e| E::SubStep(b.clone(), Box::new(e))));
                }
            }
            &B::Text(ref files) => {
                if build {
                    for (path, text) in files.iter() {
                        let realpath = Path::new("/vagga/root")
                            .join(path.rel());
                        try!(File::create(&realpath)
                            .and_then(|mut f| f.write_all(text.as_bytes()))
                            .map_err(|e| format!("Can't create file: {}", e)));
                        try!(set_permissions(&realpath,
                            Permissions::from_mode(0o755))
                            .map_err(|e| format!("Can't chmod file: {}", e)));
                    }
                }
            }
            &B::Copy(ref cinfo) => {
                if build {
                    let ref src = cinfo.source;
                    let dest = Path::new("/vagga/root").join(cinfo.path.rel());
                    let typ = try!(symlink_metadata(src)
                        .map_err(|e| E::Write(src.into(), e)));
                    if typ.is_dir() {
                        try!(create_dir(&dest, false)
                            .map_err(|e| E::Write(dest.clone(), e)));
                        let re = try!(Regex::new(&cinfo.ignore_regex));
                        try!(ScanDir::all().walk(src, |iter| {
                            for (entry, _) in iter {
                                let fpath = entry.path();
                                // We know that directory is inside
                                // the source
                                let path = fpath.rel_to(src).unwrap();
                                // We know that it's decodable
                                let strpath = path.to_str().unwrap();
                                if re.is_match(strpath) {
                                    continue;
                                }
                                let fdest = dest.join(path);
                                try!(shallow_copy(&fpath, &fdest)
                                    .map_err(|e| E::Write(fdest, e)));
                            }
                            Ok(())
                        }).map_err(E::ScanDir).and_then(|x| x));
                    } else {
                        try!(shallow_copy(&cinfo.source, &dest)
{'fraction_non_alphanumeric': 0.14215914378780828, 'fraction_numerical': 0.0006204436171862882, 'mean_word_length': 1.2267311345190812, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 30, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 27, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5959925', 'n_tokens_mistral': 3512, 'n_tokens_neox': 3338, 'n_words': 644}