diff --git a/bash_task_formatter/README.md b/bash_task_formatter/README.md new file mode 100644 index 0000000..90c4240 --- /dev/null +++ b/bash_task_formatter/README.md @@ -0,0 +1,71 @@ +# BASH CLI Formatter with Spinner + +This repository contains two scripts, `task_formatter.sh` and `example_usage.sh`, that work together to execute tasks with a spinner and formatted output. The `task_formatter.sh` script provides functions for running tasks with a spinner, while the `example_usage.sh` script demonstrates how to use these functions by defining and executing a set of tasks. + +## Example Output + +![](https://github.com/seanssmith/CLI-Formatter/blob/main/bash_task_importer/bashformatterexample.gif) + + +## Files + +### task_formatter.sh + +This script contains functions for running tasks with a spinner and formatted output. + +#### Functions + +- `spinner(pid)`: Displays a spinner while a background task is running. +- `run_task(task_description, task_command)`: Executes a task with a spinner and captures its output. +- `run_all_tasks(tasks)`: Runs all tasks passed as arguments, using the `run_task` function. + +#### Usage + +The `task_formatter.sh` script is designed to be sourced by another script, which can then call its functions to run tasks with formatted output. + +### example_usage.sh + +This script demonstrates how to use the functions provided by `task_formatter.sh` to run a set of tasks. + +#### Usage + +1. Ensure both `task_formatter.sh` and `example_usage.sh` are executable: + ```bash + chmod +x task_formatter.sh + chmod +x example_usage.sh + ``` + +2. Run the `example_usage.sh` script: + ```bash + ./example_usage.sh + ``` + +#### Example Tasks + +The `example_usage.sh` script defines three example tasks: + +- `Task 1`: Runs the `sample_task` function, which simulates a task running for 3 seconds. +- `Task 2`: Runs the `another_sample_task` function, which simulates a task running for 5 seconds and then returns an error. +- `Task 3`: Runs the `sleep 2` command, which simulates a task running for 2 seconds. + +## How It Works + +1. The `example_usage.sh` script sources the `task_formatter.sh` script to gain access to its functions. +2. The `example_usage.sh` script defines a set of tasks in an array, with each task specified as a description and a command separated by a colon (`:`). +3. The `example_usage.sh` script calls the `run_all_tasks` function from `task_formatter.sh`, passing the tasks as arguments. +4. The `run_all_tasks` function iterates over the tasks, splits each task into a description and a command, and calls the `run_task` function for each task. +5. The `run_task` function executes the task with a spinner and captures its output, displaying the task's status when it completes. + +## Spinner +The Spinner was adjusted from https://github.com/sindresorhus/cli-spinners + +## Example Output + +```plaintext +Task 1 Running [⠼] [✔] Task 1 Completed 3s +Task 2 Running [⠧] [✘] Task 2 Error 5s + +Error output: +Another sample task running + +Task 3 Running [⠹] [✔] Task 3 Completed 2s diff --git a/bash_task_formatter/bashformatterexample.gif b/bash_task_formatter/bashformatterexample.gif new file mode 100644 index 0000000..4dc8ce0 Binary files /dev/null and b/bash_task_formatter/bashformatterexample.gif differ diff --git a/bash_task_formatter/example_usage.sh b/bash_task_formatter/example_usage.sh new file mode 100644 index 0000000..03f3bfc --- /dev/null +++ b/bash_task_formatter/example_usage.sh @@ -0,0 +1,49 @@ +#!/bin/bash + +# Source the formatter script +source ./task_formatter.sh + +# Example function 1 +example_function_1() { + echo -e "This is example function 1. $CHECK_MARK" + sleep 2 +} + +# Example function 2 +example_function_2() { + echo "This is example function 2." + sleep 2 + echo -e "Done $CHECK_MARK" + sleep 2 +} + +# Example function 3 with an error +example_function_3() { + echo -e "This is example function 3 and it will fail. $CROSS_MARK" + sleep 3 + return 1 +} + +ask_reconfigure() { + read -p "Question? (y/n): " choice + case "$choice" in + y|Y ) return 0;; + n|N ) return 1;; + * ) echo "Invalid choice."; ask_reconfigure;; + esac +} + +# Using the formatter to format the output of the example functions +print_header "Example Formatter" "https://github.com/pitterpatter22/TaskFormatter/blob/main/bash_task_formatter/example_new.sh" +format_output example_function_1 "Example Function 1" +format_output example_function_2 "Example Function 2" +format_output example_function_3 "Example Function 3" +format_output_with_input ask_reconfigure "Test Reconfiguring" + + +# Print final message +final_message "Example Formatter (Success Example) $CHECK_MARK" 0 +final_message "Example Formatter (Failure Example) $CROSS_MARK" 1 + +# Exit with appropriate status +exit 0 diff --git a/bash_task_formatter/formatter_new.sh b/bash_task_formatter/formatter_new.sh new file mode 100644 index 0000000..5481e0b --- /dev/null +++ b/bash_task_formatter/formatter_new.sh @@ -0,0 +1,122 @@ +#!/bin/bash + +# Color variables +COLOR_RESET="\033[0m" +COLOR_BLUE="\033[1;34m" +COLOR_YELLOW="\033[1;33m" +COLOR_GREEN="\033[1;32m" +COLOR_RED="\033[1;31m" + +# Symbols +CHECK_MARK="\033[1;32m✔\033[0m" +CROSS_MARK="\033[1;31m✘\033[0m" + +# Function to print header with script name +print_header() { + local script_name=$1 + echo -e "${COLOR_GREEN}" + echo " _____ _ _ _ " + echo " / ____| (_) | | | " + echo " | (___ _ __ ___ _| |_| |__ ___ ___ _ ____ _____ _ __ " + echo " \\___ \\| '_ \` _ \\| | __| '_ \\/ __|/ _ \\ '__\\ \\ / / _ \\ '__|" + echo " ____) | | | | | | | |_| | | \\__ \\ __/ | \\ V / __/ | " + echo " |_____/|_| |_| |_|_|\\__|_| |_|___/\\___|_| \\_/ \\___|_| " + echo -e "${COLOR_RESET}\n" + echo -e "${COLOR_GREEN}${script_name}${COLOR_RESET}\n\n\n" +} + +# Function to display a spinner +spinner() { + local pid=$1 + local func_name=$2 + local delay=0.1 + local spinstr=("⠋" "⠙" "⠹" "⠸" "⠼" "⠴" "⠦" "⠧" "⠇" "⠏") + local temp + + # Hide cursor + tput civis + + while kill -0 "$pid" 2>/dev/null; do + for temp in "${spinstr[@]}"; do + printf "\r${COLOR_BLUE}Function: %s${COLOR_RESET} - ${COLOR_YELLOW}Status: Running... %s${COLOR_RESET}" "$func_name" "$temp" + sleep $delay + done + done + + # Show cursor + tput cnorm +} + +# Function to handle cleanup on exit +cleanup() { + local exit_status=$? + tput cnorm + if [[ -f "$temp_file" ]]; then + rm -f "$temp_file" + fi + if [[ $exit_status -ne 0 ]]; then + printf "\n${COLOR_RED}Script interrupted or an error occurred${COLOR_RESET}\n" + fi + exit $exit_status +} + +# Set trap for cleanup on exit or interrupt +trap cleanup EXIT +trap 'exit 130' INT + +# Function to format the output of another function +format_output() { + local func_name=$1 + local display_name=${2:-$func_name} + temp_file=$(mktemp) + + # Run the function in the background and capture its output + ( $func_name >"$temp_file" 2>&1 ) & + local pid=$! + spinner $pid "$display_name" + wait $pid + local exit_status=$? + + if [ $exit_status -eq 0 ]; then + printf "\r${COLOR_BLUE}Function: %s${COLOR_RESET} - ${COLOR_GREEN}Status: Finished ${CHECK_MARK}${COLOR_RESET} \n" "$display_name" + else + printf "\r${COLOR_BLUE}Function: %s${COLOR_RESET} - ${COLOR_RED}Status: Error ${CROSS_MARK}${COLOR_RESET} \n" "$display_name" + fi + + echo -e "${COLOR_BLUE}Output:${COLOR_RESET}" + cat "$temp_file" + echo "" # Ensure a new line after the function output + rm -f "$temp_file" + return $exit_status +} + +# Function to format the output of another function that requires user input +format_output_with_input() { + local func_name=$1 + local display_name=${2:-$func_name} + temp_file=$(mktemp) + + echo -e "${COLOR_BLUE}Function: $display_name${COLOR_RESET} - ${COLOR_YELLOW}Status: Running...${COLOR_RESET}" + + # Run the function in the foreground to handle interactive input + $func_name 2>&1 | tee "$temp_file" + local exit_status=${PIPESTATUS[0]} + + if [ $exit_status -eq 0 ]; then + printf "\r${COLOR_BLUE}Function: %s${COLOR_RESET} - ${COLOR_GREEN}Status: Finished ${CHECK_MARK}${COLOR_RESET} \n" "$display_name" + else + printf "\r${COLOR_BLUE}Function: %s${COLOR_RESET} - ${COLOR_RED}Status: Error ${CROSS_MARK}${COLOR_RESET} \n" "$display_name" + fi + + echo -e "${COLOR_BLUE}Output:${COLOR_RESET}" + cat "$temp_file" + echo "" # Ensure a new line after the function output + rm -f "$temp_file" + return $exit_status +} + +# Export the functions for use in other scripts +export -f print_header +export -f format_output +export -f format_output_with_input +export COLOR_RESET COLOR_BLUE COLOR_YELLOW COLOR_GREEN COLOR_RED CHECK_MARK CROSS_MARK diff --git a/bash_task_formatter/task_formatter.sh b/bash_task_formatter/task_formatter.sh new file mode 100644 index 0000000..04c5867 --- /dev/null +++ b/bash_task_formatter/task_formatter.sh @@ -0,0 +1,155 @@ +#!/bin/bash + +# Color variables +COLOR_RESET="\033[0m" +COLOR_BLUE="\033[1;34m" +COLOR_YELLOW="\033[1;33m" +COLOR_GREEN="\033[1;32m" +COLOR_RED="\033[1;31m" + +# Symbols +CHECK_MARK="\033[1;32m✔\033[0m" +CROSS_MARK="\033[1;31m✘\033[0m" + + +# Function to center text +center_text() { + local text="$1" + local colorless_text=$(echo -e "$text" | sed 's/\x1b\[[0-9;]*m//g') + local width=$(tput cols) + local text_length=${#colorless_text} + local padding=$(( (width - text_length) / 2 )) + printf "%${padding}s%s\n" "" "$text" +} + +# Function to print header with script name +print_header() { + local script_name=$1 + local script_link=$2 + clear + echo -e "${COLOR_GREEN}" + center_text " ______ _ ______ _ _ " + center_text "| ___ \ | | | ___| | | | | " + center_text "| |_/ / __ _ ___| |__ | |_ ___ _ __ _ __ ___ __ _| |_| |_ ___ _ __ " + center_text "| ___ \/ _\` / __| '_ \ | _/ _ \| '__| '_ \` _ \ / _\` | __| __/ _ \ '__|" + center_text "| |_/ / (_| \__ \ | | | | || (_) | | | | | | | | (_| | |_| || __/ | " + center_text "\____/ \__,_|___/_| |_| \_| \___/|_| |_| |_| |_|\__,_|\__|\__\___|_| " + center_text " " + echo -e "${COLOR_YELLOW}\n" + center_text "${script_name}" + echo -e "\n" + center_text "${script_link}" + echo -e "${COLOR_RESET}\n" + echo -e "\n\n" +} + + + +# Function to display a spinner +spinner() { + local pid=$1 + local func_name=$2 + local delay=0.1 + local spinstr=("⠋" "⠙" "⠹" "⠸" "⠼" "⠴" "⠦" "⠧" "⠇" "⠏") + local temp + + # Hide cursor + tput civis + + while kill -0 "$pid" 2>/dev/null; do + for temp in "${spinstr[@]}"; do + printf "\r${COLOR_BLUE}Function: %s${COLOR_RESET} - ${COLOR_YELLOW}Status: Running... %s${COLOR_RESET}" "$func_name" "$temp" + sleep $delay + done + done + + # Show cursor + tput cnorm +} + +# Function to handle cleanup on exit +cleanup() { + local exit_status=$? + tput cnorm + if [[ -f "$temp_file" ]]; then + rm -f "$temp_file" + fi + if [[ $exit_status -ne 0 ]]; then + printf "\n${COLOR_RED}Script interrupted or an error occurred${COLOR_RESET}\n" + fi + exit $exit_status +} + +# Set trap for cleanup on exit or interrupt +trap cleanup EXIT +trap 'exit 130' INT + +# Function to format the output of another function +format_output() { + local func_name=$1 + local display_name=${2:-$func_name} + temp_file=$(mktemp) + + # Run the function in the background and capture its output + ( $func_name >"$temp_file" 2>&1 ) & + local pid=$! + spinner $pid "$display_name" + wait $pid + local exit_status=$? + + if [ $exit_status -eq 0 ]; then + printf "\r${COLOR_BLUE}Function: %s${COLOR_RESET} - ${COLOR_GREEN}Status: Finished ${CHECK_MARK}${COLOR_RESET} \n" "$display_name" + else + printf "\r${COLOR_BLUE}Function: %s${COLOR_RESET} - ${COLOR_RED}Status: Error ${CROSS_MARK}${COLOR_RESET} \n" "$display_name" + fi + + echo -e "${COLOR_BLUE}Output:${COLOR_RESET}" + cat "$temp_file" + echo "" # Ensure a new line after the function output + rm -f "$temp_file" + return $exit_status +} + +# Function to format the output of another function that requires user input +format_output_with_input() { + local func_name=$1 + local display_name=${2:-$func_name} + temp_file=$(mktemp) + + echo -e "${COLOR_BLUE}Function: $display_name${COLOR_RESET} - ${COLOR_YELLOW}Status: Running...${COLOR_RESET}" + + # Run the function in the foreground to handle interactive input + $func_name 2>&1 | tee "$temp_file" + local exit_status=${PIPESTATUS[0]} + + if [ $exit_status -eq 0 ]; then + printf "\r${COLOR_BLUE}Function: %s${COLOR_RESET} - ${COLOR_GREEN}Status: Finished ${CHECK_MARK}${COLOR_RESET} \n" "$display_name" + else + printf "\r${COLOR_BLUE}Function: %s${COLOR_RESET} - ${COLOR_RED}Status: Error ${CROSS_MARK}${COLOR_RESET} \n" "$display_name" + fi + + echo "" # Ensure a new line after the function output + rm -f "$temp_file" + return $exit_status +} + +# Function to print final message +final_message() { + local script_name=$1 + local success=$2 + if [ -z "$success" ]; then + success=1 + fi + if [ "$success" -eq 0 ]; then + echo -e "\n${COLOR_GREEN}${script_name} completed successfully!${COLOR_RESET}\n" + else + echo -e "\n${COLOR_RED}${script_name} encountered errors!${COLOR_RESET}\n" + fi +} + +# Export the functions for use in other scripts +export -f print_header +export -f format_output +export -f format_output_with_input +export -f final_message +export COLOR_RESET COLOR_BLUE COLOR_YELLOW COLOR_GREEN COLOR_RED CHECK_MARK CROSS_MARK diff --git a/python_task_formatter/README.md b/python_task_formatter/README.md new file mode 100644 index 0000000..eafea46 --- /dev/null +++ b/python_task_formatter/README.md @@ -0,0 +1,73 @@ +# Formatter and Example + +This project demonstrates the use of a Python decorator to format the output of functions, showing a running spinner, and indicating success or failure with colored and formatted text. It includes two files: `formatter.py` and `example.py`. + +## Install + +`pip install TaskFormatter` + +## Example Output + + +![](https://github.com/seanssmith/CLI-Formatter/blob/main/python_task_importer/pythonformatterexample.gif) + + +## Files + +1. **formatter.py**: This file contains the `format_output` decorator that provides the desired formatting for function output. +2. **example.py**: This file demonstrates how to use the `format_output` decorator by applying it to two example functions, one that succeeds and one that fails. + +## Features + +- **Spinner Animation**: Displays a spinner animation while the function is running. +- **Success/Failure Indication**: Shows a green checkmark for successful completion and a red cross for failures. +- **Exception Handling**: Exceptions are displayed in red and underlined. +- **Function Numbering**: Each function is prefixed with a unique number. +- **Text Formatting**: Function names are displayed in bold and underlined. +- **Separation of Outputs**: Outputs from different functions are separated by a line for clarity. + +## Usage + +### 1. formatter.py + +The `format_output` decorator is defined in this file. It wraps a function to display the running spinner, success/failure message, and handle exceptions. + +### 2. example.py + +The `example.py` file demonstrates the use of the `format_output` decorator. It includes two functions, one that succeeds and one that fails, to showcase the decorator's functionality. + +``` +from TaskFormatter import format_output +from time import sleep + +@format_output +def successful_function(): + print("Starting") + sleep(2) + print("Function logic output") + +@format_output +def failing_function(): + print("Just Started") + sleep(2) + print("Running") + sleep(2) + print("Done") + raise ValueError("Custom Error") + +if __name__ == "__main__": + successful_function() + try: + failing_function() + except Exception as e: + print("Caught an exception: ", e) +``` + +## Running the Example + +1. Save formatter.py and example.py in the same directory. +2. Run example.py using the command: +``` +python example.py +``` +You should see the spinner, success, and failure messages formatted as described, with appropriate separation and formatting for each function's output. diff --git a/python_task_formatter/TaskFormatter/TaskFormatter.py b/python_task_formatter/TaskFormatter/TaskFormatter.py new file mode 100644 index 0000000..9b9f467 --- /dev/null +++ b/python_task_formatter/TaskFormatter/TaskFormatter.py @@ -0,0 +1,91 @@ +import time +import sys +import multiprocessing +from functools import wraps +import signal +import io + +# Global counter for function numbering +function_counter = multiprocessing.Value('i', 0) + +def spinner(function_number, func_name, spinner_done, print_lock): + spinner_gen = spinner_gen_func() + while not spinner_done.is_set(): + with print_lock: + sys.stdout.write(f"\r\033[1m\033[4m\033[94m{function_number}. {func_name} Running [{next(spinner_gen)}] \033[0m") + sys.stdout.flush() + time.sleep(0.1) + +def spinner_gen_func(): + while True: + for cursor in "⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏": + yield cursor + +def format_output(func): + @wraps(func) + def wrapper(*args, **kwargs): + with function_counter.get_lock(): + function_counter.value += 1 + function_number = function_counter.value + + start_time = time.time() + func_name = func.__name__ + spinner_done = multiprocessing.Event() + print_lock = multiprocessing.Lock() + + spin_process = multiprocessing.Process(target=spinner, args=(function_number, func_name, spinner_done, print_lock)) + spin_process.start() + + def handle_exit(signum, frame): + raise SystemExit("Process exited") + + signal.signal(signal.SIGTERM, handle_exit) + signal.signal(signal.SIGINT, handle_exit) + + buffer = io.StringIO() + original_stdout = sys.stdout + sys.stdout = buffer + + try: + func(*args, **kwargs) + duration = time.time() - start_time + spinner_done.set() + spin_process.join() + sys.stdout = original_stdout + with print_lock: + sys.stdout.write(f"\r\033[1m\033[4m\033[92m{function_number}. {func_name} Completed [✓] in {duration:.2f}s\033[0m\n") + sys.stdout.flush() + output = buffer.getvalue().strip() + if output: + sys.stdout.write(output + "\n") + sys.stdout.write('\n---\n') # Add separator before the next function + except SystemExit as e: + duration = time.time() - start_time + spinner_done.set() + spin_process.join() + sys.stdout = original_stdout + with print_lock: + sys.stdout.write(f"\r\033[1m\033[4m\033[91m{function_number}. {func_name} Failed [✗] in {duration:.2f}s\033[0m\n") + sys.stdout.flush() + output = buffer.getvalue().strip() + if output: + sys.stdout.write(output + "\n") + print(f"\033[91m\033[4m{e}\033[0m") + sys.stdout.write('\n---\n') # Add separator before the next function + raise e + except Exception as e: + duration = time.time() - start_time + spinner_done.set() + spin_process.join() + sys.stdout = original_stdout + with print_lock: + sys.stdout.write(f"\r\033[1m\033[4m\033[91m{function_number}. {func_name} Failed [✗] in {duration:.2f}s\033[0m\n") + sys.stdout.flush() + output = buffer.getvalue().strip() + if output: + sys.stdout.write(output + "\n") + print(f"\033[91m\033[4m{e}\033[0m") + sys.stdout.write('\n---\n') # Add separator before the next function + raise e + + return wrapper diff --git a/python_task_formatter/TaskFormatter/__init__.py b/python_task_formatter/TaskFormatter/__init__.py new file mode 100644 index 0000000..6be12b0 --- /dev/null +++ b/python_task_formatter/TaskFormatter/__init__.py @@ -0,0 +1 @@ +from .TaskFormatter import format_output \ No newline at end of file diff --git a/python_task_formatter/TaskFormatter/__pycache__/TaskFormatter.cpython-311.pyc b/python_task_formatter/TaskFormatter/__pycache__/TaskFormatter.cpython-311.pyc new file mode 100644 index 0000000..3376786 Binary files /dev/null and b/python_task_formatter/TaskFormatter/__pycache__/TaskFormatter.cpython-311.pyc differ diff --git a/python_task_formatter/TaskFormatter/__pycache__/__init__.cpython-311.pyc b/python_task_formatter/TaskFormatter/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000..39c5dc1 Binary files /dev/null and b/python_task_formatter/TaskFormatter/__pycache__/__init__.cpython-311.pyc differ diff --git a/python_task_formatter/build/lib/TaskFormatter/TaskFormatter.py b/python_task_formatter/build/lib/TaskFormatter/TaskFormatter.py new file mode 100644 index 0000000..9b9f467 --- /dev/null +++ b/python_task_formatter/build/lib/TaskFormatter/TaskFormatter.py @@ -0,0 +1,91 @@ +import time +import sys +import multiprocessing +from functools import wraps +import signal +import io + +# Global counter for function numbering +function_counter = multiprocessing.Value('i', 0) + +def spinner(function_number, func_name, spinner_done, print_lock): + spinner_gen = spinner_gen_func() + while not spinner_done.is_set(): + with print_lock: + sys.stdout.write(f"\r\033[1m\033[4m\033[94m{function_number}. {func_name} Running [{next(spinner_gen)}] \033[0m") + sys.stdout.flush() + time.sleep(0.1) + +def spinner_gen_func(): + while True: + for cursor in "⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏": + yield cursor + +def format_output(func): + @wraps(func) + def wrapper(*args, **kwargs): + with function_counter.get_lock(): + function_counter.value += 1 + function_number = function_counter.value + + start_time = time.time() + func_name = func.__name__ + spinner_done = multiprocessing.Event() + print_lock = multiprocessing.Lock() + + spin_process = multiprocessing.Process(target=spinner, args=(function_number, func_name, spinner_done, print_lock)) + spin_process.start() + + def handle_exit(signum, frame): + raise SystemExit("Process exited") + + signal.signal(signal.SIGTERM, handle_exit) + signal.signal(signal.SIGINT, handle_exit) + + buffer = io.StringIO() + original_stdout = sys.stdout + sys.stdout = buffer + + try: + func(*args, **kwargs) + duration = time.time() - start_time + spinner_done.set() + spin_process.join() + sys.stdout = original_stdout + with print_lock: + sys.stdout.write(f"\r\033[1m\033[4m\033[92m{function_number}. {func_name} Completed [✓] in {duration:.2f}s\033[0m\n") + sys.stdout.flush() + output = buffer.getvalue().strip() + if output: + sys.stdout.write(output + "\n") + sys.stdout.write('\n---\n') # Add separator before the next function + except SystemExit as e: + duration = time.time() - start_time + spinner_done.set() + spin_process.join() + sys.stdout = original_stdout + with print_lock: + sys.stdout.write(f"\r\033[1m\033[4m\033[91m{function_number}. {func_name} Failed [✗] in {duration:.2f}s\033[0m\n") + sys.stdout.flush() + output = buffer.getvalue().strip() + if output: + sys.stdout.write(output + "\n") + print(f"\033[91m\033[4m{e}\033[0m") + sys.stdout.write('\n---\n') # Add separator before the next function + raise e + except Exception as e: + duration = time.time() - start_time + spinner_done.set() + spin_process.join() + sys.stdout = original_stdout + with print_lock: + sys.stdout.write(f"\r\033[1m\033[4m\033[91m{function_number}. {func_name} Failed [✗] in {duration:.2f}s\033[0m\n") + sys.stdout.flush() + output = buffer.getvalue().strip() + if output: + sys.stdout.write(output + "\n") + print(f"\033[91m\033[4m{e}\033[0m") + sys.stdout.write('\n---\n') # Add separator before the next function + raise e + + return wrapper diff --git a/python_task_formatter/build/lib/TaskFormatter/__init__.py b/python_task_formatter/build/lib/TaskFormatter/__init__.py new file mode 100644 index 0000000..6be12b0 --- /dev/null +++ b/python_task_formatter/build/lib/TaskFormatter/__init__.py @@ -0,0 +1 @@ +from .TaskFormatter import format_output \ No newline at end of file diff --git a/python_task_formatter/dist/TaskFormatter-1.0.2-py3-none-any.whl b/python_task_formatter/dist/TaskFormatter-1.0.2-py3-none-any.whl new file mode 100644 index 0000000..d5fe25b Binary files /dev/null and b/python_task_formatter/dist/TaskFormatter-1.0.2-py3-none-any.whl differ diff --git a/python_task_formatter/dist/TaskFormatter-1.0.2.tar.gz b/python_task_formatter/dist/TaskFormatter-1.0.2.tar.gz new file mode 100644 index 0000000..8788dc5 Binary files /dev/null and b/python_task_formatter/dist/TaskFormatter-1.0.2.tar.gz differ diff --git a/python_task_formatter/example.py b/python_task_formatter/example.py new file mode 100644 index 0000000..581422a --- /dev/null +++ b/python_task_formatter/example.py @@ -0,0 +1,24 @@ +from TaskFormatter import format_output +from time import sleep + +@format_output +def successful_function(): + print("Starting") + sleep(2) + print("Function logic output") + +@format_output +def failing_function(): + print("Just Started") + sleep(2) + print("Running") + sleep(2) + print("Done") + raise ValueError("Custom Error") + +if __name__ == "__main__": + successful_function() + try: + failing_function() + except Exception as e: + print("Caught an exception: ", e) diff --git a/python_task_formatter/pythonformatterexample.gif b/python_task_formatter/pythonformatterexample.gif new file mode 100644 index 0000000..195c322 Binary files /dev/null and b/python_task_formatter/pythonformatterexample.gif differ diff --git a/python_task_formatter/setup.cfg b/python_task_formatter/setup.cfg new file mode 100644 index 0000000..3852aa4 --- /dev/null +++ b/python_task_formatter/setup.cfg @@ -0,0 +1,3 @@ +# setup.cfg +[metadata] +description-file = README.md diff --git a/python_task_formatter/setup.py b/python_task_formatter/setup.py new file mode 100644 index 0000000..26317c4 --- /dev/null +++ b/python_task_formatter/setup.py @@ -0,0 +1,20 @@ +# setup.py +from setuptools import setup, find_packages + +setup( + name="TaskFormatter", + version="1.0.2", + description="A Python package for function execution status and spinner output", + long_description=open('README.md').read(), + long_description_content_type='text/markdown', + author="Sean Smith", + author_email="sean@ssmith.app", + url="https://github.com/pitterpatter22/TaskFormatter", + packages=find_packages(), + classifiers=[ + "Programming Language :: Python :: 3", + "License :: OSI Approved :: MIT License", + "Operating System :: OS Independent", + ], + python_requires='>=3.6', +)