aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortoufic ar <contact@toufy.me>2026-05-08 15:16:45 +0300
committertoufic ar <contact@toufy.me>2026-05-08 15:16:45 +0300
commit23de5b5223829a7f8e5b39c1705f563e87119a7e (patch)
treea635249c7098c28ffa69b53abd8ce182d5bfbf99
parent6c94bf9d99851977fed49d150e56b73c785f6988 (diff)
downloadmakeshiftci-c0faf881eeb4383cfd5b9099e76ef4ae0044da13.tar.gz
makeshiftci-c0faf881eeb4383cfd5b9099e76ef4ae0044da13.zip
input checks, minor QoL improvements, crontab fixv0.1.2
-rwxr-xr-xmsci120
1 files changed, 110 insertions, 10 deletions
diff --git a/msci b/msci
index b2a533c..76b7219 100755
--- a/msci
+++ b/msci
@@ -1,5 +1,18 @@
#!/usr/bin/env bash
+if [ -z "$MSCI_HOME" ]; then
+ echo "MSCI_HOME is not set"
+ exit 1
+fi
+
+deps=("git" "jq" "openssl" "docker" "crontab")
+for dep in "${deps[@]}"; do
+ if ! command -v "$dep" >/dev/null 2>&1; then
+ echo "command '$dep' not found"
+ exit 1
+ fi
+done
+
set -e
shopt -s nullglob
mkdir -p "$MSCI_HOME"/projects \
@@ -33,7 +46,7 @@ write_cron() {
ppath="$MSCI_HOME"/projects/"$project".json
schedule=$(jq -r '.cron' "$ppath")
[ "$schedule" = 'null' ] && continue
- cfile="${cfile}$schedule $MSCI_HOME/makeshiftci run $project\n"
+ cfile="${cfile}$schedule $MSCI_HOME/msci run $project\n"
done
echo -e "$cfile" >"$MSCI_HOME"/tmp.cron
if crontab "$MSCI_HOME"/tmp.cron; then
@@ -45,7 +58,7 @@ write_cron() {
run_project() {
ppath="$MSCI_HOME"/projects/"$1".json
- repo_name=$(jq -r '.name' "$ppath")
+ repo_name="$1"
repo_url=$(jq -r '.url' "$ppath")
repo_path="$MSCI_HOME"/tmp/"$repo_name"
echo "cloning repo: $repo_url" | tee -a "$2"
@@ -81,12 +94,20 @@ run_project() {
create_project() {
name="$1"
- if find_project "$name"; then
- echo "project file already exists"
+ if [[ ! $name =~ ^[A-Za-z0-9_]+$ ]]; then
+ echo "allowed project file name regex: ^[A-Za-z0-9_]+$"
return 1
fi
- read -rp "project name: " pname
- read -rp ".makeshiftci repo URL: " purl
+ while true; do
+ read -rp "project name: " pname
+ [[ -n ${pname//[[:space:]]/} ]] && break
+ echo "name can't be empty"
+ done
+ while true; do
+ read -rp ".makeshiftci repo URL: " purl
+ [[ -n ${purl//[[:space:]]/} ]] && break
+ echo "URL can't be empty"
+ done
phidden=$(confirm_in "hidden?" && echo true || echo false)
read -rp "cron (optional): " pcron
jq -n \
@@ -122,15 +143,15 @@ edit_project() {
oldcron=$(jq -r '.cron' "$ppath")
echo "project name: $oldname"
read -rp "new name (optional): " pname
- [ -z "$pname" ] && pname=$oldname
+ [ -z "${pname//[[:space:]]/}" ] && pname=$oldname
echo ".makeshiftci repo URL: $oldurl"
read -rp "new URL (optional): " purl
- [ -z "$purl" ] && purl=$oldurl
+ [ -z "${purl//[[:space:]]/}" ] && purl=$oldurl
echo "hidden: $washidden"
phidden=$(confirm_in "$keephidden hidden?" && echo true || echo false)
echo "cron: $oldcron"
read -rp "new cron (optional): " pcron
- [ -z "$pcron" ] && pcron=$oldcron
+ [ -z "${pcron//[[:space:]]/}" ] && pcron=$oldcron
jq -n \
--arg pname "$pname" \
--arg purl "$purl" \
@@ -159,6 +180,10 @@ create)
echo "no project file name is supplied"
exit 1
fi
+ if find_project "$2"; then
+ echo "project file already exists"
+ return 1
+ fi
create_project "$2"
;;
edit)
@@ -166,6 +191,10 @@ edit)
echo "no project file name is supplied"
exit 1
fi
+ if ! find_project "$2"; then
+ echo "project file doesn't exist"
+ exit 1
+ fi
edit_project "$2"
;;
delete)
@@ -194,6 +223,10 @@ run)
echo "project file doesn't exist"
exit 1
fi
+ if [[ ! $2 =~ ^[A-Za-z0-9_]+$ ]]; then
+ echo "project file name is not allowed, rename it"
+ exit 1
+ fi
ppath="$MSCI_HOME"/projects/"$2".json
phidden=$(jq -r '.hidden' "$ppath")
stdout_type=$([ "$phidden" = 'false' ] && echo "public" || echo "private")
@@ -218,8 +251,75 @@ run)
list)
list_projects
;;
+clean)
+ case "$2" in
+ --tmp)
+ echo "cleaning tmp for all projects"
+ rm -rf "$MSCI_HOME"/tmp/*
+ ;;
+ --stdout)
+ echo "cleaning stdout for all projects"
+ rm -rf "$MSCI_HOME"/stdout/**/**/*
+ ;;
+ --all)
+ echo "cleaning stdout and tmp for all projects"
+ rm -rf "$MSCI_HOME"/tmp/*
+ rm -rf "$MSCI_HOME"/stdout/**/**/*
+ ;;
+ *)
+ if [ -z "$2" ]; then
+ echo "no project file name is supplied"
+ exit 1
+ fi
+ if ! find_project "$2"; then
+ echo "project file doesn't exist"
+ exit 1
+ fi
+ confirm_in "clear tmp?" &&
+ rm -rf "$MSCI_HOME"/tmp/"$2" &&
+ echo "cleared tmp for $2"
+ confirm_in "clear stdout?" &&
+ rm -rf "$MSCI_HOME"/stdout/"$2" &&
+ echo "cleared stdout for $2"
+ ;;
+ esac
+ ;;
*)
- echo "unknown option '$1'"
+ echo "
+usage: $(basename "$0") [OPTIONS]
+
+options:
+ <filename> is the name of a file:
+ - matching the regex ^[A-Za-z0-9_]+\$
+ - that is not necessarily the project name
+
+ create <filename> create a new project
+
+ edit <filename> edit a project
+
+ delete <filename> delete a project and clean up
+
+ run <filename> run a project
+
+ list list projects
+
+ clean <filename>|[SELECTION]
+ if <filename>, prompts for cleaning a particular project
+ selections:
+ --tmp clean tmp files, such as cloned repos
+ NOTE:
+ tmp files are automatically removed after
+ running, but they may persist in cases of errors
+ or unexpected behavior
+ only run this command in such cases
+
+ --stdout clean stdout
+ NOTE:
+ stdout is where the output for each run is stored
+ everything that was printed to stdout during the run
+ of any project, is stored under the directory by the
+ name of the project, in a file named as the run number
+"
exit 1
;;
esac