...
 
Commits (4)
SlackBuilds.org related stuff
* maintainer-status -- Using public info, list all the maintainers
of SlackBuilds.org with links to their Repology pages, last commit
date, etc.
* reports -- Various SBo status reports (e.g. problems, maintainers)
* review -- Review, approve and push SlackBuilds.org submissions
* changelog-parser -- Parse a Slackware-style ChangeLog.txt and output it
as JSON
* hooks -- git hooks for SlackBuilds.org git committers
#!/bin/sh
#
# An example hook script to check the commit log message.
# Called by git-commit with one argument, the name of the file
# that has the commit message. The hook should exit with non-zero
# status after issuing an appropriate message if it wants to stop the
# commit. The hook is allowed to edit the commit message file.
#
# To enable this hook, rename this file to "commit-msg".
# Uncomment the below to add a Signed-off-by line to the message.
# Doing this in a hook is a bad idea in general, but the prepare-commit-msg
# hook is more suited to it.
#
# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"
# This example catches duplicate Signed-off-by lines.
# test "" = "$(grep '^Signed-off-by: ' "$1" |
# sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || {
# echo >&2 Duplicate Signed-off-by lines.
# exit 1
# }
msg=$(sed "/^#/d" "$1")
test $(echo "$msg" | wc -L | cut -d " " -f 1) -lt 69 ||
{
echo "Line length of commit message exceeded 68 characters!"
exit 1
}
if [ "$(echo "$msg" | wc -l | cut -d " " -f 1)" -ge "2" ]; then
test "$(echo "$msg" | sed -n "2p")" = "" ||
{
echo "Line number 2 not empty!"
exit 1
}
fi
#!/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".
# if git-rev-parse --verify HEAD >/dev/null 2>&1
# then
# against=HEAD
# else
# # Initial commit: diff against an empty tree object
# against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
# fi
#
# # If you want to allow non-ascii filenames set this variable to true.
# allownonascii=$(git config 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')"
# then
# echo "Error: Attempt to add a non-ascii file name."
# echo
# echo "This can cause problems if you want to work"
# echo "with people on other platforms."
# echo
# echo "To be portable it is advisable to rename the file ..."
# echo
# echo "If you know what you are doing you can disable this"
# echo "check using:"
# echo
# echo " git config hooks.allownonascii true"
# echo
# exit 1
# fi
#
# exec git diff-index --check --cached $against --
ERROR="no"
FILES=$(git diff-index --cached --name-only HEAD)
HAS_INFO=$(git diff-index --cached --name-only HEAD | grep "\.info")
if ! [ -z "$FILES" ]; then
for i in $FILES; do
if [ -e $i ]; then
MODE=$(stat -c "%a" "$i")
if ! [ $MODE = "644" ]; then
echo "$i has wrong mode set ($MODE instead of 644)"
ERROR="yes"
fi
fi
done
fi
if [ "$ERROR" = "yes" ]; then
echo "Exit"
exit 1
fi
#exit 1
#!/bin/sh
#
# An example hook script to prepare the commit log message.
# Called by "git commit" with the name of the file that has the
# commit message, followed by the description of the commit
# message's source. The hook's purpose is to edit the commit
# message file. If the hook fails with a non-zero status,
# the commit is aborted.
#
# To enable this hook, rename this file to "prepare-commit-msg".
# This hook includes three examples. The first comments out the
# "Conflicts:" part of a merge commit.
#
# The second includes the output of "git diff --name-status -r"
# into the message, just before the "git status" output. It is
# commented because it doesn't cope with --amend or with squashed
# commits.
#
# The third example adds a Signed-off-by line to the message, that can
# still be edited. This is rarely a good idea.
#case "$2,$3" in
# merge,)
# /usr/bin/perl -i.bak -ne 's/^/# /, s/^# #/#/ if /^Conflicts/ .. /#/; print' "$1" ;;
# ,|template,)
# /usr/bin/perl -i.bak -pe '
# print "\n" . `git diff --cached --name-status -r`
# if /^#/ && $first++ == 0' "$1" ;;
# *) ;;
#esac
SOB=$(git var GIT_COMMITTER_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
grep -qs "^$SOB" "$1" || echo -e "\n$SOB" >> "$1"
#!/usr/bin/python3
#-----------------------------------------------------------------------
# maintainer_status
# maintainers
#
# Format a HTML report of SBo maintainers and their activity status
# David Spencer 2018-05-28
# WTFPL, if anybody is worried
#
# Usage: maintainer_status [/path/to/git/repo] > reportname.html
# Usage: maintainers [/path/to/git/repo] > reportname.html
#
# Don't run this too often, because it hammers the Repology API for
# maybe twenty minutes. Repology results may be empty or incomplete due
......@@ -312,7 +312,7 @@ for mname, mdeets in maintainerinfo.items():
# (3) Render the template and print the results.
jenv = jinja2.Environment(loader=jinja2.FileSystemLoader('templates'),autoescape=None)
rtemplate = jenv.get_template('maintainer-report.jinja2')
rtemplate = jenv.get_template('maintainers.jinja2')
print(
rtemplate.render(
maintainerinfo=maintainerinfo,
......
#!/usr/bin/python3
#-----------------------------------------------------------------------
# problems
#
# Format a HTML report of problems according to Repology
# David Spencer 2018-08-05
# WTFPL, if anybody is worried
#
# Usage: problems [/path/to/git/repo] > reportname.html
#
# Requires: python3, and the following (all built with python3 support)
# python-requests
# python-chardet
# idna
# python-certifi
# Jinja2
# MarkupSafe
#
#-----------------------------------------------------------------------
import sys
import os
import glob
import subprocess
import re
import json
import collections
import datetime
import urllib
# external modules
import requests
import jinja2
#-----------------------------------------------------------------------
# Find the repo
if len(sys.argv) >= 2:
repopath=sys.argv[1]
else:
repopath=os.path.expanduser("~/slackbuilds")
def find_catnam(prgnam):
matches=glob.glob(repopath+"/*/"+prgnam)
if len(matches) == 0:
return "Unknown"
elif len(matches) == 1:
return matches[0].split("/")[-2]
else:
return "Ambiguous"
def get_cp(prob):
return prob["catnam"]+"/"+prob["prgnam"]
#-----------------------------------------------------------------------
def repologyproblems(repo):
# Get a list of problems from the Repology API for the specified repo
# Return a list of dicts:
# {"catnam":"SBo category", "prgnam":"SBo prgnam", "problem":"problem text"}
repologyAPI="https://repology.org/api/v1/repository/{:s}/problems".format(repo)
problist=[]
# does this return chunks?
probchunk=requests.get(repologyAPI).json()
if len(probchunk) == 0:
return None
problist.extend(probchunk)
problems=[]
for p in problist:
prgnam=p["name"]
catnam=find_catnam(prgnam)
problem=p["problem"]
maintainer=p["maintainer"]
problems.append({"catnam": catnam, "prgnam": prgnam, "problem": problem, "maintainer": maintainer})
return sorted(problems,key=get_cp)
#-----------------------------------------------------------------------
report_title="SBo Problems"
report_datetime=datetime.datetime.now().strftime("%Y-%m-%d %T")
Problems = repologyproblems('slackbuilds')
#-----------------------------------------------------------------------
jenv = jinja2.Environment(loader=jinja2.FileSystemLoader('templates'),autoescape=None)
rtemplate = jenv.get_template('problems.jinja2')
print(
rtemplate.render(
problems=Problems,
report_title=report_title,
report_datetime=report_datetime,
stats_problems=len(Problems)
)
)
#-----------------------------------------------------------------------
# Finished!
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>{{ report_title }}</title>
<style>
table {border:1px solid;border-collapse:collapse}
.c {text-align:left; padding:0.5rem; border:1px solid; font-size:small}
.p {text-align:left; padding:0.5rem; border:1px solid; font-size:small}
.x {text-align:left; padding:0.5rem; border:1px solid; font-size:small}
.e {text-align:left; padding:0.5rem; border:1px solid; font-size:small}
</style>
<script src="sorttable.js"></script>
</head>
<body>
<h1>{{ report_title }}</h1>
<p>Report generated: {{ report_datetime }}
<br>Problems: {{ "{:d}".format(stats_problems) }}
</p>
<table class="sortable">
<thead>
<tr>
<th class="c"><a href="#!">catnam</a></th>
<th class="p"><a href="#!">prgnam</a></th>
<th class="x"><a href="#!">problem</a></th>
<th class="e"><a href="#!">maintainer</a></th>
</tr>
</thead>
<tbody>
{% for p in problems %}
<tr id="{{ p['catnam']+'/'+p['prgnam'] }}">
<td class="c">{{ p['catnam'] }}</td>
<td class="p">{{ p['prgnam'] }}</td>
<td class="x">{{ p['problem'] }}</td>
<td class="x">{{ p['maintainer'] }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</body>
</html>