#!/bin/bash # SPDX-License-Identifier: LGPL-3.0-or-later # See Notices.txt for copyright information set -e export ANTLR4_TOOLS_ANTLR_VERSION=4.13.2 cd "$(dirname $0)/.." pip -q --require-virtualenv install \ antlr4-python3-runtime=="$ANTLR4_TOOLS_ANTLR_VERSION" \ antlr4-tools==0.2.2 (cd takentaal; antlr4 -Dlanguage=Python3 -o takentaal takentaal.g4) cat <<'EOF' > takentaal/takentaal/__main__.py from antlr4 import * from antlr4.error.ErrorListener import ErrorListener from .takentaalLexer import takentaalLexer from .takentaalParser import takentaalParser import sys class MyErrorListener(ErrorListener): def __init__(self, filename): self.filename = filename def syntaxError(self, recognizer, offendingSymbol, line, column, msg, e): print(f"{self.filename}:{line}:{column} {msg}", file=sys.stderr) def main(): filename = sys.argv[2] parser = takentaalParser(CommonTokenStream(takentaalLexer( FileStream(filename, encoding="utf-8")))) parser.removeErrorListeners() parser.addErrorListener(MyErrorListener(filename)) getattr(parser, sys.argv[1])() if parser.getNumberOfSyntaxErrors() > 0: sys.exit(1) main() EOF touch takentaal/takentaal/__init__.py function check_plan() { python3 -m takentaal.takentaal takentaal_v1_0 "$1" } function check_amendment() { python3 -m takentaal.takentaal amendment_v1_0 "$1" } function check_progress() ( set -E filename="$1" mapfile -t lines < "$filename" function next_line() { eof=$((++line_index >= ${#lines[@]})) line="${lines[line_index]}" } line_index=-1 function diag() { local msg_line_index kind="$1" if [[ "$2" =~ ^"-line_index="([0-9]+)$ ]]; then ((msg_line_index = ${BASH_REMATCH[1]})) shift else ((msg_line_index = line_index)) fi shift echo "$filename:$((msg_line_index + 1)): $kind $@" >&2 } function error() { diag "error:" "$@" >&2 exit 1 } any_errors=0 function nonfatal_error() { diag "error:" "$@" any_errors=1 } trap error ERR next_line function match_lines() { for regex in "$@"; do eval '[[ "$line" =~ '"$regex"' ]]' || error "expected $regex" next_line done } function skip_until_item() { local missing="$1" until [[ "$line" =~ ^[[:space:]]*[-#] ]]; do if ((eof)); then [[ -z "$missing" ]] || error "missing $missing" return fi next_line done } [[ "$filename" =~ (^|'/')'nlnet-'('template'|2[0-9][0-9][0-9]-[0-9][0-9]-[0-9]+)'/progress.md'$ ]] || error "bad filename" nlnet_id="${BASH_REMATCH[2]}" [[ "$nlnet_id" != "template" ]] || nlnet_id="YYYY-MM-ID" match_lines \ "^''$" \ "^'# NLnet $nlnet_id Grant Progress'$" \ "^$" skip_until_item "top level grant header" [[ "$line" =~ ^"# € "([0-9]+)" "[^[:space:]] ]] || error "expected: # € " ((grant_amount = ${BASH_REMATCH[1]})) ((grant_line_index = line_index)) tasks_total=0 next_line skip_until_item "first task" until ((eof)); do [[ "$line" =~ ^"## € "([0-9]+)" "[^[:space:]] ]] || error "expected: ## € " ((task_amount = ${BASH_REMATCH[1]})) ((tasks_total += task_amount)) ((task_line_index = line_index)) next_line skip_until_item subtasks_total=0 until ((eof)); do subtask_expected="expected: - € [Issue #](https://git.libre-chip.org/libre-chip/grant-tracking/issues/) " [[ "$line" =~ ^([#-]+)" € "([0-9]+)" "[^[:space:]] ]] || error "$subtask_expected" [[ "${BASH_REMATCH[1]}" =~ ^[^'#'] ]] || break [[ "$line" =~ ^"- € "([0-9]+)" [Issue #"([0-9]+|"N")"](https://git.libre-chip.org/libre-chip/grant-tracking/issues"('/'([0-9]*|"N"))?") "[^[:space:]] ]] || \ error "$subtask_expected" ((subtask_amount = ${BASH_REMATCH[1]})) ((subtasks_total += subtask_amount)) issue_number="${BASH_REMATCH[2]}" issue_number2="${BASH_REMATCH[4]}" [[ "$issue_number" != "N" ]] || [[ "$nlnet_id" = "YYYY-MM-ID" ]] || nonfatal_error "issue number must be set" [[ ( "$issue_number" = "N" && -z "$issue_number2" ) || "$issue_number" = "$issue_number2" ]] || \ nonfatal_error "issue number in link name must match issue number in url" next_line skip_until_item done (( subtasks_total == task_amount )) || \ nonfatal_error -line_index="$task_line_index" "task's amount ($task_amount) doesn't match sum of subtasks' amounts ($subtasks_total)" done (( tasks_total == grant_amount )) || \ nonfatal_error -line_index="$grant_line_index" "grant's amount ($grant_amount) doesn't match sum of tasks' amounts ($tasks_total)" ((eof)) || error "extra tokens" exit $any_errors ) any_errors=0 for nlnet_dir in nlnet-*/; do for file in "${nlnet_dir}"*; do case "${file##*/}" in plan.txt) check_plan "$file" || any_errors=1 ;; plan-amendment-*.txt) check_amendment "$file" || any_errors=1 ;; progress.md) check_progress "$file" || any_errors=1 ;; *) echo "unknown file: $file" >&2 any_errors=1 esac done done exit $any_errors