]> glassweightruler.freedombox.rocks Git - xdg-ninja.git/blob - xdg-ninja.sh
xdg-ninja: security and readability fixes
[xdg-ninja.git] / xdg-ninja.sh
1 #!/bin/bash
2
3 USE_GLOW=true
4 if ! command -v glow &>/dev/null; then
5 echo "Glow not found, markdown rendering not available."
6 echo "Output will be raw markdown and might look weird."
7 echo "Install glow for easier reading & copy-paste."
8 USE_GLOW=false
9 fi
10
11 unalias -a
12
13 HELPSTRING="""\
14
15
16 \e[37;45;1mxdg-ninja\e[0m
17
18 \e[1;3mCheck your \$HOME for unwanted files.\e[1;0m
19
20 ────────────────────────────────────
21
22 \e[3m--help\e[0m \e[1mThis help menu\e[0m
23 \e[3m-h\e[0m
24
25 \e[3m--no-skip-ok\e[0m \e[1mDisplay messages for all files checked (verbose)\e[0m
26 \e[3m-v\e[0m
27
28 \e[3m--skip-ok\e[0m \e[1mDon't display anything for files that do not exist (default)\e[0m
29
30 """
31
32 SKIP_OK=true
33 for i in "$@"; do
34 if [[ $i == "--help" ]] || [[ $i == "-h" ]]; then
35 echo -e "$HELPSTRING"
36 exit
37 elif [[ $i == "--skip-ok" ]]; then
38 SKIP_OK=true
39 elif [[ $i == "--no-skip-ok" ]]; then
40 SKIP_OK=false
41 elif [[ $i == "-v" ]]; then
42 SKIP_OK=false
43 fi
44 done
45
46 if ! command -v jq &>/dev/null; then
47 echo "jq is needed to run this script, but it wasn't found. Please install it to be able to use this script."
48 exit
49 fi
50
51 # Function to expand enviornment variables in string
52 # https://stackoverflow.com/a/20316582/11110290
53 apply_shell_expansion() {
54 declare data="$1"
55 declare delimiter="__apply_shell_expansion_delimiter__"
56 declare command="cat <<$delimiter"$'\n'"$data"$'\n'"$delimiter"
57 eval "$command"
58 }
59
60 # Returns 0 if the path doesn't lead anywhere
61 # Return 1 if the path points to a file, 2 if it points to a directory
62 check_not_exists_file() {
63 FILE_PATH=$(apply_shell_expansion "$1")
64 if [ -f "$FILE_PATH" ]; then
65 return 1
66 elif [ -d "$FILE_PATH" ]; then
67 return 2
68 else
69 return 0
70 fi
71 }
72
73 # Function to handle the formatting of output
74 log() {
75 MODE="$1"
76 NAME="$2"
77 FILENAME="$3"
78 HELP="$4"
79
80 case "$MODE" in
81
82 ERR)
83 printf '[\e[1;31m%s\e[1;0m]: \e[1;3m%s\e[1;0m\n' "$NAME" "$FILENAME"
84 ;;
85
86 WARN)
87 printf '[\e[1;33m%s\e[1;0m]: \e[1;3m%s\e[1;0m\n' "$NAME" "$FILENAME"
88 ;;
89
90 INFO)
91 printf '[\e[1;36m%s\e[1;0m]: \e[1;3m%s\e[1;0m\n' "$NAME" "$FILENAME"
92 ;;
93
94 SUCS)
95 [ "$SKIP_OK" = false ] &&
96 printf '[\e[1;32m%s\e[1;0m]: \e[1;3m%s\e[1;0m\n' "$NAME" "$FILENAME"
97 ;;
98
99 HELP)
100 if $USE_GLOW; then
101 echo "$HELP" | glow -
102 else
103 echo "$HELP"
104 fi
105 ;;
106
107 esac
108 }
109
110 # Checks that the given file does not exist, otherwise outputs help
111 check_file() {
112 INPUT="$1"
113 NAME="$2"
114
115 FILENAME=$(echo -E "$INPUT" | jq -r .path)
116 MOVABLE=$(echo -E "$INPUT" | jq -r .movable)
117 HELP=$(echo -E "$INPUT" | jq -r .help)
118
119 check_not_exists_file "$FILENAME"
120
121 case $? in
122
123 0)
124 log SUCS "$NAME" "$FILENAME" "$HELP"
125 ;;
126
127 1 | 2)
128 if "$MOVABLE"; then
129 log ERR "$NAME" "$FILENAME" "$HELP"
130 else
131 log WARN "$NAME" "$FILENAME" "$HELP"
132 fi
133 if [ "$HELP" ]; then
134 log HELP "$NAME" "$FILENAME" "$HELP"
135 else
136 log HELP "$NAME" "$FILENAME" "_No help available._"
137 fi
138 ;;
139
140 esac
141 }
142
143 # Reads a file from programs/, calls check_file on each file specified for the program
144 check_program() {
145 INPUT=$1
146
147 NAME=$(echo "$INPUT" | jq -r .name)
148
149 while IFS= read -r file; do
150 check_file "$file" "$NAME"
151 done <<<"$(echo "$INPUT" | jq -rc '.files[]')"
152 }
153
154 # Loops over all files in the programs/ directory and calls check_program
155 enumerate_programs() {
156 echo -e "\e[1;3mStarting to check your \e[1;36m\$HOME.\e[1;0m"
157 echo -e ""
158 for prog_filename in ./programs/*; do
159 check_program "$(cat "$prog_filename")"
160 done
161 echo -e "\e[1;3mDone checking your \e[1;36m\$HOME.\e[1;0m"
162 echo -e ""
163 echo -e "\e[3mIf you have files in your \e[1;36m\$HOME\e[1;0m that shouldn't be there, but weren't recognised by xdg-ninja, please consider creating a configuration file for it and opening a pull request on github.\e[1;0m"
164 echo -e ""
165 }
166
167 enumerate_programs