diff --git a/source-install.sh b/source-install.sh
index c632ff21647160abfd6eb9f01a8db3bcb65213b1..9158ca387bb95396a3af800fc339c4ffd46a00a5 100644
--- a/source-install.sh
+++ b/source-install.sh
@@ -1,6 +1,6 @@
 #!/usr/bin/env sh
 
 cargo build --release
-strip release/target/crunch
-chmod u+x release/target/crunch
-cp release/target/crunch "$HOME/.local/bin/crunch"
\ No newline at end of file
+strip target/release/crunch
+chmod u+x target/release/crunch
+cp target/release/crunch "$HOME/.local/bin/crunch"
\ No newline at end of file
diff --git a/src/commands/pipeline.rs b/src/commands/pipeline.rs
index 90e860f8fa8cb2eec3804728357e563d8c76cb99..3d27ac69a68973adb17e15f004e90975b5189809 100644
--- a/src/commands/pipeline.rs
+++ b/src/commands/pipeline.rs
@@ -1,4 +1,3 @@
-use glob::{glob_with, MatchOptions};
 use std::collections::HashMap;
 use std::path::{Path, PathBuf};
 
@@ -7,6 +6,7 @@ use serde::{Deserialize, Serialize};
 use thiserror::Error;
 
 use crate::cli_args::CrunchCommand;
+use crate::format::make_paths;
 use crate::{commands, load_image};
 
 #[derive(Error, Debug)]
@@ -50,19 +50,44 @@ pub fn execute_pipeline<IN: ToString, OUT: ToString>(
 	file_path: IN,
 	_outpath: OUT,
 ) -> anyhow::Result<()> {
-	let path = file_path.to_string();
-	if !&path.ends_with(".toml") && !&path.ends_with(".json") {
+	let path = std::env::current_dir().map(|path| path.join(file_path.to_string()))?;
+	let path_string = format!("{}", &path.display());
+
+	log::debug!("Trying to read from input file: {}", &path.display());
+
+	if !&path_string.ends_with(".toml") && !&path_string.ends_with(".json") {
 		Err(PipelineError::FormatDetection)?;
 	}
 
-	let file_contents = std::fs::read(file_path.to_string())?;
-	let pipeline_data: PipelineFile = if path.ends_with(".toml") {
+	let file_contents = std::fs::read(path)?;
+
+	log::debug!("Found correct file type and read bytes, trying to parse");
+	let pipeline_data: PipelineFile = if path_string.ends_with(".toml") {
 		toml::from_slice(&file_contents)?
 	} else {
 		serde_json::from_slice(&file_contents)?
 	};
 
+	log::debug!("Expanding pipeline file into targets");
 	get_targets(&pipeline_data).for_each(|(input_path, output_path, actions)| {
+		match make_paths(&output_path) {
+			Ok(_) => {}
+			Err(e) => {
+				log::error!("Failed to create target directory {}; {}", &output_path, e);
+				return;
+			}
+		}
+
+		if actions.is_empty() {
+			match std::fs::copy(&input_path, &output_path) {
+				Ok(_) => {}
+				Err(e) => {
+					log::error!("Failed to copy {} to {}; {}", input_path, output_path, e);
+				}
+			};
+			return;
+		}
+
 		let mut file = match load_image(&input_path, None) {
 			Ok(image) => image,
 			Err(e) => {
@@ -71,6 +96,11 @@ pub fn execute_pipeline<IN: ToString, OUT: ToString>(
 			}
 		};
 
+		log::debug!(
+			"Loaded {}, Executing {} actions",
+			&input_path,
+			actions.len()
+		);
 		let mut count = 1;
 		for step in actions {
 			match step {
@@ -248,15 +278,9 @@ fn get_targets(
 				.map(|value| (*value).actions.clone())
 				.flat_map(|actions| {
 					let mut paths = Vec::new();
-					for entry in glob_with(
-						pattern.as_str(),
-						MatchOptions {
-							case_sensitive: true,
-							..Default::default()
-						},
-					)
-					.unwrap()
-					{
+					log::debug!("Mapping glob paths for '{}'", pattern.as_str());
+					for entry in glob::glob(pattern.as_str()).unwrap() {
+						log::debug!("Found a glob match: [{:?}]", entry);
 						paths.push((actions.clone(), entry));
 					}
 					paths
diff --git a/src/format.rs b/src/format.rs
index d671d4e94728028ddca000d9922978b9c0d4e5d9..82ee1a40dd2b46d5cdc08812e166dffb725fbaf9 100644
--- a/src/format.rs
+++ b/src/format.rs
@@ -64,3 +64,11 @@ pub fn load_image<T: AsRef<Path>>(
 
 	Ok(file)
 }
+
+pub fn make_paths<T: AsRef<Path>>(path: T) -> anyhow::Result<(), std::io::Error> {
+	if let Some(target) = path.as_ref().parent() {
+		std::fs::create_dir_all(target)
+	} else {
+		Ok(())
+	}
+}