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 zcmd1j<>g{vU|^W^BR7eck%8ech=Yuo7#J8F7#J9e%@`OMQW#Pga~Pr+!8B7YGZOPnQNG8n6sH`S!!5{JxW*>u%@uq zu%t1juz|$Wm=?06u$QncU|+~k#!#$V!m@y)hG`*Vkx>cD0!|Psk1>TE%w}H5n8GoK zNsOVEHH9;UtA;g`QH-IMt%R$DWdU~$+d{@>#wNxT1{Q`|mRjZ%hF}IwZojG|{iMu1 z{iMX=3DM#FW$`YlUcqgp}0eoW!D31zk6V8in#?1>Kwk z1>Mv_g@n}fqSOMA&bYMFyyTM1{JaUBTkJ)tCCT|IshUht%mtMOAi}tc zFR{2dwWtKF$W*f!BxtJ1bBigz_!etHenD#9EtaCx#FSgC$vOGOskgWs3Mxxdi%a4Y zi*5-r{j6sEki4&CDsu%qzadmXn{Hm{WX9BEC2yzceQW ztTaA7CqF4MCq6GRH}w{0d~sr0D#(Oee2!p;Waj6&78T_e-4c#Z%P-1JEQwF8D9B07 zO9X|5CVLc9TE;E5{L+$w(vl)j!ieGqSqbrk5i-XR!hslKg3K{n$xtN9z`*d!SU)2_ zH&x#yu_)UuHL)ZkwMf6XC|N%=FEc$SzeFG8&tfnc4~oy6%p|>n%3A^;VX#1aW^O@# zQ3(quX>u?yFbFVmFmf=~Fcyh3FfeFx-r|4-L=hhY1H&!Jcu3IcK^&WzpQl%pT3(b{ zl6s31E(D4suviff0|P@5$kg{vU|=Zxlbdvffq~&Mh=Yuo7#J8F7#J9e%@`OMQW#Pga~Pr+!8B7YGZOUi%485@sO3!&ND-{z1*_sK;VEHRz+1z&kg=Jui7|zN zg`t*>g`t+2g`t*}g`t*(g`t+CmOX_bm_bv>ugWMbGcQHKBR@a8SV6a>vLICRxW$%OP>`CJa*HoMEx#x?u_QhzKR+kG;1-`F*om3>d9Fo8`9-&cVe+XJ1v!a% zi6xo&d7AuDOlcWKYzzzxMXU@A3{l)5cR>7Rh|DoT<`^S$45Gkphw3pz;Tb>_LfmDB z%&~x|gUA>fqwq{ocxEU(i>%+J#+N-ZzSEJ?k^2^RvTJFr+0Hz+tkrN%8bh(55fV0R-C cVjz<_Y;yBcN^?@}K&h%26c0)a9E?0n01N?Wl>h($ 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 zcmd1j<>g{vU|@L5keAfY%)sy%#6iYP3=9ko3=9m#ehdr@DGVu$ISf&ZV45kHnTdgs zA(thJl@TJt7R3gZVUJ=@VM<|cVTj^LVM$?aVTj^PVM}3eVTj^N;Yi_ZVTj^RVGL%_ zTSc*MLSQfCRu-34oF{ZGA#M77-vZSz=uq|L;$WX>mtXsme zfTM$HIq?{p_Z+LtAu3%cMaP@ z#%9JQ#uNq?hFX?d<`jlt22F0iswDlS%sl<1#NrGE-DCyz;{4L0rflFaOh#g>zwoS0L5OCr8FBfm5!1*|kaJtsdYF(*DRF*o%VXMAyDS}Mqd zTYQdShh*mGxfT`W7u^z$Ps=aLO)QB|ttiMz%u57?#Y*;DOlcXn*z!wD3Q9|gxEUB2 zqPRg;LOfw~3yEV0k%1Uu0+E4m%vLfKDKaoH{4&f z56#O=&&e;*2l=xYOvY#C7UUO|6zdgK-Vy)_$AcmmD#`*%nj8!a3<8WCj2w(Lj77=} z3=Al#Sb%|n0i*()ienfFr{Z)5P>QN$sbQ*N$!4l$tzoTYt6?qDDq+ZCsb#NW&tk3R zNMWtztl_BPY-X(Gs^O|-t6?ji14`E^Y&EQDj4A9Oz2MZ&QNpo+6P(%|OV}20fzo)9 zTM63&ZV)SvF@*!nW?9IX!U<08+$mfs+%??b)Xr1Gynv^MXCWgaLk(+DdkRkqFWj^Y zkZC0h3mJ=YK_-A$d5kH%Aa)J=LPjvn0i`*iG}l7L6uvpEVhpvsV3T=4CYP`+;H_a! z;a|v<$sop1%asl1xudR?y8?0L4|YezIPEX^Dcfeol^FMiDau149ug&WczW7#OO!k(3mH z;s};`j1ZZ}RI?bI)>blsvWHO-A1Lv#gR+%5B*&QlN&@i=%{7a;s$nbzNX|1fh6@^l zj0ER2LqoWrAzaW>vskYnu_S}5Rxh(SEi)&Tt5ySSn5ky5CRc3{C>5<_1v$Yoilv~^ z&=5=-gGtj{AQAH-Mv&9^A=v?JlaYaDF-XqHV5I=qgd#yu00@ByVFm_$}K)v-b~8R&&e++k^-raW?*1gDNrN}V#|RD zQ1&d62kAq~me8CCaiK9JTS7PnkkSLfF*Jw*mnBf15em-)g=bcz0Jj5@!7U&rK{$pM z5YxuJ%|`I#e$SUMbyz#EVuwdHUpe&i`3vj zt`1^pf(R`Tp$#HHX{SgB!~&&|B7G3c07Mvq2s01?DiV=GLI~uBc!;Z@!2veJ4y4u| zJrF>3Gzf!AxFS#^0aO<%q6R`yu7Yk*8q|kcAm5|=4dN3}fP?c}5f8{NUJwDwaz*?g zmJEnMb1OJV;)_yq^UG4>^Gi#L!HHJ|q!QFv(d4 + /// 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