Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds new version of help50 #210

Open
wants to merge 83 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 59 commits
Commits
Show all changes
83 commits
Select commit Hold shift + click to select a range
e7781bf
added helpers for make
dmalan Jan 5, 2024
1f25bf5
tidying helper framework
dmalan Jan 5, 2024
f92afe5
using functions instead of aliases
dmalan Jan 6, 2024
5470fcf
removed support for exit statuses, supporting any executable helper
dmalan Jan 6, 2024
c4b6fbe
added PIPESTATUS for helpers
dmalan Jan 6, 2024
8ee1e52
removed PIPESTATUS
dmalan Jan 6, 2024
b003947
removed test file
dmalan Jan 6, 2024
9279b1d
added _helpful, _helpless
dmalan Jan 6, 2024
26e431d
removed, updated wrappers
dmalan Jan 6, 2024
a0783ce
updated formatting
dmalan Jan 6, 2024
cadd890
added _help function to standardize formatting
dmalan Jan 6, 2024
3041bf9
added on/off
dmalan Jan 6, 2024
a3c55b3
added icon to _help
dmalan Jan 9, 2024
7f315ae
WIP
dmalan Jan 17, 2024
5c70d23
WIP
dmalan Jan 17, 2024
36c860c
WIP
dmalan Jan 18, 2024
22a873b
WIP
dmalan Jan 18, 2024
bbaa372
WIP
dmalan Jan 18, 2024
b1b2360
checking for ctl-z
dmalan Jan 18, 2024
bd215bc
checking parent dirs
dmalan Jan 18, 2024
a69df22
added _find helper
dmalan Jan 18, 2024
ebaec05
renamed helper
dmalan Jan 18, 2024
bba678c
added helper
dmalan Jan 18, 2024
1a38952
added helper
dmalan Jan 18, 2024
501a59d
added helpers
dmalan Jan 19, 2024
d96a3d5
Merge pull request #201 from cs50/main
dmalan Jan 27, 2024
bc67d10
Merge branch 'main' into help50
dmalan Jan 31, 2024
383f4a2
tidied formatting, filesystem
dmalan Jan 31, 2024
72c3d53
capping size of help50 input
dmalan Jan 31, 2024
eb6647d
improved non-greedy matching
dmalan Feb 2, 2024
26facb7
added helper for .c
dmalan Feb 2, 2024
45cb7f3
use arm64 github runner for building arm image
rongxin-liu Apr 28, 2024
372761f
build amd64 and arm64 docker images concurrently
rongxin-liu Apr 28, 2024
b9a5ee3
create canary build
rongxin-liu Apr 28, 2024
2919d87
updated workflow actions versions
rongxin-liu Apr 28, 2024
f5b22c4
added comments
rongxin-liu Apr 28, 2024
d3a6a9c
Merge pull request #209 from cs50/arm64-runner
rongxin-liu Apr 28, 2024
fe13454
updated actions/github-script to version v7
rongxin-liu May 2, 2024
8556c53
WIP
dmalan May 6, 2024
5f11fef
WIP
dmalan May 6, 2024
a91969f
WIP2
dmalan May 7, 2024
73601b9
WIP2
dmalan May 7, 2024
d6fc53a
WIP3
dmalan May 7, 2024
0c96044
WIP4
dmalan May 7, 2024
72dd67f
WIP5
dmalan May 8, 2024
d5a938c
WIP6
dmalan May 8, 2024
f96d245
WIP7
dmalan May 8, 2024
4b19fc4
added WORKDIR
dmalan May 8, 2024
2801456
WIP7
dmalan May 8, 2024
35dd708
WIP8
dmalan May 8, 2024
29ddbfd
removed Makefile check
dmalan May 8, 2024
2ec2530
WIP8
dmalan May 8, 2024
db691ca
WIP
dmalan May 9, 2024
1b88177
WIP
dmalan May 9, 2024
16154b3
Merge branch 'main' into help50
dmalan May 9, 2024
9e77045
removed TAG from Makefile
dmalan May 9, 2024
6aa50ee
removed hardcoding of typescript path
dmalan May 9, 2024
3eae3bd
omitting dot directories
dmalan May 9, 2024
e43789b
added helpers
dmalan May 9, 2024
f2b776a
removed ls helper
dmalan May 10, 2024
7a6c051
handling lack of -type in _find
dmalan May 10, 2024
7c3c7db
improved, documented Python helpers
dmalan May 10, 2024
f5cffb7
removed break from CLI library
dmalan May 13, 2024
42c2a85
added _trap
dmalan May 13, 2024
f6e2329
added helper for "syntax error near unexpected token"
dmalan May 18, 2024
2051c45
merged in main
dmalan Jun 24, 2024
3192a87
added detection of backslash
dmalan Jun 24, 2024
aa21d92
detecting miscapitalized commands
dmalan Jul 2, 2024
52bce67
passing $1, $2, etc. to helpers now
dmalan Jul 3, 2024
1fdf4a5
added helper for, e.g., "check 50"
dmalan Jul 3, 2024
fb3c69d
fixed _sure
dmalan Aug 11, 2024
6baca23
installing file command
dmalan Aug 11, 2024
bbd4820
improved DEBUG trap
dmalan Aug 11, 2024
84d7819
added Python helper
dmalan Aug 11, 2024
21148f6
removed DEBUG trap
dmalan Aug 12, 2024
50b0adc
removed check for executable in ./
dmalan Aug 12, 2024
3f09407
added _fold
dmalan Aug 14, 2024
56d8fb7
style
dmalan Aug 15, 2024
3e9ca9e
WIP
dmalan Oct 5, 2024
852ad29
Merge branch 'main' into help50
dmalan Oct 5, 2024
be19810
merged
dmalan Oct 5, 2024
8b8ae78
WIP
dmalan Oct 5, 2024
c6fe70f
WIP
dmalan Oct 6, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 73 additions & 12 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
on: push

jobs:
build:
build-amd64:
runs-on: ubuntu-latest-64-cores
steps:
- name: Set up QEMU
uses: docker/setup-qemu-action@v2

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
uses: docker/setup-buildx-action@v3

- name: Log into Docker Hub
uses: docker/login-action@v2
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
Expand All @@ -21,14 +19,16 @@ jobs:
python-version: '3.11'

- name: Build for linux/amd64
uses: docker/build-push-action@v3
uses: docker/build-push-action@v5
with:
build-args: |
VCS_REF=${{ github.sha }}
BUILDARCH=amd64
load: true
platforms: linux/amd64
tags: cs50/cli:amd64
tags: |
cs50/cli:amd64
cs50/cli:canary-amd64
cache-from: type=registry,ref=cs50/cli:amd64-buildcache
cache-to: type=registry,ref=cs50/cli:amd64-buildcache,mode=max

Expand All @@ -37,15 +37,55 @@ jobs:
run: |
docker push cs50/cli:amd64
- name: Push linux/amd64 build to Docker Hub (canary)
run: |
docker push cs50/cli:canary-amd64
build-arm64:
runs-on: ubuntu-latest-64-cores-arm
steps:
- name: Install Docker (remove once Docker is pre-installed on arm64 runners)
run: |
export DEBIAN_FRONTEND=noninteractive
sudo apt update
sudo apt install -y ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo usermod -aG docker $USER
sudo apt install -y acl
sudo setfacl --modify user:$USER:rw /var/run/docker.sock
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Log into Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Install Python (replace with setup-python once available on arm64 runners)
run: |
sudo apt install -y python3
- name: Build for linux/arm64
uses: docker/build-push-action@v3
uses: docker/build-push-action@v5
with:
build-args: |
VCS_REF=${{ github.sha }}
BUILDARCH=arm64
load: true
platforms: linux/arm64
tags: cs50/cli:arm64
tags: |
cs50/cli:arm64
cs50/cli:canary-arm64
cache-from: type=registry,ref=cs50/cli:arm64-buildcache
cache-to: type=registry,ref=cs50/cli:arm64-buildcache,mode=max

Expand All @@ -54,6 +94,20 @@ jobs:
run: |
docker push cs50/cli:arm64
- name: Push linux/arm64 build to Docker Hub (canary)
run: |
docker push cs50/cli:canary-arm64
finalize:
needs: [build-amd64, build-arm64]
runs-on: ubuntu-latest
steps:
- name: Log into Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Create multi-arch manifest and push to Docker Hub
if: ${{ github.ref == 'refs/heads/main' }}
run: |
Expand All @@ -62,9 +116,16 @@ jobs:
--amend cs50/cli:arm64
docker manifest push cs50/cli:latest
- name: Create multi-arch manifest and push to Docker Hub (canary)
run: |
docker manifest create cs50/cli:canary \
--amend cs50/cli:canary-amd64 \
--amend cs50/cli:canary-arm64
docker manifest push cs50/cli:canary
- name: Re-deploy depdendents
if: ${{ github.ref == 'refs/heads/main' }}
uses: actions/github-script@v6
uses: actions/github-script@v7
with:
github-token: ${{ secrets.DEPLOY50_PAT }}
script: |
Expand All @@ -78,4 +139,4 @@ jobs:
workflow_id: 'main.yml',
ref: 'main'
});
}
}
3 changes: 2 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -171,11 +171,13 @@ RUN apt update && \
build-essential `# dpkg-dev, libc, gcc, g++, make, etc.`\
ca-certificates \
clang \
colorized-logs `# For help50` \
coreutils `# For fold` \
cowsay \
curl \
dos2unix \
dnsutils `# For nslookup` \
expect `# For help50` \
fonts-noto-color-emoji `# For render50` \
gdb \
git \
Expand Down Expand Up @@ -243,7 +245,6 @@ RUN pip3 install --no-cache-dir \
cs50 \
Flask \
Flask-Session \
help50 \
pytest \
render50 \
setuptools \
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ rebuild:
docker build --build-arg VCS_REF=$(shell git rev-parse HEAD) --no-cache --tag $(IMAGE) .

run:
docker run --env LANG=$(LANG) --env LOCAL_WORKSPACE_FOLDER="$(PWD)" --interactive --publish-all --rm --security-opt seccomp=unconfined --tty --volume "$(PWD)":/mnt --volume /var/run/docker.sock:/var/run/docker-host.sock --workdir /mnt $(IMAGE) bash --login || true
docker run --env LANG=$(LANG) --env LOCAL_WORKSPACE_FOLDER="$(PWD)" --env WORKDIR=/mnt --interactive --publish-all --rm --security-opt seccomp=unconfined --tty --volume "$(PWD)":/mnt --volume /var/run/docker.sock:/var/run/docker-host.sock --workdir /mnt cs50/cli bash --login || true

squash: depends
docker-squash --tag $(IMAGE) $(IMAGE)
7 changes: 6 additions & 1 deletion etc/profile.d/cli.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# If not root
if [ "$(whoami)" != "root" ]; then
if [ `id -u` -ne 0 ]; then

# $PATH
export PATH="/opt/cs50/bin":"/opt/bin":"$PATH"
Expand Down Expand Up @@ -60,4 +60,9 @@ if [ "$(whoami)" != "root" ]; then

# Valgrind
export VALGRIND_OPTS="--memcheck:leak-check=full --memcheck:show-leak-kinds=all --memcheck:track-origins=yes"

## TODO: Start help50 if enabled
# if help50 is-enabled > /dev/null; then
# help50 start
# fi
fi
114 changes: 114 additions & 0 deletions etc/profile.d/help50.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
# If not started
if [[ -z "$HELP50" ]]; then
return
fi

# Directory with helpers
HELPERS="/opt/cs50/lib/help50"

# Library
. /opt/cs50/lib/cli

# Ignore duplicates (but not commands that begin with spaces)
export HISTCONTROL="ignoredups"

function _help50() {

# Get exit status of last command
local status=$?

# Get last command line, independent of user's actual history
histfile=$(mktemp)
HISTFILE=$histfile history -a
local argv=$(HISTFILE=$histfile history 1 | cut -c 8-) # Could technically contain multiple commands, separated by ; or &&
rm --force $histfile

# Remove aliases
for name in n no y yes; do
unalias $name 2> /dev/null
done

# If last command erred (and is not ctl-c or ctl-z)
# https://tldp.org/LDP/abs/html/exitcodes.html
if [[ $status -ne 0 && $status -ne 130 && $status -ne 148 ]]; then

# Ignore ./* if executable file
local argv0=$(echo "$argv" | awk '{print $1}') # Assume for simplicity it's just a single command
if [[ "$argv0" =~ ^\./ && -f "$argv0" && -x "$argv0" ]]; then
break
fi

# Read typescript from disk
local typescript=$(cat $HELP50)

# Remove script's own output (if this is user's first command)
typescript=$(echo "$typescript" | sed '1{/^Script started on .*/d}')

# Cap typescript at MIN(1K lines, 1M bytes), else `read` is slow
typescript=$(echo "$typescript" | head -n 1024 | cut -b 1-1048576)

# Remove any line continuations from command line
local lines=""
while IFS= read -r line || [[ -n "$line" ]]; do
if [[ -z $done && $line =~ \\$ ]]; then
lines+="${line%\\}"
else
lines+="$line"$'\n'
local done=1
fi
done <<< "$typescript"
typescript="$lines"

# Remove command line from typescript
typescript=$(echo "$typescript" | sed '1d')

# Remove ANSI characters
typescript=$(echo "$typescript" | ansi2txt)

# Remove control characters
# https://superuser.com/a/237154
typescript=$(echo "$typescript" | col -bp)

# Try to get help
for helper in $HELPERS/*; do
if [[ -f $helper && -x $helper ]]; then
local help=$($helper <<< "$typescript")
if [[ -n "$help" ]]; then
break
fi
fi
done
if [[ -n "$help" ]]; then # If helpful
_helpful "$help"
elif [[ $status -ne 0 ]]; then # If helpless
_helpless "$typescript"
fi
fi

# Truncate typescript
truncate -s 0 $HELP50
}

function _question() {
_alert "That was a rhetorical question. :)"
}

# Default helpers
if ! type _helpful >/dev/null 2>&1; then
function _helpful() {

# Intercept accidental invocation of `yes` and `n`, which are actual programs
for name in n no y yes; do
alias $name=_question
done

# Output help
local output=$(_ansi "$1")
_alert "$output"
}
fi
if ! type _helpless >/dev/null 2>&1; then
function _helpless() { :; } # Silent
fi

export PROMPT_COMMAND=_help50
Loading