From b1063097481a90e60d121095eb80dbb770b0469a Mon Sep 17 00:00:00 2001 From: Toby Vincent Date: Thu, 1 Jun 2023 19:53:41 -0500 Subject: build: improve xtask cli structure --- xtask/src/dist.rs | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++++ xtask/src/lib.rs | 94 +------------------------------------------------------ xtask/src/main.rs | 10 +++--- 3 files changed, 97 insertions(+), 97 deletions(-) create mode 100644 xtask/src/dist.rs (limited to 'xtask') diff --git a/xtask/src/dist.rs b/xtask/src/dist.rs new file mode 100644 index 0000000..119eece --- /dev/null +++ b/xtask/src/dist.rs @@ -0,0 +1,90 @@ +use std::{ + env::consts::ARCH, + fs::File, + path::{Path, PathBuf}, +}; + +use anyhow::{ensure, Result}; +use flate2::{write::GzEncoder, Compression}; +use tar::Builder; + +use crate::{BIN_NAME, PKG_INCLUDE, PKG_VER}; + +pub fn generate_tar_gz(profile: &str, tag: Option<&str>) -> Result { + let pkg_name = format!("{BIN_NAME}-{PKG_VER}-{ARCH}.tar.gz"); + + let target_dir = PathBuf::from("target").canonicalize()?; + let profile_dir = target_dir.join(profile); + let dist_dir = target_dir.join("dist"); + let out_dir = find_out_dir(&profile_dir)?; + + let bin_path = profile_dir.join(BIN_NAME); + let pkg_path = dist_dir.join(pkg_name); + + ensure!( + !tag.is_some_and(|t| t.trim_start_matches('v') != PKG_VER), + "Package version does not match provided tag: {PKG_VER} != {}", + tag.unwrap().trim_start_matches('v') + ); + + ensure!( + bin_path.exists(), + "Package binary does not exist: {}", + bin_path.display() + ); + + ensure!( + out_dir.exists(), + "Build's out directory does not exist: {}", + out_dir.display() + ); + + let _ = std::fs::remove_dir_all(&dist_dir); + std::fs::create_dir_all(&dist_dir)?; + + let tar_gz = File::create(&pkg_path)?; + let enc = GzEncoder::new(tar_gz, Compression::default()); + let mut tar = Builder::new(enc); + + tar.append_path_with_name(bin_path, PathBuf::from("bin").join(BIN_NAME))?; + tar.append_dir_all(".", out_dir)?; + PKG_INCLUDE.iter().try_for_each(|p| tar.append_path(p))?; + + tar.into_inner()?.finish()?; + + Ok(pkg_path) +} + +pub fn find_out_dir>(profile: P) -> Result { + let build_dir = PathBuf::from("target").join(profile).join("build"); + + build_dir + .canonicalize() + .and_then(|p| p.read_dir()) + .map_err(|_| { + anyhow::anyhow!( + "Package build directory does not exist: {}", + build_dir.display() + ) + })? + .flatten() + .filter_map(|d| { + d.file_name() + .to_str()? + .starts_with(BIN_NAME) + .then(|| d.path().join("invoked.timestamp")) + .filter(|p| p.exists()) + }) + .reduce(|acc, path_buf| { + std::cmp::max_by_key(path_buf, acc, |p| { + p.metadata() + .and_then(|m| m.modified()) + .unwrap_or(std::time::SystemTime::UNIX_EPOCH) + }) + }) + .map(|p| p.with_file_name("out")) + .ok_or(anyhow::anyhow!( + "Package out directory not found in build directory: {}", + build_dir.display() + )) +} diff --git a/xtask/src/lib.rs b/xtask/src/lib.rs index 5e876d5..f01fe7b 100644 --- a/xtask/src/lib.rs +++ b/xtask/src/lib.rs @@ -1,13 +1,3 @@ -use std::{ - env::consts::ARCH, - fs::File, - path::{Path, PathBuf}, -}; - -use anyhow::{ensure, Result}; -use flate2::{write::GzEncoder, Compression}; -use tar::Builder; - const BIN_NAME: &str = "projectr"; const PKG_VER: &str = env!("CARGO_PKG_VERSION"); const PKG_INCLUDE: &[&str] = &[ @@ -17,86 +7,4 @@ const PKG_INCLUDE: &[&str] = &[ "LICENSE", ]; -pub fn generate_tar_gz>( - root: &P, - profile: &str, - tag: Option<&str>, -) -> Result { - let pkg_name = format!("{BIN_NAME}-{PKG_VER}-{ARCH}.tar.gz"); - - let target_dir = root.as_ref().join("target"); - let profile_dir = target_dir.join(profile); - let dist_dir = target_dir.join("dist"); - let out_dir = find_out_dir(&profile_dir)?; - - let bin_path = profile_dir.join(BIN_NAME); - let pkg_path = dist_dir.join(pkg_name); - - ensure!( - !tag.is_some_and(|t| t.trim_start_matches('v') != PKG_VER), - "Package version does not match provided tag: {PKG_VER} != {}", - tag.unwrap().trim_start_matches('v') - ); - - ensure!( - bin_path.exists(), - "Package binary does not exist: {}", - bin_path.display() - ); - - ensure!( - out_dir.exists(), - "Build's out directory does not exist: {}", - out_dir.display() - ); - - let _ = std::fs::remove_dir_all(&dist_dir); - std::fs::create_dir_all(&dist_dir)?; - - let tar_gz = File::create(&pkg_path)?; - let enc = GzEncoder::new(tar_gz, Compression::default()); - let mut tar = Builder::new(enc); - - std::env::set_current_dir(root)?; - - tar.append_path_with_name(bin_path, PathBuf::from("bin").join(BIN_NAME))?; - tar.append_dir_all(".", out_dir)?; - PKG_INCLUDE.iter().try_for_each(|p| tar.append_path(p))?; - - tar.into_inner()?.finish()?; - - Ok(pkg_path) -} - -pub fn find_out_dir>(profile_dir: P) -> Result { - let build_dir = profile_dir.as_ref().join("build"); - - build_dir - .read_dir() - .map_err(|_| { - anyhow::anyhow!( - "Package build directory does not exist: {}", - build_dir.display() - ) - })? - .flatten() - .filter_map(|d| { - d.file_name() - .to_str()? - .starts_with(BIN_NAME) - .then(|| d.path().join("invoked.timestamp")) - .filter(|p| p.exists()) - }) - .reduce(|acc, path_buf| { - std::cmp::max_by_key(path_buf, acc, |p| { - p.metadata() - .and_then(|m| m.modified()) - .unwrap_or(std::time::SystemTime::UNIX_EPOCH) - }) - }) - .map(|p| p.with_file_name("out")) - .ok_or(anyhow::anyhow!( - "Package out directory not found: {}", - profile_dir.as_ref().display() - )) -} +pub mod dist; diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 2282efd..51d5491 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -10,18 +10,20 @@ use std::path::PathBuf; use anyhow::Result; use clap::{Parser, Subcommand}; +use xtask::{dist, release}; fn main() -> Result<()> { let cli = Cli::parse(); + std::env::set_current_dir(cli.directory)?; + match cli.command { Commands::Dist { tag } => { - let targz = xtask::generate_tar_gz(&cli.directory, &cli.profile, tag.as_deref())?; + let targz = dist::generate_tar_gz(&cli.profile, tag.as_deref())?; println!("{}", targz.display()); } Commands::OutDir => { - let profile_dir = cli.directory.join("target").join(&cli.profile); - let out_dir = xtask::find_out_dir(profile_dir)?; + let out_dir = dist::find_out_dir(&cli.profile)?; println!("{}", out_dir.display()); } }; @@ -39,7 +41,7 @@ struct Cli { #[arg(short, long, default_value = "release")] profile: String, - /// Path to root directory of package. + /// Change to DIRECTORY before doing anything #[arg(short='C', long, default_value_os_t = get_package_dir())] directory: PathBuf, } -- cgit v1.2.3-70-g09d2