diff --git a/.gitignore b/.gitignore index ede2ada..c6d3e2d 100644 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,8 @@ # Generated by Cargo # will have compiled files and executables /target/ -linux_target/ +dockerbuild.json +/target_*/ # These are backup files generated by rustfmt **/*.rs.bk diff --git a/Cargo.toml b/Cargo.toml index 3afd30f..e377b2d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "dockerbuild" -version = "0.1.3" +version = "0.1.4" authors = ["Hatter Jiang "] edition = "2018" license = "MIT" diff --git a/src/config.rs b/src/config.rs index de79834..f29d948 100644 --- a/src/config.rs +++ b/src/config.rs @@ -3,9 +3,17 @@ use std::path::PathBuf; use serde::{Serialize, Deserialize}; use rust_util::util_file; -#[derive(Serialize, Deserialize)] +#[derive(Debug, Serialize, Deserialize)] +pub struct DockerBuildImage { + pub name: String, + pub image: String, + pub target_dir: Option, +} + +#[derive(Debug, Serialize, Deserialize)] pub struct DockerBuildConfig { pub image: Option, + pub images: Option>, pub mirror: Option, } @@ -13,6 +21,7 @@ pub fn load_docker_build_config_or_default() -> DockerBuildConfig { load_docker_build_config().unwrap_or_else(|| { DockerBuildConfig { image: Some("rust".into()), + images: None, mirror: None, } }) diff --git a/src/docker_util.rs b/src/docker_util.rs index c7f13fa..e47f322 100644 --- a/src/docker_util.rs +++ b/src/docker_util.rs @@ -20,6 +20,7 @@ pub struct DockerCmd { volumns: Vec<(String, String)>, mirror: Option, tty: bool, + builder_args: Vec, } #[allow(dead_code)] @@ -63,6 +64,11 @@ impl DockerCmd { self } + pub fn add_build_arg(&mut self, arg: T) -> &mut Self where T: Into { + self.builder_args.push(arg.into()); + self + } + pub fn exec(self, cmds: &[String]) -> XResult<()> { let mut cmd = Command::new(DOCKER_CMD); cmd.arg("run"); @@ -99,7 +105,7 @@ impl DockerCmd { success!("Build crates mirror: {}", mirror); } - let mut builder_cmd = builder_name; + let mut builder_cmd = builder_name.clone(); let mut sub_build_cmd = vec![]; let mut cmds_iter = cmds.iter(); if let Some(cmd0) = cmds_iter.next() { @@ -117,6 +123,12 @@ impl DockerCmd { final_sub_cmd.push_str(&builder_cmd); final_sub_cmd.push(' '); final_sub_cmd.push_str(&sub_build_cmd.iter().map(|arg| escape_arg(arg)).collect::>().join(" ")); + if !self.builder_args.is_empty() { + for build_arg in &self.builder_args { + final_sub_cmd.push(' '); + final_sub_cmd.push_str(build_arg); + } + } sub_cmd.push_str(&final_sub_cmd); fs::write(DCOLER_TEMP_CMD, &sub_cmd).ok(); diff --git a/src/main.rs b/src/main.rs index 723788b..2b6ebd8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,6 +8,8 @@ mod docker_util; use std::fs; use std::env; use std::path::{Path, PathBuf}; +use config::{DockerBuildConfig, DockerBuildImage}; +use fs::File; use rust_util::util_file; use docker_util::DockerCmd; @@ -25,7 +27,65 @@ fn main() { let docker_build_config = config::load_docker_build_config_or_default(); let mut args_iter = env::args().skip(1).peekable(); + + if args_iter.peek().map(|arg| vec!["--help", "-h", "::help"].contains(&&arg.as_str())).unwrap_or(false) { + println!("dockerbuild [::init]"); + return; + } + + if args_iter.peek().map(|arg| arg == "::init").unwrap_or(false) { + let docker_build_json = "dockerbuild.json"; + if let Ok(_) = File::open(docker_build_json) { + failure!("File exists: {}", docker_build_json); + return; + } + let config = DockerBuildConfig{ + image: None, + images: Some(vec![DockerBuildImage{ + name: "linux_x64".into(), + image: "rust".into(), + target_dir: Some("target_linux_x64".into()), + }, DockerBuildImage{ + name: "linux_x86".into(), + image: "i386/rust".into(), + target_dir: Some("target_linux_x86".into()), + }]), + mirror: Some("git://mirrors.ustc.edu.cn/crates.io-index".into()), + }; + fs::write( + docker_build_json, + serde_json::to_string_pretty(&config).expect("Generate file failed!") + ).expect("Write file failed!"); + return; + } + + let docker_build_image_opt = if let Some(first_arg) = args_iter.peek() { + if first_arg.starts_with(":name:") { + let name = first_arg[6..].to_string(); + args_iter.next(); // skip ':name:*' + match &docker_build_config.images { + None => { + failure!("Images is not configed: {}", &name); + return; + }, + Some(images) => { + let docker_build_image = images.iter().find(|i| i.name == name); + match docker_build_image { + None => { + failure!("Image name not found: {}", &name); + return; + }, + Some(docker_build_image) => Some(docker_build_image), + } + }, + } + } else { None } + } else { None }; + let mut get_docker_image = || { + if let Some(docker_build_image) = docker_build_image_opt { + return docker_build_image.image.to_string(); + } if let Some(first_arg) = args_iter.peek() { if first_arg.starts_with(":image:") { let image_name = first_arg[7..].to_string(); @@ -59,6 +119,12 @@ fn main() { docker_cmd.mirror(&Some(mirror)); } } + if let Some(docker_build_image) = docker_build_image_opt { + if let Some(target_dir) = &docker_build_image.target_dir { + docker_cmd.add_build_arg("--target-dir"); + docker_cmd.add_build_arg(target_dir); + } + } docker_cmd.exec(&args).unwrap(); }