From f034d627a60eb01557b25c6206e89e9210220623 Mon Sep 17 00:00:00 2001 From: DarkFeather Date: Sat, 30 Apr 2022 23:14:56 -0500 Subject: [PATCH] Starting to use Uniglot for hooks standardization. --- .gitignore | 2 + Bash/header | 13 +++-- Hooks/pre-commit | 18 ++++++ Hooks/pre-receive | 17 ++++++ Hooks/scripts.d/nonascii | 30 ++++++++++ Hooks/scripts.d/pytest | 8 +++ Hooks/scripts.d/stop-foxtrots | 20 +++++++ Hooks/scripts.d/whitespace | 23 ++++++++ Makefile | 10 ++-- PKGBUILD | 2 +- bin/uniglot-clone | 53 ++++++++++++++++++ .../test_bashlib.cpython-310-pytest-7.1.2.pyc | Bin 0 -> 950 bytes .../test_hooks.cpython-310-pytest-7.1.2.pyc | Bin 0 -> 1265 bytes .../test_imports.cpython-310-pytest-7.1.2.pyc | Bin 0 -> 2415 bytes tests/test.csharp | 15 +++++ tests/test_hooks.py | 8 +++ tests/test_imports.py | 26 +++++++++ 17 files changed, 234 insertions(+), 11 deletions(-) create mode 100755 Hooks/pre-commit create mode 100755 Hooks/pre-receive create mode 100755 Hooks/scripts.d/nonascii create mode 100755 Hooks/scripts.d/pytest create mode 100755 Hooks/scripts.d/stop-foxtrots create mode 100755 Hooks/scripts.d/whitespace create mode 100755 bin/uniglot-clone create mode 100644 tests/__pycache__/test_bashlib.cpython-310-pytest-7.1.2.pyc create mode 100644 tests/__pycache__/test_hooks.cpython-310-pytest-7.1.2.pyc create mode 100644 tests/__pycache__/test_imports.cpython-310-pytest-7.1.2.pyc create mode 100644 tests/test.csharp create mode 100644 tests/test_hooks.py create mode 100644 tests/test_imports.py diff --git a/.gitignore b/.gitignore index d5fbbf8..78b9616 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ pkg/ src/ *.tar.xz +*.tar.zst +tests/*.out diff --git a/Bash/header b/Bash/header index 0d7c300..065cc3d 100644 --- a/Bash/header +++ b/Bash/header @@ -250,17 +250,18 @@ function getmagnetlink { fi } -### AniNIX Foundation help ### +### AniNIX/Foundation help ### function findaninixcheckouts { - find /usr/local/src/ -type f -name config -exec egrep -l 'url[[:space:]]=[[:space:]]/srv/foundation|url[[:space:]]=[[:space:]]https://aninix.net|url[[:space:]]=[[:space:]]([a-zA-Z0-9])+@aninix.net' {} \; 2>/dev/null | sed 's#.git/config$##' + ### Find git checkouts in $pwd that are from AniNIX/Foundation + find . -type f -name config -exec egrep -l 'url[[:space:]]=[[:space:]]/srv/foundation|url[[:space:]]=[[:space:]]https://(foundation.)aninix.net|url[[:space:]]=[[:space:]]([a-zA-Z0-9])+@(foundation.)aninix.net' {} \; 2>/dev/null | sed 's#.git/config$##' } function aninixgitstatus { for i in `findaninixcheckouts`; do - infoheader BEGIN REPORT for "$i" - git -C "$i" status - infoheader END REPORT - echo + status="$(git -C "$i" status)" + if [ -n "$status" ]; then + echo "$i" has work in flight. + fi done } diff --git a/Hooks/pre-commit b/Hooks/pre-commit new file mode 100755 index 0000000..b36ea79 --- /dev/null +++ b/Hooks/pre-commit @@ -0,0 +1,18 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed. +# Called by "git commit" with no arguments. The hook should +# exit with non-zero status after issuing an appropriate message if +# it wants to stop the commit. +# +# To enable this hook, rename this file to "pre-commit". + +# Run all our checking scripts. +for script in $(find `dirname "$0"`/scripts.d -type f); do + "$script" + if [ $? -ne 0 ]; then + echo "$script" failed checks. + exit 1; + fi +done +echo "Pre-commit checks passed." diff --git a/Hooks/pre-receive b/Hooks/pre-receive new file mode 100755 index 0000000..c66fc9a --- /dev/null +++ b/Hooks/pre-receive @@ -0,0 +1,17 @@ +#!/bin/bash + +# Check each commit +while read oldrev newrev refname; do + + # Thanks to https://blog.developer.atlassian.com/stop-foxtrots-now/ for the inspiration + if [ "$refname" == "refs/heads/main" ]; then + match=`git log --first-parent --pretty='%H %P' $oldrev..$newrev | + grep $oldrev | + awk '{ print $2 }'` + if [ "$oldrev" != "$match" ]; then + echo "Foxtrot detected. Please `git rebase origin/main`." + exit 1 + fi + fi + +done diff --git a/Hooks/scripts.d/nonascii b/Hooks/scripts.d/nonascii new file mode 100755 index 0000000..e8bd335 --- /dev/null +++ b/Hooks/scripts.d/nonascii @@ -0,0 +1,30 @@ +#!/bin/bash + +# Sourced from https://github.com/git/git/blob/master/templates/hooks--pre-commit.sample + +# If you want to allow non-ASCII filenames set this variable to true. +allownonascii=$(git config --bool hooks.allownonascii) + +# Cross platform projects tend to avoid non-ASCII filenames; prevent +# them from being added to the repository. We exploit the fact that the +# printable range starts at the space character and ends with tilde. +if [ "$allownonascii" != "true" ] && + # Note that the use of brackets around a tr range is ok here, (it's + # even required, for portability to Solaris 10's /usr/bin/tr), since + # the square bracket bytes happen to fall in the designated range. + test $(git diff --cached --name-only --diff-filter=A -z $against | + LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0 +then + cat <<\EOF +Error: Attempt to add a non-ASCII file name. + +This can cause problems if you want to work with people on other platforms. + +To be portable it is advisable to rename the file. + +If you know what you are doing you can disable this check using: + + git config hooks.allownonascii true +EOF + exit 1 +fi diff --git a/Hooks/scripts.d/pytest b/Hooks/scripts.d/pytest new file mode 100755 index 0000000..b8c6062 --- /dev/null +++ b/Hooks/scripts.d/pytest @@ -0,0 +1,8 @@ +#!/bin/bash + +# Run python3 tests + +if [ -d venv ]; then + source venv/bin/activate +fi +python3 -m pytest diff --git a/Hooks/scripts.d/stop-foxtrots b/Hooks/scripts.d/stop-foxtrots new file mode 100755 index 0000000..09bb25e --- /dev/null +++ b/Hooks/scripts.d/stop-foxtrots @@ -0,0 +1,20 @@ +#!/bin/bash + +# Borrowing from https://github.com/syncier/pre-commit-hooks-jumanjihouse/blob/master/pre_commit_hooks/protect-first-parent + +# Find the correct reference, or fallback to HEAD's abbrev-ref +base="$( + git rev-parse --abbrev-ref --symbolic-full-name '@{upstream}' 2>/dev/null \ + || git branch -avv | awk '/->/ {print $NF}' 2>/dev/null \ + || : +)" +if [ -z "$base" ]; then base="$(git rev-parse --abbrev-ref HEAD)"; fi + +firstParent="$(git show-ref -s "${base}")" + +if git rev-list --first-parent "${base}^".. | grep -q "^${firstParent}$"; then + exit 0 +else + echo Foxtrot detected -- please either rebase or '`git reset --soft`' to recreate your commit. + exit 1 +fi diff --git a/Hooks/scripts.d/whitespace b/Hooks/scripts.d/whitespace new file mode 100755 index 0000000..afe00b5 --- /dev/null +++ b/Hooks/scripts.d/whitespace @@ -0,0 +1,23 @@ +#!/bin/bash + +# Sourced from https://github.com/git/git/blob/master/templates/hooks--pre-commit.sample + +if egrep -irl '\s\+$' .; then + echo The above lines have trailing whitespace. Run "sed -i 's/\s\+$//'" on the affected files. + exit 1 +fi + +if git rev-parse --verify HEAD >/dev/null 2>&1 +then + against=HEAD +else + # Initial commit: diff against an empty tree object + against=$(git hash-object -t tree /dev/null) +fi + +# Redirect output to stderr. +exec 1>&2 + + +# If there are whitespace errors, print the offending file names and fail. +exec git diff-index --check --cached $against -- diff --git a/Makefile b/Makefile index c9b8c58..4e61442 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ installdir = ${pkgdir}/opt/aninix/Uniglot/ -targets = Bash C CSharp +targets = Bash C CSharp Hooks compile: @echo Nothing to compile. @@ -7,6 +7,8 @@ compile: install: compile mkdir -p ${installdir} for target in ${targets}; do rsync -avzzl "$$target" ${installdir}; done + mkdir -p ${pkgdir}/usr/local/bin + install -m 0755 -o root -g root bin/uniglot-clone ${pkgdir}/usr/local/bin make checkperm clean: @@ -16,11 +18,11 @@ uninstall: rm -Rf ${installdir} test: - @echo Nothing to do. + python3 -m pytest checkperm: - chmod -R 0755 ${installdir} - chown root:root ${installdir} + chmod -R 0755 ${installdir} ${pkgdir}/usr/local/bin/uniglot-clone + chown root:root ${installdir} ${pkgdir}/usr/local/bin/uniglot-clone diff: ${INSTALLFIR} diff -rc . ${installdir} diff --git a/PKGBUILD b/PKGBUILD index 735f131..98f7d94 100644 --- a/PKGBUILD +++ b/PKGBUILD @@ -1,5 +1,5 @@ depends=('bash>=4.4') -makedepends=('make>=4.2') +makedepends=('make>=4.2','gcc','mono') checkdepends=() optdepends=() pkgname="$(git config remote.origin.url | rev | cut -f 1 -d '/' | rev | sed 's/.git$//')" diff --git a/bin/uniglot-clone b/bin/uniglot-clone new file mode 100755 index 0000000..661a135 --- /dev/null +++ b/bin/uniglot-clone @@ -0,0 +1,53 @@ +#!/bin/bash + +# File: uniglot-clone +# +# Description: This is a convenience script to ensure our hooks are standardized. +# +# Package: AniNIX/Uniglot +# Copyright: WTFPL +# +# Author: DarkFeather + +function uniglotClone() { + target="$1" + git-clone "$target" + clone="$(basename "$1" | sed 's/.git$//')" + cd "$clone" +} + + +### usage +### param retcode: what to return +function usage() { + retcode="$1" + echo "Usage: $0 # Update the current clone" + echo " $0 -t target # Clone the target and set hooks" + echo " $0 -h # Help" + echo Add -v for verbosity. +} + +### Main +if [ `basename "$0"` == "uniglot-clone" ]; then + while getopts 'ht:v' OPTION; do + case "$OPTION" in + h) echo AniNIX/Uniglot git-clone standardization; usage 0 ;; + t) target="$OPTARG" ;; + v) set -x ;; + *) usage 1 ;; + esac + done + + # Sanity + if [ ! -d .git ]; then + echo "This should be run from the root of the clone." + exit 2 + fi + + # Standardizations + if git config remote.origin.url | grep -q AniNIX/Uniglot; then + git config core.hooksPath $PWD/Hooks + else + git config core.hooksPath /opt/aninix/Uniglot/Hooks + fi +fi diff --git a/tests/__pycache__/test_bashlib.cpython-310-pytest-7.1.2.pyc b/tests/__pycache__/test_bashlib.cpython-310-pytest-7.1.2.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4d54c8e0263cd7ff8953d85adecd6b2885a93808 GIT binary patch literal 950 zcmYjQJ#W-77`B~UF1=o>0;0ecAtA_c4Yafi94cQGQy0V%K5|Ly>xCw9upLUP+ybmD z%pH0of5|IT{{iX(uX8FoM}GW%=Y8Hdd}XDFVEz14Br6!9-$q$n1e9IaatDASigOg= z_9TTx5JrU^cJSQegih<}hFwai^&N#S#jlZXpF=L%PYqtKE(m5nhb>P56#9rMHhI+k zVNFqk&d3Z+F`O2hgrcd{kj6SBQ@gR{D`lT`Xs5Bqm^#KjCNrCMm2=jeq0dMT!0$F> zhQ%gGOGYX&_>FAMFm+GKI+}Lq674me41?^b9(b1m5#2cjEUCC>aGVdAa!Gy(>iAUaBZ$w#|$AWo-J+JYOQg4utyaD^^W{E3R2te8|$ zEcBHqjq^N$hDFMY3i#+gxTB=ba+Q@*J2{64sc%Md!t0#2q0vFklQ@scxPZh{fR^i`9gQK#DYYQ)bYk3Jg!#Vr0H&o+TUAv0iKG8$*;8 z6&K1jSJMSp!!A4x7B@igm$Z912(bzVeJh%eZe!jo(Af~|NMs7e@ZV%UQfm`^$PuQj hcIJ6)*|zZoST_OgW4H!&&Yr-ZiKGK?8@aeo{s9q*7U=*0 literal 0 HcmV?d00001 diff --git a/tests/__pycache__/test_hooks.cpython-310-pytest-7.1.2.pyc b/tests/__pycache__/test_hooks.cpython-310-pytest-7.1.2.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9e7be56d56b8d0a00644e4828f4ba51ebf061292 GIT binary patch literal 1265 zcmY*ZNsk;g6t-P!?^#5ETLlS;I?VL+WVQ$z1p!e`xgahjM5(6jo^DN5yRfTCx^W#y z_zj#mbRGFWoP6b!zYrnBvnvyNTzb#%d&}qNMa2h$E`ssXKgH!=F#m19{vZIJfXFjY z6j7X`1lySu4nY_dZsOrK;wQe11W7;%b$&xhNbz?lcHclPdOkDyW{kiHK)wc%&oDw2 z+F^uUIh#T8&Fb)174^Z8qA?>Kn5`*1U&aSJv z4aNx8{Pi7w2>e~Mw&m}==U-TU*o7!8Cs@GWvvvUdeaqjY13FYa%ip*BeZvn~J>}3* zLzW0u9?(1Vt{T{^VbzD|Kn)xG8oz?`cTw$wI3ON~3li1=MR3~po^Oxm%N32DaeghM zgKATgb2hBNeeL!OG~z1M%YE4O}JCD8_HebQrx5oi5D#IxIJOWY6Ei)Vwkmc%=EQba4pZzxW7= z4*|v<9o}4p7=S~6oVJ&D*zOVz?ohB7Vp+jOymy&*XMLgvHNyNgwBOcQTHE)YdSDX5 VFA7fAIs4MQDrxTF6BOb;`40>MXq5l} literal 0 HcmV?d00001 diff --git a/tests/__pycache__/test_imports.cpython-310-pytest-7.1.2.pyc b/tests/__pycache__/test_imports.cpython-310-pytest-7.1.2.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c007c7b7ac402109b3615eead42d3a9f9ef59c11 GIT binary patch literal 2415 zcmai0OLyBu6dt{0`H?h*((+UbC3PTn?DQ2NrKQlrVUYzrY)nCsHFE4$w#1Cw(jaXp z=dj}N2eOEl{!7}j>Vj2wSpfIWD8cDD9Gs(X?wxye=b`VLNnEcx1b%;#N&k0^kU!8_ z{HfsFhKKI}P(qc6^c2ymV@)Lr8S6bmkrA_Jiip*-s7ke8NYAD^HK46flUmR^)TR|^ zt5ms9n$B~mNp=FnnfoMg*P~r`J^aDl4fj}>;G5qMrjsBY#ghl_;@i9KcdLcM zp8pNMxmxJsn1)5AKOGE0Hk$0sl_Pa~d#>!ST)vV#-Dq-md)q~Gv&jpKg=ql!bG4^I z5MlGE;d36cR3u%4Ba8l?D=3N*;6!WlfZYNLEkf)x{iZfo|N0A2; zWBt7DpI|@DDL}_H}S_XbC3HlbEr@>?ud!N zioakiX2n@=5VNtLdf|^rHBu9^DK5bQrQWXF>a$$q43{wsDLn~ zdv&Cy4X~`(@Rup2g4M;n( zP*yjjVs0Gu(d&Tg{B&%&Qh6PaUfBuOacAeG6Rfgxs|f@H8ajDv#0R4&bn+{r7>wU^ za)vCL8#slno(`jR1a1nvR$$K!2HYY?OADIr!XbdM?#6ssRA6Tyg{>f*1%Ma~S(tJ} z_6qjDif|6$HH7mB7XS*=PvAtLMdMhT{Wy-|guRX#Zvem;Z=wA*0?L!U1F$H|Qi*bg zn~RYRd3wl5XQL<1lG5v*@~)opt~2*!3@PxNvXXQ1$vdaG>Kf{itLcANnkjth|qAd#x3SzLK$+ zR`#sE%vf;%@wUvz8iKa$eHdA8`6^mXgf)Z@5Rg0ULj+_9Ya?tRbP%p1;E}kn6Dx8j z#H`Bg5Jhfb+NS`gHevCeX82D6-h~%WZvq>;>t7Gb6|UjTUtXJB32wMtNe!(!0!of8 zA-sw3(p=@4%))W}IP{<{7vy~pGj9VlYlVG$DG6Q|7d&~5wIsjbYH6|X2^*zwC7pEP zg(>=^Dsc6MDc=)Eyr6>E3NgyUq{Q?DpX^WIhMq>@E!=jF>$ybWmQZceHf!cT!xnz| literal 0 HcmV?d00001 diff --git a/tests/test.csharp b/tests/test.csharp new file mode 100644 index 0000000..e083e7b --- /dev/null +++ b/tests/test.csharp @@ -0,0 +1,15 @@ +using AniNIX.Shared; + +namespace AniNIX.Uniglot { + + /// Test class + public class Test { + + /// + /// The default function + /// + static int Main(string[] args) { + return 0; + } + } +} diff --git a/tests/test_hooks.py b/tests/test_hooks.py new file mode 100644 index 0000000..e2edb2a --- /dev/null +++ b/tests/test_hooks.py @@ -0,0 +1,8 @@ +import os +import pytest + +def test_hooks_exec(): + fh = os.popen("find Hooks -type f -exec ls -l {} \\; | egrep ^-rw-") + output = fh.read() + retcode = fh.close() + assert retcode == 256 and output == '' diff --git a/tests/test_imports.py b/tests/test_imports.py new file mode 100644 index 0000000..b61b290 --- /dev/null +++ b/tests/test_imports.py @@ -0,0 +1,26 @@ +import os +import pytest + +def test_bash_import(): + fh = os.popen("/bin/bash -c 'source Bash/header; [ `declare -F | wc -l` -eq `egrep -c ^function\\ Bash/header` ]'", mode='r', buffering=-1) + output = fh.read() + retcode = fh.close() + assert retcode == None + +def test_c_import(): + fh = os.popen("gcc -o tests/c.out C/ll.h", mode='r', buffering=-1) + output = fh.read() + retcode = fh.close() + assert retcode == None and os.path.isfile('tests/c.out') + +def test_csharp_import(): + fh = os.popen("/bin/bash -c 'mcs -out:tests/csharp.out CSharp/*.csharp tests/test.csharp'", mode='r', buffering=-1) + output = fh.read() + retcode = fh.close() + assert retcode == None and os.path.isfile('tests/csharp.out') + +def test_remove_outs(): + fh = os.popen("/bin/bash -c 'rm -Rf tests/*.out'", mode='r', buffering=-1) + output = fh.read() + retcode = fh.close() + assert retcode == None