[
  {
    "path": "LICENSE",
    "content": "Copyright 2020 Gauge Krahe\n\nPermission to use, copy, modify, and/or distribute this software for any\npurpose with or without fee is hereby granted, provided that the above\ncopyright notice and this permission notice appear in all copies.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\nWITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\nMERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\nANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\nWHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\nACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\nOR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "<div align=\"center\">\n<h1>fet.sh</h1>\na fetch written in POSIX shell with no external commands\n<br>\n<img src=\"screenshot.png\" width=\"250px\">\n</div>\n\n### Installing\n**Arch:** [fet.sh-git](https://aur.archlinux.org/packages/fet.sh-git) (AUR)  \n**Gentoo:** [app-misc/fetsh](https://gpo.zugaina.org/Overlays/guru/app-misc/fetsh) (GURU overlay)  \n**KISS:** [fetsh](https://github.com/kisslinux/community/tree/master/community/fetsh) (Community)  \n**Nix:** [fet-sh](https://search.nixos.org/packages?show=fet-sh&query=fet-sh&channel=unstable) (nixpkgs-unstable)  \nAlternatively, copy `fet.sh` to somewhere in $PATH and mark it as executable (`chmod +x fet.sh`)\n\n### Customization\n`fet.sh` has a few basic configuration options using environment variables, for example:\n```\n$ info='n os wm sh n' fet.sh\n```\nSupported options are:\n- `accent` (0-7)\n- `info`\n- `separator`\n- `colourblocks`\n\nFor less trivial configuration I recommend editing the script, I tried to keep it simple.\n\n### Known Issues\nMacOS, BSD, and Android don't show much info.\n"
  },
  {
    "path": "fet.sh",
    "content": "#!/bin/sh\n#\n#    fet.sh\n#  a fetch in pure POSIX shell\n#\n\n# supress errors\nexec 2>/dev/null\nset --\neq() {  # equals  |  [ a = b ] with globbing\n\tcase $1 in\n\t\t$2) ;;\n\t\t*) return 1;;\n\tesac\n}\n\n## DE\nwm=$XDG_CURRENT_DESKTOP\n[ \"$wm\" ] || wm=$DESKTOP_SESSION\n\n## Distro\n# freedesktop.org/software/systemd/man/os-release.html\n# a common file that has variables about the distro\nfor os in /etc/os-release /usr/lib/os-release; do\n\t# some POSIX shells exit when trying to source a file that doesn't exist\n\t[ -f $os ] && . $os && break\ndone\n\nif [ -e /proc/$$/comm ]; then\n\t## Terminal\n\twhile [ ! \"$term\" ]; do\n\t\t# loop over lines in /proc/pid/status until it reaches PPid\n\t\t# then save that to a variable and exit the file\n\t\twhile read -r line; do\n\t\t\teq \"$line\" 'PPid*' && ppid=${line##*:?} && break\n\t\tdone < \"/proc/${ppid:-$PPID}/status\"\n\n\t\t# Make sure not to do an infinite loop\n\t\t[ \"$pppid\" = \"$ppid\" ] && break\n\t\tpppid=$ppid\n\n\t\t# get name of binary\n\t\tread -r name < \"/proc/$ppid/comm\"\n\n\t\tcase $name in\n\t\t\t*sh|\"${0##*/}\") ;;  # skip shells\n\t\t\t*[Ll]ogin*|*init|*systemd*) break;;  # exit when the top is reached\n\t\t\t# anything else can be assumed to be the terminal\n\t\t\t# this has the side affect of catching tmux, but tmux\n\t\t\t# detaches from the terminal and therefore ignoring that\n\t\t\t# will just make the init the term\n\t\t\t*) term=$name\n\t\tesac\n\tdone\n\n\t## WM/DE\n\t[ \"$wm\" ] ||\n\t\t# loop over all processes and check the binary name\n\t\tfor i in /proc/*/comm; do\n\t\t\tread -r c < \"$i\"\n\t\t\tcase $c in\n\t\t\t\t*bar*|*rc) ;;\n\t\t\t\tawesome|xmonad*|qtile|sway|i3|[bfo]*box|*wm*) wm=${c%%-*}; break;;\n\t\t\tesac\n\t\tdone\n\n\t## Memory\n\t# loop over lines in /proc/meminfo until it reaches MemTotal,\n\t# then convert the amount (second word) from KB to MB\n\twhile read -r line; do\n\t\teq \"$line\" 'MemTotal*' && set -- $line && break\n\tdone < /proc/meminfo\n\tmem=\"$(( $2 / 1000 ))MB\"\n\n\t## Processor\n\twhile read -r line; do\n\t\tcase $line in\n\t\t\tvendor_id*) vendor=\"${line##*: } \";;\n\t\t\tmodel\\ name*) cpu=${line##*: }; break;;\n\t\tesac\n\tdone < /proc/cpuinfo\n\n\t## Uptime\n\t# the simple math is shamefully stolen from aosync\n\tIFS=. read -r uptime _ < /proc/uptime\n\td=$((uptime / 60 / 60 / 24))\n\tup=$(printf %02d:%02d $((uptime / 60 / 60 % 24)) $((uptime / 60 % 60)))\n\t[ \"$d\" -gt 0 ] && up=\"${d}d $up\"\n\n\t## Kernel\n\tread -r _ _ version _ < /proc/version\n\tkernel=${version%%-*}\n\teq \"$version\" '*Microsoft*' && ID=\"fake $ID\"\n\n\t## Motherboard // laptop\n\tread -r model < /sys/devices/virtual/dmi/id/product_name\n\t# invalid model handling\n\tcase $model in\n\t\t# alternate file with slightly different info\n\t\t# on my laptop it has the device model (instead of 'hp notebook')\n\t\t# on my desktop it has the extended motherboard model\n\t\t'System '*|'Default '*|'To Be Filled'*)\n\t\t\tread -r model < /sys/devices/virtual/dmi/id/board_name\n\tesac\n\n\t## Packages\n\t# clean environment, then make every file in the dir an argument,\n\t# then save the argument count to $pkgs\n\tset --\n\t# kiss, arch, debian, void, gentoo\n\tfor i in '/var/db/kiss/installed/*'  '/var/lib/pacman/local/[0-9a-z]*' \\\n\t'/var/lib/dpkg/info/*.list'  '/var/db/xbps/.*'  '/var/db/pkg/*/*'; do\n\t\tset -- $i\n\t\t[ $# -gt 1 ] && pkgs=$# && break\n\tdone\n\n\tread -r host < /proc/sys/kernel/hostname\nelif [ -f /var/run/dmesg.boot ]; then\n\t# Both OpenBSD and FreeBSD use this file, however they're formatted differently\n\tread -r bsd < /var/run/dmesg.boot\n\tcase $bsd in\n\tOpen*)\n\t\t## OpenBSD cpu/mem/name\n\t\twhile read -r line; do\n\t\t\tcase $line in\n\t\t\t\t'real mem'*)\n\t\t\t\t\t# use the pre-formatted value which is in brackets\n\t\t\t\t\tmem=${line##*\\(}\n\t\t\t\t\tmem=${mem%\\)*}\n\t\t\t\t;;\n\t\t\t\t# set $cpu to everything before a comma and after the field name\n\t\t\t\tcpu0:*)\n\t\t\t\t\tcpu=${line#cpu0: }\n\t\t\t\t\t# Remove excess info after the actual CPU name\n\t\t\t\t\tcpu=${cpu%%,*}\n\t\t\t\t\t# Set the CPU Manufacturer to the first word of the cpu\n\t\t\t\t\t# variable [separated by '(' or ' ']\n\t\t\t\t\tvendor=${cpu%%[\\( ]*}\n\t\t\t\t\t# We got all the info we want, stop reading\n\t\t\t\t\tbreak\n\t\t\t\t;;\n\t\t\t\t# First 2 words in the file are OpenBSD <version>\n\t\t\t\t*) [ \"$ID\" ] || { set -- $line; ID=\"$1 $2\"; }\n\t\t\tesac\n\t\tdone < /var/run/dmesg.boot\n\t\t[ -d /var/db/pkg ] && set -- /var/db/pkg/* && pkgs=$#\n\t\tread -r host < /etc/myname\n\t\thost=${host%.*}\n\t;;\n\t# Everything else, assume FreeBSD (first line is ---<<BOOT>> or something)\n\t*)\n\t\t# shellcheck source=/dev/null\n\t\t. /etc/rc.conf\n\t\t# shut shellcheck up without disabling the warning\n\t\thost=${hostname:-}\n\n\t\twhile read -r line; do\n\t\t\tcase $line in\n\t\t\t\t# os version\n\t\t\t\tFreeBSD*)\n\t\t\t\t\t# If the OS is already set, no need to set it again\n\t\t\t\t\t[ \"$ID\" ] && continue\n\t\t\t\t\tID=${line%%-R*}\n\t\t\t\t;;\n\n\t\t\t\tCPU:*)\n\t\t\t\t\tcpu=${cpu#CPU: }\n\t\t\t\t\t# Remove excess info from after the actual CPU name\n\t\t\t\t\tcpu=${line%\\(*}\n\t\t\t\t;;\n\t\t\t\t*Origin=*)\n\t\t\t\t\t# CPU Manufacturer\n\t\t\t\t\tvendor=${line#*Origin=\\\"}\n\t\t\t\t\tvendor=\"${vendor%%\\\"*} \"\n\t\t\t\t;;\n\n\t\t\t\t'real memory'*)\n\t\t\t\t\t# Get the pre-formatted amount which is inside brackets\n\t\t\t\t\tmem=${line##*\\(}\n\t\t\t\t\tmem=${mem%\\)*}\n\t\t\t\t\t# This appears to be the final thing we need from the file,\n\t\t\t\t\t# no need to read it more.\n\t\t\t\t\tbreak\n\t\t\tesac\n\t\tdone < /var/run/dmesg.boot\n\t;;\n\tesac\nelif v=/System/Library/CoreServices/SystemVersion.plist; [ -f \"$v\" ]; then\n\t## Macos\n\t# make sure this variable is empty as to not break the following loop\n\ttemp=\n\twhile read -r line; do\n\t\tcase $line in\n\t\t\t# set a variable so the script knows it's on the correct line\n\t\t\t# (the line after this one is the important one)\n\t\t\t*ProductVersion*) temp=.;;\n\t\t\t*)\n\t\t\t\t# check if the script is reading the derired line, if not\n\t\t\t\t# don't do anything\n\t\t\t\t[ \"$temp\" ] || continue\n\t\t\t\t# Remove everything before and including the first '>'\n\t\t\t\tID=${line#*>}\n\t\t\t\t# Remove the other side of the XML tag, and insert the actual OS name\n\t\t\t\tID=\"MacOS ${ID%<*}\"\n\t\t\t\t# We got the info we want, end the loop.\n\t\t\t\tbreak\n\t\tesac\n\tdone < \"$v\"\nfi\n\neq \"$0\" '*fetish' && printf 'Step on me daddy\\n' && exit\n\n# help i dont know if it's a capital consistently\neq \"$wm\" '*[Gg][Nn][Oo][Mm][Ee]*' && wm='foot DE'\n\n## GTK\nwhile read -r line; do\n\teq \"$line\" 'gtk-theme*' && gtk=${line##*=} && break\ndone < \"${XDG_CONFIG_HOME:=$HOME/.config}/gtk-3.0/settings.ini\"\n\n# Shorten $cpu and $vendor\n# this is so messy due to so many inconsistencies in the model names\nvendor=${vendor##*Authentic}\nvendor=${vendor##*Genuine}\ncpu=${cpu##*) }\ncpu=${cpu%% @*}\ncpu=${cpu%% CPU}\ncpu=${cpu##CPU }\ncpu=${cpu##*AMD }\ncpu=${cpu%% with*}\ncpu=${cpu% *-Core*}\n\ncol() {\n\tprintf '  '\n\tfor i in 1 2 3 4 5 6; do\n\t\tprintf '\\033[9%sm%s' \"$i\" \"${colourblocks:-▅▅}\"\n\tdone\n\tprintf '\\033[0m\\n'\n}\n\nprint() {\n\t[ \"$2\" ] && printf '\\033[9%sm%6s\\033[0m%b%s\\n' \\\n\t\t\"${accent:-4}\" \"$1\" \"${separator:- ~ }\" \"$2\"\n}\n\n# default value\n: \"${info:=n user os sh wm up gtk cpu mem host kern pkgs term col n}\"\n\nfor i in $info; do\n\tcase $i in\n\t\tn) echo;;\n\t\tos) print os \"$ID\";;\n\t\tsh) print sh \"${SHELL##*/}\";;\n\t\twm) print wm \"${wm##*/}\";;\n\t\tup) print up \"$up\";;\n\t\tgtk) print gtk \"${gtk# }\";;\n\t\tcpu) print cpu \"$vendor$cpu\";;\n\t\tmem) print mem \"$mem\";;\n\t\thost) print host \"$model\";;\n\t\tkern) print kern \"$kernel\";;\n\t\tpkgs) print pkgs \"$pkgs\";;\n\t\tterm) print term \"$term\";;\n\t\tuser) printf '%7s@%s\\n' \"$USER\" \"$host\";;\n\t\tcol) col;;\n\tesac\ndone\n"
  }
]