Skip to content

Commit

Permalink
feat: configure work dir where a task will be run
Browse files Browse the repository at this point in the history
  • Loading branch information
harshdoesdev committed Oct 16, 2024
1 parent b2f826c commit 134d67f
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 7 deletions.
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "shuru"
version = "0.0.19"
version = "0.0.20"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

A task runner and version manager for Node.js and Python, written in Rust! Shuru simplifies your development workflow by automating tasks and managing language versions.

[![Version](https://img.shields.io/badge/version-0.0.19-blue)](https://github.com/shuru-project/shuru/releases)
[![Version](https://img.shields.io/badge/version-0.0.20-blue)](https://github.com/shuru-project/shuru/releases)
[![License](https://img.shields.io/badge/license-MIT-lightgrey)](https://opensource.org/licenses/MIT)
[![CI Status](https://img.shields.io/badge/build-passing-brightgreen)](https://github.com/shuru-project/shuru/actions)
[![Contributors](https://img.shields.io/badge/contributors-5-orange)](https://github.com/shuru-project/shuru/graphs/contributors)
Expand Down
35 changes: 35 additions & 0 deletions src/command_runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,39 @@ impl CommandRunner {
pub fn run_command(&self, name: &str) -> Result<ExitStatus, Error> {
let task = self.find_task(name)?;

let current_dir = std::env::current_dir().map_err(|e| {
Error::CommandExecutionError(format!("Failed to get current directory: {}", e))
})?;

let work_dir = if let Some(dir) = &task.dir {
let resolved_dir = current_dir.join(dir);

if !resolved_dir.exists() {
return Err(Error::CommandExecutionError(format!(
"Specified directory does not exist: '{}'",
resolved_dir.display()
)));
}

let canonical_dir = std::fs::canonicalize(&resolved_dir).map_err(|e| {
Error::CommandExecutionError(format!(
"Failed to canonicalize directory '{}': {}",
resolved_dir.display(),
e
))
})?;

if !canonical_dir.starts_with(&current_dir) {
return Err(Error::CommandExecutionError(format!(
"Invalid directory '{}'. Cannot navigate outside of the current directory.",
dir
)));
}
canonical_dir
} else {
current_dir
};

let env_path = self.config.versions.iter().try_fold(
String::new(),
|env_path, (versioned_command, version_info)| {
Expand All @@ -45,6 +78,7 @@ impl CommandRunner {

let status = if cfg!(target_os = "windows") {
Command::new("cmd")
.current_dir(work_dir)
.env("PATH", final_env_path)
.args(["/C", &task.command])
.status()
Expand All @@ -55,6 +89,7 @@ impl CommandRunner {
let shell = std::env::var("SHELL").unwrap_or_else(|_| "/bin/sh".to_string());

Command::new(shell)
.current_dir(work_dir)
.env("PATH", final_env_path)
.arg("-c")
.arg(&task.command)
Expand Down
15 changes: 12 additions & 3 deletions src/config.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
use crate::version_manager::VersionInfo;
use serde::Deserialize;
use shuru::{
error::{ConfigValidationError, Error},
version_manager::{deserialize_versions, VersionedCommand},
};
use std::collections::HashMap;

use crate::version_manager::VersionInfo;

#[derive(Debug, Deserialize)]
pub struct TaskConfig {
pub command: String,
pub dir: Option<String>,
pub default: Option<bool>,
}

Expand All @@ -24,7 +24,7 @@ pub struct Config {
impl TaskConfig {
pub fn validate(&self, task_name: &str) -> Result<(), ConfigValidationError> {
self.validate_command(task_name)?;

self.validate_dir(task_name)?;
Ok(())
}

Expand All @@ -36,6 +36,15 @@ impl TaskConfig {
}
Ok(())
}

fn validate_dir(&self, task_name: &str) -> Result<(), ConfigValidationError> {
if let Some(dir) = &self.dir {
if dir.is_empty() {
return Err(ConfigValidationError::EmptyDirError(task_name.to_string()));
}
}
Ok(())
}
}

impl Config {
Expand Down
3 changes: 3 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ pub enum ConfigValidationError {

#[error("Command cannot be empty for task: '{0}'.")]
EmptyCommandError(String),

#[error("Directory cannot be empty for task: '{0}'.")]
EmptyDirError(String),
}

#[derive(Debug, Error)]
Expand Down

0 comments on commit 134d67f

Please sign in to comment.