razel 0.5.7

a command executor with caching for data processing pipelines
Documentation
use crate::executors::AsyncTask;
use crate::make_file_executable;
use async_trait::async_trait;
use futures_util::StreamExt;
use std::path::PathBuf;
use tokio::fs::File;
use tokio::io::AsyncWriteExt;

pub struct DownloadFileTask {
    pub url: String,
    pub output: PathBuf,
    pub executable: bool,
}

#[async_trait]
impl AsyncTask for DownloadFileTask {
    async fn exec(&self, sandbox_dir: Option<PathBuf>) -> Result<(), anyhow::Error> {
        let mut stream = reqwest::get(&self.url)
            .await?
            .error_for_status()?
            .bytes_stream();
        let mut file = File::create(
            sandbox_dir
                .map(|x| x.join(&self.output))
                .unwrap_or_else(|| PathBuf::from(&self.output)),
        )
        .await?;
        while let Some(item) = stream.next().await {
            let chunk = item?;
            file.write_all(&chunk).await?;
        }
        if self.executable {
            make_file_executable(&file).await?;
        }
        file.sync_all().await?;
        Ok(())
    }
}