]> glassweightruler.freedombox.rocks Git - xdg-ninja.git/blob - xdg-ninja.sh
Merge pull request #278 from pavelskipenes/pciutils
[xdg-ninja.git] / xdg-ninja.sh
1 #!/usr/bin/env sh
2
3 has_command() {
4 command -v "$1" >/dev/null 2>/dev/null
5 return $?
6 }
7
8 auto_set_decoder() {
9 DECODER="cat"
10 if has_command glow; then
11 DECODER="glow -"
12 elif has_command batcat; then
13 DECODER="batcat -pp --decorations=always --color=always --language markdown"
14 printf "Markdown rendering will be done by bat. (Glow is recommended)\n"
15 elif has_command bat; then
16 DECODER="bat -pp --decorations=always --color=always --language markdown"
17 printf "Markdown rendering will be done by bat. (Glow is recommended)\n"
18 elif has_command pygmentize; then
19 DECODER="pygmentize -l markdown"
20 printf "Markdown rendering will be done by pygmentize. (Glow is recommended)\n"
21 elif has_command highlight; then
22 DECODER="highlight --out-format ansi --syntax markdown"
23 printf "Markdown rendering will be done by highlight. (Glow is recommended)\n"
24 else
25 printf "Install glow for easier reading & copy-paste.\n"
26 fi
27 }
28 auto_set_decoder
29
30 unalias -a
31
32 init_constants() {
33 FX_RESET="\033[0m"
34 FX_BOLD="\033[1m"
35 FX_ITALIC="\033[3m"
36
37 FG_RED="\033[31m"
38 FG_GREEN="\033[32m"
39 FG_YELLOW="\033[33m"
40 FG_CYAN="\033[36m"
41 FG_WHITE="\033[37m"
42
43 BG_MAGENTA="\033[45m"
44 }
45 init_constants
46
47 help() {
48 init_constants
49 HELPSTRING="""\
50
51
52 ${FG_WHITE}${BG_MAGENTA}${FX_BOLD}xdg-ninja${FX_RESET}
53
54 ${FX_BOLD}${FX_ITALIC}Check your \$HOME for unwanted files.${FX_RESET}
55
56 ────────────────────────────────────
57
58 ${FX_ITALIC}--help${FX_RESET} ${FX_BOLD}This help menu${FX_RESET}
59 ${FX_ITALIC}-h\033${FX_RESET}
60
61 ${FX_ITALIC}--no-skip-ok${FX_RESET} ${FX_BOLD}Display messages for all files checked (verbose)${FX_RESET}
62 ${FX_ITALIC}-v${FX_RESET}
63
64 ${FX_ITALIC}--skip-ok${FX_RESET} ${FX_BOLD}Don't display anything for files that do not exist (default)${FX_RESET}
65
66 ${FX_ITALIC}--skip-unsupported${FX_RESET} ${FX_BOLD}Don't display anything for files that do not have fixes available${FX_RESET}
67
68 """
69 printf "%b" "$HELPSTRING"
70 }
71
72 SKIP_OK=true
73 SKIP_UNSUPPORTED=false
74 for i in "$@"; do
75 if [ "$i" = "--help" ] || [ "$i" = "-h" ]; then
76 help
77 exit
78 elif [ "$i" = "--skip-ok" ]; then
79 SKIP_OK=true
80 elif [ "$i" = "--no-skip-ok" ]; then
81 SKIP_OK=false
82 elif [ "$i" = "--skip-unsupported" ]; then
83 SKIP_UNSUPPORTED=true
84 elif [ "$i" = "-v" ]; then
85 SKIP_OK=false
86 fi
87 done
88
89 if [ -z "${XDG_DATA_HOME}" ]; then
90 printf '%b%s%b\n' "${FX_BOLD}${FG_CYAN}" "The \$XDG_DATA_HOME environment variable is not set, make sure to add it to your shell's configuration before setting any of the other environment variables!" "${FX_RESET}"
91 printf "%b ⤷ The recommended value is: %b\$HOME/.local/share%b\n" "${FX_BOLD}${FG_CYAN}" "${FX_BOLD}${FX_ITALIC}" "${FX_RESET}"
92 fi
93 if [ -z "${XDG_CONFIG_HOME}" ]; then
94 printf '%b%s%b\n' "${FX_BOLD}${FG_CYAN}" "The \$XDG_CONFIG_HOME environment variable is not set, make sure to add it to your shell's configuration before setting any of the other environment variables!" "${FX_RESET}"
95 printf "%b ⤷ The recommended value is: %b\$HOME/.config%b\n" "${FX_BOLD}${FG_CYAN}" "${FX_BOLD}${FX_ITALIC}" "${FX_RESET}"
96 fi
97 if [ -z "${XDG_STATE_HOME}" ]; then
98 printf '%b%s%b\n' "${FX_BOLD}${FG_CYAN}" "The \$XDG_STATE_HOME environment variable is not set, make sure to add it to your shell's configuration before setting any of the other environment variables!" "${FX_RESET}"
99 printf "%b ⤷ The recommended value is: %b\$HOME/.local/state%b\n" "${FX_BOLD}${FG_CYAN}" "${FX_BOLD}${FX_ITALIC}" "${FX_RESET}"
100 fi
101 if [ -z "${XDG_CACHE_HOME}" ]; then
102 printf '%b%s%b\n' "${FX_BOLD}${FG_CYAN}" "The \$XDG_CACHE_HOME environment variable is not set, make sure to add it to your shell's configuration before setting any of the other environment variables!" "${FX_RESET}"
103 printf "%b ⤷ The recommended value is: %b\$HOME/.cache%b\n" "${FX_BOLD}${FG_CYAN}" "${FX_BOLD}${FX_ITALIC}" "${FX_RESET}"
104 fi
105 if [ -z "${XDG_RUNTIME_DIR}" ]; then
106 printf '%b%s%b\n' "${FX_BOLD}${FG_CYAN}" "The \$XDG_RUNTIME_DIR environment variable is not set, make sure to add it to your shell's configuration before setting any of the other environment variables!" "${FX_RESET}"
107 printf "%b ⤷ The recommended value is: %b/run/user/\$UID%b\n" "${FX_BOLD}${FG_CYAN}" "${FX_BOLD}${FX_ITALIC}" "${FX_RESET}"
108 fi
109
110 if ! command -v jq >/dev/null 2>/dev/null; then
111 printf "jq is needed to run this script, but it wasn't found. Please install it to be able to use this script.\n"
112 exit
113 fi
114
115 printf "\n"
116
117 # Function to expand environment variables in string
118 # https://stackoverflow.com/a/20316582/11110290
119 apply_shell_expansion() {
120 data="$1"
121 delimiter="__apply_shell_expansion_delimiter__"
122 command=$(printf "cat <<%s\n%s\n%s" "$delimiter" "$data" "$delimiter")
123 eval "$command"
124 }
125
126 # Returns 0 if the path doesn't lead anywhere
127 # Returns 1 if the path leads to something
128 check_if_file_exists() {
129 FILE_PATH=$(apply_shell_expansion "$1")
130 if [ -e "$FILE_PATH" ]; then
131 return 1
132 else
133 return 0
134 fi
135 }
136
137 decode_string() {
138 printf "%s" "$1" | sed -e 's/\\n/\
139 /g' -e 's/\\\"/\"/g' -e '$ s/\n*$/\
140 \
141 /' # Replace \n with literal newline and \" with ", normalize number of trailing newlines to 2
142 }
143
144 # Counter to keep track of how many files can be moved
145 FIXABLE=0
146
147 # Function to handle the formatting of output
148 log() {
149 MODE="$1"
150 NAME="$2"
151 FILENAME="$3"
152 HELP="$4"
153
154 case "$MODE" in
155
156 ERR)
157 printf '[%b%s%b]: %b%s%b\n' "${FX_BOLD}${FG_RED}" "$NAME" "${FX_RESET}" "${FX_BOLD}${FX_ITALIC}" "$FILENAME" "${FX_RESET}"
158 FIXABLE=$((FIXABLE+1))
159 ;;
160
161 WARN)
162 [ "$SKIP_UNSUPPORTED" = false ] &&
163 printf '[%b%s%b]: %b%s%b\n' "${FX_BOLD}${FG_YELLOW}" "$NAME" "${FX_RESET}" "${FX_BOLD}${FX_ITALIC}" "$FILENAME" "${FX_RESET}"
164 ;;
165
166 INFO)
167 printf '[%b%s%b]: %b%s%b\n' "${FX_BOLD}${FG_CYAN}" "$NAME" "${FX_RESET}" "${FX_BOLD}${FX_ITALIC}" "$FILENAME" "${FX_RESET}"
168 ;;
169
170 SUCS)
171 [ "$SKIP_OK" = false ] &&
172 printf '[%b%s%b]: %b%s%b\n' "${FX_BOLD}${FG_GREEN}" "$NAME" "${FX_RESET}" "${FX_BOLD}${FX_ITALIC}" "$FILENAME" "${FX_RESET}"
173 ;;
174
175 HELP)
176 decode_string "$HELP" | PAGER="cat" $DECODER
177 ;;
178
179 esac
180 }
181
182 # Checks that the given file does not exist, otherwise outputs help
183 check_file() {
184 NAME="$1"
185 FILENAME="$2"
186 MOVABLE="$3"
187 HELP="$4"
188
189 check_if_file_exists "$FILENAME"
190
191 case $? in
192
193 0)
194 log SUCS "$NAME" "$FILENAME" "$HELP"
195 ;;
196
197 1)
198 if [ "$MOVABLE" = true ]; then
199 log ERR "$NAME" "$FILENAME" "$HELP"
200 else
201 log WARN "$NAME" "$FILENAME" "$HELP"
202 fi
203 if [ "$HELP" ]; then
204 if [ "$MOVABLE" = true ] || [ "$SKIP_UNSUPPORTED" = false ]; then
205 log HELP "$NAME" "$FILENAME" "$HELP"
206 fi
207 else
208 log HELP "$NAME" "$FILENAME" "_No help available._"
209 fi
210 ;;
211
212 esac
213 }
214
215 # Reads files from programs/, calls check_file on each file specified for each program
216 do_check_programs() {
217 while IFS="
218 " read -r name; read -r filename; read -r movable; read -r help; do
219 check_file "$name" "$filename" "$movable" "$help"
220 done <<EOF
221 $(jq 'inputs as $input | $input.files[] as $file | $input.name, $file.path, $file.movable, $file.help' "$XN_PROGRAMS_DIR"/* | sed -e 's/^"//' -e 's/"$//')
222 EOF
223 # sed is to trim quotes
224 }
225
226 check_programs() {
227 printf "%bStarting to check your %b\$HOME%b.\n" "${FX_BOLD}${FX_ITALIC}" "${FG_CYAN}" "${FX_RESET}"
228 printf "\n"
229 do_check_programs
230 printf "%bDone checking your %b\$HOME.%b\n" "${FX_BOLD}${FX_ITALIC}" "${FG_CYAN}" "${FX_RESET}"
231 printf "\n"
232 printf "%bIf you have files in your %b\$HOME%b 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.%b\n" "${FX_ITALIC}" "${FG_CYAN}" "${FX_RESET}${FX_ITALIC}" "${FX_RESET}"
233 printf "\n"
234 }
235
236 [ "$XN_PROGRAMS_DIR" ] ||
237 XN_PROGRAMS_DIR="$(realpath "$0" | xargs dirname | sed 's:/bin$:/share/xdg-ninja:g')/programs"
238
239 check_programs
240 if [ $FIXABLE -gt 100 ]; then
241 exit 101
242 else
243 exit $FIXABLE
244 fi