Skip to content

Commit

Permalink
added helpers for make
Browse files Browse the repository at this point in the history
  • Loading branch information
dmalan committed Jan 5, 2024
1 parent 58b173e commit e7781bf
Show file tree
Hide file tree
Showing 8 changed files with 142 additions and 20 deletions.
3 changes: 2 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -153,10 +153,12 @@ RUN curl https://packagecloud.io/install/repositories/cs50/repo/script.deb.sh |
bash-completion \
build-essential `# dpkg-dev, libc, gcc, g++, make, etc.`\
clang \
colorized-logs `# For help50` \
coreutils `# For fold` \
cowsay \
dos2unix \
dnsutils `# For nslookup` \
expect `# For help50` \
fonts-noto-color-emoji `# For render50` \
gdb \
git \
Expand Down Expand Up @@ -188,7 +190,6 @@ RUN curl https://packagecloud.io/install/repositories/cs50/repo/script.deb.sh |
cs50 \
Flask \
Flask-Session \
help50 \
pytest \
render50 \
setuptools \
Expand Down
66 changes: 66 additions & 0 deletions etc/profile.d/help50.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Directory with helpers
HELPERS="/opt/cs50/lib/help50"

# TEMP
alias make="help50 make"

# Formatting
bold=$(tput bold)
normal=$(tput sgr0)


help50() {

# Check for helper
if [[ $# -gt 0 && ! -f "${HELPERS}/${1}.sh" ]]; then
echo "Sorry, ${bold}help50${normal} does not yet know how to help with this!"
return 1
fi

# Duplicate file descriptors
exec 3>&1 4>&2

# Redirect output to a file too
local file="/tmp/help50.$$" # Use PID to support multiple terminals
exec > >(tee -a "$file") 2>&1

# Execute command
if [[ "$(type -P -t "$1")" == "file" ]]; then
unbuffer "$@" # Else, e.g., ls isn't colorized
else
"$@" # Can't unbuffer builtins (e.g., cd)
fi

# Remember status
local status=$?

# Remember command
local command="$1"

# Remove command from $@
shift

# Get redirected output
local output=$(cat "$file")

# Remove any ANSI codes
output=$(echo "$output" | ansi2txt | col -b)

# Restore file descriptors
exec 1>&3 2>&4

# Close file descriptors
exec 3>&- 4>&-

# Remove file
rm --force "$file"

# Preserve command's status for helpers
(exit $status)

# Try to get help
local help=$( . "${HELPERS}/${command}.sh" <<< "$output" )
if [[ -n "$help" ]]; then
echo "🦆 $help"
fi
}
35 changes: 16 additions & 19 deletions opt/cs50/bin/make
100755 → 100644
Original file line number Diff line number Diff line change
@@ -1,23 +1,20 @@
#!/bin/bash

# Ensure no targets end with .c
args=""
invalid_args=0
for arg; do
case "$arg" in
(*.c) arg=${arg%.c}; invalid_args=1;;
esac
args="$args $arg"
done
if [ $invalid_args -eq 1 ]; then
echo "Did you mean 'make$args'?"
exit 1
fi
# If a single target and not an option
if [[ $# -eq 1 ]] && [[ "$1" != -* ]]; then

# If no Makefile
if [[ ! -f Makefile && ! -f makefile ]]; then

# Run make
if [[ -d "$1" ]]; then
echo "$1 is a directory"
exit 1
else
/usr/bin/make -B -s $*
# If target ends with .c or is a directory
if [[ "$1" == *?.c || -d "$1" ]]; then

# Don't suppress "Nothing to be done" with --silent
/usr/bin/make "$1"
exit $?
fi
fi
fi

# Don't echo recipes
/usr/bin/make --always-make --silent "$@"
9 changes: 9 additions & 0 deletions opt/cs50/lib/help50/cd.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
echo "EXIT: $?"
local stdin=$(cat)
#echo "stdout[$stdout]"
#echo "1[$1]"
#echo "2[$2]"
#echo "pwd[$PWD]"
#echo "STDOUT:$stdout"
echo "STDIN:$stdin"
return 0
6 changes: 6 additions & 0 deletions opt/cs50/lib/help50/ls.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
echo "argv:[$argv]"
echo "stdout[$stdout]"
echo "1[$1]"
echo "2[$2]"
echo "pwd[$PWD]"
return 0
42 changes: 42 additions & 0 deletions opt/cs50/lib/help50/make.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
local output=$(cat)

local regex="make: Nothing to be done for '(.*)'"
if [[ "$output" =~ $regex ]]; then

# If target is a directory
if [[ -d "$1" ]]; then
echo "Cannot run ${bold}make${normal} on a directory. Did you mean to ${bold}cd ${1}${normal} first?"
return
fi

# If target ends with .c
if [[ "$1" == *?.c ]]; then
base="${1%.c}"
if [[ -n "$base" && ! -d "$base" ]]; then
echo "Did you mean to ${bold}make ${base}${normal}?"
return
fi
fi

fi

local regex="No rule to make target '(.*)'"
if [[ "$output" =~ $regex ]]; then

# If no .c file for target
local c="$1.c"
if [[ ! -f "$c" ]]; then

# Search recursively for .c file
paths=$(find * -name "$c" 2> /dev/null)
lines=$(echo "$paths" | grep -c .)
echo -n "There isn't a file called ${bold}${c}${normal} in your current directory."
if [[ "$lines" -eq 1 ]]; then # If unambiguous
d=$(dirname "$paths")
echo " Did you mean to ${bold}cd ${d}${normal} first?"
else
echo
fi
return
fi
fi
1 change: 1 addition & 0 deletions tests/bar.c
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
int main(void) {}
Empty file added tests/foo/baz.c
Empty file.

0 comments on commit e7781bf

Please sign in to comment.